1 45 package org.exolab.jms.net.rmi; 46 47 import java.io.IOException ; 48 import java.rmi.AccessException ; 49 import java.rmi.MarshalException ; 50 import java.rmi.MarshalledObject ; 51 import java.rmi.NotBoundException ; 52 import java.rmi.RemoteException ; 53 import java.rmi.registry.LocateRegistry ; 54 import java.rmi.registry.Registry ; 55 import java.rmi.server.UnicastRemoteObject ; 56 import java.security.Principal ; 57 58 import org.apache.commons.logging.Log; 59 import org.apache.commons.logging.LogFactory; 60 61 import org.exolab.jms.common.uuid.UUIDGenerator; 62 import org.exolab.jms.net.connector.AbstractManagedConnection; 63 import org.exolab.jms.net.connector.Caller; 64 import org.exolab.jms.net.connector.CallerImpl; 65 import org.exolab.jms.net.connector.ConnectException; 66 import org.exolab.jms.net.connector.Connection; 67 import org.exolab.jms.net.connector.IllegalStateException; 68 import org.exolab.jms.net.connector.InvocationHandler; 69 import org.exolab.jms.net.connector.Request; 70 import org.exolab.jms.net.connector.ResourceException; 71 import org.exolab.jms.net.connector.Response; 72 import org.exolab.jms.net.connector.SecurityException; 73 import org.exolab.jms.net.connector.MarshalledInvocation; 74 import org.exolab.jms.net.uri.InvalidURIException; 75 import org.exolab.jms.net.uri.URI; 76 import org.exolab.jms.net.uri.URIHelper; 77 78 79 86 class RMIManagedConnection extends AbstractManagedConnection { 87 88 91 private RMIInvokerImpl _localInvoker; 92 93 96 private RMIInvoker _remoteInvoker; 97 98 101 private InvocationHandler _invoker; 102 103 106 private URI _remoteURI; 107 108 111 private URI _localURI; 112 113 116 private Principal _principal; 117 118 121 private Caller _caller; 122 123 126 private static final Log _log = 127 LogFactory.getLog(RMIManagedConnection.class); 128 129 130 137 protected RMIManagedConnection(Principal principal, RMIRequestInfo info) 138 throws ResourceException { 139 140 Registry registry; 141 _remoteURI = URIHelper.convertHostToAddress(info.getURI()); 142 _localURI = generateLocalURI(); 143 144 try { 145 registry = LocateRegistry.getRegistry(info.getHost(), 146 info.getPort()); 147 } catch (RemoteException exception) { 148 throw new ConnectException("Failed to get registry" 149 + ", host=" + info.getHost() 150 + ", port=" + info.getPort(), 151 exception); 152 } 153 154 String name = RegistryHelper.getName(_remoteURI); 155 RMIInvokerFactory factory; 156 try { 157 factory = (RMIInvokerFactory) registry.lookup(name); 158 } catch (RemoteException exception) { 159 throw new ConnectException("Failed to lookup connection proxy" 160 + ", host=" + info.getHost() 161 + ", port=" + info.getPort(), 162 exception); 163 } catch (NotBoundException exception) { 164 throw new ConnectException("Connection proxy=" + name 165 + " not bound in " 166 + "registry, host=" + info.getHost() 167 + ", port=" + info.getPort(), 168 exception); 169 } 170 171 _localInvoker = new RMIInvokerImpl(); 172 _localInvoker.setConnection(this); 173 try { 174 UnicastRemoteObject.exportObject(_localInvoker); 175 } catch (RemoteException exception) { 176 throw new ResourceException("Failed to export invocation handler", 177 exception); 178 } 179 try { 180 _remoteInvoker = factory.createInvoker(principal, _localInvoker, 181 _localURI.toString()); 182 } catch (AccessException exception) { 183 throw new SecurityException (exception.getMessage(), exception); 184 } catch (RemoteException exception) { 185 if (exception.detail instanceof AccessException ) { 186 throw new SecurityException (exception.getMessage(), 187 exception.detail); 188 } 189 throw new ResourceException("Failed to create invocation handler", 190 exception); 191 } 192 _principal = principal; 193 } 194 195 208 protected RMIManagedConnection(Principal principal, 209 RMIInvokerImpl localInvoker, 210 URI localURI, 211 RMIInvoker remoteInvoker, 212 URI remoteURI) 213 214 throws RemoteException { 215 localInvoker.setConnection(this); 216 UnicastRemoteObject.exportObject(localInvoker, localURI.getPort()); 217 _localInvoker = localInvoker; 218 _localURI = localURI; 219 _remoteInvoker = remoteInvoker; 220 _remoteURI = remoteURI; 221 _principal = principal; 222 _caller = new CallerImpl(_remoteURI, _localURI); 223 } 224 225 232 public synchronized Connection getConnection() 233 throws IllegalStateException { 234 if (_invoker == null) { 235 throw new IllegalStateException ("No InvocationHandler registered"); 236 } 237 return new RMIConnection(this); 238 } 239 240 246 public synchronized void setInvocationHandler(InvocationHandler handler) 247 throws IllegalStateException { 248 if (_invoker != null) { 249 throw new IllegalStateException ( 250 "An invocation handler is already registered"); 251 } 252 _invoker = handler; 253 } 254 255 260 public boolean isAlive() { 261 boolean alive = false; 262 RMIInvoker invoker; 263 synchronized (this) { 264 invoker = _remoteInvoker; 265 } 266 if (invoker != null) { 267 try { 268 invoker.ping(); 269 alive = true; 270 } catch (RemoteException exception) { 271 _log.debug("Failed to ping remote server", exception); 272 } 273 } 274 return alive; 275 } 276 277 282 public void destroy() throws ResourceException { 283 try { 284 RMIInvoker invoker; 285 synchronized (this) { 286 invoker = _localInvoker; 287 } 288 if (invoker != null) { 289 if (!UnicastRemoteObject.unexportObject(invoker, true)) { 290 _log.warn("Failed to unexport invocation handler"); 291 } 292 } 293 } catch (RemoteException exception) { 294 throw new ResourceException( 295 "Failed to unexport invocation handler", exception); 296 } finally { 297 synchronized (this) { 298 _localInvoker = null; 299 _remoteInvoker = null; 300 } 301 } 302 } 303 304 309 public URI getRemoteURI() { 310 return _remoteURI; 311 } 312 313 318 public URI getLocalURI() { 319 return _localURI; 320 } 321 322 330 public boolean hasPrincipal(Principal principal) { 331 boolean result = false; 332 if ((_principal != null && _principal.equals(principal)) 333 || (_principal == null && principal == null)) { 334 result = true; 335 } 336 return result; 337 } 338 339 347 protected Response invoke(Connection connection, Request request) 348 throws RemoteException { 349 Response response = null; 350 try { 351 MarshalledObject wrappedRequest = new MarshalledObject (request); 352 MarshalledObject wrappedResponse = 353 _remoteInvoker.invoke(wrappedRequest); 354 response = (Response) wrappedResponse.get(); 355 } catch (ClassNotFoundException exception) { 356 response = new Response(exception); 357 } catch (IOException exception) { 358 response = new Response(exception); 359 } 360 return response; 361 } 362 363 370 protected MarshalledObject invokeLocal(MarshalledObject request) 371 throws MarshalException { 372 MarshalledInvocation invocation 373 = new MarshalledInvocation(request, _caller); 374 _invoker.invoke(invocation); 375 376 MarshalledObject response = null; 377 try { 378 response = invocation.getMarshalledResponse(); 379 } catch (IOException exception) { 380 throw new MarshalException ("Failed to marshal response", 381 exception); 382 } 383 return response; 384 } 385 386 392 private URI generateLocalURI() throws ResourceException { 393 URI result; 394 String path = UUIDGenerator.create(); 395 try { 396 result = URIHelper.create("rmi", null, -1, path); 397 } catch (InvalidURIException exception) { 398 throw new ResourceException("Failed to generate local URI", 399 exception); 400 } 401 return result; 402 } 403 404 } 405 | Popular Tags |