org/objectweb/proactive/core/runtime/rmi/RmiProActiveRuntimeImpl.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.core.runtime.rmi;
00032 
00033 import java.io.IOException;
00034 import java.lang.reflect.InvocationTargetException;
00035 import java.net.UnknownHostException;
00036 import java.rmi.AccessException;
00037 import java.rmi.ConnectException;
00038 import java.rmi.RemoteException;
00039 import java.rmi.server.RMIClientSocketFactory;
00040 import java.rmi.server.RMIServerSocketFactory;
00041 import java.rmi.server.UnicastRemoteObject;
00042 import java.security.PublicKey;
00043 import java.security.cert.X509Certificate;
00044 import java.util.ArrayList;
00045 
00046 import org.objectweb.proactive.Body;
00047 import org.objectweb.proactive.core.Constants;
00048 import org.objectweb.proactive.core.ProActiveException;
00049 import org.objectweb.proactive.core.body.UniversalBody;
00050 import org.objectweb.proactive.core.body.ft.checkpointing.Checkpoint;
00051 import org.objectweb.proactive.core.descriptor.data.ProActiveDescriptor;
00052 import org.objectweb.proactive.core.descriptor.data.VirtualNode;
00053 import org.objectweb.proactive.core.mop.ConstructorCall;
00054 import org.objectweb.proactive.core.mop.ConstructorCallExecutionFailedException;
00055 import org.objectweb.proactive.core.node.NodeException;
00056 import org.objectweb.proactive.core.process.ExternalProcess;
00057 import org.objectweb.proactive.core.process.UniversalProcess;
00058 import org.objectweb.proactive.core.rmi.RegistryHelper;
00059 import org.objectweb.proactive.core.runtime.ProActiveRuntime;
00060 import org.objectweb.proactive.core.runtime.ProActiveRuntimeImpl;
00061 import org.objectweb.proactive.core.runtime.VMInformation;
00062 import org.objectweb.proactive.core.util.UrlBuilder;
00063 import org.objectweb.proactive.ext.security.Communication;
00064 import org.objectweb.proactive.ext.security.ProActiveSecurityManager;
00065 import org.objectweb.proactive.ext.security.SecurityContext;
00066 import org.objectweb.proactive.ext.security.crypto.KeyExchangeException;
00067 import org.objectweb.proactive.ext.security.exceptions.RenegotiateSessionException;
00068 import org.objectweb.proactive.ext.security.exceptions.SecurityNotAvailableException;
00069 import org.objectweb.proactive.ext.security.securityentity.Entity;
00070 
00071 
00078 public class RmiProActiveRuntimeImpl extends UnicastRemoteObject
00079     implements RmiProActiveRuntime {
00080     //attemps to register when having an AlreadyBoundException
00081     private static final int NUMBER_OF_REGISTER_ATTEMPTS = 2;
00082 
00083     //  In few methods this field is cast into a ProActiveRuntimeImpl
00084     // First because we are sure that it is an instance of such object
00085     // and it avoids throwing an exception
00086     protected transient ProActiveRuntime proActiveRuntime;
00087     protected String proActiveRuntimeURL;
00088 
00089     //stores nodes urls to be able to unregister nodes
00090     private ArrayList<String> nodesArray;
00091 
00092     //store vn urls to be able to unregister vns
00093     private ArrayList<String> vnNodesArray;
00094     private boolean hasCreatedRegistry;
00095 
00096     public RmiProActiveRuntimeImpl()
00097         throws java.rmi.RemoteException, java.rmi.AlreadyBoundException {
00098         construct();
00099     }
00100 
00101     public RmiProActiveRuntimeImpl(RMIClientSocketFactory csf,
00102         RMIServerSocketFactory ssf)
00103         throws java.rmi.RemoteException, java.rmi.AlreadyBoundException {
00104         super(0, csf, ssf);
00105         construct();
00106     }
00107 
00108     public RmiProActiveRuntimeImpl(boolean isJini)
00109         throws java.rmi.RemoteException {
00110     }
00111 
00112     //  
00113     // -- CONSTRUCTORS -----------------------------------------------
00114     //
00115     private void construct() throws java.rmi.RemoteException {
00116         //System.out.println("toto");
00117         this.hasCreatedRegistry = RegistryHelper.getRegistryCreator();
00118 
00119         int registerAttempts = NUMBER_OF_REGISTER_ATTEMPTS;
00120 
00121         while (registerAttempts > 0) {
00122             try {
00123                 this.proActiveRuntime = ProActiveRuntimeImpl.getProActiveRuntime();
00124             } catch (ExceptionInInitializerError e) {
00125                 e.printStackTrace();
00126                 throw e;
00127             }
00128 
00129             this.nodesArray = new java.util.ArrayList<String>();
00130             this.vnNodesArray = new java.util.ArrayList<String>();
00131 
00132             //this.urlBuilder = new UrlBuilder();
00133             this.proActiveRuntimeURL = buildRuntimeURL();
00134 
00135             try {
00136                 //java.rmi.Naming.bind(proActiveRuntimeURL, this);
00137                 register(proActiveRuntimeURL, false);
00138                 registerAttempts = 0; //registration was ok
00139             } catch (java.rmi.AlreadyBoundException e) {
00140                 registerAttempts--;
00141             }
00142         }
00143 
00144         //System.out.println ("ProActiveRuntime successfully bound in registry at "+proActiveRuntimeURL);
00145     }
00146 
00147     //
00148     // -- PUBLIC METHODS -----------------------------------------------
00149     //
00150     public ExternalProcess getProcessToDeploy(
00151         ProActiveRuntime proActiveRuntimeDist, String creatorID, String vmName,
00152         String padURL) throws ProActiveException, IOException {
00153         return proActiveRuntime.getProcessToDeploy(proActiveRuntimeDist,
00154             creatorID, vmName, padURL);
00155     }
00156 
00157     public String createLocalNode(String nodeName,
00158         boolean replacePreviousBinding,
00159         ProActiveSecurityManager securityManager, String VNname, String jobId)
00160         throws NodeException, RemoteException, java.rmi.AlreadyBoundException {
00161         String nodeURL = null;
00162 
00163         //Node node;
00164         try {
00165             //first we build a well-formed url
00166             nodeURL = buildNodeURL(nodeName);
00167 
00168             //then take the name of the node
00169             String name = UrlBuilder.getNameFromUrl(nodeURL);
00170 
00171             //register the url in rmi registry
00172             register(nodeURL, replacePreviousBinding);
00173 
00174             proActiveRuntime.createLocalNode(name, replacePreviousBinding,
00175                 securityManager, VNname, jobId);
00176         } catch (java.net.UnknownHostException e) {
00177             throw new java.rmi.RemoteException("Host unknown in " + nodeURL, e);
00178         }
00179 
00180         nodesArray.add(nodeURL);
00181 
00182         return nodeURL;
00183     }
00184 
00185     public void killAllNodes() throws RemoteException, ProActiveException {
00186         for (int i = 0; i < nodesArray.size(); i++) {
00187             String url = nodesArray.get(i);
00188             killNode(url);
00189         }
00190 
00191         proActiveRuntime.killAllNodes();
00192     }
00193 
00194     public void killNode(String nodeName)
00195         throws RemoteException, ProActiveException {
00196         String nodeUrl = null;
00197         String name = null;
00198 
00199         try {
00200             nodeUrl = buildNodeURL(nodeName);
00201             name = UrlBuilder.getNameFromUrl(nodeUrl);
00202             unregister(nodeUrl);
00203         } catch (UnknownHostException e) {
00204             throw new java.rmi.RemoteException("Host unknown in " + nodeUrl, e);
00205         }
00206 
00207         proActiveRuntime.killNode(name);
00208     }
00209 
00210     public void createVM(UniversalProcess remoteProcess)
00211         throws IOException, ProActiveException {
00212         proActiveRuntime.createVM(remoteProcess);
00213     }
00214 
00215     public String[] getLocalNodeNames()
00216         throws RemoteException, ProActiveException {
00217         return proActiveRuntime.getLocalNodeNames();
00218     }
00219 
00220     public VMInformation getVMInformation() {
00221         //we can cast because for sure the runtime is a runtimeImpl
00222         // and we avoid throwing an exception
00223         return ((ProActiveRuntimeImpl) proActiveRuntime).getVMInformation();
00224     }
00225 
00226     public void register(ProActiveRuntime proActiveRuntimeDist,
00227         String proActiveRuntimeName, String creatorID, String creationProtocol,
00228         String vmName) throws RemoteException, ProActiveException {
00229         proActiveRuntime.register(proActiveRuntimeDist, proActiveRuntimeName,
00230             creatorID, creationProtocol, vmName);
00231     }
00232 
00237     public void unregister(ProActiveRuntime proActiveRuntimeDist,
00238         String proActiveRuntimeName, String creatorID, String creationProtocol,
00239         String vmName) throws RemoteException, ProActiveException {
00240         this.proActiveRuntime.unregister(proActiveRuntimeDist,
00241             proActiveRuntimeURL, creatorID, creationProtocol, vmName);
00242     }
00243 
00244     public ProActiveRuntime[] getProActiveRuntimes()
00245         throws RemoteException, ProActiveException {
00246         return proActiveRuntime.getProActiveRuntimes();
00247     }
00248 
00249     public ProActiveRuntime getProActiveRuntime(String proActiveRuntimeName)
00250         throws RemoteException, ProActiveException {
00251         return proActiveRuntime.getProActiveRuntime(proActiveRuntimeName);
00252     }
00253 
00254     public void addAcquaintance(String proActiveRuntimeName)
00255         throws RemoteException, ProActiveException {
00256         proActiveRuntime.addAcquaintance(proActiveRuntimeName);
00257     }
00258 
00259     public String[] getAcquaintances()
00260         throws RemoteException, ProActiveException {
00261         return proActiveRuntime.getAcquaintances();
00262     }
00263 
00264     public void rmAcquaintance(String proActiveRuntimeName)
00265         throws RemoteException, ProActiveException {
00266         proActiveRuntime.rmAcquaintance(proActiveRuntimeName);
00267     }
00268 
00269     public void killRT(boolean softly) throws Exception {
00270         killAllNodes();
00271         unregisterAllVirtualNodes();
00272         unregister(proActiveRuntimeURL);
00273 
00274         if (hasCreatedRegistry) {
00275             if (softly) {
00276                 if (RegistryHelper.getRegistry().list().length > 0) {
00277                     new RMIKillerThread().start();
00278 
00279                     return;
00280                 }
00281             }
00282         }
00283 
00284         proActiveRuntime.killRT(softly);
00285     }
00286 
00287     public String getURL() {
00288         return proActiveRuntimeURL;
00289     }
00290 
00291     //    public void setPortNumber(int p) {
00292     //          this.portNumber = p;
00293     //    }
00294     //    
00295     //    public int getPortNumber() {
00296     //          return this.portNumber;
00297     //    }
00298     public ArrayList getActiveObjects(String nodeName)
00299         throws RemoteException, ProActiveException {
00300         return proActiveRuntime.getActiveObjects(nodeName);
00301     }
00302 
00303     public ArrayList getActiveObjects(String nodeName, String objectName)
00304         throws RemoteException, ProActiveException {
00305         return proActiveRuntime.getActiveObjects(nodeName, objectName);
00306     }
00307 
00308     public VirtualNode getVirtualNode(String virtualNodeName)
00309         throws RemoteException, ProActiveException {
00310         return proActiveRuntime.getVirtualNode(virtualNodeName);
00311     }
00312 
00313     public void registerVirtualNode(String virtualNodeName,
00314         boolean replacePreviousBinding)
00315         throws RemoteException, java.rmi.AlreadyBoundException {
00316         String virtualNodeURL = null;
00317 
00318         try {
00319             //first we build a well-formed url
00320             virtualNodeURL = buildNodeURL(virtualNodeName);
00321 
00322             //register it with the url
00323             register(virtualNodeURL, replacePreviousBinding);
00324         } catch (java.net.UnknownHostException e) {
00325             throw new java.rmi.RemoteException("Host unknown in " +
00326                 virtualNodeURL, e);
00327         }
00328 
00329         vnNodesArray.add(virtualNodeURL);
00330     }
00331 
00332     public void unregisterVirtualNode(String virtualnodeName)
00333         throws RemoteException, ProActiveException {
00334         String virtualNodeURL = null;
00335         proActiveRuntime.unregisterVirtualNode(UrlBuilder.removeVnSuffix(
00336                 virtualnodeName));
00337 
00338         try {
00339             //first we build a well-formed url
00340             virtualNodeURL = buildNodeURL(virtualnodeName);
00341             unregister(virtualNodeURL);
00342         } catch (java.net.UnknownHostException e) {
00343             throw new java.rmi.RemoteException("Host unknown in " +
00344                 virtualNodeURL, e);
00345         }
00346 
00347         vnNodesArray.remove(virtualNodeURL);
00348     }
00349 
00350     public void unregisterAllVirtualNodes()
00351         throws RemoteException, ProActiveException {
00352         for (int i = 0; i < vnNodesArray.size(); i++) {
00353             String url = vnNodesArray.get(i);
00354             unregisterVirtualNode(url);
00355         }
00356     }
00357 
00358     public UniversalBody createBody(String nodeName,
00359         ConstructorCall bodyConstructorCall, boolean isNodeLocal)
00360         throws RemoteException, ConstructorCallExecutionFailedException,
00361             ProActiveException, InvocationTargetException {
00362         return proActiveRuntime.createBody(nodeName, bodyConstructorCall,
00363             isNodeLocal);
00364     }
00365 
00366     public UniversalBody receiveBody(String nodeName, Body body)
00367         throws RemoteException, ProActiveException {
00368         return proActiveRuntime.receiveBody(nodeName, body);
00369     }
00370 
00371     public UniversalBody receiveCheckpoint(String nodeURL, Checkpoint ckpt,
00372         int inc) throws RemoteException, ProActiveException {
00373         return proActiveRuntime.receiveCheckpoint(nodeURL, ckpt, inc);
00374     }
00375 
00380     public String getJobID(String nodeUrl)
00381         throws RemoteException, ProActiveException {
00382         return proActiveRuntime.getJobID(nodeUrl);
00383     }
00384 
00385     public byte[] getClassDataFromParentRuntime(String className)
00386         throws RemoteException, ProActiveException {
00387         try {
00388             return proActiveRuntime.getClassDataFromParentRuntime(className);
00389         } catch (ProActiveException e) {
00390             throw new ProActiveException("class not found : " + className, e);
00391         }
00392     }
00393 
00394     public byte[] getClassDataFromThisRuntime(String className)
00395         throws RemoteException, ProActiveException {
00396         return proActiveRuntime.getClassDataFromThisRuntime(className);
00397     }
00398 
00399     public void launchMain(String className, String[] parameters)
00400         throws IOException, ClassNotFoundException, NoSuchMethodException,
00401             ProActiveException {
00402         proActiveRuntime.launchMain(className, parameters);
00403     }
00404 
00405     public void newRemote(String className)
00406         throws IOException, ClassNotFoundException, ProActiveException {
00407         proActiveRuntime.newRemote(className);
00408     }
00409 
00410     public ProActiveDescriptor getDescriptor(String url,
00411         boolean isHierarchicalSearch) throws IOException, ProActiveException {
00412         return proActiveRuntime.getDescriptor(url, isHierarchicalSearch);
00413     }
00414 
00415     //
00416     // ---PRIVATE METHODS--------------------------------------
00417     //
00418     private void register(String url, boolean replacePreviousBinding)
00419         throws java.rmi.RemoteException, java.rmi.AlreadyBoundException {
00420         try {
00421             if (replacePreviousBinding) {
00422                 java.rmi.Naming.rebind(UrlBuilder.removeProtocol(url,
00423                         getProtocol()), this);
00424             } else {
00425                 java.rmi.Naming.bind(UrlBuilder.removeProtocol(url,
00426                         getProtocol()), this);
00427             }
00428 
00429             if (url.indexOf("PA_JVM") < 0) {
00430                 runtimeLogger.info(url + " successfully bound in registry at " +
00431                     url);
00432             }
00433         } catch (java.rmi.AlreadyBoundException e) {
00434             runtimeLogger.warn(url + " already bound in registry", e);
00435             throw e;
00436         } catch (java.net.MalformedURLException e) {
00437             throw new java.rmi.RemoteException("cannot bind in registry at " +
00438                 url, e);
00439         }
00440     }
00441 
00442     private void unregister(String url) throws java.rmi.RemoteException {
00443         try {
00444             java.rmi.Naming.unbind(UrlBuilder.removeProtocol(url, getProtocol()));
00445 
00446             if (url.indexOf("PA_JVM") < 0) {
00447                 runtimeLogger.info(url + " unbound in registry");
00448             }
00449         } catch (ConnectException e) {
00450             //if we get a connect exception, the rmi registry is unreachable. We cannot throw
00451             //an exception otherwise the killRT method cannot reach the end!
00452             if ((e.getCause().getClass().getName()
00453                       .equals("java.net.ConnectException") &&
00454                     e.getCause().getMessage().equals("Connection refused"))) {
00455                 if (url.indexOf("PA_JVM") < 0) {
00456                     runtimeLogger.info("RMIRegistry unreachable on host " +
00457                         UrlBuilder.getHostNameorIP(getVMInformation()
00458                                                        .getInetAddress()) +
00459                         " to unregister " + url + ". Killed anyway !!!");
00460                 }
00461             }
00462         } catch (java.net.MalformedURLException e) {
00463             throw new java.rmi.RemoteException("cannot unbind in registry at " +
00464                 url, e);
00465         } catch (java.rmi.NotBoundException e) {
00466             //No need to throw an exception if an object is already unregistered
00467             runtimeLogger.info("WARNING " + url +
00468                 " is not bound in the registry ");
00469         }
00470     }
00471 
00472     protected String getProtocol() {
00473         return Constants.RMI_PROTOCOL_IDENTIFIER;
00474     }
00475 
00476     private String buildRuntimeURL() {
00477         int port = RmiRuntimeFactory.getRegistryHelper().getRegistryPortNumber();
00478         String host = UrlBuilder.getHostNameorIP(getVMInformation()
00479                                                      .getInetAddress());
00480         String name = getVMInformation().getName();
00481 
00482         return UrlBuilder.buildUrl(host, name, getProtocol(), port);
00483     }
00484 
00485     private String buildNodeURL(String url)
00486         throws java.net.UnknownHostException {
00487         int i = url.indexOf('/');
00488 
00489         if (i == -1) {
00490             //it is an url given by a descriptor
00491             String host = UrlBuilder.getHostNameorIP(getVMInformation()
00492                                                          .getInetAddress());
00493 
00494             int port = RmiRuntimeFactory.getRegistryHelper()
00495                                         .getRegistryPortNumber();
00496 
00497             return UrlBuilder.buildUrl(host, url, getProtocol(), port);
00498         } else {
00499             return UrlBuilder.checkUrl(url);
00500         }
00501     }
00502 
00503     public String getVNName(String nodename)
00504         throws RemoteException, ProActiveException {
00505         return proActiveRuntime.getVNName(nodename);
00506     }
00507 
00508     // Security methods 
00509     public X509Certificate getCertificate()
00510         throws SecurityNotAvailableException, IOException {
00511         return proActiveRuntime.getCertificate();
00512     }
00513 
00514     public long startNewSession(Communication policy)
00515         throws SecurityNotAvailableException, RenegotiateSessionException,
00516             IOException {
00517         return proActiveRuntime.startNewSession(policy);
00518     }
00519 
00520     public PublicKey getPublicKey()
00521         throws SecurityNotAvailableException, IOException {
00522         return proActiveRuntime.getPublicKey();
00523     }
00524 
00525     public byte[] randomValue(long sessionID, byte[] clientRandomValue)
00526         throws SecurityNotAvailableException, RenegotiateSessionException,
00527             IOException {
00528         return proActiveRuntime.randomValue(sessionID, clientRandomValue);
00529     }
00530 
00531     public byte[][] publicKeyExchange(long sessionID, byte[] myPublicKey,
00532         byte[] myCertificate, byte[] signature)
00533         throws SecurityNotAvailableException, RenegotiateSessionException,
00534             KeyExchangeException, IOException {
00535         return proActiveRuntime.publicKeyExchange(sessionID, myPublicKey,
00536             myCertificate, signature);
00537     }
00538 
00539     public byte[][] secretKeyExchange(long sessionID, byte[] encodedAESKey,
00540         byte[] encodedIVParameters, byte[] encodedClientMacKey,
00541         byte[] encodedLockData, byte[] parametersSignature)
00542         throws SecurityNotAvailableException, RenegotiateSessionException,
00543             IOException {
00544         return proActiveRuntime.secretKeyExchange(sessionID, encodedAESKey,
00545             encodedIVParameters, encodedClientMacKey, encodedLockData,
00546             parametersSignature);
00547     }
00548 
00549     public SecurityContext getPolicy(SecurityContext securityContext)
00550         throws SecurityNotAvailableException, IOException {
00551         return proActiveRuntime.getPolicy(securityContext);
00552     }
00553 
00554     public byte[] getCertificateEncoded()
00555         throws SecurityNotAvailableException, IOException {
00556         return proActiveRuntime.getCertificateEncoded();
00557     }
00558 
00559     public ArrayList<Entity> getEntities()
00560         throws SecurityNotAvailableException, IOException {
00561         return proActiveRuntime.getEntities();
00562     }
00563 
00564     public void terminateSession(long sessionID)
00565         throws IOException, SecurityNotAvailableException {
00566         proActiveRuntime.terminateSession(sessionID);
00567     }
00568 
00569     //
00570     // ----------------- INNER CLASSES --------------------------------
00571     //
00572     private class RMIKillerThread extends Thread {
00573         public RMIKillerThread() {
00574         }
00575 
00576         public void run() {
00577             try {
00578                 while (RegistryHelper.getRegistry().list().length > 0) {
00579                     // the thread sleeps for 10 minutes
00580                     Thread.sleep(600000);
00581                 }
00582 
00583                 ((ProActiveRuntimeImpl) proActiveRuntime).killRT(false);
00584             } catch (InterruptedException e) {
00585                 ((ProActiveRuntimeImpl) proActiveRuntime).killRT(false);
00586                 e.printStackTrace();
00587             } catch (AccessException e) {
00588                 runtimeLogger.error(e.getMessage());
00589                 ((ProActiveRuntimeImpl) proActiveRuntime).killRT(false);
00590             } catch (Exception e) {
00591                 runtimeLogger.error(e.getMessage());
00592                 ((ProActiveRuntimeImpl) proActiveRuntime).killRT(false);
00593             }
00594         }
00595     }
00596 
00597     public Object setLocalNodeProperty(String nodeName, String key, String value)
00598         throws ProActiveException, IOException {
00599         return this.proActiveRuntime.setLocalNodeProperty(nodeName, key, value);
00600     }
00601 
00602     public String getLocalNodeProperty(String nodeName, String key)
00603         throws ProActiveException, IOException {
00604         return this.proActiveRuntime.getLocalNodeProperty(nodeName, key);
00605     }
00606 }

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