00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
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
00080
00081
00085 public P2PNodeManager() {
00086
00087 }
00088
00089
00090
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
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
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
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
00184 if (this.descriptorPath == null) {
00185 this.proactiveRuntime.killNode(nodeUrl);
00186 logger.info("Node @" + nodeUrl + " left");
00187
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
00219
00220
00224 public void initActivity(Body body) {
00225 logger.debug("Entering initActivity");
00226
00227 try {
00228
00229 this.p2pServiceNode = NodeFactory.getNode(body.getNodeURL());
00230
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
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
00267
00268
00275 private Node createNewNode()
00276 throws NodeException, ProActiveException, AlreadyBoundException {
00277
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
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
00311 if (new Boolean(System.getProperty(PROPERTY_NO_SHARING)).booleanValue()) {
00312 nodes = 0;
00313 }
00314
00315
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
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
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 }