| 1 25 26 package org.objectweb.jonas.ws; 27 28 import java.io.File ; 29 import java.io.IOException ; 30 import java.io.UnsupportedEncodingException ; 31 import java.net.MalformedURLException ; 32 import java.net.URL ; 33 import java.net.URLClassLoader ; 34 import java.net.URLEncoder ; 35 import java.util.ArrayList ; 36 import java.util.HashMap ; 37 import java.util.Iterator ; 38 import java.util.List ; 39 import java.util.Map ; 40 import java.util.Stack ; 41 import java.util.StringTokenizer ; 42 43 import javax.management.MBeanServer ; 44 import javax.management.MalformedObjectNameException ; 45 import javax.management.ObjectName ; 46 import javax.naming.Context ; 47 import javax.naming.InitialContext ; 48 import javax.naming.NamingException ; 49 import javax.naming.Reference ; 50 import javax.naming.StringRefAddr ; 51 import javax.xml.namespace.QName ; 52 53 import org.objectweb.jonas_lib.I18n; 54 import org.objectweb.jonas_lib.deployment.api.HandlerDesc; 55 import org.objectweb.jonas_lib.loader.WebappClassLoader; 56 import org.objectweb.jonas_lib.naming.ContainerNaming; 57 import org.objectweb.jonas_lib.naming.factory.URLFactory; 58 59 import org.objectweb.jonas_web.deployment.api.WebContainerDeploymentDesc; 60 import org.objectweb.jonas_web.deployment.api.WebContainerDeploymentDescException; 61 import org.objectweb.jonas_web.deployment.lib.wrapper.WebManagerWrapper; 62 63 import org.objectweb.jonas_ws.deployment.api.JaxRpcPortComponentDesc; 64 import org.objectweb.jonas_ws.deployment.api.PortComponentDesc; 65 import org.objectweb.jonas_ws.deployment.api.SSBPortComponentDesc; 66 import org.objectweb.jonas_ws.deployment.api.ServiceDesc; 67 import org.objectweb.jonas_ws.deployment.api.WSDLFile; 68 import org.objectweb.jonas_ws.deployment.api.WSDeploymentDesc; 69 import org.objectweb.jonas_ws.deployment.api.WSDeploymentDescException; 70 import org.objectweb.jonas_ws.deployment.lib.wrapper.WSManagerWrapper; 71 72 import org.objectweb.jonas.common.JProp; 73 import org.objectweb.jonas.common.Log; 74 import org.objectweb.jonas.ear.EarServiceImpl; 75 import org.objectweb.jonas.jmx.J2eeObjectName; 76 import org.objectweb.jonas.jmx.JmxService; 77 import org.objectweb.jonas.naming.CompNamingContext; 78 import org.objectweb.jonas.naming.NamingManager; 79 import org.objectweb.jonas.service.AbsServiceImpl; 80 import org.objectweb.jonas.service.ServiceException; 81 import org.objectweb.jonas.service.ServiceManager; 82 import org.objectweb.jonas.web.JWebContainerService; 83 import org.objectweb.jonas.web.JWebContainerServiceException; 84 import org.objectweb.jonas.ws.handler.WSDLHandler; 85 import org.objectweb.jonas.ws.handler.WSDLHandlerFactory; 86 import org.objectweb.jonas.ws.mbean.Handler; 87 import org.objectweb.jonas.ws.mbean.PortComponent; 88 import org.objectweb.jonas.ws.mbean.Service; 89 import org.objectweb.jonas.ws.mbean.WebServicesObjectName; 90 91 import org.objectweb.util.monolog.api.BasicLevel; 92 import org.objectweb.util.monolog.api.Logger; 93 94 100 public abstract class AbsWebServicesServiceImpl extends AbsServiceImpl implements WebServicesService, 101 AbsWebServicesServiceImplMBean { 102 103 107 public static final String PARSINGWITHVALIDATION = "jonas.service.ws.parsingwithvalidation"; 108 109 110 public static final String WSDL_HANDLERS = "jonas.service.ws.wsdlhandlers"; 111 112 116 public static final String WS_BASE = "jonas.service.ws."; 117 118 119 120 121 private static Logger logger = null; 122 123 124 private static I18n i18n = I18n.getInstance(AbsWebServicesServiceImpl.class); 125 126 127 private WSDLManager wsdlManager = null; 128 129 130 private JWebContainerService webService = null; 131 132 133 private MBeanServer mbeanServer = null; 134 135 138 private Map deployments = null; 139 140 143 private Map webservicesMBeans = null; 144 145 150 protected void doInit(Context ctx) throws ServiceException { 151 logger = Log.getLogger(Log.JONAS_WS_PREFIX); 153 154 155 ServiceManager serviceManager = null; 156 try { 157 serviceManager = ServiceManager.getInstance(); 158 } catch (Exception e) { 159 throw new ServiceException("Cannot initialize the WebServices Service", e); 160 } 161 162 deployments = new HashMap (); 164 webservicesMBeans = new HashMap (); 165 166 String parsingMode = "false"; 168 169 try { 170 parsingMode = (String ) ctx.lookup(PARSINGWITHVALIDATION); 171 } catch (NamingException e) { 172 parsingMode = "false"; 175 } 176 177 WSManagerWrapper.setParsingWithValidation("true".equalsIgnoreCase(parsingMode)); 178 179 if ("false".equalsIgnoreCase(parsingMode)) { 180 logger.log(BasicLevel.DEBUG, "WebServices XML parsing without validation"); 181 } else { 182 logger.log(BasicLevel.DEBUG, "WebServices XML parsing with validation"); 183 } 184 185 try { 186 JmxService jmxService = (JmxService) serviceManager.getJmxService(); 188 mbeanServer = jmxService.getJmxServer(); 189 } catch (ServiceException e) { 190 mbeanServer = null; 192 } 193 194 wsdlManager = new WSDLManager(); 196 197 JProp jp = null; 199 200 try { 201 jp = JProp.getInstance(); 202 } catch (Exception e) { 203 String err = i18n.getMessage("AbsWebServicesServiceImpl.doInit.noJProp"); 204 logger.log(BasicLevel.ERROR, err + " " + e.getMessage()); 205 throw new WSServiceException(err, e); 206 } 207 208 String [] handlers = jp.getValueAsArray(WSDL_HANDLERS); 209 210 if (handlers == null) { 211 String err = i18n.getMessage("AbsWebServicesServiceImpl.doInit.noHandlers", WSDL_HANDLERS); 212 logger.log(BasicLevel.ERROR, err); 213 throw new WSServiceException(err); 214 } 215 216 218 WSDLHandlerFactory factory = WSDLHandlerFactory.newInstance(); 219 220 for (int i = 0; i < handlers.length; i++) { 222 223 WSDLHandler handler = factory.newHandler(handlers[i]); 225 226 if (logger.isLoggable(BasicLevel.DEBUG)) { 227 logger.log(BasicLevel.DEBUG, "Adding WSDLHandler '" + handlers[i] + "'"); 228 } 229 230 wsdlManager.addHandler(handler); 232 } 233 } 234 235 249 public void deployWebServices(Context ctx) throws WSServiceException { 250 255 256 if (webService == null) { 258 try { 259 webService = (JWebContainerService) ServiceManager.getInstance().getWebContainerService(); 260 } catch (Exception e) { 261 String err = i18n.getMessage("AbsWebServicesServiceImpl.deployWebServices.noWeb"); 262 logger.log(BasicLevel.ERROR, err); 263 throw new WSServiceException(err, e); 264 } 265 } 266 267 URL [] jarUrls = null; 269 URL [] warUrls = null; 270 URL earURL = null; 271 ClassLoader ejbClassLoader = null; 272 ClassLoader earClassLoader = null; 273 Map warCtxRootMapping = null; 274 String unpackDir = null; 275 276 try { 278 jarUrls = (URL []) ctx.lookup("jarUrls"); 279 warUrls = (URL []) ctx.lookup("warUrls"); 280 unpackDir = (String ) ctx.lookup("unpackDir"); 281 } catch (NamingException e) { 282 String err = i18n.getMessage("AbsWebServicesServiceImpl.deployWebServices.ctxParamProblem"); 283 logger.log(BasicLevel.ERROR, err + e.getMessage()); 284 throw new WSServiceException(err, e); 285 } 286 287 try { 289 earURL = (URL ) ctx.lookup("earURL"); 290 earClassLoader = (ClassLoader ) ctx.lookup("earClassLoader"); 291 warCtxRootMapping = (Map ) ctx.lookup("warCtxRootMapping"); 292 ejbClassLoader = (ClassLoader ) ctx.lookup("ejbClassLoader"); 293 } catch (NamingException ne) { 294 earURL = null; 296 earClassLoader = null; 297 warCtxRootMapping = null; 298 ejbClassLoader = null; 299 } 300 301 URLClassLoader loaderForCls = null; 303 String earAppName = null; 304 if (earURL != null) { 305 earAppName = EarServiceImpl.buildJ2eeApplicationName(earURL); 306 } 307 308 String fileName = null; 309 WSDeploymentDesc wsDD = null; 310 311 for (int i = 0; i < warUrls.length; i++) { 312 fileName = warUrls[i].getFile(); 314 logger.log(BasicLevel.DEBUG, "Analyzing war '" + fileName + "' for web services"); 315 316 loaderForCls = webService.getClassLoader(warUrls[i], earAppName, ejbClassLoader); 318 319 WebappClassLoader webLoader = (WebappClassLoader) loaderForCls; 320 URL url = webLoader.getBaseURL(); 321 322 try { 324 wsDD = WSManagerWrapper.getDeploymentDesc(warUrls[i], url, loaderForCls, earClassLoader); 325 } catch (WSDeploymentDescException wsdde) { 326 String err = i18n.getMessage("AbsWebServicesServiceImpl.deployWebServices.wsddEx", fileName); 327 logger.log(BasicLevel.ERROR, err + ": " + wsdde); 328 throw new WSServiceException(err, wsdde); 329 } 330 331 if (wsDD != null) { 332 try { 334 Context compCtx = new CompNamingContext(fileName); 335 compCtx.rebind("wsDD", wsDD); 336 compCtx.rebind("cl", loaderForCls); 337 338 if (earClassLoader != null) { 339 compCtx.rebind("earCL", earClassLoader); 340 } 341 compCtx.rebind("warURL", warUrls[i]); 342 343 if (warCtxRootMapping != null) { 345 compCtx.rebind("warContextRoot", warCtxRootMapping.get(warUrls[i])); 346 347 } else { 349 compCtx.rebind("warContextRoot", ""); 350 } 351 352 doDeployWebServices(compCtx); 353 } catch (NamingException ne) { 354 String err = i18n.getMessage("AbsWebServicesServiceImpl.deployWebServices.bindError", fileName); 355 logger.log(BasicLevel.ERROR, err); 356 throw new WSServiceException(err, ne); 357 } 358 } 359 } 360 362 if ((jarUrls.length != 0) && (warCtxRootMapping == null)) { 365 String err = i18n.getMessage("AbsWebServicesServiceImpl.deployWebServices.ctxRootMappingMissing"); 366 logger.log(BasicLevel.ERROR, err); 367 throw new WSServiceException(err); 368 } 369 370 for (int i = 0; i < jarUrls.length; i++) { 371 fileName = jarUrls[i].getFile(); 373 logger.log(BasicLevel.DEBUG, "Analyzing EjbJar '" + fileName + "' for web services"); 374 375 URLClassLoader webClassLoader = null; 376 377 try { 379 wsDD = WSManagerWrapper.getDeploymentDesc(jarUrls[i], ejbClassLoader, earClassLoader); 380 } catch (WSDeploymentDescException wsdde) { 381 String err = i18n.getMessage("AbsWebServicesServiceImpl.deployWebServices.wsddEx", fileName); 382 logger.log(BasicLevel.ERROR, err + ": " + wsdde); 383 throw new WSServiceException(err, wsdde); 384 } 385 386 if (wsDD != null) { 387 URL warURL = null; 389 390 try { 391 395 if (wsDD.getWarFile() != null) { 396 warURL = new File (new URL (unpackDir + File.separator + wsDD.getWarFile()).getFile()).getCanonicalFile().toURL(); 399 } else { 401 String ejb = new File (jarUrls[i].getFile()).getName(); 402 String war = ejb.substring(0, ejb.length() - ".jar".length()); 403 warURL = new File (new URL (unpackDir + File.separator + war + ".war").getFile()).getCanonicalFile().toURL(); 405 } 406 logger.log(BasicLevel.DEBUG, "Unpack Dir : " + unpackDir); 407 logger.log(BasicLevel.DEBUG, "Computed URL : " + warURL); 408 409 boolean present = false; 411 412 for (int w = 0; w < warUrls.length; w++) { 413 if (warUrls[w].equals(warURL)) { 414 present = true; 415 } 416 logger.log(BasicLevel.DEBUG, "warUrls[" + w + "]=" + warUrls[w]); 417 } 418 419 webClassLoader = webService.getClassLoader(warURL, earAppName, ejbClassLoader); 421 422 if (!present) { 423 String err = i18n.getMessage("AbsWebServicesServiceImpl.deployWebServices.webappNotFound", 424 warURL); 425 logger.log(BasicLevel.ERROR, err); 426 throw new WSServiceException(err); 427 } 428 } catch (MalformedURLException mue) { 429 String err = i18n.getMessage("AbsWebServicesServiceImpl.deployWebServices.mue"); 430 logger.log(BasicLevel.ERROR, mue.getMessage()); 431 throw new WSServiceException(err, mue); 432 } catch (IOException ioe) { 433 String err = "Cannot locate file : " + ioe.getMessage(); 435 logger.log(BasicLevel.ERROR, err); 436 throw new WSServiceException(err, ioe); 437 } 438 439 try { 440 Context compCtx = new CompNamingContext(fileName); 441 compCtx.rebind("wsDD", wsDD); 442 443 compCtx.rebind("cl", webClassLoader); 445 compCtx.rebind("earCL", earClassLoader); 446 447 compCtx.rebind("warURL", warURL); 448 449 compCtx.rebind("warContextRoot", warCtxRootMapping.get(warURL)); 452 doDeployWebServices(compCtx); 453 } catch (NamingException ne) { 454 String err = i18n.getMessage("AbsWebServicesServiceImpl.deployWebServices.bindError", fileName); 455 logger.log(BasicLevel.ERROR, err); 456 throw new WSServiceException(err, ne); 457 } 458 } 459 } 460 461 } 463 464 469 protected void doDeployWebServices(Context ctx) throws WSServiceException { 470 476 WSDeploymentDesc wsDD = null; 477 ClassLoader cl = null; 478 ClassLoader earCL = null; 479 String warContextRoot = null; 480 URL warURL = null; 481 482 try { 483 wsDD = (WSDeploymentDesc) ctx.lookup("wsDD"); 484 cl = (ClassLoader ) ctx.lookup("cl"); 485 warContextRoot = (String ) ctx.lookup("warContextRoot"); 486 warURL = (URL ) ctx.lookup("warURL"); 487 } catch (NamingException ne) { 488 String err = i18n.getMessage("AbsWebServicesServiceImpl.doDeployWebServices.namingError"); 489 logger.log(BasicLevel.ERROR, err); 490 throw new WSServiceException(err, ne); 491 } 492 493 if (logger.isLoggable(BasicLevel.DEBUG)) { 494 logger.log(BasicLevel.DEBUG, "Deploying WebServices for '" + warURL + "'"); 495 } 496 497 try { 498 earCL = (ClassLoader ) ctx.lookup("earCL"); 499 } catch (NamingException ne) { 500 earCL = null; 502 } 503 504 ClassLoader key = cl; 506 if (earCL != null) { 507 key = earCL; 508 } 509 Stack s = (Stack ) deployments.get(key); 510 if (s == null) { 511 s = new Stack (); 512 deployments.put(key, s); 513 } 514 s.push(new WSDeployInfo(warURL, wsDD)); 515 516 517 List sds = wsDD.getServiceDescs(); 518 519 for (Iterator i = sds.iterator(); i.hasNext();) { 521 ServiceDesc sd = (ServiceDesc) i.next(); 522 WSDLFile wsdl = sd.getWSDL(); 523 524 for (Iterator pc = sd.getPortComponents().iterator(); pc.hasNext();) { 527 PortComponentDesc pcd = (PortComponentDesc) pc.next(); 528 QName portQName = pcd.getQName(); 529 URL endpoint = null; 530 if (pcd.hasJaxRpcImpl()) { 531 endpoint = getEndpointURL(wsDD, (JaxRpcPortComponentDesc) pcd, warURL, warContextRoot); 532 } else { 533 endpoint = getEndpointURL(wsDD, (SSBPortComponentDesc) pcd, warURL, cl, earCL, warContextRoot); 534 } 535 536 pcd.setEndpointURL(endpoint); 537 wsdl.setLocation(portQName, endpoint); 538 539 Context registry; 543 try { 544 registry = new InitialContext (); 545 Reference urlRef = new Reference (URL .class.getName(), URLFactory.class.getName(), null); 546 urlRef.add(new StringRefAddr ("url", endpoint.toString())); 547 registry.rebind(pcd.getName(), urlRef); 548 logger.log(BasicLevel.DEBUG, "Bind updated URL (" + endpoint + ") in " + pcd.getName()); 549 } catch (NamingException ne) { 550 throw new WSServiceException("Cannot bind updated URL for port-component '" + pcd.getName() 551 + "'", ne); 552 } 553 554 } 555 556 wsdlManager.publish(sd); 558 } 559 } 560 561 566 private void addHandlerMBeansToPortComponent(PortComponent pcMBean, PortComponentDesc pcd) { 567 568 for (Iterator i = pcd.getHandlers().iterator(); i.hasNext();) { 570 HandlerDesc hd = (HandlerDesc) i.next(); 571 572 Handler hMBean = createHandlerMBean(hd.getName(), pcMBean); 575 576 hMBean.setClassname(hd.getHandlerClassName()); 577 hMBean.setName(hd.getName()); 578 List sh = hd.getSOAPHeaders(); 580 String [] headers = new String [sh.size()]; 582 int index = 0; 583 for (Iterator j = sh.iterator(); j.hasNext();) { 584 headers[index++] = ((QName ) j.next()).toString(); 586 } 587 hMBean.setSoapHeaders(headers); 588 List sr = hd.getSOAPRoles(); 590 hMBean.setSoapRoles((String []) sr.toArray(new String [sr.size()])); 591 592 hMBean.setInitParams(hd.getInitParams()); 593 594 } 595 596 } 597 598 603 private static Handler createHandlerMBean(String name, PortComponent parent) { 604 Handler h = null; 605 try { 606 h = new Handler(WebServicesObjectName.handler(name, parent.getRealObjectName()).toString()); 607 } catch (MalformedObjectNameException e) { 608 logger.log(BasicLevel.DEBUG, "Should never happen", e); 610 } 611 parent.addHandlerMBean(h); 613 return h; 614 } 615 616 621 private static PortComponent createPortComponentMBean(String name, Service parent) { 622 PortComponent pc = null; 623 try { 624 pc = new PortComponent(WebServicesObjectName.portComponent(name, parent.getRealObjectName()).toString()); 625 } catch (MalformedObjectNameException e) { 626 logger.log(BasicLevel.DEBUG, "Should never happen", e); 628 } 629 parent.addPortComponentMBean(pc); 631 return pc; 632 } 633 634 639 private static Service createServiceMBean(String name, ObjectName parent) { 640 Service service = null; 641 try { 642 service = new Service(WebServicesObjectName.service(name, parent).toString()); 643 } catch (MalformedObjectNameException e) { 644 logger.log(BasicLevel.DEBUG, "Should never happen", e); 646 } 647 return service; 648 } 649 650 659 private URL getEndpointURL(WSDeploymentDesc wsDD, JaxRpcPortComponentDesc jpcd, URL warURL, String contextRoot) 660 throws WSServiceException { 661 662 logger.log(BasicLevel.DEBUG, "get endpoint for JaxRpc Port Component"); 663 664 return getEndpointURL(wsDD, jpcd.getWebDesc(), warURL, contextRoot, jpcd); 665 666 } 667 668 679 private URL getEndpointURL(WSDeploymentDesc wsDD, SSBPortComponentDesc spcd, URL warURL, ClassLoader cl, 680 ClassLoader earCL, String contextRoot) throws WSServiceException { 681 682 logger.log(BasicLevel.DEBUG, "get endpoint for StatelessSessionBean Port Component"); 683 684 WebContainerDeploymentDesc webDD = null; 685 686 try { 687 webDD = WebManagerWrapper.getDeploymentDesc(warURL, cl, earCL); 688 } catch (WebContainerDeploymentDescException e) { 689 String err = i18n.getMessage("AbsWebServicesServiceImpl.getEndpointURL.webDDException", warURL.getFile()); 690 logger.log(BasicLevel.ERROR, err); 691 throw new WSServiceException(err, e); 692 } 693 694 return getEndpointURL(wsDD, webDD, warURL, contextRoot, spcd);
|