1 9 package org.jboss.remoting.transport; 10 11 import java.net.InetAddress ; 12 import java.util.HashMap ; 13 import java.util.Iterator ; 14 import java.util.Map ; 15 import java.util.StringTokenizer ; 16 import javax.management.MBeanRegistration ; 17 import javax.management.MBeanServer ; 18 import javax.management.MBeanServerInvocationHandler ; 19 import javax.management.MalformedObjectNameException ; 20 import javax.management.ObjectName ; 21 import org.jboss.logging.Logger; 22 import org.jboss.remoting.InvokerLocator; 23 import org.jboss.remoting.InvokerRegistry; 24 import org.jboss.remoting.ServerInvocationHandler; 25 import org.jboss.remoting.ServerInvoker; 26 import org.jboss.remoting.marshal.MarshalFactory; 27 import org.jboss.remoting.marshal.MarshallLoaderFactory; 28 import org.w3c.dom.Element ; 29 import org.w3c.dom.NamedNodeMap ; 30 import org.w3c.dom.Node ; 31 import org.w3c.dom.NodeList ; 32 33 100 public class Connector implements MBeanRegistration , ConnectorMBean 101 { 102 protected ServerInvoker invoker; 103 104 private String locatorURI; 105 106 private Element xml; 107 108 private MBeanServer server; 109 110 private Connector marshallerLoaderConnector = null; 111 private boolean isMarshallerLoader = false; 112 113 private boolean isStarted = false; 114 private boolean isCreated = false; 115 116 protected final Logger log = Logger.getLogger(getClass()); 117 118 public Connector() 119 { 120 121 } 122 123 protected Connector(boolean isMarshallerConnector) 124 { 125 this(); 126 this.isMarshallerLoader = isMarshallerConnector; 127 } 128 129 public boolean isStarted() 130 { 131 return isStarted; 132 } 133 134 152 public ObjectName preRegister(MBeanServer server, ObjectName name) 153 throws Exception 154 { 155 this.server = server; 156 return name; 157 } 158 159 166 public void postRegister(Boolean registrationDone) 167 { 168 } 169 170 178 public void preDeregister() 179 throws Exception 180 { 181 } 182 183 187 public void postDeregister() 188 { 189 } 190 191 197 public void start() 198 throws Exception 199 { 200 if(!isStarted) 201 { 202 203 if(!isCreated) 206 { 207 create(); 208 } 209 210 ClassLoader cl = Thread.currentThread().getContextClassLoader(); 211 212 if(cl == null) 213 { 214 cl = getClass().getClassLoader(); 215 } 216 217 configureHandlers(cl); 220 221 if(!isMarshallerLoader) 223 { 224 if(marshallerLoaderConnector != null && !marshallerLoaderConnector.isStarted()) 225 { 226 marshallerLoaderConnector.start(); 227 } 228 } 229 230 if(invoker.isStarted() == false) 232 { 233 try 234 { 235 invoker.start(); 236 } 237 catch(Exception e) 238 { 239 if(marshallerLoaderConnector != null) 240 { 241 marshallerLoaderConnector.stop(); 242 } 243 log.error("Error starting connector.", e); 244 throw e; 245 } 246 } 247 isStarted = true; 248 } 249 250 } 251 252 258 public void start(boolean runAsNewThread) throws Exception 259 { 260 261 Runnable r = new Runnable () 262 { 263 public void run() 264 { 265 try 266 { 267 start(); 268 } 269 catch(Exception e) 270 { 271 log.error("Error starting Connector.", e); 272 } 273 } 274 }; 275 Thread t = new Thread (r); 276 t.setDaemon(false); 277 t.start(); 278 } 279 280 private void init() 281 throws Exception 282 { 283 Map invokerConfig = new HashMap (); 284 285 if(locatorURI == null) 286 { 287 if(xml != null) 289 { 290 getInvokerConfig(invokerConfig); 291 } 292 } 293 294 if(locatorURI == null) 295 { 296 throw new IllegalStateException ("Connector not configured with LocatorURI."); 297 } 298 299 InvokerLocator locator = new InvokerLocator(locatorURI); 300 301 if(invoker == null) 302 { 303 invoker = InvokerRegistry.createServerInvoker(locator, invokerConfig); 305 306 if(server != null) 308 { 309 try 310 { 311 ObjectName objName = new ObjectName (invoker.getMBeanObjectName()); 312 if(!server.isRegistered(objName)) 313 { 314 server.registerMBean(invoker, objName); 315 invoker.setMBeanServer(server); 316 } 317 } 318 catch(Throwable e) 319 { 320 log.warn("Error registering invoker " + invoker + " with MBeanServer.", e); 321 } 322 } 323 324 invoker.create(); 325 } 326 327 locatorURI = invoker.getLocator().getLocatorURI(); 330 331 332 if(!isMarshallerLoader) 333 { 334 if(marshallerLoaderConnector == null) 336 { 337 marshallerLoaderConnector = createMarshallerLoader(invoker.getLocator()); 338 } 339 } 340 341 } 342 343 private Connector createMarshallerLoader(InvokerLocator locator) 344 { 345 353 MarshalFactory.getMarshaller(locator, this.getClass().getClassLoader()); 354 355 Connector marshallerLoader = null; 356 InvokerLocator loaderLocator = MarshallLoaderFactory.convertLocator(locator); 357 if(loaderLocator != null) 359 { 360 marshallerLoader = MarshallLoaderFactory.createMarshallLoader(loaderLocator); 361 } 362 return marshallerLoader; 363 } 364 365 private void getInvokerConfig(Map invokerConfig) 366 { 367 try 368 { 369 NodeList invokerNodes = xml.getElementsByTagName("invoker"); 370 371 if(invokerNodes != null && invokerNodes.getLength() >= 1) 372 { 373 Node invokerNode = invokerNodes.item(0); 375 376 NamedNodeMap attributes = invokerNode.getAttributes(); 377 Node transportNode = attributes.getNamedItem("transport"); 378 379 if(transportNode != null) 380 { 381 String transport = transportNode.getNodeValue(); 382 383 if(invokerNodes.getLength() > 1) 385 { 386 log.warn("Found more than one invokers defined in configuration. " + 387 "Will only be using the first one - " + transport); 388 } 389 390 Map paramConfig = new HashMap (); 392 NodeList invokerAttributes = invokerNode.getChildNodes(); 393 int len = invokerAttributes.getLength(); 394 for(int x = 0; x < len; x++) 395 { 396 Node attr = invokerAttributes.item(x); 397 if("attribute".equals(attr.getNodeName())) 398 { 399 String name = attr.getAttributes().getNamedItem("name").getNodeValue(); 400 String value = attr.getFirstChild().getNodeValue(); 401 invokerConfig.put(name, value); 402 Node isParamAttribute = attr.getAttributes().getNamedItem("isParam"); 403 if(isParamAttribute != null && Boolean.valueOf(isParamAttribute.getNodeValue()).booleanValue()) 404 { 405 paramConfig.put(name, value); 406 } 407 } 408 } 409 410 String clientConnectAddress = (String ) invokerConfig.get("clientConnectAddress"); 413 String clientConnectPort = (String ) invokerConfig.get("clientConnectPort"); 414 String serverBindAddress = (String ) invokerConfig.get("serverBindAddress"); 415 String serverBindPort = (String ) invokerConfig.get("serverBindPort"); 416 417 String host = clientConnectAddress != null ? clientConnectAddress : serverBindAddress != null ? serverBindAddress : InetAddress.getLocalHost().getHostAddress(); 418 int port = clientConnectPort != null ? Integer.parseInt(clientConnectPort) : serverBindPort != null ? Integer.parseInt(serverBindPort) : PortUtil.findFreePort(); 419 420 if("0.0.0.0".equals(host)) 421 { 422 host = InetAddress.getLocalHost().getHostAddress(); 423 } 424 425 String tempURI = transport + "://" + host + ":" + port; 427 428 if(paramConfig.size() > 0) 430 { 431 tempURI += "/?"; 432 Iterator keyItr = paramConfig.keySet().iterator(); 433 if(keyItr.hasNext()) 434 { 435 Object name = keyItr.next(); 436 Object value = paramConfig.get(name); 437 tempURI += name + "=" + value; 438 } 439 while(keyItr.hasNext()) 440 { 441 tempURI += "&"; 442 Object name = keyItr.next(); 443 Object value = paramConfig.get(name); 444 tempURI += name + "=" + value; 445 } 446 } 447 locatorURI = tempURI; 448 } 449 else 450 { 451 log.error("Invoker element within Configuration attribute does not contain a transport attribute."); 452 } 453 454 } 455 } 456 catch(Exception e) 457 { 458 log.error("Error configuring invoker for connector.", e); 459 throw new IllegalStateException ("Error configuring invoker for connector. Can not continue without invoker."); 460 } 461 } 462 463 private void configureHandlers(ClassLoader cl) 464 throws Exception 465 { 466 if(xml != null) 467 { 468 NodeList handlersNodes = xml.getElementsByTagName("handler"); 469 470 if(handlersNodes == null || handlersNodes.getLength() <= 0) 471 { 472 throw new IllegalArgumentException ("required 'handler' element not found"); 473 } 474 475 int len = handlersNodes.getLength(); 476 477 for(int c = 0; c < len; c++) 478 { 479 Node node = handlersNodes.item(c); 480 Node subNode = node.getAttributes().getNamedItem("subsystem"); 481 482 if(subNode == null) 483 { 484 throw new IllegalArgumentException ("Required 'subsystem' attribute on 'handler' element"); 485 } 486 487 String handlerClass = node.getFirstChild().getNodeValue(); 488 489 boolean isObjName = false; 490 ServerInvocationHandler handler = null; 491 492 try 494 { 495 ObjectName objName = new ObjectName (handlerClass); 496 handler = createHandlerProxy(objName); 497 isObjName = true; 498 } 499 catch(MalformedObjectNameException e) 500 { 501 log.debug("Handler supplied is not an object name."); 502 } 503 504 if(!isObjName) 505 { 506 handler = (ServerInvocationHandler ) cl.loadClass(handlerClass).newInstance(); 507 } 508 509 StringTokenizer tok = new StringTokenizer (subNode.getNodeValue(), ","); 510 511 while(tok.hasMoreTokens()) 512 { 513 String subsystem = tok.nextToken(); 514 addInvocationHandler(subsystem, handler); 515 } 516 } 517 } 518 } 519 520 private ServerInvocationHandler createHandlerProxy(ObjectName objName) 521 { 522 ServerInvocationHandler handler; 523 if(server != null) 524 { 525 handler = (ServerInvocationHandler ) 526 MBeanServerInvocationHandler.newProxyInstance(server, 527 objName, 528 ServerInvocationHandler .class, 529 false); 530 } 531 else 532 { 533 throw new RuntimeException ("Can not register MBean invocation handler as the Connector has not been registered with a MBeanServer."); 534 } 535 return handler; 536 } 537 538 544 public void stop() 545 { 546 if(isStarted) 547 { 548 if(invoker != null) 549 { 550 invoker.stop(); 551 invoker.destroy(); 552 InvokerRegistry.destroyServerInvoker(invoker); 553 invoker = null; 554 } 555 if(marshallerLoaderConnector != null && marshallerLoaderConnector.isStarted) 556 { 557 marshallerLoaderConnector.stop(); 558 marshallerLoaderConnector = null; 559 } 560 isCreated = false; 561 isStarted = false; 562 } 563 } 564 565 570 public void create() 571 throws Exception 572 { 573 if(!isCreated) 574 { 575 init(); 576 } 577 } 578 579 584 public void destroy() 585 { 586 } 588 589 public ServerInvoker getServerInvoker() 590 { 591 return invoker; 592 } 593 594 599 public ServerInvocationHandler [] getInvocationHandlers() 600 { 601 ServerInvocationHandler [] handlers = null; 602 if(invoker != null) 603 { 604 handlers = invoker.getInvocationHandlers(); 605 } 606 607 return handlers; 608 } 609 610 618 public InvokerLocator getLocator() 619 { 620 return invoker.getLocator(); 621 } 622 623 633 public void setInvokerLocator(String locator) 634 throws Exception 635 { 636 locatorURI = locator; 637 } 638 639 640 647 public String getInvokerLocator() throws Exception 648 { 649 return locatorURI; 650 } 651 652 663 public void setConfiguration(Element xml) 664 throws Exception 665 { 666 this.xml = xml; 667 } 668 669 676 public Element getConfiguration() 677 { 678 return xml; 679 } 680 681 701 public ServerInvocationHandler addInvocationHandler(String subsystem, ObjectName handlerObjectName) throws Exception 702 { 703 ServerInvocationHandler invocationHandler = createHandlerProxy(handlerObjectName); 704 return addInvocationHandler(subsystem, invocationHandler); 705 } 706 707 723 public ServerInvocationHandler addInvocationHandler(String subsystem, ServerInvocationHandler handler) 724 throws Exception 725 { 726 if(invoker == null) 727 { 728 throw new IllegalStateException ("You may only add handlers once the Connector is created (via create() method)."); 729 } 730 731 handler.setMBeanServer(server); 732 return invoker.addInvocationHandler(subsystem, handler); 733 } 734 735 747 public void removeInvocationHandler(String subsystem) throws Exception 748 { 749 ServerInvocationHandler handler = invoker.removeInvocationHandler(subsystem); 750 751 if(handler != null) 752 { 753 handler.setMBeanServer(null); 754 } 755 } 756 757 } 758 | Popular Tags |