1 package org.sapia.ubik.rmi.server; 2 3 import java.io.IOException ; 4 import java.lang.reflect.Proxy ; 5 import java.rmi.RemoteException ; 6 import java.util.ArrayList ; 7 import java.util.List ; 8 import java.util.Properties ; 9 10 import javax.naming.Name ; 11 12 import org.sapia.taskman.PeriodicTaskDescriptor; 13 import org.sapia.taskman.TaskManager; 14 import org.sapia.ubik.net.Connection; 15 import org.sapia.ubik.net.ServerAddress; 16 import org.sapia.ubik.net.TCPAddress; 17 import org.sapia.ubik.rmi.Consts; 18 import org.sapia.ubik.rmi.server.gc.CommandRefer; 19 import org.sapia.ubik.rmi.server.perf.PerfAnalyzer; 20 import org.sapia.ubik.rmi.server.transport.Connections; 21 import org.sapia.ubik.rmi.server.transport.TransportManager; 22 23 24 34 public class Hub { 35 36 public static final TaskManager taskMan = new UbikTaskManager(); 37 38 39 public static final ClientRuntime clientRuntime = new ClientRuntime(taskMan); 40 41 42 public static final ServerRuntime serverRuntime = new ServerRuntime(taskMan); 43 static final PerfAnalyzer _perf; 44 static boolean _callback; 45 static boolean _shutdown; 46 47 static { 48 List tasks = new ArrayList (); 49 tasks.add(new PeriodicTaskDescriptor("Perf. Analyzer", 25000, 50 _perf = PerfAnalyzer.getInstance())); 51 52 taskMan.addTaskDescriptors(tasks); 53 54 _callback = (System.getProperty(Consts.CALLBACK_ENABLED) != null) && 55 System.getProperty(Consts.CALLBACK_ENABLED).equalsIgnoreCase("true"); 56 } 57 58 64 public static Object toStub(Object o) throws RemoteException { 65 if (o instanceof Stub) { 66 return o; 67 } 68 69 if (!serverRuntime.server.isInit(ServerTable.DEFAULT_TRANSPORT_TYPE)) { 70 serverRuntime.server.init(o, ServerTable.DEFAULT_TRANSPORT_TYPE); 71 72 ServerRef ref = serverRuntime.server.getServerRef(ServerTable.DEFAULT_TRANSPORT_TYPE); 73 74 return ref.stub; 75 } else { 76 return getStubFor(serverRuntime.server.initStub(o, 77 ServerTable.DEFAULT_TRANSPORT_TYPE), o); 78 } 79 } 80 81 95 public static Object toReliableStub(Object obj) { 96 if (obj instanceof Stub && Proxy.isProxyClass(obj.getClass())) { 97 RemoteRef handler = (RemoteRef) Proxy.getInvocationHandler(obj); 98 99 RemoteRefReliable rmiHandler = new RemoteRefReliable(handler.getOid(), 100 handler.getServerAddress()); 101 rmiHandler.setCallBack(handler.isCallBack()); 102 103 ObjectTable.Ref ref = (ObjectTable.Ref) serverRuntime.objectTable.getRefs() 104 .get(handler.getOid()); 105 106 if (ref == null) { 107 throw new NullPointerException ("no object for: " + handler.getOid()); 108 } 109 110 Object proxy = Proxy.newProxyInstance(Thread.currentThread() 111 .getContextClassLoader(), 112 ServerTable.getInterfacesFor(ref._obj.getClass()), rmiHandler); 113 114 return proxy; 115 } else { 116 return obj; 117 } 118 } 119 120 130 public static Object toStatelessStub(Name name, String domain, Object obj) { 131 if (obj instanceof Stub && Proxy.isProxyClass(obj.getClass())) { 132 RemoteRef handler = (RemoteRef) Proxy.getInvocationHandler(obj); 133 134 RemoteRefStateless rmiHandler; 135 List lst = new ArrayList (1); 136 lst.add(handler); 137 rmiHandler = RemoteRefStateless.fromRemoteRefs(name, domain, lst); 138 139 ObjectTable.Ref ref = (ObjectTable.Ref) serverRuntime.objectTable.getRefs() 140 .get(handler.getOid()); 141 142 if (ref == null) { 143 throw new NullPointerException ("no object for: " + handler.getOid()); 144 } 145 146 Object proxy = Proxy.newProxyInstance(Thread.currentThread() 147 .getContextClassLoader(), 148 ServerTable.getInterfacesFor(ref._obj.getClass()), rmiHandler); 149 150 return proxy; 151 } else { 152 return obj; 153 } 154 } 155 156 167 public static Object exportObject(Object o) throws RemoteException { 168 if (!serverRuntime.server.isInit(ServerTable.DEFAULT_TRANSPORT_TYPE)) { 169 serverRuntime.server.init(o, ServerTable.DEFAULT_TRANSPORT_TYPE); 170 171 ServerRef ref = serverRuntime.server.getServerRef(ServerTable.DEFAULT_TRANSPORT_TYPE); 172 173 return ref.stub; 174 } else { 175 return getStubFor(serverRuntime.server.initStub(o, 176 ServerTable.DEFAULT_TRANSPORT_TYPE), o); 177 } 178 } 179 180 187 public static Object exportObject(Object o, int port) 188 throws RemoteException { 189 if (!serverRuntime.server.isInit(ServerTable.DEFAULT_TRANSPORT_TYPE)) { 190 serverRuntime.server.init(o, port); 191 192 ServerRef ref = serverRuntime.server.getServerRef(ServerTable.DEFAULT_TRANSPORT_TYPE); 193 194 return ref.stub; 195 } else { 196 return getStubFor(serverRuntime.server.initStub(o, 197 ServerTable.DEFAULT_TRANSPORT_TYPE), o); 198 } 199 } 200 201 213 public static Object exportObject(Object o, Properties props) 214 throws RemoteException { 215 String transportType = props.getProperty(Consts.TRANSPORT_TYPE); 216 217 if (transportType == null) { 218 transportType = System.getProperty(Consts.TRANSPORT_TYPE); 219 } 220 221 if (transportType == null) { 222 throw new RemoteException (Consts.TRANSPORT_TYPE + 223 " property not specified"); 224 } 225 226 if (!serverRuntime.server.isInit(transportType)) { 227 serverRuntime.server.init(o, transportType, props); 228 229 ServerRef ref = serverRuntime.server.getServerRef(transportType); 230 231 return ref.stub; 232 } else { 233 return getStubFor(serverRuntime.server.initStub(o, transportType), o); 234 } 235 } 236 237 249 public static Object exportObject(Object o, String transportType) 250 throws RemoteException { 251 if (!serverRuntime.server.isInit(transportType)) { 252 throw new RemoteException ("No server was exported for transport: " + 253 transportType); 254 } else { 255 return getStubFor(serverRuntime.server.initStub(o, transportType), o); 256 } 257 } 258 259 272 public static void unexport(Object o) { 273 serverRuntime.objectTable.remove(o); 274 } 275 276 289 public static void unexport(ClassLoader loader) { 290 serverRuntime.objectTable.remove(loader); 291 } 292 293 299 public static Object connect(String host, int port) throws RemoteException { 300 return connect(new TCPAddress(host, port)); 301 } 302 303 311 public static Object connect(ServerAddress address) throws RemoteException { 312 Connection conn = null; 313 Object toReturn; 314 315 try { 316 conn = TransportManager.getConnectionsFor(address).acquire(); 317 318 try { 319 conn.send(new CommandConnect(address.getTransportType())); 320 } catch (RemoteException e) { 321 Connections conns = TransportManager.getConnectionsFor(address); 322 conns.clear(); 323 conn = conns.acquire(); 324 conn.send(new CommandConnect(address.getTransportType())); 325 } 326 327 toReturn = conn.receive(); 328 } catch (IOException e) { 329 throw new RemoteException ("error connecting to remote server", e); 330 } catch (ClassNotFoundException e) { 331 throw new RemoteException ("could not find class", e); 332 } finally { 333 if (conn != null) { 334 TransportManager.getConnectionsFor(address).release(conn); 335 } 336 } 337 338 if (toReturn instanceof Throwable ) { 339 if (toReturn instanceof RuntimeException ) { 340 throw (RuntimeException ) toReturn; 341 } else { 342 throw new RemoteException ("problem connecting to remote server", 343 (Throwable ) toReturn); 344 } 345 } 346 347 return toReturn; 348 } 349 350 355 public static ServerAddress getServerAddressFor(String transportType) { 356 return serverRuntime.server.getServerAddress(transportType); 357 } 358 359 373 public static Object asRemote(Object o, VmId caller, String transportType) 374 throws RemoteException { 375 if (o instanceof Stub) { 376 return o; 377 } 378 379 return getStubFor(asRemoteRef(o, caller, transportType), o); 380 } 381 382 394 public static RemoteRef asRemoteRef(Object o, VmId caller, 395 String transportType) throws RemoteException { 396 if (_perf.isEnabled()) { 397 _perf.getTopic(Hub.class.getName() + ".CreateRemoteRef").start(); 398 } 399 400 if (!serverRuntime.server.isInit(transportType)) { 401 serverRuntime.server.init(transportType); 402 } 403 404 OID oid = ServerTable.generateOID(); 405 406 if (_perf.isEnabled()) { 407 _perf.getTopic(Hub.class.getName() + ".RegisterRemoteRef").start(); 408 } 409 410 serverRuntime.gc.registerRef(caller, oid, o); 411 412 if (_perf.isEnabled()) { 413 _perf.getTopic(Hub.class.getName() + ".RegisterRemoteRef").end(); 414 } 415 416 RemoteRef rmiHandler; 417 418 if (_perf.isEnabled()) { 419 _perf.getTopic(Hub.class.getName() + ".InstantiateRemoteRef").start(); 420 } 421 422 rmiHandler = new RemoteRefEx(oid, 423 serverRuntime.server.getServerRef(transportType).server.getServerAddress()); 424 425 rmiHandler.setCallBack(_callback); 426 427 if (_perf.isEnabled()) { 428 _perf.getTopic(Hub.class.getName() + ".InstantiateRemoteRef").end(); 429 } 430 431 if (_perf.isEnabled()) { 432 _perf.getTopic(Hub.class.getName() + ".CreateRemoteRef").end(); 433 } 434 435 return rmiHandler; 436 } 437 438 443 public static boolean isShutdown() { 444 return _shutdown; 445 } 446 447 454 public static synchronized void shutdown(long timeout) 455 throws InterruptedException { 456 if (_shutdown) { 457 return; 458 } 459 460 Log.warning(Hub.class, "Shutting down task manager"); 461 taskMan.shutdown(); 462 Log.warning(Hub.class, "Shutting down client runtime"); 463 clientRuntime.shutdown(timeout); 464 Log.warning(Hub.class, "Shutting down server runtime"); 465 serverRuntime.shutdown(timeout); 466 Log.warning(Hub.class, "Shutting down event channels"); 467 EventChannelSingleton.shutdown(); 468 Log.warning(Hub.class, "Shutting down transport manager"); 469 TransportManager.shutdown(); 470 Log.warning(Hub.class, "Shut down completed"); 471 _shutdown = true; 472 } 473 474 public static Object getStubFor(RemoteRef ref, Object remote) { 475 Class [] cachedInterfaces = ServerTable.getInterfacesFor(remote.getClass()); 476 477 if (_perf.isEnabled()) { 478 _perf.getTopic(Hub.class.getName() + ".CreateStub").start(); 479 } 480 481 Object proxy = Proxy.newProxyInstance(Thread.currentThread() 482 .getContextClassLoader(), 483 cachedInterfaces, ref); 484 485 if (_perf.isEnabled()) { 486 _perf.getTopic(Hub.class.getName() + ".CreateStub").end(); 487 } 488 489 return proxy; 490 } 491 492 static void createReference(ServerAddress address, OID oid) 493 throws RemoteException { 494 Connections conns = TransportManager.getConnectionsFor(address); 495 496 try { 497 doSend(conns, oid); 498 } catch (ClassNotFoundException e) { 499 throw new RemoteException ("could refer to object: " + oid + "@" + 500 address, e); 501 } catch (RemoteException e) { 502 conns.clear(); 503 504 try { 505 doSend(conns, oid); 506 } catch (Exception e2) { 507 throw new RemoteException ("could refer to object: " + oid + "@" + 508 address, e2); 509 } 510 } catch (IOException e) { 511 throw new RemoteException ("could refer to object: " + oid + "@" + 512 address, e); 513 } 514 } 515 516 private static void doSend(Connections conns, OID oid) 517 throws RemoteException , IOException , ClassNotFoundException { 518 Connection conn = null; 519 520 try { 521 conn = conns.acquire(); 522 conn.send(new CommandRefer(oid)); 523 conn.receive(); 524 } finally { 525 if (conn != null) { 526 conns.release(conn); 527 } 528 } 529 } 530 } 531 | Popular Tags |