From: Thomas D. <tdi...@us...> - 2004-04-28 14:37:36
|
User: tdiesler Date: 04/04/28 07:37:28 Modified: src/main/org/jboss/webservice AxisService.java Added: src/main/org/jboss/webservice InvokerProvider.java InvokerProviderEJB.java InvokerProviderJSE.java ServerLoginHandler.java ServiceDeployer.java ServiceDeployerEJB.java ServiceDeployerJSE.java ServiceException.java Removed: src/main/org/jboss/webservice AbstractWebserviceDeployer.java EJBInvokerProvider.java WebInvokerProvider.java WebInvokerServlet.java WebserviceBaseProvider.java WebserviceEJBDeployer.java WebserviceException.java WebserviceWARDeployer.java Log: + use Constants interface + add ServerLoginHandler + better service naming + use more intuetive class names Revision Changes Path 1.5 +6 -6 webservice/src/main/org/jboss/webservice/AxisService.java Index: AxisService.java =================================================================== RCS file: /cvsroot/jboss/webservice/src/main/org/jboss/webservice/AxisService.java,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- AxisService.java 27 Apr 2004 16:47:36 -0000 1.4 +++ AxisService.java 28 Apr 2004 14:37:25 -0000 1.5 @@ -5,10 +5,10 @@ * See terms of license at gnu.org. */ -// $Id: AxisService.java,v 1.4 2004/04/27 16:47:36 tdiesler Exp $ +// $Id: AxisService.java,v 1.5 2004/04/28 14:37:25 tdiesler Exp $ package org.jboss.webservice; -// $Id: AxisService.java,v 1.4 2004/04/27 16:47:36 tdiesler Exp $ +// $Id: AxisService.java,v 1.5 2004/04/28 14:37:25 tdiesler Exp $ import org.apache.axis.EngineConfiguration; import org.apache.axis.MessageContext; @@ -96,9 +96,9 @@ throws DeploymentException { ClassLoader cl = getClass().getClassLoader(); - InputStream inputStream = cl.getResourceAsStream("META-INF/axis-client.xml"); + InputStream inputStream = cl.getResourceAsStream(Constants.AXIS_CLIENT_CONFIG); if (inputStream == null) - throw new DeploymentException("Cannot obtain the axis-client configuration"); + throw new DeploymentException("Cannot obtain configuration: " + Constants.AXIS_CLIENT_CONFIG); EngineConfiguration clientConfig = new FileProvider(inputStream); return clientConfig; @@ -111,9 +111,9 @@ throws DeploymentException { ClassLoader cl = getClass().getClassLoader(); - InputStream inputStream = cl.getResourceAsStream("META-INF/axis-server.xml"); + InputStream inputStream = cl.getResourceAsStream(Constants.AXIS_SERVER_CONFIG); if (inputStream == null) - throw new DeploymentException("Cannot obtain the axis-server configuration"); + throw new DeploymentException("Cannot obtain configuration: " + Constants.AXIS_SERVER_CONFIG); EngineConfiguration serverConfig = new FileProvider(inputStream); return serverConfig; 1.1 webservice/src/main/org/jboss/webservice/InvokerProvider.java Index: InvokerProvider.java =================================================================== /* * JBoss, the OpenSource J2EE webOS * * Distributable under LGPL license. * See terms of license at gnu.org. */ package org.jboss.webservice; // $Id: InvokerProvider.java,v 1.1 2004/04/28 14:37:25 tdiesler Exp $ import org.apache.axis.AxisFault; import org.apache.axis.Handler; import org.apache.axis.MessageContext; import org.apache.axis.handlers.soap.SOAPService; import org.apache.axis.providers.java.RPCProvider; import org.apache.axis.transport.http.HTTPConstants; import org.jboss.deployment.DeploymentInfo; import org.jboss.deployment.MainDeployerMBean; import org.jboss.mx.util.MBeanServerLocator; import org.jboss.webservice.metadata.PortComponent; import org.jboss.webservice.metadata.WebserviceDescription; import org.jboss.webservice.metadata.Webservices; import org.jboss.logging.Logger; import org.w3c.dom.Document; import javax.management.MBeanServer; import javax.servlet.http.HttpServletRequest; import javax.wsdl.Definition; import javax.wsdl.Port; import javax.wsdl.Service; import javax.wsdl.WSDLException; import javax.wsdl.extensions.soap.SOAPAddress; import javax.wsdl.factory.WSDLFactory; import javax.wsdl.xml.WSDLWriter; import java.net.MalformedURLException; import java.net.URL; import java.util.Iterator; import java.util.Map; /** * An RPC provider base that provides access to some * webservice specific meta-data artifacts through JMX. * * @author Tho...@jb... * @since 15-April-2004 */ public class InvokerProvider extends RPCProvider { // provide logging protected Logger log = Logger.getLogger(getClass()); // The MBeanServer protected MBeanServer server; /** this webservice description */ protected WebserviceDescription webserviceDescription; /** this port component */ protected PortComponent portComponent; /** the deployment info */ protected DeploymentInfo di; // true when the port location was corrected private boolean wsdlInitialized; /** Get deployment meta info * @param msgContext the SOAP MessageContext, or null */ public void initServiceDesc(SOAPService service, MessageContext msgContext) throws AxisFault { // Note, the msgContext may be null if the first request is not a SOAP message // this is the case for the list operation http://localhost:8080/ws4ee/servlet/AxisServlet try { // locate the MBeanServer server = MBeanServerLocator.locateJBoss(); // build objectname and position from service parameters URL url = new URL((String) service.getOption(PortComponent.PARAMETER_DEPLOYMENT_URL)); di = (DeploymentInfo) server.invoke(MainDeployerMBean.OBJECT_NAME, "getDeployment", new Object[]{url}, new String[]{URL.class.getName()}); if (di == null) throw new ServiceException("Cannot obtain deployment info for: " + url); Webservices wsMetaData = (Webservices) server.invoke(AxisServiceMBean.OBJECT_NAME, "getWebservices", new Object[]{url}, new String[]{URL.class.getName()}); if (wsMetaData == null) throw new ServiceException("Cannot obtain webservice meta data for: " + url); // get the webservice description Integer wsdIndex = new Integer((String) service.getOption(PortComponent.PARAMETER_WEBSERVICE_INDEX)); webserviceDescription = wsMetaData.getWebserviceDescriptions()[wsdIndex.intValue()]; if (webserviceDescription == null) throw new ServiceException("Cannot obtain webservice description for index: " + wsdIndex); // get the port component Integer pcIndex = new Integer((String) service.getOption(PortComponent.PARAMETER_PORT_COMPONENT_INDEX)); portComponent = webserviceDescription.getPortComponents()[pcIndex.intValue()]; if (portComponent == null) throw new ServiceException("Cannot obtain port component for index: " + pcIndex); } catch (Exception e) { throw new ServiceException("Cannot initialize webservice", e); } // delegate to parent super.initServiceDesc(service, msgContext); } /** * Generate the WSDL for this service. * * Put in the "WSDL" property of the message context * as a org.w3c.dom.Document */ public void generateWSDL(MessageContext msgContext) throws AxisFault { try { if (wsdlInitialized == false) { replacePortLocation(msgContext, webserviceDescription.getWsdlDefinition()); wsdlInitialized = true; } } catch (WSDLException e) { throw new ServiceException("Cannot replace port location", e); } Document wsdlDocument = webserviceDescription.getWsdlDocument(); msgContext.setProperty("WSDL", wsdlDocument); } /** * Returns the Class info about the service class. */ protected Class getServiceClass(String clsName, SOAPService service, MessageContext msgContext) throws AxisFault { Class seiClass = portComponent.getServiceEndpointInterfaceClass(); if (seiClass == null) throw new ServiceException("Cannot load service endpoint interface"); return seiClass; } /** * Return the class name of the service. * We return the SEI instead. */ protected String getServiceClassName(Handler arg0) { return portComponent.getServiceEndpointInterface(); } /** Replace the port location with the actual one in JBoss */ private void replacePortLocation(MessageContext msgContext, Definition wsdlDefinition) throws WSDLException, AxisFault { HttpServletRequest req = (HttpServletRequest) msgContext.getProperty(HTTPConstants.MC_HTTP_SERVLETREQUEST); if (req == null) throw new ServiceException("Cannot obtain request from msgContext"); String scheme = req.getScheme(); String serverHostName = req.getServerName(); int serverPort = req.getServerPort(); // navigate down to the port location and replace it boolean replaced = false; Map serviceMap = wsdlDefinition.getServices(); Iterator itServices = serviceMap.keySet().iterator(); while (itServices.hasNext()) { Object serviceKey = itServices.next(); Service wsdlService = (Service) serviceMap.get(serviceKey); Map portMap = wsdlService.getPorts(); Iterator itPorts = portMap.keySet().iterator(); while (itPorts.hasNext()) { Object portKey = itPorts.next(); Port wsdlPort = (Port) portMap.get(portKey); // find the localpart for this port name String wsdlPortName = wsdlPort.getName(); String webservicesPortName = portComponent.getWsdlPort().getLocalPart(); if (wsdlPortName.equals(webservicesPortName)) { String serviceName = portComponent.getServiceName(); Iterator itElements = wsdlPort.getExtensibilityElements().iterator(); while (itElements.hasNext()) { Object obj = itElements.next(); if (obj instanceof SOAPAddress) { SOAPAddress address = (SOAPAddress) obj; String wsdlURI = address.getLocationURI(); String jbossURI = scheme + "://" + serverHostName + ":" + serverPort + "/ws4ee/services/" + serviceName; log.info("Replace port location '" + wsdlURI + "' with '" + jbossURI + "'"); address.setLocationURI(jbossURI); replaced = true; } } } } } // write the WSDL Document back if (replaced == true) { WSDLFactory wsdlFactory = WSDLFactory.newInstance(); WSDLWriter wsdlWriter = wsdlFactory.newWSDLWriter(); Document wsdlDocument = wsdlWriter.getDocument(wsdlDefinition); webserviceDescription.setWsdlDocument(wsdlDocument); } else { log.warn("Could not replace service location in WSDL document"); } } } 1.1 webservice/src/main/org/jboss/webservice/InvokerProviderEJB.java Index: InvokerProviderEJB.java =================================================================== /* * JBoss, the OpenSource J2EE webOS * * Distributable under LGPL license. * See terms of license at gnu.org. */ // $Id: InvokerProviderEJB.java,v 1.1 2004/04/28 14:37:25 tdiesler Exp $ package org.jboss.webservice; // $Id: InvokerProviderEJB.java,v 1.1 2004/04/28 14:37:25 tdiesler Exp $ import org.apache.axis.AxisFault; import org.apache.axis.MessageContext; import org.apache.axis.handlers.soap.SOAPService; import org.jboss.ejb.AllowedOperationsFlags; import org.jboss.invocation.Invocation; import org.jboss.invocation.InvocationKey; import org.jboss.invocation.InvocationType; import org.jboss.metadata.ApplicationMetaData; import org.jboss.metadata.BeanMetaData; import javax.management.MalformedObjectNameException; import javax.management.ObjectName; import java.lang.reflect.Method; /** * An Axis RPC provider for EJB endpoints. * * @author Tho...@jb... * @since 15-April-2004 */ public class InvokerProviderEJB extends InvokerProvider implements AllowedOperationsFlags { private String jndiName; private ObjectName containerName; /** * Get deployment meta info */ public void initServiceDesc(SOAPService service, MessageContext msgContext) throws AxisFault { super.initServiceDesc(service, msgContext); String ejbLink = portComponent.getEjbLink(); if (ejbLink == null) throw new ServiceException("Cannot obtain ejb-link from port component"); ApplicationMetaData applMetaData = (ApplicationMetaData) di.metaData; BeanMetaData beanMetaData = applMetaData.getBeanByEjbName(ejbLink); if (beanMetaData == null) throw new ServiceException("Cannot obtain ejb meta data for: " + ejbLink); // get the bean's JNDI name jndiName = beanMetaData.getContainerObjectNameJndiName(); if (jndiName == null) throw new ServiceException("Cannot obtain JNDI name for: " + ejbLink); try { containerName = new ObjectName("jboss.j2ee:jndiName=" + jndiName + ",service=EJB"); } catch (MalformedObjectNameException e) { throw new ServiceException(e.toString()); } } /** The actual invocation is done through the container, not through this object. */ protected Object makeNewServiceObject(MessageContext msgContext, String className) throws Exception { return null; } /** * This method encapsulates the method invocation. * @param msgContext MessageContext * @param method the target method. * @param obj the target object * @param argValues the method arguments */ protected Object invokeMethod(MessageContext msgContext, Method method, Object obj, Object[] argValues) throws Exception { // setup the invocation Invocation inv = new Invocation(null, method, argValues, null, null, null); inv.setValue(InvocationKey.SOAP_MESSAGE_CONTEXT, msgContext); inv.setType(InvocationType.REMOTE); // invoke on the container Object ret = server.invoke(containerName, "invoke", new Object[]{inv}, new String[]{Invocation.class.getName()}); return ret; } } 1.1 webservice/src/main/org/jboss/webservice/InvokerProviderJSE.java Index: InvokerProviderJSE.java =================================================================== /* * JBoss, the OpenSource J2EE webOS * * Distributable under LGPL license. * See terms of license at gnu.org. */ // $Id: InvokerProviderJSE.java,v 1.1 2004/04/28 14:37:25 tdiesler Exp $ package org.jboss.webservice; // $Id: InvokerProviderJSE.java,v 1.1 2004/04/28 14:37:25 tdiesler Exp $ import javax.servlet.http.HttpSessionBindingEvent; import javax.servlet.http.HttpSessionBindingListener; import javax.xml.rpc.server.ServiceLifecycle; import org.apache.axis.MessageContext; import java.lang.reflect.Method; import java.util.Map; import java.util.HashMap; /** * An Axis RPC provider for WEB endpoints. * * @author Tho...@jb... * @since 15-April-2004 */ public class InvokerProviderJSE extends InvokerProvider { // maps the SEI Method to the endpoint bean Method private Map methodMap = new HashMap(); /** * Create an instance of the Servlet */ protected Object makeNewServiceObject(MessageContext msgContext, String clsName) throws Exception { String serviceEndpointBean = portComponent.getServiceEndpointBean(); if (serviceEndpointBean == null) throw new ServiceException("Service endpoint bean class not set"); Object obj = super.makeNewServiceObject(msgContext, serviceEndpointBean); return obj; } /** * This method encapsulates the method invocation. * @param msgContext MessageContext * @param method the target method. * @param obj the target object * @param argValues the method arguments */ protected Object invokeMethod(MessageContext msgContext, Method method, Object obj, Object[] argValues) throws Exception { // map the SEI method to the bean method Method beanMethod = (Method)methodMap.get(method); if (beanMethod == null) { beanMethod = obj.getClass().getMethod(method.getName(), method.getParameterTypes()); methodMap.put(method, beanMethod); } // the bean must implement the SEI Object retObj = beanMethod.invoke(obj, argValues); return retObj; } } 1.1 webservice/src/main/org/jboss/webservice/ServerLoginHandler.java Index: ServerLoginHandler.java =================================================================== /* * JBoss, the OpenSource J2EE webOS * * Distributable under LGPL license. * See terms of license at gnu.org. */ // $Id: ServerLoginHandler.java,v 1.1 2004/04/28 14:37:25 tdiesler Exp $ package org.jboss.webservice; // $Id: ServerLoginHandler.java,v 1.1 2004/04/28 14:37:25 tdiesler Exp $ import org.jboss.logging.Logger; import org.jboss.security.SecurityAssociation; import javax.xml.namespace.QName; import javax.xml.rpc.JAXRPCException; import javax.xml.rpc.handler.GenericHandler; import javax.xml.rpc.handler.MessageContext; import javax.xml.rpc.handler.soap.SOAPMessageContext; import javax.xml.soap.Name; import javax.xml.soap.SOAPException; import javax.xml.soap.SOAPFactory; import javax.xml.soap.SOAPHeader; import javax.xml.soap.SOAPHeaderElement; import javax.xml.soap.SOAPMessage; import java.security.Principal; /** * Add username/password from the SecurityAssociation as * SOAP header elements. * * @author Tho...@jb... * @since 27-April-2004 */ public class ServerLoginHandler extends GenericHandler { // provide logging private static final Logger log = Logger.getLogger(ServerLoginHandler.class); // The headers known to this handler private static QName[] headerNames = { new QName(Constants.WS4EE_NAMESPACE_URI, "username"), new QName(Constants.WS4EE_NAMESPACE_URI, "password") }; /** * Gets the header blocks processed by this Handler instance. * * new QName("http://webservice.jboss.com/ws4ee", "username") * new QName("http://webservice.jboss.com/ws4ee", "password") * * @return Array of QNames of header blocks processed by this handler instance. * QName is the qualified name of the outermost element of the Header block. */ public QName[] getHeaders() { return headerNames; } /** * Get principal/credential from SOAP header elements and put them into the SecurityAssociation. * @param context the message context * @return true/false */ public boolean handleRequest(MessageContext context) { Principal principal = SecurityAssociation.getPrincipal(); Object credential = SecurityAssociation.getCredential(); try { SOAPMessageContext soapCtx = (SOAPMessageContext)context; SOAPMessage soapMessage = soapCtx.getMessage(); SOAPHeader soapHeader = soapMessage.getSOAPPart().getEnvelope().getHeader(); } catch (SOAPException e) { log.error ("Cannot handle request: " + e.toString()); throw new JAXRPCException(e); } return true; } } 1.1 webservice/src/main/org/jboss/webservice/ServiceDeployer.java Index: ServiceDeployer.java =================================================================== /* * JBoss, the OpenSource J2EE webOS * * Distributable under LGPL license. * See terms of license at gnu.org. */ // $Id: ServiceDeployer.java,v 1.1 2004/04/28 14:37:25 tdiesler Exp $ package org.jboss.webservice; // $Id: ServiceDeployer.java,v 1.1 2004/04/28 14:37:25 tdiesler Exp $ import org.dom4j.Document; import org.dom4j.io.OutputFormat; import org.dom4j.io.SAXReader; import org.dom4j.io.XMLWriter; import org.jboss.deployment.DeploymentException; import org.jboss.deployment.DeploymentInfo; import org.jboss.deployment.SubDeployer; import org.jboss.logging.Logger; import org.jboss.mx.util.MBeanServerLocator; import org.jboss.system.ServiceMBeanSupport; import org.jboss.webservice.metadata.PortComponent; import org.jboss.webservice.metadata.WebserviceDescription; import org.jboss.webservice.metadata.Webservices; import org.jboss.webservice.metadata.WebservicesFactory; import org.jboss.xml.binding.ObjectModelFactory; import org.jboss.xml.binding.Unmarshaller; import javax.management.InstanceNotFoundException; import javax.management.MBeanServer; import javax.management.Notification; import javax.management.NotificationFilterSupport; import javax.management.NotificationListener; import javax.management.ObjectName; import java.io.File; import java.io.FileWriter; import java.io.InputStream; import java.io.StringReader; import java.io.StringWriter; import java.net.URL; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map; /** * A deployer service that manages WS4EE compliant Web-Services within JMX * by translating/delegating to an axis deployer. * <p/> * This service receives deployment notifications from the EJBDeployer and * AbstractWebContainer and deploys the webservices using the {@link AxisService} * * @jmx.mbean * description="Abstract Webservice deployer" * extends="org.jboss.system.ServiceMBean" * * @author Tho...@jb... * @since 15-April-2004 */ public abstract class ServiceDeployer extends ServiceMBeanSupport implements ServiceDeployerMBean, NotificationListener { // provide logging protected final Logger log = Logger.getLogger(getClass()); // JBoss MBeanServer private MBeanServer server; /** * Register this service as NotificationListener to the * EJBDeployer, WARDeployer */ protected void startService() throws Exception { server = MBeanServerLocator.locateJBoss(); } /** * Unregister this service as NotificationListener from the * EJBDeployer, WARDeployer */ protected void stopService() { server = null; } /** * Get the webservices metadata for a given EJB/WAR deployment * @param url the URL of the deployment * @return the webservices metadata, or null */ protected Webservices getWebservices(URL url) { try { Webservices webservices = (Webservices)server.invoke( AxisServiceMBean.OBJECT_NAME, "getWebservices", new Object[]{url}, new String[]{URL.class.getName()}); return webservices; } catch (Exception e) { log.error ("Cannot obtain webservices for: " + url, e); return null; } } /** Register the Webservices meta data * @param url the URL of the parent deployment * @param webservices Webservices meta data */ private void registerWebservice(URL url, Webservices webservices) { try { server.invoke( AxisServiceMBean.OBJECT_NAME, "registerWebservice", new Object[]{url, webservices}, new String[]{URL.class.getName(), Webservices.class.getName()}); } catch (Exception e) { log.error ("Cannot register webservices for: " + url, e); } } /** Unregister the Webservices meta data * @param url the URL of the parent deployment */ private void unregisterWebservice(URL url) { try { server.invoke( AxisServiceMBean.OBJECT_NAME, "unregisterWebservice", new Object[]{url}, new String[]{URL.class.getName()}); } catch (Exception e) { log.error ("Cannot unregister webservices for: " + url, e); } } /** * Callback method from the broadcaster MBean this listener implementation * is registered to. * * @param notification the notification object * @param handback the handback object given to the broadcaster * upon listener registration */ public void handleNotification(Notification notification, Object handback) { DeploymentInfo di = (DeploymentInfo) notification.getUserData(); // this isn't a webservices deployment if (getWebservicesDescriptor(di) == null) return; String moduleName = di.shortName; try { if (notification.getType().equals(SubDeployer.INIT_NOTIFICATION)) initWebservice(di); else if (notification.getType().equals(SubDeployer.CREATE_NOTIFICATION)) createWebservice(di); else if (notification.getType().equals(SubDeployer.START_NOTIFICATION)) startWebservice(di); } catch (Throwable e) { handleStartupException(moduleName, e); } try { if (notification.getType().equals(SubDeployer.STOP_NOTIFICATION)) stopWebservice(di); else if (notification.getType().equals(SubDeployer.DESTROY_NOTIFICATION)) destroyWebservice(di); } catch (Throwable e) { handleShutdownException(moduleName, e); } } /** Overwrite to initialize the webservice * Is called when the parent deployer sends the INIT_NOTIFICATION. * * This implementation does nothing */ protected void initWebservice(DeploymentInfo di) throws DeploymentException { } /** Overwrite to create the webservice * Is called when the parent deployer sends the CREATE_NOTIFICATION. * * This implementation parses webservices.xml and puts it in the local registry. */ protected void createWebservice(DeploymentInfo di) throws DeploymentException { URL url = getWebservicesDescriptor(di); if (url != null) { Webservices webservices = parseWebservicesXML(di, url); registerWebservice(di.url, webservices); } } /** Get the resource name of the webservices.xml descriptor. */ protected abstract URL getWebservicesDescriptor(DeploymentInfo di); /** Overwrite to start the webservice * Is called when the parent deployer sends the START_NOTIFICATION. * * This implementation deployes the webservices to Axis. */ protected void startWebservice(DeploymentInfo di) throws DeploymentException { Webservices webservices = getWebservices(di.url); if (webservices != null) deployWebservices(di, webservices); } /** Overwrite to stop the webservice * Is called when the parent deployer sends the STOP_NOTIFICATION. * * This implementation undeployes the webservices to Axis and * removes the webservices.xml from the local registry. */ protected void stopWebservice(DeploymentInfo di) { Webservices webservices = getWebservices(di.url); if (webservices != null) { undeployWebservices(webservices); unregisterWebservice(di.url); } } /** Overwrite to destroy the webservice * This method is called when the parent deployer sends the DESTROY_NOTIFICATION. */ protected void destroyWebservice(DeploymentInfo di) { } // PROTECTED ******************************************************************************************************* /** * Handle all webservice deployment exceptions. * * You can either simply logs the problem and keep the EJB/WAR module * alive or undeploy properly. */ protected void handleStartupException(String moduleName, Throwable th) { log.error("Cannot startup webservice for: " + moduleName, th); } /** * Handle all webservice deployment exceptions. * * You can either simply logs the problem and keep the EJB/WAR module * alive or undeploy properly. */ protected void handleShutdownException(String moduleName, Throwable th) { log.error("Cannot shutdown webservice for: " + moduleName, th); } /** * Register the notification listener */ protected void registerNotificationListener(ObjectName serviceName) throws InstanceNotFoundException { NotificationFilterSupport filter = new NotificationFilterSupport(); filter.enableType(SubDeployer.INIT_NOTIFICATION); filter.enableType(SubDeployer.CREATE_NOTIFICATION); filter.enableType(SubDeployer.START_NOTIFICATION); filter.enableType(SubDeployer.STOP_NOTIFICATION); filter.enableType(SubDeployer.DESTROY_NOTIFICATION); server.addNotificationListener(serviceName, this, filter, null); } /** * Unregister the notification listener */ protected void unregisterNotificationListener(ObjectName serviceName) { try { server.removeNotificationListener(serviceName, this); } catch (Exception e) { log.error("Cannot remove notification listener: " + e.toString()); } } /** * Unmarshal the webservices.xml */ protected Webservices parseWebservicesXML(DeploymentInfo di, URL webservicesURL) throws DeploymentException { Webservices webservices = null; try { // let the object model factory to create an instance and populate it with data from XML InputStream is = webservicesURL.openStream(); try { // setup the XML binding Unmarshaller Unmarshaller unmarshaller = new Unmarshaller(); ObjectModelFactory factory = new WebservicesFactory(di); webservices = (Webservices) unmarshaller.unmarshal(is, factory, null); } finally { is.close(); } } catch (Exception e) { throw new DeploymentException("Cannot obtain webservices meta data", e); } return webservices; } /** * Generate the Axis deployment WSDD from the webservices meta data. */ protected Map getAxisDeployments(DeploymentInfo di, Webservices webservices) throws DeploymentException { WebserviceDescription[] wsdarr = webservices.getWebserviceDescriptions(); Map wsddMap = new LinkedHashMap(); for (int wsdIndex = 0; wsdIndex < wsdarr.length; wsdIndex++) { WebserviceDescription wsDescription = wsdarr[wsdIndex]; PortComponent[] pcarr = wsDescription.getPortComponents(); for (int pcIndex = 0; pcIndex < pcarr.length; pcIndex++) { PortComponent portComponent = pcarr[pcIndex]; StringBuffer buffer = new StringBuffer(); buffer.append("<deployment"); buffer.append(" xmlns='http://xml.apache.org/axis/wsdd/'"); buffer.append(" xmlns:java='http://xml.apache.org/axis/wsdd/providers/java'"); buffer.append(" xmlns:xsi='http://www.w3.org/2000/10/XMLSchema-instance'>"); String serviceName = portComponent.getServiceName(); buffer.append("<service name='" + serviceName + "' provider='Handler'>"); buffer.append("<parameter name='" + PortComponent.PARAMETER_WEBSERVICE_INDEX + "' value='" + wsdIndex + "' />"); buffer.append("<parameter name='" + PortComponent.PARAMETER_PORT_COMPONENT_INDEX + "' value='" + pcIndex + "' />"); buffer.append("<parameter name='" + PortComponent.PARAMETER_DEPLOYMENT_URL + "' value='" + di.url + "' />"); String ejbLink = portComponent.getEjbLink(); String servletLink = portComponent.getServletLink(); if (ejbLink != null) buffer.append("<parameter name='handlerClass' value='" + InvokerProviderEJB.class.getName() + "' />"); else if (servletLink != null) buffer.append("<parameter name='handlerClass' value='" + InvokerProviderJSE.class.getName() + "' />"); /* appendExtraTypeMappings(buffer); if (handlers.length != 0) { buffer.append("<handlerInfoChain>"); for (int count = 0; count < handlers.length; count++) { handlers[count].getDeploymentWSDD(buffer); } for (int count = 0; count < handlers.length; count++) { Iterator allRoles = handlers[count].soapRoles.iterator(); while (allRoles.hasNext()) { ((SoapRole) allRoles.next()).getDeploymentWSDD(buffer); } } buffer.append("</handlerInfoChain>"); } */ buffer.append("</service>"); //jaxrpcMapping.getDeploymentWSDD(buffer); buffer.append("</deployment>"); try { // format nicely SAXReader reader = new SAXReader(); Document document = reader.read(new StringReader(buffer.toString())); OutputFormat format = OutputFormat.createPrettyPrint(); StringWriter wsddWriter = new StringWriter(buffer.length()); XMLWriter writer = new XMLWriter(wsddWriter, format); writer.write(document); // write the deployment.xml to a temp file File tmpFile = File.createTempFile("deployment", ".xml"); FileWriter fos = new FileWriter(tmpFile); fos.write(wsddWriter.toString()); fos.close(); if (wsddMap.containsKey(serviceName)) throw new DeploymentException("Cannot deploy same serviceName more than once: " + serviceName); wsddMap.put(serviceName, tmpFile.toURL()); log.debug("deployment.xml\n" + wsddWriter.toString()); } catch (Exception e) { throw new DeploymentException("Cannot generate Axis deployment", e); } } } return wsddMap; } /** * Deploy the webservices using the AxisService MBean */ protected void deployWebservices(DeploymentInfo di, Webservices webservices) throws DeploymentException { MBeanServer server = MBeanServerLocator.locateJBoss(); Map wsddMap = getAxisDeployments(di, webservices); try { Iterator it = wsddMap.entrySet().iterator(); while (it.hasNext()) { Map.Entry entry = (Map.Entry) it.next(); String serviceName = (String) entry.getKey(); URL wsddURL = (URL) entry.getValue(); server.invoke(AxisServiceMBean.OBJECT_NAME, "deployService", new Object[]{serviceName, wsddURL}, new String[]{String.class.getName(), URL.class.getName()}); if (new File(wsddURL.getPath()).delete() == false) log.warn("Cannot delete temp file: " + wsddURL); } } catch (Exception e) { throw new DeploymentException("Cannot deploy webservice", e); } } /** * Undeploy the webservices using the AxisService MBean */ protected void undeployWebservices(Webservices webservices) { if (webservices != null) { WebserviceDescription[] wsdarr = webservices.getWebserviceDescriptions(); for (int wsdIndex = 0; wsdIndex < wsdarr.length; wsdIndex++) { WebserviceDescription wsDescription = wsdarr[wsdIndex]; PortComponent[] pcarr = wsDescription.getPortComponents(); for (int pcIndex = 0; pcIndex < pcarr.length; pcIndex++) { PortComponent portComponent = pcarr[pcIndex]; try { MBeanServer server = MBeanServerLocator.locateJBoss(); server.invoke(AxisService.OBJECT_NAME, "undeployService", new Object[]{portComponent.getServiceName()}, new String[]{String.class.getName()}); } catch (Exception ignore) { log.warn("Cannot undeploy webservice: " + ignore); } } } } } } 1.1 webservice/src/main/org/jboss/webservice/ServiceDeployerEJB.java Index: ServiceDeployerEJB.java =================================================================== /* * JBoss, the OpenSource J2EE webOS * * Distributable under LGPL license. * See terms of license at gnu.org. */ // $Id: ServiceDeployerEJB.java,v 1.1 2004/04/28 14:37:25 tdiesler Exp $ package org.jboss.webservice; // $Id: ServiceDeployerEJB.java,v 1.1 2004/04/28 14:37:25 tdiesler Exp $ import org.jboss.deployment.DeploymentException; import org.jboss.deployment.DeploymentInfo; import org.jboss.webservice.metadata.Webservices; import javax.management.ObjectName; import java.net.URL; /** * A deployer service that manages WS4EE compliant Web-Services for EJB * * @jmx.mbean name="jboss.webservice:service=ServiceDeployerEJB" * description="Webservice EJB deployer" * extends="org.jboss.webservice.ServiceDeployerMBean" * * @author Tho...@jb... * @since 15-April-2004 */ public class ServiceDeployerEJB extends ServiceDeployer implements ServiceDeployerEJBMBean { // service name of the EJB deployer private ObjectName ejbDeployer; /** * Set the service name of the EJB deployer * @jmx.managed-attribute */ public void setEJBDeployer(ObjectName deployerName) { this.ejbDeployer = deployerName; } /** * Register this service as NotificationListener to the EJBDeployer */ protected void startService() throws Exception { super.startService(); registerNotificationListener(ejbDeployer); } /** * Unregister this service as NotificationListener from the EJBDeployer */ protected void stopService() { unregisterNotificationListener(ejbDeployer); super.stopService(); } /** Get the resource name of the webservices.xml descriptor. */ protected URL getWebservicesDescriptor(DeploymentInfo di) { return di.localCl.findResource("META-INF/webservices.xml"); } } 1.1 webservice/src/main/org/jboss/webservice/ServiceDeployerJSE.java Index: ServiceDeployerJSE.java =================================================================== /* * JBoss, the OpenSource J2EE webOS * * Distributable under LGPL license. * See terms of license at gnu.org. */ // $Id: ServiceDeployerJSE.java,v 1.1 2004/04/28 14:37:25 tdiesler Exp $ package org.jboss.webservice; // $Id: ServiceDeployerJSE.java,v 1.1 2004/04/28 14:37:25 tdiesler Exp $ import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.io.OutputFormat; import org.dom4j.io.SAXReader; import org.dom4j.io.XMLWriter; import org.jboss.deployment.DeploymentException; import org.jboss.deployment.DeploymentInfo; import org.jboss.webservice.metadata.PortComponent; import org.jboss.webservice.metadata.WebserviceDescription; import org.jboss.webservice.metadata.Webservices; import javax.management.ObjectName; import java.io.File; import java.io.FileOutputStream; import java.net.URL; import java.util.Iterator; import java.util.ArrayList; /** * A deployer service that manages WS4EE compliant Web-Services for WAR * * @jmx.mbean name="jboss.webservice:service=ServiceDeployerJSE" * description="Webservice WAR deployer" * extends="org.jboss.webservice.ServiceDeployerMBean" * * @author Tho...@jb... * @since 15-April-2004 */ public class ServiceDeployerJSE extends ServiceDeployer implements ServiceDeployerJSEMBean { // service name of the EJB deployer private ObjectName warDeployer; /** * Set the service name of the WAR deployer * @jmx.managed-attribute */ public void setWARDeployer(ObjectName deployerName) { this.warDeployer = deployerName; } /** * Register this service as NotificationListener to the WARDeployer */ protected void startService() throws Exception { super.startService(); registerNotificationListener(warDeployer); } /** * Unregister this service as NotificationListener from the WARDeployer */ protected void stopService() { unregisterNotificationListener(warDeployer); super.stopService(); } /** Get the resource name of the webservices.xml descriptor. */ protected URL getWebservicesDescriptor(DeploymentInfo di) { return di.localCl.findResource("WEB-INF/webservices.xml"); } /** Is called when the parent deployer sends the CREATE_NOTIFICATION. * * This implemantation modifies the servlet entries in web.xml */ protected void createWebservice(DeploymentInfo di) throws DeploymentException { // parse webservices.xml and put it in the local registry. super.createWebservice(di); Webservices webservices = getWebservices(di.url); modifyWebXML(di, webservices); } /** Modify the deployed web.xml to replace the servlet entries */ private void modifyWebXML(DeploymentInfo di, Webservices webservices) throws DeploymentException { if (webservices == null) throw new DeploymentException("webservices.xml not registerd"); File warFile = new File(di.localUrl.getFile()); if (warFile.isDirectory() == false) throw new DeploymentException("Expected a war directory: " + di.localUrl); File webXML = new File(di.localUrl.getFile() + "/WEB-inf/web.xml"); if (webXML.isFile() == false) throw new DeploymentException("Cannot find web.xml: " + webXML); try { SAXReader reader = new SAXReader(); Document doc = reader.read(webXML); modifyServletEntries(doc, webservices); // rename the web.xml File orgWebXML = new File(webXML.getCanonicalPath() + ".org"); if (webXML.renameTo(orgWebXML) == false) throw new DeploymentException("Cannot rename web.xml: " + orgWebXML); OutputFormat format = OutputFormat.createPrettyPrint(); FileOutputStream fos = new FileOutputStream(webXML); XMLWriter writer = new XMLWriter(fos, format); writer.write(doc); } catch (DeploymentException e) { throw e; } catch (Exception e) { throw new DeploymentException(e); } } private void modifyServletEntries(Document doc, Webservices webservices) throws DeploymentException { WebserviceDescription[] wsDescriptions = webservices.getWebserviceDescriptions(); for (int i = 0; i < wsDescriptions.length; i++) { WebserviceDescription wsDescription = wsDescriptions[i]; PortComponent[] portComponents = wsDescription.getPortComponents(); for (int j = 0; j < portComponents.length; j++) { PortComponent pc = portComponents[j]; Element servletElement = null; // get the servlet link String servletLink = pc.getServletLink(); if (servletLink == null) throw new DeploymentException("Cannot find servlet-link in port-component: " + pc.getPortComponentName()); // find the corresponding servlet Iterator it = doc.getRootElement().elements("servlet").iterator(); while (it.hasNext() && servletElement == null) { Element el = (Element)it.next(); String servletName = el.elementTextTrim("servlet-name"); if (servletLink.equals(servletName)) servletElement = el; } if (servletElement == null) throw new DeploymentException("Cannot find servlet in web.xml: " + servletLink); // find the servlet-class Element classElement = servletElement.element("servlet-class"); if (classElement == null) throw new DeploymentException("Cannot find servlet-class for servlet: " + servletLink); // replace the class name String className = classElement.getTextTrim(); classElement.setText(JBossAxisServlet.class.getName()); pc.setServiceEndpointBean(className); // build a list of detached elements that come after <servlet-class> boolean startDetach = false; ArrayList detachedElements = new ArrayList(); it = servletElement.elements().iterator(); while (it.hasNext()) { Element el = (Element)it.next(); if (startDetach == true) { detachedElements.add(el); el.detach(); } if (el.equals(classElement)) startDetach = true; } // add additional init params // none yet // reattach the elements it = detachedElements.iterator(); while (it.hasNext()) { Element el = (Element)it.next(); servletElement.add(el); } } } } } 1.1 webservice/src/main/org/jboss/webservice/ServiceException.java Index: ServiceException.java =================================================================== /* * JBoss, the OpenSource J2EE webOS * * Distributable under LGPL license. * See terms of license at gnu.org. */ package org.jboss.webservice; // $Id: ServiceException.java,v 1.1 2004/04/28 14:37:25 tdiesler Exp $ import org.apache.axis.AxisFault; import org.apache.axis.server.AxisServer; import org.apache.axis.transport.http.AxisServlet; import org.jboss.mx.util.MBeanServerLocator; import org.jboss.logging.Logger; import javax.management.MBeanServer; /** * A simple exception wrapper that does logging * * @author Tho...@jb... * @since 15-April-2004 */ public class ServiceException extends AxisFault { // provide logging private static final Logger log = Logger.getLogger(ServiceException.class); public ServiceException(String message) { super(message); log.error(message); } public ServiceException(String message, Throwable t) { super(message, t); log.error(message, t); } public ServiceException(Exception target) { super(target); log.error(target); } } |