Save This Page
Home » jboss-5.0.0.CR1-src » org » jboss » net » axis » server » [javadoc | source]
    1   /*
    2    * JBoss, the OpenSource J2EE webOS
    3    *
    4    * Distributable under LGPL license.
    5    * See terms of license at gnu.org.
    6    */
    7   
    8   // $Id: AxisService.java,v 1.25.2.7 2003/11/06 15:36:05 cgjung Exp $
    9   
   10   package org.jboss.net.axis.server;
   11   
   12   import org.jboss.net.axis.XMLResourceProvider;
   13   import org.jboss.net.axis.AttacheableService;
   14   import org.jboss.net.axis.Deployment;
   15   
   16   import org.jboss.net.DefaultResourceBundle;
   17   
   18   import org.jboss.deployment.DeploymentException;
   19   import org.jboss.deployment.DeploymentInfo;
   20   import org.jboss.deployment.MainDeployerMBean;
   21   import org.jboss.deployment.SubDeployer;
   22   import org.jboss.deployment.SubDeployerSupport;
   23   import org.jboss.logging.Log4jLoggerPlugin;
   24   import org.jboss.mx.loading.UnifiedClassLoader;
   25   import org.jboss.web.WebApplication;
   26   
   27   import org.apache.log4j.Category;
   28   import org.apache.log4j.Priority;
   29   
   30   import org.apache.axis.MessageContext;
   31   import org.apache.axis.utils.XMLUtils;
   32   import org.apache.axis.AxisFault;
   33   import org.apache.axis.server.AxisServer;
   34   import org.apache.axis.AxisProperties;
   35   import org.apache.axis.deployment.wsdd.WSDDProvider;
   36   import org.apache.axis.deployment.wsdd.WSDDUndeployment;
   37   import org.apache.axis.client.Service;
   38   import org.apache.axis.EngineConfiguration;
   39   import org.apache.axis.configuration.EngineConfigurationFactoryFinder;
   40   import org.apache.axis.EngineConfigurationFactory;
   41   
   42   import org.jboss.naming.Util;
   43   import org.jboss.metadata.MetaData;
   44   import org.jboss.system.server.ServerConfigLocator;
   45   
   46   import org.w3c.dom.Document;
   47   import org.w3c.dom.Element;
   48   import org.w3c.dom.Attr;
   49   import org.w3c.dom.Node;
   50   import org.w3c.dom.NamedNodeMap;
   51   import org.w3c.dom.NodeList;
   52   
   53   import javax.management.MBeanRegistration;
   54   import javax.management.MBeanServer;
   55   import javax.management.MBeanServerFactory;
   56   import javax.management.ObjectName;
   57   import javax.management.MalformedObjectNameException;
   58   
   59   import javax.naming.InitialContext;
   60   import javax.naming.LinkRef;
   61   import javax.naming.Context;
   62   import javax.naming.NamingException;
   63   
   64   import java.io.FilenameFilter;
   65   import java.io.File;
   66   import java.io.IOException;
   67   import java.io.InputStream;
   68   import java.io.OutputStream;
   69   import java.io.FileOutputStream;
   70   import java.io.PrintStream;
   71   
   72   import java.net.URL;
   73   import java.net.URLClassLoader;
   74   import java.net.MalformedURLException;
   75   
   76   import javax.xml.parsers.ParserConfigurationException;
   77   
   78   import java.util.Map;
   79   import java.util.Iterator;
   80   import java.util.Collection;
   81   
   82   import java.lang.reflect.Proxy;
   83   
   84   /**
   85    * A deployer service that installs Axis and manages Web-Services 
   86    * within JMX.
   87    * @created 27. September 2001
   88    * @author <a href="mailto:Christoph.Jung@infor.de">Christoph G. Jung</a>
   89    * @version $Revision: 1.25.2.7 $
   90    */
   91   
   92   public class AxisService
   93      extends SubDeployerSupport
   94      implements AxisServiceMBean, MBeanRegistration
   95   {
   96   
   97      // 
   98      // Attributes
   99      //
  100   
  101      /**
  102       * A map of current deployment names to the
  103       * wsdd docs that created them.
  104       */
  105      protected Map deployments = new java.util.HashMap();
  106   
  107      /** this is where the axis "web-application" has been installed */
  108      protected DeploymentInfo myDeploymentInfo = null;
  109   
  110      /** the engine belonging to this service */
  111      protected AxisServer axisServer;
  112   
  113      /** the client configuration belonging to this service*/
  114      protected XMLResourceProvider clientConfiguration;
  115   
  116      /** the server configuration belonging to this service*/
  117      protected XMLResourceProvider serverConfiguration;
  118   
  119      /** the web deployer that hosts our servlet */
  120      protected SubDeployer webDeployer;
  121   
  122      /** the initial context into which we bind external web-service proxies */
  123      protected InitialContext initialContext;
  124   
  125      //
  126      // Constructors
  127      //
  128   
  129      /** default */
  130      public AxisService()
  131      {
  132         // we fake internationalisation if it is not globally catered
  133         Category cat = ((Log4jLoggerPlugin) log.getLoggerPlugin()).getCategory();
  134         if (cat.getResourceBundle() == null)
  135            cat.setResourceBundle(new DefaultResourceBundle());
  136      }
  137   
  138      //
  139      // Some helper methods
  140      //
  141   
  142      /**
  143       * deploy an external web service reference
  144       */
  145   
  146      protected synchronized void deployExternalWebService(Element deployElement)
  147         throws DeploymentException
  148      {
  149   
  150         try
  151         {
  152            if (initialContext == null)
  153            {
  154               initialContext = new InitialContext();
  155            }
  156   
  157            NamedNodeMap attributes = deployElement.getAttributes();
  158   
  159            String jndiName = attributes.getNamedItem("jndiName").getNodeValue();
  160            String serviceClassName =
  161               attributes.getNamedItem("serviceImplClass").getNodeValue();
  162            Object factory =
  163               new AttacheableService(
  164                  serviceClassName,
  165                  serviceName.getCanonicalName());
  166            initialContext.bind(jndiName, factory);
  167         }
  168         catch (NamingException e)
  169         {
  170            throw new DeploymentException(
  171               "Could not deploy item " + deployElement,
  172               e);
  173         }
  174      }
  175   
  176      /** undeploys an external web service reference */
  177      protected synchronized void undeployExternalWebService(Element deployElement)
  178      {
  179         try
  180         {
  181            if (initialContext == null)
  182            {
  183               initialContext = new InitialContext();
  184            }
  185   
  186            NamedNodeMap attributes = deployElement.getAttributes();
  187   
  188            String jndiName = attributes.getNamedItem("jndiName").getNodeValue();
  189   
  190            if (jndiName != null)
  191            {
  192               initialContext.unbind(jndiName);
  193            }
  194         }
  195         catch (NamingException e)
  196         {
  197   
  198            // what?
  199   
  200            ((Log4jLoggerPlugin) log.getLoggerPlugin()).getCategory().l7dlog(
  201               Priority.WARN,
  202               "Could not undeploy " + deployElement,
  203               new Object[0],
  204               e);
  205         }
  206      }
  207   
  208      //----------------------------------------------------------------------------
  209      // 'service' interface
  210      //----------------------------------------------------------------------------
  211   
  212      /**
  213       * start service means
  214       *  - initialise axis engine
  215       *  - register Axis servlet in WebContainer
  216       *  - contact the maindeployer
  217       */
  218      protected void startService() throws Exception
  219      {
  220   
  221         // find the global config file in classpath
  222         URL resource =
  223            getClass().getClassLoader().getResource(
  224               Constants.AXIS_CONFIGURATION_FILE);
  225   
  226         Category cat = ((Log4jLoggerPlugin) log.getLoggerPlugin()).getCategory();
  227         if (resource == null)
  228         {
  229            cat.l7dlog(
  230               Priority.WARN,
  231               Constants.COULD_NOT_FIND_AXIS_CONFIGURATION_0,
  232               new Object[]{Constants.AXIS_CONFIGURATION_FILE},
  233               null);
  234            throw new Exception(Constants.COULD_NOT_FIND_AXIS_CONFIGURATION_0);
  235         }
  236   
  237         serverConfiguration = new XMLResourceProvider(resource);
  238   
  239         axisServer = new AxisServer(serverConfiguration);
  240         
  241         // we annotate the server configuration with our serviceName
  242         serverConfiguration.getGlobalOptions().put(
  243            org.jboss.net.axis.Constants.CONFIGURATION_CONTEXT,
  244            serviceName.toString());
  245   
  246         // find the client config file in classpath
  247         resource =
  248            getClass().getClassLoader().getResource(
  249               Constants.AXIS_CLIENT_CONFIGURATION_FILE);
  250   
  251         if (resource == null)
  252         {
  253            cat.l7dlog(
  254               Priority.WARN,
  255               Constants.COULD_NOT_FIND_AXIS_CONFIGURATION_0,
  256               new Object[]{Constants.AXIS_CONFIGURATION_FILE},
  257               null);
  258            throw new Exception(Constants.COULD_NOT_FIND_AXIS_CONFIGURATION_0);
  259         }
  260   
  261         clientConfiguration = new XMLResourceProvider(resource);
  262   
  263         clientConfiguration.buildDeployment();
  264   
  265         clientConfiguration.getGlobalOptions().put(
  266            org.jboss.net.axis.Constants.CONFIGURATION_CONTEXT,
  267            serviceName.toString());
  268   
  269         // make sure that Axis/Discovery wont register any application classloaders for system lookup
  270         AxisProperties.getNameDiscoverer();
  271         // register our client configuration there 
  272         Class initializeThisFuckingStaticStuff =
  273            EngineConfigurationFactoryFinder.class;
  274         System.setProperty(
  275            EngineConfigurationFactory.SYSTEM_PROPERTY_NAME,
  276            JMXEngineConfigurationFactory.class.getName());
  277         super.startService();
  278      }
  279   
  280      /** what to do to stop axis temporarily --> undeploy the servlet */
  281      protected void stopService() throws Exception
  282      {
  283   
  284         super.stopService();
  285   
  286         // tear down all running web services
  287         //Is this really what you want to do? Not leave services running anyway? 
  288         for (Iterator apps =
  289            new java.util.ArrayList(deployments.values()).iterator();
  290              apps.hasNext();
  291            )
  292         {
  293            DeploymentInfo info = (DeploymentInfo) apps.next();
  294            try
  295            {
  296               //unregister through server so it's bookeeping is up to date.
  297               server.invoke(
  298                  MainDeployerMBean.OBJECT_NAME,
  299                  "undeploy",
  300                  new Object[]{info},
  301                  new String[]{"org.jboss.deployment.DeploymentInfo"});
  302            }
  303            catch (Exception e)
  304            {
  305               log.error("Could not undeploy deployment " + info, e);
  306            }
  307         }
  308   
  309         axisServer.stop();
  310         super.stopService();
  311         myDeploymentInfo = null;
  312      }
  313   
  314      //----------------------------------------------------------------------------
  315      // Deployer interface
  316      //----------------------------------------------------------------------------
  317   
  318      /**
  319       * Provides a filter that decides whether a file can be deployed by
  320       * this deployer based on the filename.  This is for the benefit of
  321       * the {@link org.jboss.deployer.MainDeployer} service.
  322       *
  323       * @return a <tt>FilenameFilter</tt> that only
  324       *         <tt>accept</tt>s files with names that can be
  325       *         deployed by this deployer
  326       */
  327      public boolean accepts(DeploymentInfo sdi)
  328      {
  329         if (sdi.shortName.endsWith("-axis.xml")
  330            || sdi.localCl.getResource(Constants.WEB_SERVICE_DESCRIPTOR) != null)
  331         {
  332            return true;
  333         }
  334         return false;
  335      }
  336   
  337      /*
  338       * Init a deployment
  339       *
  340       * parse the XML MetaData.  Init and deploy are separate steps allowing for subDeployment
  341       * in between.
  342       *
  343       * @param url    The URL to deploy.
  344       *
  345       * @throws MalformedURLException    Invalid URL
  346       * @throws IOException              Failed to fetch content
  347       * @throws DeploymentException      Failed to deploy
  348       */
  349   
  350      public void init(DeploymentInfo sdi) throws DeploymentException
  351      {
  352         super.init(sdi);
  353   
  354         try
  355         {
  356            URL metaInfos = null;
  357   
  358            if (sdi.metaData == null)
  359            {
  360               metaInfos =
  361                  sdi.localCl.getResource(Constants.WEB_SERVICE_DESCRIPTOR);
  362            }
  363            else
  364            {
  365               metaInfos = (URL) sdi.metaData;
  366            }
  367   
  368            sdi.metaData = XMLUtils.newDocument(metaInfos.openStream());
  369   
  370            // Resolve what to watch
  371            if (sdi.url.getProtocol().equals("file"))
  372            {
  373               sdi.watch = metaInfos;
  374            }
  375            else
  376            {
  377               // We watch the top only, no directory support
  378               sdi.watch = sdi.url;
  379            }
  380         }
  381         catch (Exception e)
  382         {
  383            throw new DeploymentException(e);
  384         }
  385      }
  386   
  387      /**
  388       * Describe <code>create</code> method here.
  389       *
  390       * This step should include deployment steps that expose the existence of the unit being 
  391       * deployed to other units.
  392       *
  393       * @param sdi a <code>DeploymentInfo</code> value
  394       * @exception DeploymentException if an error occurs
  395       */
  396      public void create(DeploymentInfo sdi) throws DeploymentException
  397      {
  398         ((Log4jLoggerPlugin) log.getLoggerPlugin()).getCategory().l7dlog(
  399            Priority.DEBUG,
  400            Constants.ABOUT_TO_CREATE_AXIS_0,
  401            new Object[]{sdi},
  402            null);
  403   
  404         if (deployments.containsKey(sdi.url))
  405         {
  406            throw new DeploymentException(
  407               "attempting to redeploy a depoyed module! " + sdi.url);
  408         }
  409         else
  410         {
  411            deployments.put(sdi.url, sdi);
  412         }
  413   
  414      }
  415   
  416      /**
  417       * Describe <code>start</code> method here.
  418       *
  419       * This should only include deployment activities that refer to resources
  420       * outside the unit being deployed.
  421       *
  422       * @param sdi a <code>DeploymentInfo</code> value
  423       * @exception DeploymentException if an error occurs
  424       */
  425      public void start(DeploymentInfo sdi) throws DeploymentException
  426      {
  427         ((Log4jLoggerPlugin) log.getLoggerPlugin()).getCategory().l7dlog(
  428            Priority.DEBUG,
  429            Constants.ABOUT_TO_START_AXIS_0,
  430            new Object[]{sdi},
  431            null);
  432   
  433         // remember old classloader
  434         ClassLoader previous = Thread.currentThread().getContextClassLoader();
  435   
  436         // build new classloader for naming purposes
  437         URLClassLoader serviceLoader =
  438            URLClassLoader.newInstance(new URL[0], sdi.ucl);
  439   
  440         try
  441         {
  442            InitialContext iniCtx = new InitialContext();
  443            Context envCtx = null;
  444   
  445            // create a new naming context java:comp/env
  446            try
  447            {
  448               // enter the apartment
  449               Thread.currentThread().setContextClassLoader(serviceLoader);
  450               envCtx = (Context) iniCtx.lookup("java:comp");
  451               envCtx = envCtx.createSubcontext("env");
  452            }
  453            finally
  454            {
  455               // enter the apartment
  456               Thread.currentThread().setContextClassLoader(previous);
  457            }
  458   
  459            Document doc = (Document) sdi.metaData;
  460            // the original command
  461            Element root = doc.getDocumentElement();
  462            // the deployment command document
  463            Document deployDoc = XMLUtils.newDocument();
  464            // the client deployment command document
  465            Document deployClientDoc = XMLUtils.newDocument();
  466            // create command
  467            Element deploy =
  468               deployDoc.createElementNS(root.getNamespaceURI(), "deployment");
  469            // create command
  470            Element deployClient =
  471               deployClientDoc.createElementNS(
  472                  root.getNamespaceURI(),
  473                  "deployment");
  474   
  475            NamedNodeMap attributes = root.getAttributes();
  476            for (int count = 0; count < attributes.getLength(); count++)
  477            {
  478               Attr attribute = (Attr) attributes.item(count);
  479               deploy.setAttributeNodeNS(
  480                  (Attr) deployDoc.importNode(attribute, true));
  481               deployClient.setAttributeNodeNS(
  482                  (Attr) deployClientDoc.importNode(attribute, true));
  483            }
  484   
  485            // and insert the nodes from the original document
  486            // and sort out the ejb-ref extensions
  487            NodeList children = root.getChildNodes();
  488            for (int count = 0; count < children.getLength(); count++)
  489            {
  490               Node actNode = children.item(count);
  491               if (actNode instanceof Element)
  492               {
  493                  Element actElement = (Element) actNode;
  494   
  495                  if (actElement.getTagName().equals("ejb-ref"))
  496                  {
  497   
  498                     String refName =
  499                        MetaData.getElementContent(
  500                           MetaData.getUniqueChild(
  501                              (Element) actNode,
  502                              "ejb-ref-name"));
  503                     String linkName =
  504                        MetaData.getElementContent(
  505                           MetaData.getUniqueChild((Element) actNode, "ejb-link"));
  506   
  507                     log.warn(
  508                        "Web Service Deployment "
  509                        + sdi
  510                        + " makes use of the deprecated ejb-ref feature. "
  511                        + "Please adjust any ejb-providing service tag inside your web-service.xml pointing to "
  512                        + refName
  513                        + " to use the absolute "
  514                        + linkName
  515                        + " instead.");
  516   
  517                     if (refName == null)
  518                        throw new DeploymentException(
  519                           Constants.EJB_REF_MUST_HAVE_UNIQUE_NAME);
  520                     if (linkName == null)
  521                        throw new DeploymentException(
  522                           Constants.EJB_REF_MUST_HAVE_UNIQUE_LINK);
  523   
  524                     Util.bind(envCtx, refName, new LinkRef(linkName));
  525                  }
  526                  else if (actElement.getTagName().equals("ext-service"))
  527                  {
  528                     deployExternalWebService(actElement);
  529                  }
  530                  else
  531                  {
  532                     if (!actElement.getTagName().equals("service"))
  533                     {
  534                        deployClient.appendChild(
  535                           deployClientDoc.importNode(actNode, true));
  536                     }
  537                     deploy.appendChild(deployDoc.importNode(actNode, true));
  538                  }
  539               }
  540               else
  541               {
  542                  deployClient.appendChild(
  543                     deployClientDoc.importNode(actNode, true));
  544                  deploy.appendChild(deployDoc.importNode(actNode, true));
  545               }
  546            }
  547   
  548            // insert command into document
  549            deployDoc.appendChild(deploy);
  550            deployClientDoc.appendChild(deployClient);
  551   
  552            try
  553            {
  554               Thread.currentThread().setContextClassLoader(serviceLoader);
  555               new Deployment(deploy).deployToRegistry(
  556                  ((XMLResourceProvider) axisServer.getConfig()).getDeployment());
  557               new Deployment(deployClient).deployToRegistry(
  558                  clientConfiguration.buildDeployment());
  559               axisServer.refreshGlobalOptions();
  560               axisServer.saveConfiguration();
  561            }
  562            catch (Exception e)
  563            {
  564               throw new DeploymentException(
  565                  Constants.COULD_NOT_DEPLOY_DESCRIPTOR,
  566                  e);
  567            }
  568            finally
  569            {
  570               Thread.currentThread().setContextClassLoader(previous);
  571            }
  572         }
  573         catch (NamingException e)
  574         {
  575            throw new DeploymentException(
  576               Constants.COULD_NOT_DEPLOY_DESCRIPTOR,
  577               e);
  578         }
  579         catch (ParserConfigurationException parserError)
  580         {
  581            throw new DeploymentException(Constants.COULD_NOT_DEPLOY_DESCRIPTOR,
  582               parserError);
  583         }
  584   
  585      }
  586   
  587      /** 
  588       * this tiny helper copies all children of the given element that
  589       * are elements and match the given name to the other element
  590       */
  591      protected void copyChildren(Document sourceDoc, Element source, String match, Element target)
  592      {
  593         NodeList children = source.getChildNodes();
  594         for (int count = 0; count < children.getLength(); count++)
  595         {
  596            Node actNode = children.item(count);
  597            if (actNode instanceof Element)
  598            {
  599               if (((Element) actNode).getLocalName().equals(match))
  600               {
  601                  target.appendChild(sourceDoc.importNode(actNode, true));
  602               }
  603            }
  604         }
  605      }
  606   
  607      /** stop a given deployment */
  608      public void stop(DeploymentInfo sdi) throws DeploymentException
  609      {
  610         ((Log4jLoggerPlugin) log.getLoggerPlugin()).getCategory().l7dlog(
  611            Priority.DEBUG,
  612            Constants.ABOUT_TO_STOP_AXIS_0,
  613            new Object[]{sdi},
  614            null);
  615         if (!deployments.containsKey(sdi.url))
  616         {
  617            throw new DeploymentException(
  618               "Attempting to undeploy a not-deployed unit! " + sdi.url);
  619         }
  620         // this was the deployment command
  621         Element root = (Element) ((Document) sdi.metaData).getDocumentElement();
  622         // from which we extract an undeployment counterpart
  623         Document undeployDoc = null;
  624         try
  625         {
  626            undeployDoc = XMLUtils.newDocument();
  627         }
  628         catch (ParserConfigurationException parserError)
  629         {
  630            throw new DeploymentException(Constants.COULD_NOT_DEPLOY_DESCRIPTOR,
  631               parserError);
  632         }
  633         Element undeploy =
  634            undeployDoc.createElementNS(root.getNamespaceURI(), "undeployment");
  635         
  636         // copy over administrational attributes
  637         NamedNodeMap attributes = root.getAttributes();
  638         for (int count = 0; count < attributes.getLength(); count++)
  639         {
  640            Attr attribute = (Attr) attributes.item(count);
  641            undeploy.setAttributeNodeNS(
  642               (Attr) undeployDoc.importNode(attribute, true));
  643         }
  644   
  645         // external services are just a matter of us
  646         NodeList children = root.getElementsByTagName("ext-service");
  647         for (int count = 0; count < children.getLength(); count++)
  648         {
  649            Element actNode = (Element) children.item(count);
  650            undeployExternalWebService(actNode);
  651         }
  652   
  653         // all service and handler entries are copied in the
  654         // undeployment document
  655         copyChildren(undeployDoc, root, "service", undeploy);
  656         copyChildren(undeployDoc, root, "handler", undeploy);
  657         copyChildren(undeployDoc, root, "typemapping", undeploy);
  658         copyChildren(undeployDoc, root, "beanmapping", undeploy);
  659   
  660         // put command into document
  661         undeployDoc.appendChild(undeploy);
  662   
  663         try
  664         {
  665            // and call the administrator
  666            new WSDDUndeployment(undeploy).undeployFromRegistry(
  667               ((XMLResourceProvider) axisServer.getConfig()).getDeployment());
  668            // and call the administrator
  669            new WSDDUndeployment(undeploy).undeployFromRegistry(
  670               clientConfiguration.buildDeployment());
  671            axisServer.refreshGlobalOptions();
  672            axisServer.saveConfiguration();
  673         }
  674         catch (Exception e)
  675         {
  676            throw new DeploymentException(Constants.COULD_NOT_UNDEPLOY, e);
  677         }
  678      }
  679   
  680      /** destroy a given deployment */
  681      public void destroy(DeploymentInfo sdi) throws DeploymentException
  682      {
  683         ((Log4jLoggerPlugin) log.getLoggerPlugin()).getCategory().l7dlog(
  684            Priority.DEBUG,
  685            Constants.ABOUT_TO_DESTROY_AXIS_0,
  686            new Object[]{sdi},
  687            null);
  688         deployments.remove(sdi.url);
  689      }
  690   
  691      /** return the associated client configuration */
  692      public EngineConfiguration getClientEngineConfiguration()
  693      {
  694         return clientConfiguration;
  695      }
  696   
  697      /** return the associated server configuration */
  698      public EngineConfiguration getServerEngineConfiguration()
  699      {
  700         return serverConfiguration;
  701      }
  702   
  703      /** return the associated server */
  704      public AxisServer getAxisServer()
  705      {
  706         return axisServer;
  707      }
  708   
  709   }

Save This Page
Home » jboss-5.0.0.CR1-src » org » jboss » net » axis » server » [javadoc | source]