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.core.runtime.jini;
00032
00033 import java.io.IOException;
00034 import java.rmi.AlreadyBoundException;
00035 import java.rmi.RemoteException;
00036 import java.security.SecureRandom;
00037 import java.util.Hashtable;
00038 import java.util.Vector;
00039
00040 import org.objectweb.proactive.core.ProActiveException;
00041 import org.objectweb.proactive.core.node.NodeException;
00042 import org.objectweb.proactive.core.process.ExternalProcess;
00043 import org.objectweb.proactive.core.runtime.ProActiveRuntime;
00044 import org.objectweb.proactive.core.runtime.ProActiveRuntimeImpl;
00045 import org.objectweb.proactive.core.runtime.rmi.RmiProActiveRuntime;
00046 import org.objectweb.proactive.core.runtime.rmi.RmiProActiveRuntimeImpl;
00047 import org.objectweb.proactive.core.util.UrlBuilder;
00048 import org.objectweb.proactive.ext.security.ProActiveSecurityManager;
00049
00050 import net.jini.core.entry.Entry;
00051 import net.jini.core.lease.Lease;
00052 import net.jini.core.lookup.ServiceID;
00053 import net.jini.core.lookup.ServiceItem;
00054 import net.jini.core.lookup.ServiceRegistrar;
00055 import net.jini.core.lookup.ServiceRegistration;
00056 import net.jini.discovery.DiscoveryEvent;
00057 import net.jini.lease.LeaseRenewalEvent;
00058 import net.jini.lookup.entry.Name;
00059
00060
00067 public class JiniRuntimeImpl extends RmiProActiveRuntimeImpl
00068 implements java.io.Serializable, net.jini.discovery.DiscoveryListener,
00069 net.jini.lease.LeaseListener, RmiProActiveRuntime {
00070
00071
00072
00073
00074 protected java.util.Vector<ServiceRegistrar> registrarsTable;
00075
00076
00077
00078
00079 protected java.util.Hashtable<String, Vector<ServiceRegistration>> jiniRuntimeMap;
00080
00081
00082 protected java.util.Hashtable<String, Vector<ServiceRegistration>> jiniNodeMap;
00083
00084
00085
00086 protected java.util.Hashtable<String, Vector<ServiceRegistration>> jiniVirtualNodeMap;
00087 private volatile boolean isRuntimeRegistered = false;
00088
00089
00090 protected transient net.jini.lease.LeaseRenewalManager leaseManager = new net.jini.lease.LeaseRenewalManager();
00091
00092
00093
00094
00095 public JiniRuntimeImpl() throws java.rmi.RemoteException {
00096 super(true);
00097 this.proActiveRuntime = ProActiveRuntimeImpl.getProActiveRuntime();
00098 this.proActiveRuntimeURL = buildRuntimeURL();
00099 this.jiniRuntimeMap = new java.util.Hashtable<String, Vector<ServiceRegistration>>();
00100 jiniRuntimeMap.put(proActiveRuntimeURL, new java.util.Vector<ServiceRegistration>());
00101 this.jiniNodeMap = new java.util.Hashtable<String, Vector<ServiceRegistration>>();
00102 this.jiniVirtualNodeMap = new java.util.Hashtable<String, Vector<ServiceRegistration>>();
00103 this.registrarsTable = new java.util.Vector<ServiceRegistrar>();
00104 net.jini.discovery.LookupDiscovery discover = null;
00105 try {
00106 discover = new net.jini.discovery.LookupDiscovery(net.jini.discovery.LookupDiscovery.ALL_GROUPS);
00107
00108
00109 } catch (Exception e) {
00110 runtimeLogger.error(e.toString());
00111 }
00112
00113 discover.addDiscoveryListener(this);
00114 }
00115
00116
00117
00118
00119
00120
00121
00122 public ExternalProcess getProcessToDeploy(
00123 ProActiveRuntime proActiveRuntimeDist, String creatorID, String vmName,
00124 String padURL) throws ProActiveException, IOException {
00125 return proActiveRuntime.getProcessToDeploy(proActiveRuntimeDist,
00126 creatorID, vmName, padURL);
00127 }
00128
00129 public String createLocalNode(String nodeName,
00130 boolean replacePreviousBinding,
00131 ProActiveSecurityManager securityManager, String vnname, String jobId)
00132 throws RemoteException, NodeException, AlreadyBoundException {
00133
00134
00135
00136
00137
00138
00139 while (!isRuntimeRegistered) {
00140 }
00141 String nodeURL = null;
00142
00143
00144 try {
00145 nodeURL = buildNodeURL(nodeName);
00146
00147 String name = UrlBuilder.getNameFromUrl(nodeURL);
00148
00149
00150
00151
00152 proActiveRuntime.createLocalNode(name, replacePreviousBinding,
00153 securityManager, vnname, jobId);
00154 } catch (java.net.UnknownHostException e) {
00155 throw new java.rmi.RemoteException("Host unknown in " + nodeURL, e);
00156 }
00157
00158 jiniNodeMap.put(nodeURL, registerService(nodeURL));
00159
00160 return nodeURL;
00161 }
00162
00163 public void killAllNodes() throws RemoteException, ProActiveException {
00164 for (java.util.Enumeration<String> e = jiniNodeMap.keys(); e.hasMoreElements();) {
00165 String nodeURL = e.nextElement();
00166 killNode(nodeURL);
00167 }
00168 proActiveRuntime.killAllNodes();
00169 }
00170
00171 public void killNode(String nodeName)
00172 throws RemoteException, ProActiveException {
00173 String nodeUrl = null;
00174 String name = null;
00175 try {
00176 nodeUrl = buildNodeURL(nodeName);
00177 name = UrlBuilder.getNameFromUrl(nodeUrl);
00178 unregisterService(nodeUrl, jiniNodeMap);
00179 } catch (java.net.UnknownHostException e) {
00180 throw new java.rmi.RemoteException("Host unknown in " + nodeUrl, e);
00181 }
00182 proActiveRuntime.killNode(name);
00183 }
00184
00185 public void killRT(boolean softly) throws Exception {
00186 killAllNodes();
00187 unregisterAllVirtualNodes();
00188 unregisterService(proActiveRuntimeURL, jiniRuntimeMap);
00189 proActiveRuntime.killRT(false);
00190 }
00191
00192 public String getURL() {
00193 return proActiveRuntimeURL;
00194 }
00195
00196 public void registerVirtualNode(String virtualNodeName,
00197 boolean replacePreviousBinding) throws RemoteException {
00198 String virtualNodeURL = null;
00199
00200
00201 try {
00202 virtualNodeURL = buildNodeURL(virtualNodeName);
00203 } catch (java.net.UnknownHostException e) {
00204 throw new java.rmi.RemoteException("Host unknown in " +
00205 virtualNodeURL, e);
00206 }
00207
00208 if (replacePreviousBinding) {
00209 if (jiniVirtualNodeMap.get(virtualNodeURL) != null) {
00210 jiniVirtualNodeMap.remove(virtualNodeURL);
00211 }
00212 }
00213 if (!replacePreviousBinding &&
00214 (jiniVirtualNodeMap.get(virtualNodeURL) != null)) {
00215 throw new java.rmi.RemoteException("VirtualNode " + virtualNodeURL +
00216 " already registered as Jini service");
00217 }
00218
00219 jiniVirtualNodeMap.put(virtualNodeURL, registerService(virtualNodeURL));
00220 }
00221
00222 public void unregisterVirtualNode(String virtualNodeName)
00223 throws RemoteException, ProActiveException {
00224 String virtualNodeURL = null;
00225 proActiveRuntime.unregisterVirtualNode(UrlBuilder.removeVnSuffix(
00226 virtualNodeName));
00227
00228 try {
00229 virtualNodeURL = buildNodeURL(virtualNodeName);
00230 unregisterService(virtualNodeURL, jiniVirtualNodeMap);
00231 } catch (java.net.UnknownHostException e) {
00232 throw new java.rmi.RemoteException("Host unknown in " +
00233 virtualNodeURL, e);
00234 }
00235 }
00236
00237 public void unregisterAllVirtualNodes()
00238 throws RemoteException, ProActiveException {
00239 for (java.util.Enumeration<String> e = jiniVirtualNodeMap.keys();
00240 e.hasMoreElements();) {
00241 String vnNodeURL = e.nextElement();
00242 unregisterVirtualNode(vnNodeURL);
00243 }
00244 }
00245
00246
00247
00248
00249 public void discovered(DiscoveryEvent evt) {
00250 ServiceRegistrar[] registrars = evt.getRegistrars();
00251
00252
00253
00254 for (int n = 0; n < registrars.length; n++) {
00255 ServiceRegistrar registrar = registrars[n];
00256
00257 ServiceRegistration reg = null;
00258 try {
00259
00260
00261 ServiceItem item = new ServiceItem(newServiceID(), this,
00262 new Entry[] { new Name(proActiveRuntimeURL) });
00263 reg = registrar.register(item, Lease.FOREVER);
00264 } catch (Exception e) {
00265
00266 runtimeLogger.error("register exception " + e.toString());
00267 continue;
00268 }
00269 jiniRuntimeMap.get(proActiveRuntimeURL).add(reg);
00270
00271
00272 registrarsTable.add(registrar);
00273
00274 registerServiceAfterDiscovery(jiniNodeMap, registrar);
00275 registerServiceAfterDiscovery(jiniVirtualNodeMap, registrar);
00276
00277 leaseManager.renewUntil(reg.getLease(), Lease.FOREVER, this);
00278 isRuntimeRegistered = true;
00279 }
00280
00281
00282
00283
00284 isRuntimeRegistered = true;
00285 }
00286
00287 public void discarded(DiscoveryEvent evt) {
00288 }
00289
00290 public void notify(LeaseRenewalEvent evt) {
00291 runtimeLogger.info("Lease expired " + evt.toString());
00292 runtimeLogger.info(evt.getException().getMessage());
00293 }
00294
00295
00296
00297
00298 protected ServiceID newServiceID() {
00299
00301 SecureRandom secRand = new SecureRandom();
00302
00304 byte[] secRandBuf16 = new byte[16];
00305
00306 secRand.nextBytes(secRandBuf16);
00307 secRandBuf16[6] &= 0x0f;
00308 secRandBuf16[6] |= 0x40;
00309 secRandBuf16[8] &= 0x3f;
00310 secRandBuf16[8] |= 0x80;
00311 secRandBuf16[10] |= 0x80;
00312 long mostSig = 0;
00313 for (int i = 0; i < 8; i++) {
00314 mostSig = (mostSig << 8) | (secRandBuf16[i] & 0xff);
00315 }
00316 long leastSig = 0;
00317 for (int i = 8; i < 16; i++) {
00318 leastSig = (leastSig << 8) | (secRandBuf16[i] & 0xff);
00319 }
00320 return new ServiceID(mostSig, leastSig);
00321 }
00322
00323
00324
00325
00326
00327
00328
00329 private void registerServiceAfterDiscovery(Hashtable<String, Vector<ServiceRegistration>> jiniObjectTable,
00330 ServiceRegistrar registrar) {
00331 ServiceRegistration reg = null;
00332 ServiceID serviceID = null;
00333 if (!jiniObjectTable.isEmpty()) {
00334 synchronized (jiniObjectTable) {
00335 for (java.util.Enumeration<String> e = jiniObjectTable.keys();
00336 e.hasMoreElements();) {
00337 String objectURL = e.nextElement();
00338 Vector serviceRegistrationTable = jiniObjectTable.get(objectURL);
00339 if (!serviceRegistrationTable.isEmpty()) {
00340 serviceID = ((ServiceRegistration) serviceRegistrationTable.get(0)).getServiceID();
00341 } else {
00342 serviceID = newServiceID();
00343 }
00344 ServiceItem item = new ServiceItem(serviceID, this,
00345 new Entry[] { new Name(objectURL) });
00346 try {
00347 reg = registrar.register(item, Lease.FOREVER);
00348 } catch (Exception ex) {
00349 runtimeLogger.info("register exception " +
00350 ex.toString());
00351 continue;
00352 }
00353 runtimeLogger.info(" Service Registered " + objectURL);
00354
00355
00356 leaseManager.renewUntil(reg.getLease(), Lease.FOREVER, this);
00357 jiniObjectTable.get(objectURL).add(reg);
00358 }
00359 }
00360 }
00361 }
00362
00363 private String buildRuntimeURL() {
00364 String host = UrlBuilder.getHostNameorIP(getVMInformation()
00365 .getInetAddress());
00366 String name = getVMInformation().getName();
00367 return UrlBuilder.buildUrl(host, name, "jini:");
00368 }
00369
00370 private String buildNodeURL(String url)
00371 throws java.net.UnknownHostException {
00372 int i = url.indexOf('/');
00373 if (i == -1) {
00374
00375 String host = UrlBuilder.getHostNameorIP(getVMInformation()
00376 .getInetAddress());
00377 return UrlBuilder.buildUrl(host, url, "jini:");
00378 } else {
00379 return UrlBuilder.checkUrl(url);
00380 }
00381 }
00382
00383 private Vector<ServiceRegistration> registerService(String objectUrl)
00384 throws java.rmi.RemoteException {
00385
00386
00387 int counter = 0;
00388 ServiceID serviceID = newServiceID();
00389 Vector<ServiceRegistration> serviceRegistrationTable = new Vector<ServiceRegistration>();
00390
00391
00392 for (int n = 0; n < registrarsTable.size(); n++) {
00393 ServiceRegistrar registrar = registrarsTable.get(n);
00394 ServiceRegistration reg = null;
00395 try {
00396 ServiceItem item = new ServiceItem(serviceID, this,
00397 new Entry[] { new Name(objectUrl) });
00398 reg = registrar.register(item, Lease.FOREVER);
00399 counter++;
00400 } catch (Exception e) {
00401 runtimeLogger.info("register exception " + e.toString());
00402 continue;
00403 }
00404
00405
00406 if (counter == 0) {
00407 throw new java.rmi.RemoteException("register exception ");
00408 }
00409 runtimeLogger.info("Service registered " + objectUrl);
00410
00411
00412 leaseManager.renewUntil(reg.getLease(), Lease.FOREVER, this);
00413 serviceRegistrationTable.add(reg);
00414 }
00415 return serviceRegistrationTable;
00416 }
00417
00418 private void unregisterService(String objectUrl, Hashtable<String, Vector<ServiceRegistration>> jiniObjectTable)
00419 throws java.rmi.RemoteException {
00420 if (!jiniObjectTable.isEmpty()) {
00421 synchronized (jiniObjectTable) {
00422 try {
00423 Vector serviceRegistrationTable = jiniObjectTable.get(objectUrl);
00424 if (!serviceRegistrationTable.isEmpty()) {
00425 for (int i = 0; i < serviceRegistrationTable.size();
00426 i++) {
00427 ServiceRegistration reg = (ServiceRegistration) serviceRegistrationTable.get(i);
00428 reg.getLease().cancel();
00429 }
00430 if (objectUrl.indexOf("PA_JVM") < 0) {
00431 runtimeLogger.info("Lease cancelled for " +
00432 objectUrl);
00433 }
00434 }
00435 } catch (net.jini.core.lease.UnknownLeaseException e) {
00436 throw new java.rmi.RemoteException(
00437 "Unable to get the Lease for virtualNode " + objectUrl,
00438 e);
00439 } finally {
00440 jiniObjectTable.remove(objectUrl);
00441 }
00442 }
00443 }
00444 }
00445 }