1 7 8 package org.jboss.webservice; 10 11 import java.io.InputStream ; 12 import java.net.URL ; 13 import java.util.ArrayList ; 14 import java.util.HashMap ; 15 import java.util.Iterator ; 16 import java.util.Map ; 17 import javax.management.InstanceNotFoundException ; 18 import javax.management.Notification ; 19 import javax.management.NotificationFilterSupport ; 20 import javax.management.NotificationListener ; 21 import javax.management.ObjectName ; 22 import org.dom4j.Document; 23 import org.dom4j.Element; 24 import org.jboss.deployment.DeploymentException; 25 import org.jboss.deployment.DeploymentInfo; 26 import org.jboss.deployment.MainDeployerMBean; 27 import org.jboss.deployment.SubDeployer; 28 import org.jboss.logging.Logger; 29 import org.jboss.metadata.ApplicationMetaData; 30 import org.jboss.metadata.BeanMetaData; 31 import org.jboss.metadata.EjbPortComponentMetaData; 32 import org.jboss.metadata.WebMetaData; 33 import org.jboss.mx.util.MBeanProxy; 34 import org.jboss.mx.util.MBeanProxyCreationException; 35 import org.jboss.system.ServiceMBeanSupport; 36 import org.jboss.webservice.metadata.PortComponentMetaData; 37 import org.jboss.webservice.metadata.WebserviceDescriptionMetaData; 38 import org.jboss.webservice.metadata.WebservicesFactory; 39 import org.jboss.webservice.metadata.WebservicesMetaData; 40 import org.jboss.xb.binding.ObjectModelFactory; 41 import org.jboss.xb.binding.Unmarshaller; 42 import org.jboss.xb.binding.UnmarshallerFactory; 43 44 58 public abstract class ServiceDeployer extends ServiceMBeanSupport 59 implements ServiceDeployerMBean, NotificationListener 60 { 61 private final Logger log = Logger.getLogger(ServiceDeployer.class); 63 64 public static final String INIT_PARAM_WEBSERVICE_ID = "WebServiceID"; 66 public static final String INIT_PARAM_SERVICE_ENDPOINT_IMPL = "ServiceEndpointImpl"; 68 69 private AxisServiceMBean axisService; 71 72 75 protected Map webservicesMap = new HashMap (); 76 77 79 protected void startService() throws Exception 80 { 81 super.startService(); 82 axisService = (AxisServiceMBean)MBeanProxy.get(AxisServiceMBean.class, AxisServiceMBean.OBJECT_NAME, server); 83 } 84 85 93 public void handleNotification(Notification notification, Object handback) 94 { 95 DeploymentInfo di = (DeploymentInfo)notification.getUserData(); 96 97 String moduleName = di.shortName; 98 String type = notification.getType(); 99 log.debug("handleNotification: " + type + "," + moduleName); 100 101 if (isWebservicesDeployment(di)) 102 { 103 try 104 { 105 if (type.equals(SubDeployer.INIT_NOTIFICATION)) 106 initWebservice(di); 107 else if (type.equals(SubDeployer.CREATE_NOTIFICATION)) 108 createWebservice(di); 109 else if (type.equals(SubDeployer.START_NOTIFICATION)) 110 startWebservice(di); 111 } 112 catch (Throwable e) 113 { 114 handleStartupException(di, e); 115 } 116 117 try 118 { 119 if (type.equals(SubDeployer.STOP_NOTIFICATION)) 120 stopWebservice(di); 121 else if (type.equals(SubDeployer.DESTROY_NOTIFICATION)) 122 destroyWebservice(di); 123 } 124 catch (Throwable e) 125 { 126 handleShutdownException(moduleName, e); 127 } 128 } 129 } 130 131 137 protected void initWebservice(DeploymentInfo di) throws DeploymentException 138 { 139 if (di.metaData instanceof ApplicationMetaData) 140 { 141 ApplicationMetaData applMetaData = (ApplicationMetaData)di.metaData; 142 applMetaData.setWebServiceDeployment(true); 143 } 144 145 if (di.metaData instanceof WebMetaData) 146 { 147 WebMetaData webMetaData = (WebMetaData)di.metaData; 148 webMetaData.setWebServiceDeployment(true); 149 } 150 } 151 152 158 protected void createWebservice(DeploymentInfo di) throws DeploymentException 159 { 160 URL url = getWebservicesDescriptor(di); 161 if (url != null) 162 { 163 WebservicesMetaData wsMetaData = parseWebservicesXML(di, url); 164 webservicesMap.put(di.url, wsMetaData); 165 } 166 } 167 168 169 protected abstract URL getWebservicesDescriptor(DeploymentInfo di); 170 171 172 private boolean isWebservicesDeployment(DeploymentInfo di) 173 { 174 boolean isWebservicesDeployment = false; 175 if (di.metaData instanceof ApplicationMetaData) 176 { 177 ApplicationMetaData applMetaData = (ApplicationMetaData)di.metaData; 178 isWebservicesDeployment = applMetaData.isWebServiceDeployment() || getWebservicesDescriptor(di) != null; 179 } 180 181 if (di.metaData instanceof WebMetaData) 182 { 183 WebMetaData webMetaData = (WebMetaData)di.metaData; 184 isWebservicesDeployment = webMetaData.isWebServiceDeployment() || getWebservicesDescriptor(di) != null; 185 } 186 187 return isWebservicesDeployment; 188 } 189 190 196 protected void startWebservice(DeploymentInfo di) throws DeploymentException 197 { 198 WebservicesMetaData webservices = (WebservicesMetaData)webservicesMap.get(di.url); 199 if (webservices != null) 200 { 201 ServiceLocationResolver locationResolver = new ServiceLocationResolver(di); 203 WebserviceDescriptionMetaData[] wsdArray = webservices.getWebserviceDescriptions(); 204 for (int i = 0; i < wsdArray.length; i++) 205 { 206 WebserviceDescriptionMetaData wsdMetaData = wsdArray[i]; 207 wsdMetaData.updateServiceAddress(locationResolver); 208 String wsdName = wsdMetaData.getWebserviceDescriptionName(); 209 210 if (di.metaData instanceof ApplicationMetaData) 212 { 213 ApplicationMetaData applMetaData = (ApplicationMetaData)di.metaData; 214 String wsdlPublishLocation = applMetaData.getWsdlPublishLocationByName(wsdName); 215 wsdMetaData.setWsdlPublishLocation(wsdlPublishLocation); 216 } 217 218 if (di.metaData instanceof WebMetaData) 220 { 221 WebMetaData webMetaData = (WebMetaData)di.metaData; 222 String wsdlPublishLocation = webMetaData.getWsdlPublishLocationByName(wsdName); 223 wsdMetaData.setWsdlPublishLocation(wsdlPublishLocation); 224 } 225 } 226 227 WSDLFilePublisher wsdlfp = new WSDLFilePublisher(di); 228 wsdlfp.publishWsdlFile(webservices); 229 deployWebservices(di, webservices); 230 } 231 } 232 233 240 protected void stopWebservice(DeploymentInfo di) 241 { 242 WebservicesMetaData webservices = (WebservicesMetaData)webservicesMap.get(di.url); 243 if (webservices != null) 244 { 245 undeployWebservices(di, webservices); 246 WSDLFilePublisher wsdlfp = new WSDLFilePublisher(di); 247 wsdlfp.unpublishWsdlFile(); 248 } 249 } 250 251 255 protected void destroyWebservice(DeploymentInfo di) 256 { 257 webservicesMap.remove(di.url); 258 } 259 260 262 268 protected void handleStartupException(DeploymentInfo di, Throwable th) 269 { 270 log.error("Cannot startup webservice for: " + di.shortName, th); 271 try 272 { 273 MainDeployerMBean mainDeployer = (MainDeployerMBean)MBeanProxy.get(MainDeployerMBean.class, MainDeployerMBean.OBJECT_NAME, server); 274 mainDeployer.undeploy(di); 275 } 276 catch (MBeanProxyCreationException e) 277 { 278 e.printStackTrace(); 279 } 280 } 281 282 288 protected void handleShutdownException(String moduleName, Throwable th) 289 { 290 log.error("Cannot shutdown webservice for: " + moduleName, th); 291 } 292 293 296 protected void registerNotificationListener(ObjectName serviceName) 297 throws InstanceNotFoundException 298 { 299 NotificationFilterSupport filter = new NotificationFilterSupport (); 300 filter.enableType(SubDeployer.INIT_NOTIFICATION); 301 filter.enableType(SubDeployer.CREATE_NOTIFICATION); 302 filter.enableType(SubDeployer.START_NOTIFICATION); 303 filter.enableType(SubDeployer.STOP_NOTIFICATION); 304 filter.enableType(SubDeployer.DESTROY_NOTIFICATION); 305 server.addNotificationListener(serviceName, this, filter, null); 306 } 307 308 311 protected void unregisterNotificationListener(ObjectName serviceName) 312 { 313 try 314 { 315 server.removeNotificationListener(serviceName, this); 316 } 317 catch (Exception e) 318 { 319 log.error("Cannot remove notification listener: " + e.toString()); 320 } 321 } 322 323 326 protected WebservicesMetaData parseWebservicesXML(DeploymentInfo di, URL webservicesURL) throws DeploymentException 327 { 328 WebservicesMetaData webservices = null; 329 try 330 { 331 InputStream is = webservicesURL.openStream(); 333 try 334 { 335 Unmarshaller unmarshaller = UnmarshallerFactory.newInstance() 337 .newUnmarshaller(); 338 ObjectModelFactory factory = new WebservicesFactory(di.localCl); 339 webservices = (WebservicesMetaData)unmarshaller.unmarshal(is, factory, null); 340 } 341 finally 342 { 343 is.close(); 344 } 345 } 346 catch (Exception e) 347 { 348 throw new DeploymentException("Cannot obtain webservices meta data", e); 349 } 350 return webservices; 351 } 352 353 356 protected void deployWebservices(DeploymentInfo di, WebservicesMetaData webservices) 357 throws DeploymentException 358 { 359 try 360 { 361 WebserviceDescriptionMetaData[] wsdArr = webservices.getWebserviceDescriptions(); 362 for (int i = 0; i < wsdArr.length; i++) 363 { 364 WebserviceDescriptionMetaData wsd = wsdArr[i]; 365 PortComponentMetaData[] pcArr = wsd.getPortComponents(); 366 for (int j = 0; j < pcArr.length; j++) 367 { 368 PortComponentMetaData pcMetaData = pcArr[j]; 369 PortComponentInfo pcInfo = new PortComponentInfo(di, pcMetaData); 370 axisService.deployService(pcInfo); 371 } 372 } 373 } 374 catch (Exception e) 375 { 376 throw new DeploymentException("Cannot deploy webservice", e); 377 } 378 } 379 380 383 protected void undeployWebservices(DeploymentInfo di, WebservicesMetaData webservices) 384 { 385 try 386 { 387 WebserviceDescriptionMetaData[] wsdarr = webservices.getWebserviceDescriptions(); 388 for (int i = 0; i < wsdarr.length; i++) 389 { 390 WebserviceDescriptionMetaData wsDescription = wsdarr[i]; 391 PortComponentMetaData[] pcarr = wsDescription.getPortComponents(); 392 for (int j = 0; j < pcarr.length; j++) 393 { 394 PortComponentMetaData pcMetaData = pcarr[j]; 395 PortComponentInfo pcInfo = new PortComponentInfo(di, pcMetaData); 396 String wsID = pcInfo.getServiceID(); 397 axisService.undeployService(wsID); 398 } 399 } 400 } 401 catch (Exception ignore) 402 { 403 log.warn("Cannot undeploy webservice: " + ignore); 404 } 405 } 406 407 409 protected boolean modifyServletConfig(Document doc, String servletName, PortComponentInfo pcInfo) throws DeploymentException 410 { 411 Element servletElement = null; 412 413 Iterator itServlet = doc.getRootElement().elements("servlet").iterator(); 414 while (itServlet.hasNext() && servletElement == null) 415 { 416 Element el = (Element)itServlet.next(); 417 String elName = el.elementTextTrim("servlet-name"); 418 if (servletName.equals(elName)) 419 servletElement = el; 420 } 421 if (servletElement == null) 422 throw new DeploymentException("Cannot find <servlet> with servlet-name: " + servletName); 423 424 Element classElement = servletElement.element("servlet-class"); 426 if (classElement == null) 427 throw new DeploymentException("Cannot find <servlet-class> for servlet-name: " + servletName); 428 429 String servletClass = classElement.getTextTrim(); 431 String serviceEndpointServletName = getServiceEndpointServletName(); 432 433 if (isAlreadyModified(servletElement) == false) 435 { 436 classElement.setText(serviceEndpointServletName); 437 438 boolean startDetach = false; 440 ArrayList detachedElements = new ArrayList (); 441 itServlet = servletElement.elements().iterator(); 442 while (itServlet.hasNext()) 443 { 444 Element el = (Element)itServlet.next(); 445 if (startDetach == true) 446 { 447 detachedElements.add(el); 448 el.detach(); 449 } 450 if (el.equals(classElement)) 451 startDetach = true; 452 } 453 454 Element paramElement = servletElement.addElement("init-param"); 456 paramElement.addElement("param-name").addText(INIT_PARAM_WEBSERVICE_ID); 457 paramElement.addElement("param-value").addText(pcInfo.getServiceID()); 458 459 if (servletClass.equals(serviceEndpointServletName) == false) 462 { 463 paramElement = servletElement.addElement("init-param"); 464 paramElement.addElement("param-name").addText(INIT_PARAM_SERVICE_ENDPOINT_IMPL); 465 paramElement.addElement("param-value").addText(servletClass); 466 } 467 468 PortComponentMetaData pcMetaData = pcInfo.getPortComponentMetaData(); 469 pcMetaData.setServiceEndpointBean(servletClass); 470 471 itServlet = detachedElements.iterator(); 473 while (itServlet.hasNext()) 474 { 475 Element el = (Element)itServlet.next(); 476 servletElement.add(el); 477 } 478 479 return true; 480 } 481 else 482 { 483 Iterator it = servletElement.elementIterator("init-param"); 484 while (it.hasNext()) 485 { 486 Element elParam = (Element)it.next(); 487 if (INIT_PARAM_SERVICE_ENDPOINT_IMPL.equals(elParam.elementText("param-name"))) 488 { 489 String serviceEndpointImpl = elParam.elementText("param-value"); 490 PortComponentMetaData pcMetaData = pcInfo.getPortComponentMetaData(); 491 pcMetaData.setServiceEndpointBean(serviceEndpointImpl); 492 } 493 } 494 495 return false; 496 } 497 } 498 499 private boolean isAlreadyModified(Element servletElement) 501 { 502 String serviceID = null; 503 504 Iterator it = servletElement.elementIterator("init-param"); 505 while (serviceID == null && it.hasNext()) 506 { 507 Element elParam = (Element)it.next(); 508 if (INIT_PARAM_WEBSERVICE_ID.equals(elParam.elementText("param-name"))) 509 serviceID = elParam.elementText("param-value"); 510 } 511 512 return serviceID != null; 513 } 514 515 518 protected abstract String getServiceEndpointServletName(); 519 520 523 public class ServiceLocationResolver 524 { 525 private DeploymentInfo di; 526 527 public ServiceLocationResolver(DeploymentInfo di) 528 { 529 this.di = di; 530 } 531 532 public boolean alwaysResolve() 533 { 534 return axisService.isAlwaysModifySOAPAddress(); 535 } 536 537 547 public String getServiceLocation(String schema, PortComponentMetaData pcmd) 548 { 549 String ejbLink = pcmd.getEjbLink(); 550 String servletLink = pcmd.getServletLink(); 551 String serviceName = pcmd.getPortComponentName(); 552 553 String servicePath = null; 554 555 if (servletLink != null) 557 { 558 WebMetaData metaData = (WebMetaData)di.metaData; 559 Map servletMappings = metaData.getServletMappings(); 560 String urlPattern = (String )servletMappings.get(servletLink); 561 if (urlPattern == null) 562 throw new IllegalStateException ("Cannot obtain servlet-mapping for: " + servletLink); 563 564 if (urlPattern.startsWith("/") == false) 565 urlPattern = "/" + urlPattern; 566 567 servicePath = metaData.getContextRoot() + urlPattern; 568 } 569 else if (ejbLink != null) 570 { 571 ApplicationMetaData amd = (ApplicationMetaData)di.metaData; 572 BeanMetaData bmd = (BeanMetaData)amd.getBeanByEjbName(ejbLink); 573 if (bmd == null) 574 throw new IllegalStateException ("Cannot find ejb-name: " + ejbLink); 575 576 String contextRoot = amd.getWebServiceContextRoot(); 578 579 if (contextRoot == null) 581 { 582 String shortName = di.shortName; 583 contextRoot = shortName.substring(0, shortName.indexOf('.')); 584 contextRoot = "/" + contextRoot; 585 amd.setWebServiceContextRoot(contextRoot); 586 } 587 588 EjbPortComponentMetaData ejbpcMetaData = bmd.getPortComponent(); 589 if (ejbpcMetaData != null && ejbpcMetaData.getPortComponentURI() != null) 590 { 591 servicePath = contextRoot + ejbpcMetaData.getPortComponentURI(); 592 } 593 else 594 { 595 servicePath = contextRoot + "/" + serviceName; 596 } 597 } 598 else 599 { 600 throw new IllegalStateException ("Cannot find valid <servlet-link> nor <ejb-link> in port component meta data"); 601 } 602 603 if (servicePath.endsWith("/*")) 604 servicePath = servicePath.substring(0, servicePath.indexOf("/*")); 605 606 if (schema == null) 607 schema = "http://"; 608 609 int port = 0; 610 String host = null; 611 String serviceEndpointAddress = null; 612 try 613 { 614 host = axisService.getWebServiceHost(); 615 port = axisService.getWebServicePort(); 616 if ("https://".equals(schema)) 617 port = axisService.getWebServiceSecurePort(); 618 619 serviceEndpointAddress = new URL (schema + host + ":" + port + servicePath).toExternalForm(); 620 } 621 catch (Exception e) 622 { 623 log.error("Cannot obtain attribute from AxisService, cause: " + e.toString()); 624 } 625 626 return serviceEndpointAddress; 627 } 628 } 629 } 630 | Popular Tags |