1 10 package org.mmbase.module; 11 12 import java.lang.reflect.Constructor ; 13 import java.net.MalformedURLException ; 14 import java.rmi.*; 15 import java.rmi.registry.Registry ; 16 import java.rmi.server.UnicastRemoteObject ; 17 18 import org.mmbase.bridge.CloudContext; 19 import org.mmbase.bridge.LocalContext; 20 import org.mmbase.bridge.remote.RemoteCloudContext; 21 import org.mmbase.bridge.remote.rmi.RemoteCloudContext_Rmi; 22 import org.mmbase.module.core.MMBase; 23 import org.mmbase.util.logging.*; 24 25 34 public class RemoteMMCI extends ProcessorModule { 35 36 private Registry registry; 37 38 static final Logger log = Logging.getLoggerInstance(RemoteMMCI.class); 40 41 44 public static final int DEFAULT_RMIREGISTRY_PORT = 1111; 45 46 49 public static final String DEFAULT_BIND_NAME = "remotecontext"; 50 51 55 public void init() { 56 super.init(); loadInitParameters("mmbase/rmmci"); 58 log.debug("Module RemoteMMCI starting"); 59 60 int registryPort = getPort(); 61 int stubPort = getStubPort(registryPort); 62 String host = getHost(); 63 String bindName = getBindName(); 64 createRemoteMMCI(host, registryPort, bindName, stubPort); 65 log.info("RemoteMMCI registry listening on rmi://" + host + ":" + registryPort + "/" + bindName); 66 log.info("RemoteMMCI stubs listening on rmi://" + host + ":" + stubPort); 67 startChecker(this); 68 } 69 70 public String getBindName() { 71 String bindName = DEFAULT_BIND_NAME; 72 String bindNameParam = getInitParameter("bindname"); 73 if (bindNameParam != null) { 74 if (bindNameParam.equals("$MACHINENAME")) { 75 bindName = MMBase.getMMBase().getMachineName(); 77 } else { 78 bindName = bindNameParam; 79 } 80 } else { 81 log.warn("missing bindname init param, using default '" + bindName + "'"); 82 } 83 return bindName; 84 } 85 86 public String getHost() { 87 String host = getInitParameter("RMIRegistryServer"); 89 if (host == null || host.equals("")) { 91 try { 92 MMBase mmbase = MMBase.getMMBase(); 94 host = mmbase.getHost(); 95 log.debug("using host FROM MMBASEROOT " + host); 96 java.net.InetAddress.getByName(host); 97 System.setProperty("java.rmi.server.hostname", host); 98 } catch (java.net.UnknownHostException uhn) { 99 log.warn("property host in mmbaseroot.xml is not set correctly."); 100 log.warn("Chances are big the Remote MMCI will not work"); 101 } 102 } else { 103 log.debug("RemoteMMCI is using the RMIRegistryServer{" + host + "} as hostname to create/connect to the RMI registry"); 104 } 105 return host; 106 } 107 108 public int getPort() { 109 int registryPort = DEFAULT_RMIREGISTRY_PORT; 110 111 String portString = getInitParameter("port"); 113 if (portString != null) { 114 try { 115 registryPort = Integer.parseInt(portString); 116 } catch (NumberFormatException nfe) { 117 log.warn("port parameter '" + portString + "' of rmmci.xml is not of type int."); 118 }; 119 } else { 120 log.service("Missing port init param, using default " + registryPort); 121 } 122 return registryPort; 123 } 124 125 126 public int getStubPort(int registryPort) { 127 int stubPort = -1; 128 129 String portString = getInitParameter("stubport"); 131 if (portString != null) { 132 try { 133 stubPort = Integer.parseInt(portString); 134 } catch (NumberFormatException nfe) { 135 log.warn("stubport parameter '" + portString + "' of rmmci.xml is not of type int."); 136 }; 137 } else { 138 if (stubPort == -1) { 139 stubPort = registryPort + 1; 140 } 141 log.service("Missing port init param, using default " + stubPort); 142 } 143 return stubPort; 144 } 145 146 147 152 private void createRemoteMMCI(String host, int registryPort, String bindName, int stubPort) { 153 try { 155 Registry reg = getRegistry(host, registryPort); 156 if (reg != null) { 157 register(reg, bindName, stubPort); 158 log.debug("Module RemoteMMCI Running on (tcp port,name)=(" + registryPort + "," + bindName + ")"); 159 } 160 else { 161 log.warn("Module RemoteMMCI MOT running and failed to bind " + bindName + ")"); 162 } 163 } catch (RemoteException rex) { 164 log.fatal("RMI Registry not started because of exception {" + rex.getMessage() + Logging.stackTrace(rex) + "}"); 165 } 166 } 167 168 public Registry getRegistry(String host, int registryPort) throws RemoteException { 169 Registry reg = null; 170 try { 171 176 reg = java.rmi.registry.LocateRegistry.getRegistry(host, registryPort); 177 reg.list(); 179 log.debug("using an existing RMI registry"); 181 } catch (RemoteException rex) { 182 205 registry = java.rmi.registry.LocateRegistry.createRegistry(registryPort); 206 log.debug("creating a new RMI registry"); 207 if (registry != null) { 208 reg = java.rmi.registry.LocateRegistry.getRegistry(host, registryPort); 209 } 210 else { 211 log.fatal("RMI Registry not created."); 212 } 213 } 214 return reg; 215 } 216 217 218 public void register(Registry reg, String bindName, int stubPort) throws RemoteException, AccessException { 219 RemoteCloudContext remoteCloudContext = new RemoteCloudContext_Rmi(LocalContext.getCloudContext(), stubPort); 222 223 log.debug("bind RemoteCloudContext in the registry using name=" + bindName); 224 225 reg.rebind(bindName, remoteCloudContext); 227 } 228 229 public String [] getListOfNames(String host, int registryPort) { 230 try { 231 Registry reg = getRegistry(host, registryPort); 232 if (reg != null) { 233 return reg.list(); 234 } 235 } catch (java.rmi.RemoteException rex) { 236 log.fatal("RMI Registry not started because of exception {" + rex.getMessage() + "}"); 237 } 238 return new String [0]; 239 } 240 241 242 246 protected void shutdown() { 247 if (registry != null) { 248 stopRegistry(); 249 } 250 super.shutdown(); 251 } 252 253 private void stopRegistry() { 254 log.info("Stopping the RMI registry"); 255 try { 256 String [] names = registry.list(); 257 for (int x = 0; x < names.length; x++) { 258 try { 259 log.service("Unbind " + names[x]); 260 registry.unbind(names[x]); 261 } catch (NotBoundException e1) { 262 log.warn(Logging.stackTrace(e1)); 263 } 264 } 265 if (!UnicastRemoteObject.unexportObject(registry, true)) { 266 log.warn("Could not unexport " + registry); 267 } else { 268 log.service("Unexported " + registry); 269 } 270 } catch (AccessException e) { 271 log.warn(Logging.stackTrace(e)); 272 } catch (RemoteException e) { 273 log.warn(Logging.stackTrace(e)); 274 } 275 registry = null; 276 Runtime.getRuntime().gc(); 279 } 280 281 public boolean test(String host, int registryPort, String bindName) { 282 try { 283 String uri = "rmi://" + host + ":" + registryPort + "/" + bindName; 284 Object remoteCloudContext = Naming.lookup(uri); 285 if (remoteCloudContext != null) { 286 log.debug("RMI lookup ok"); 287 try { 288 Class clazz = Class.forName("org.mmbase.bridge.remote.implementation.RemoteCloudContext_Impl"); 289 Constructor constr = clazz.getConstructor(new Class [] { Class.forName("org.mmbase.bridge.remote.RemoteCloudContext") }); 290 CloudContext cloudContext = (CloudContext) constr.newInstance(new Object [] { remoteCloudContext } ); 291 292 cloudContext.getCloud("mmbase"); 293 log.debug("RMI cloud object found"); 294 } catch (Exception e){ 295 log.warn("RMI cloud object failure"); 296 log.warn(Logging.stackTrace(e)); 297 return false; 298 } 299 } 300 else { 301 log.warn("RMI lookup failed " + bindName); 302 return false; 303 } 304 } catch (AccessException e) { 305 log.warn(Logging.stackTrace(e)); 306 } catch (RemoteException e) { 307 log.warn(Logging.stackTrace(e)); 308 return false; 309 } catch (NotBoundException e) { 310 log.warn(Logging.stackTrace(e)); 311 return false; 312 } catch (MalformedURLException e) { 313 log.warn(Logging.stackTrace(e)); 314 } 315 return true; 316 } 317 318 public void resetBind(String host, int registryPort, String bindName, int stubPort) throws RemoteException, AccessException { 319 Registry reg = getRegistry(host, registryPort); 320 try { 321 reg.unbind(bindName); 322 } catch (AccessException e) { 323 log.warn(Logging.stackTrace(e)); 324 } catch (RemoteException e) { 325 log.warn(Logging.stackTrace(e)); 326 } catch (NotBoundException e) { 327 log.info("Unbind failed for " + bindName + " in RMIregistry " + host + ":" + registryPort); 328 } 329 register(reg, bindName, stubPort); 330 } 331 332 private void startChecker(RemoteMMCI remoteMMCI) { 333 String checkConnection = getInitParameter("checkconnection"); 334 if (checkConnection != null && !checkConnection.equals("")){ 335 log.info("RemoteMMCI will check connection every " + checkConnection + " ms"); 336 337 RemoteChecker runnable = new RemoteChecker(remoteMMCI, Integer.parseInt(checkConnection)); 338 339 Thread checker = new Thread (runnable, "RMICloudChecker"); 340 checker.setDaemon(true); 341 checker.start(); 342 } 343 } 344 345 static class RemoteChecker implements Runnable { 346 347 int interval = 60 * 1000; 348 RemoteMMCI remoteMMCI = null; 349 350 public RemoteChecker(RemoteMMCI remoteMMCI, int interval) { 351 this.remoteMMCI = remoteMMCI; 352 this.interval = interval; 353 } 354 355 public void run() { 356 while (true) { 357 try { 358 Thread.sleep(interval); 359 } 360 catch (InterruptedException e) { 361 } 363 testRMI(); 364 } 365 } 366 367 private void testRMI() { 368 try { 369 String bindName = remoteMMCI.getBindName(); 370 int port = remoteMMCI.getPort(); 371 String host = remoteMMCI.getHost(); 372 int stubPort = remoteMMCI.getStubPort(port); 373 if (!remoteMMCI.test(host, port, bindName)) { 374 remoteMMCI.resetBind(host, port, bindName, stubPort); 375 } 376 } catch (RemoteException e) { 377 log.warn(e.getClass().getName() + ": " + e.getMessage(), e); 378 } 379 } 380 } 381 382 } 383 | Popular Tags |