org/objectweb/proactive/p2p/service/node/P2PNodeManager.java

00001 /* 
00002  * ################################################################
00003  * 
00004  * ProActive: The Java(TM) library for Parallel, Distributed, 
00005  *            Concurrent computing with Security and Mobility
00006  * 
00007  * Copyright (C) 1997-2007 INRIA/University of Nice-Sophia Antipolis
00008  * Contact: proactive@objectweb.org
00009  * 
00010  * This library is free software; you can redistribute it and/or
00011  * modify it under the terms of the GNU Lesser General Public
00012  * License as published by the Free Software Foundation; either
00013  * version 2.1 of the License, or any later version.
00014  *  
00015  * This library is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018  * Lesser General Public License for more details.
00019  * 
00020  * You should have received a copy of the GNU Lesser General Public
00021  * License along with this library; if not, write to the Free Software
00022  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
00023  * USA
00024  *  
00025  *  Initial developer(s):               The ProActive Team
00026  *                        http://www.inria.fr/oasis/ProActive/contacts.html
00027  *  Contributor(s): 
00028  * 
00029  * ################################################################
00030  */ 
00031 package org.objectweb.proactive.p2p.service.node;
00032 
00033 import java.io.IOException;
00034 import java.io.Serializable;
00035 import java.rmi.AlreadyBoundException;
00036 import java.util.Iterator;
00037 import java.util.Vector;
00038 
00039 import org.apache.log4j.Logger;
00040 import org.objectweb.proactive.Body;
00041 import org.objectweb.proactive.EndActive;
00042 import org.objectweb.proactive.InitActive;
00043 import org.objectweb.proactive.ProActive;
00044 import org.objectweb.proactive.ProActiveInternalObject;
00045 import org.objectweb.proactive.core.ProActiveException;
00046 import org.objectweb.proactive.core.body.AbstractBody;
00047 import org.objectweb.proactive.core.descriptor.data.ProActiveDescriptor;
00048 import org.objectweb.proactive.core.descriptor.data.VirtualNode;
00049 import org.objectweb.proactive.core.node.Node;
00050 import org.objectweb.proactive.core.node.NodeException;
00051 import org.objectweb.proactive.core.node.NodeFactory;
00052 import org.objectweb.proactive.core.runtime.ProActiveRuntime;
00053 import org.objectweb.proactive.core.util.log.Loggers;
00054 import org.objectweb.proactive.core.util.log.ProActiveLogger;
00055 import org.objectweb.proactive.ext.security.ProActiveSecurityManager;
00056 import org.objectweb.proactive.ext.security.exceptions.SecurityNotAvailableException;
00057 import org.objectweb.proactive.p2p.service.util.P2PConstants;
00058 
00059 
00065 public class P2PNodeManager implements Serializable, InitActive, EndActive,
00066     P2PConstants, ProActiveInternalObject {
00067     private static final Logger logger = ProActiveLogger.getLogger(Loggers.P2P_NODES);
00068     private static final int PROC = Runtime.getRuntime().availableProcessors();
00069     private Node p2pServiceNode = null;
00070     private ProActiveRuntime proactiveRuntime = null;
00071     private Vector<Node> availbaleNodes = new Vector<Node>();
00072     private Vector<Object> bookedNodes = new Vector<Object>();
00073     private Vector usingNodes = new Vector();
00074     private int nodeCounter = 0;
00075     private final String descriptorPath = System.getProperty(PROPERPY_XML_PATH);
00076     private ProActiveDescriptor pad = null;
00077 
00078     //--------------------------------------------------------------------------
00079     // Class Constructors
00080     //--------------------------------------------------------------------------
00081 
00085     public P2PNodeManager() {
00086         // The empty constructor
00087     }
00088 
00089     //--------------------------------------------------------------------------
00090     // Public Class methods
00091     // -------------------------------------------------------------------------
00092 
00098     public P2PNode askingNode(String nodeFamilyRegexp) {
00099         logger.debug("Asking a node to the nodes manager");
00100         if ((nodeFamilyRegexp == null) || (nodeFamilyRegexp.length() == 0) ||
00101                 System.getProperty("os.name").matches(nodeFamilyRegexp)) {
00102             logger.debug("Family Match");
00103             if ((this.availbaleNodes.size() == 0) &&
00104                     (this.bookedNodes.size() == 0) &&
00105                     (this.usingNodes.size() == 0)) {
00106                 this.deployingDefaultSharedNodes();
00107             }
00108             if (this.availbaleNodes.size() > 0) {
00109                 Node node = this.availbaleNodes.remove(0);
00110                 this.bookedNodes.add(new Booking(node));
00111                 logger.debug("Yes the manager has a node");
00112                 return new P2PNode(node,
00113                     (P2PNodeManager) ProActive.getStubOnThis());
00114             }
00115         }
00116 
00117         // All nodes is already assigned
00118         logger.debug("Sorry no availbale node for the moment");
00119         return new P2PNode(null, null);
00120     }
00121 
00122     public Vector<Node> askingAllNodes(String nodeFamilyRegexp) {
00123         logger.debug("Asking all nodes to the nodes manager");
00124         if ((nodeFamilyRegexp == null) || (nodeFamilyRegexp.length() == 0) ||
00125                 System.getProperty("os.name").matches(nodeFamilyRegexp)) {
00126             logger.debug("Family Match");
00127             if ((this.availbaleNodes.size() == 0) &&
00128                     (this.bookedNodes.size() == 0) &&
00129                     (this.usingNodes.size() == 0)) {
00130                 this.deployingDefaultSharedNodes();
00131             }
00132             if (this.availbaleNodes.size() > 0) {
00133                 Vector<Node> allNodes = new Vector<Node>(this.availbaleNodes);
00134                 this.availbaleNodes.removeAllElements();
00135                 this.bookedNodes.addAll(allNodes);
00136                 logger.debug("Yes the manager has some nodes");
00137                 return allNodes;
00138             }
00139         }
00140 
00141         // All nodes is already assigned
00142         logger.debug("Sorry no availbale node for the moment");
00143         return new Vector<Node>();
00144     }
00145 
00146     public P2PNode askingNode(boolean evenIfItIsShared) {
00147         if (!evenIfItIsShared) {
00148             return askingNode(null);
00149         }
00150         logger.debug("Asking a node to the nodes manager");
00151         if ((this.availbaleNodes.size() == 0) &&
00152                 (this.bookedNodes.size() == 0) &&
00153                 (this.usingNodes.size() == 0)) {
00154             this.deployingDefaultSharedNodes();
00155         }
00156         if (this.availbaleNodes.size() > 0) {
00157             Node node = this.availbaleNodes.remove(0);
00158             this.bookedNodes.add(new Booking(node));
00159             logger.debug("Yes, the manager has an empty node");
00160             return new P2PNode(node, (P2PNodeManager) ProActive.getStubOnThis());
00161         } else if (this.bookedNodes.size() > 0) {
00162             Node node = ((Booking) this.bookedNodes.get(0)).getNode();
00163             logger.debug("Yes, the manager has a shared node");
00164             return new P2PNode(node, (P2PNodeManager) ProActive.getStubOnThis());
00165         } else {
00166             // All nodes is already assigned
00167             logger.debug("Sorry no availbale node for the moment");
00168             return new P2PNode(null, null);
00169         }
00170     }
00171 
00178     public void leaveNode(Node nodeToFree, String vnName) {
00179         String nodeUrl = nodeToFree.getNodeInformation().getURL();
00180         logger.debug("LeaveNode message received for node @" + nodeUrl);
00181         this.usingNodes.remove(nodeToFree);
00182         try {
00183             // Kill the node
00184             if (this.descriptorPath == null) {
00185                 this.proactiveRuntime.killNode(nodeUrl);
00186                 logger.info("Node @" + nodeUrl + " left");
00187                 // Creating a new node
00188                 this.createNewNode();
00189             } else {
00190                 this.availbaleNodes.add(nodeToFree);
00191             }
00192         } catch (Exception e) {
00193             logger.fatal("Coudln't delete or create a shared node", e);
00194         }
00195     }
00196 
00201     public void noMoreNodeNeeded(Node givenNode) {
00202         Iterator<Object> it = this.bookedNodes.iterator();
00203         while (it.hasNext()) {
00204             Booking current = (Booking) it.next();
00205             if (current.getNode().equals(givenNode)) {
00206                 this.bookedNodes.remove(current);
00207                 break;
00208             }
00209         }
00210         this.availbaleNodes.add(givenNode);
00211         if (logger.isInfoEnabled()) {
00212             logger.info("Booked node " +
00213                 givenNode.getNodeInformation().getURL() + " is now shared");
00214         }
00215     }
00216 
00217     //--------------------------------------------------------------------------
00218     // Active Object methods
00219     //--------------------------------------------------------------------------
00220 
00224     public void initActivity(Body body) {
00225         logger.debug("Entering initActivity");
00226 
00227         try {
00228             // Getting reference to the P2P node
00229             this.p2pServiceNode = NodeFactory.getNode(body.getNodeURL());
00230             // Getting ProActive runtime
00231             this.proactiveRuntime = this.p2pServiceNode.getProActiveRuntime();
00232         } catch (NodeException e) {
00233             logger.fatal("Couldn't get reference to the local p2pServiceNode", e);
00234         }
00235         if (logger.isDebugEnabled()) {
00236             logger.debug("P2P node manager is running at " +
00237                 this.p2pServiceNode.getNodeInformation().getURL());
00238             logger.debug("ProActiveRuntime at " +
00239                 this.proactiveRuntime.getURL());
00240         }
00241 
00242         // Creating shared nodes
00243         if (this.descriptorPath == null) {
00244             this.deployingDefaultSharedNodes();
00245         } else {
00246             this.deployingXmlSharedNodes();
00247         }
00248 
00249         logger.debug("Exiting initActivity");
00250     }
00251 
00255     public void endActivity(Body body) {
00256         if (this.pad != null) {
00257             try {
00258                 this.pad.killall(false);
00259             } catch (ProActiveException e) {
00260                 logger.warn("Couldn't kill deployed nodes", e);
00261             }
00262         }
00263     }
00264 
00265     // -------------------------------------------------------------------------
00266     // Private class method
00267     // -------------------------------------------------------------------------
00268 
00275     private Node createNewNode()
00276         throws NodeException, ProActiveException, AlreadyBoundException {
00277         // security 
00278         ProActiveSecurityManager newNodeSecurityManager = null;
00279 
00280         try {
00281             newNodeSecurityManager = ((AbstractBody) ProActive.getBodyOnThis()).getProActiveSecurityManager()
00282                                       .generateSiblingCertificate(P2PConstants.VN_NAME);
00283         } catch (IOException e) {
00284             e.printStackTrace();
00285         } catch (SecurityNotAvailableException e) {
00286             // well nothing to do except maybe log it
00287             ProActiveLogger.getLogger(Loggers.SECURITY_NODE).debug("Node created without security manager");
00288         }
00289 
00290         Node newNode = NodeFactory.createNode(P2PConstants.SHARED_NODE_NAME +
00291                 "_" + this.nodeCounter++, true, newNodeSecurityManager,
00292                 P2PConstants.VN_NAME);
00293         this.availbaleNodes.add(newNode);
00294         logger.info("New shared node created @" +
00295             newNode.getNodeInformation().getURL());
00296         return newNode;
00297     }
00298 
00302     private void deployingDefaultSharedNodes() {
00303         assert PROC > 0 : "Processor count = 0";
00304         logger.debug("Number of available processors for this JVM: " + PROC);
00305         int nodes = PROC;
00306         if (!new Boolean(System.getProperty(PROPERTY_MULTI_PROC_NODES)).booleanValue()) {
00307             nodes = 1;
00308         }
00309 
00310         // No sharing enable
00311         if (new Boolean(System.getProperty(PROPERTY_NO_SHARING)).booleanValue()) {
00312             nodes = 0;
00313         }
00314 
00315         // Starting default shared nodes
00316         for (int procNumber = 0; procNumber < nodes; procNumber++) {
00317             try {
00318                 Node node = this.createNewNode();
00319                 logger.debug("Default shared node succefuly created at: " +
00320                     node.getNodeInformation().getURL());
00321             } catch (Exception e) {
00322                 logger.warn("Couldn't create default shared node", e);
00323             }
00324         }
00325         logger.info(nodes + " shared nodes deployed");
00326     }
00327 
00331     private void deployingXmlSharedNodes() {
00332         try {
00333             this.pad = ProActive.getProactiveDescriptor(this.descriptorPath);
00334         } catch (ProActiveException e) {
00335             logger.fatal("Could't get ProActive Descripor at " +
00336                 this.descriptorPath, e);
00337             return;
00338         }
00339         VirtualNode[] virtualNodes = this.pad.getVirtualNodes();
00340         this.pad.activateMappings();
00341         for (int i = 0; i < virtualNodes.length; i++) {
00342             VirtualNode currentVn = virtualNodes[i];
00343             Node[] nodes;
00344             try {
00345                 nodes = currentVn.getNodes();
00346                 for (int j = 0; j < nodes.length; j++) {
00347                     this.availbaleNodes.add(nodes[j]);
00348                 }
00349             } catch (NodeException e) {
00350                 logger.warn("Problem with nodes for " + currentVn.getName(), e);
00351             }
00352         }
00353 
00354         // Killing deployed nodes at the JVM shutdown
00355         XmlNodeKiller killer = new XmlNodeKiller(pad);
00356         Runtime.getRuntime().addShutdownHook(new Thread(killer));
00357 
00358         logger.info(this.availbaleNodes.size() + " shared nodes deployed");
00359     }
00360 
00361     // -------------------------------------------------------------------------
00362     // Inner class
00363     // -------------------------------------------------------------------------
00364 
00373     private class Booking {
00374         private Node node = null;
00375 
00380         public Booking(Node node) {
00381             this.node = node;
00382         }
00383 
00387         public Node getNode() {
00388             return this.node;
00389         }
00390     }
00391 }

Generated on Mon Jan 22 15:16:11 2007 for ProActive by  doxygen 1.5.1