mx4j/src/tools/mx4j/tools/remote/resolver/soap SOAPResolver.java,1.5,1.6

Simone Bordet <[email protected]>
Newsgroups gmane.comp.java.mx4j.cvs
Message-ID <[email protected]>
Update of /cvsroot/mx4j/mx4j/src/tools/mx4j/tools/remote/resolver/soap
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv32381/src/tools/mx4j/tools/remote/resolver/soap

Modified Files:
	SOAPResolver.java 
Log Message:
Simplied usage by allowing:
+ Simple URLs: not anymore soap://host:8080/path/id/1 but only soap://host:8080/path
+ Allow more in-VM SOAPConnectorServers to share one instance only of Jetty (on different paths)

Index: SOAPResolver.java
===================================================================
RCS file: /cvsroot/mx4j/mx4j/src/tools/mx4j/tools/remote/resolver/soap/SOAPResolver.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -C2 -d -r1.5 -r1.6
*** SOAPResolver.java	1 Mar 2004 18:25:31 -0000	1.5
--- SOAPResolver.java	18 Jul 2004 21:43:29 -0000	1.6
***************
*** 12,25 ****
  import java.io.InputStream;
  import java.util.HashMap;
! import java.util.List;
  import java.util.Map;
! import java.security.AccessController;
! import java.security.PrivilegedExceptionAction;
! import java.security.PrivilegedActionException;
! 
! import javax.management.JMException;
! import javax.management.MBeanServer;
! import javax.management.MBeanServerFactory;
! import javax.management.ObjectName;
  import javax.management.remote.JMXServiceURL;
  
--- 12,19 ----
  import java.io.InputStream;
  import java.util.HashMap;
! import java.util.HashSet;
  import java.util.Map;
! import java.util.Set;
! import javax.management.remote.JMXConnectorServerFactory;
  import javax.management.remote.JMXServiceURL;
  
***************
*** 29,36 ****
  import mx4j.tools.remote.soap.SOAPConnector;
  import mx4j.tools.remote.soap.SOAPConnectorServer;
  import org.apache.axis.client.AdminClient;
  import org.apache.axis.client.Service;
- import org.apache.axis.utils.Options;
  import org.apache.axis.configuration.FileProvider;
  
  /**
--- 23,32 ----
  import mx4j.tools.remote.soap.SOAPConnector;
  import mx4j.tools.remote.soap.SOAPConnectorServer;
+ import mx4j.tools.remote.soap.web.WebContainer;
  import org.apache.axis.client.AdminClient;
  import org.apache.axis.client.Service;
  import org.apache.axis.configuration.FileProvider;
+ import org.apache.axis.transport.http.AxisServlet;
+ import org.apache.axis.utils.Options;
  
  /**
***************
*** 38,51 ****
   * @version $Revision$
   */
  public class SOAPResolver extends ConnectionResolver
  {
     private static final String SERVICE_JMX_SOAP = "service:jmx:soap";
-    private static final String ID_CONTEXT = "/id/";
     private static final String SERVER_DEPLOY_WSDD = "server-deploy.wsdd";
     private static final String SERVER_UNDEPLOY_WSDD = "server-undeploy.wsdd";
     private static final String CLIENT_WSDD = "client.wsdd";
!    private static int connectorID;
  
!    private final Map mbeanServerIds = new HashMap();
  
     public Object lookupClient(JMXServiceURL address, Map environment) throws IOException
--- 34,71 ----
   * @version $Revision$
   */
+ 
+ /**
+  * TODO: IMPLEMENTATION NOTES - FIXME IF POSSIBLE
+  * The most annoying thing is that the client JMXServiceURL is not the one used to start the server,
+  * but the one *after* the server has been started. VERY annoying. Starting the server with
+  * service:jmx:soap://localhost:8080/axis/services/jmxconnector result in the client to be able to
+  * connect only with this JMXServiceURL:
+  * service:jmx:soap://localhost:8080/axis/services/jmxconnector/id/1
+  * There is a reason for that, however.
+  * First, the service has always name 'jmxconnector' (hardcoded in server-deploy.wsdd).
+  * This is due to how Axis works (or to how I have understood it works). Up to now, I've found no way to load
+  * a server-deploy.wsdd and change the name of the service. Maybe it can be done, but sure there is no simple
+  * API in the AdminClient to do that.
+  * Second, let's assume I want to deploy on the same port (say 8080) two SOAPConnectorServers. Best solution
+  * would be to specify 2 different paths in the JMXServiceURLs, say /one/jmxconnector and /two/jmxconnector
+  * (with the limitation imposed by the previous point, it must end with 'jmxconnector').
+  * To start the second, I specify SOAPConnectorServer.USE_EXTERNAL_WEB_CONTAINER to true (so I don't start again
+  * the web container on the same port), but then I have to add a servlet mapping (namely '/two/jmxconnector')
+  * to an existing servlet (since there is one pivot per application, as specified in server-deploy.wsdd).
+  * I doubt very much that any existing web container is able to add a servlet mapping without being restarted,
+  * but I could be wrong. Jetty does not seem to have this API, I tried and servlets added after start() don't get
+  * enabled, but I have to ask Greg to be sure.
+  */
  public class SOAPResolver extends ConnectionResolver
  {
     private static final String SERVICE_JMX_SOAP = "service:jmx:soap";
     private static final String SERVER_DEPLOY_WSDD = "server-deploy.wsdd";
     private static final String SERVER_UNDEPLOY_WSDD = "server-undeploy.wsdd";
     private static final String CLIENT_WSDD = "client.wsdd";
!    private static final String AXIS_DEPLOY_SERVICE = "AdminService";
  
!    // TODO: maybe worth to use weak references to hold web containers
!    private static Map webContainers = new HashMap();
!    private static Map deployedURLs = new HashMap();
  
     public Object lookupClient(JMXServiceURL address, Map environment) throws IOException
***************
*** 89,177 ****
     public Object createServer(JMXServiceURL url, Map environment) throws IOException
     {
!       String connectorID = findConnectorID(url);
!       if (connectorID == null) return null;
  
!       String mbeanServerId = findMBeanServerId(connectorID);
!       if (mbeanServerId == null) return null;
  
!       List servers = MBeanServerFactory.findMBeanServer(mbeanServerId);
!       if (servers.size() == 1) return servers.get(0);
!       return null;
     }
  
!    private String findConnectorID(JMXServiceURL url)
     {
!       String path = url.getURLPath();
!       if (path == null) return null;
!       int index = path.indexOf(ID_CONTEXT);
!       if (index < 0) return null;
!       return path.substring(index + ID_CONTEXT.length());
     }
  
!    private String findMBeanServerId(String connectorID)
     {
!       synchronized (mbeanServerIds)
!       {
!          return (String)mbeanServerIds.get(connectorID);
!       }
     }
  
     public JMXServiceURL bindServer(Object server, JMXServiceURL url, Map environment) throws IOException
     {
!       String existingID = findConnectorID(url);
!       String connectorID = existingID;
!       if (connectorID == null) connectorID = generateConnectorID();
! 
!       final MBeanServer mbeanServer = (MBeanServer)server;
!       try
        {
!          try
!          {
!             String mbeanServerId = (String)AccessController.doPrivileged(new PrivilegedExceptionAction()
!             {
!                public Object run() throws JMException
!                {
!                   return mbeanServer.getAttribute(new ObjectName("JMImplementation:type=MBeanServerDelegate"), "MBeanServerId");
!                }
!             });
!             synchronized (mbeanServerIds)
!             {
!                String existing = findMBeanServerId(connectorID);
!                if (existing != null && !existing.equals(mbeanServerId)) throw new IOException("SOAPConnectorServer with ID " + connectorID + " is already attached to MBeanServer with ID " + existing);
!                mbeanServerIds.put(connectorID, mbeanServerId);
!             }
!          }
!          catch (PrivilegedActionException x)
           {
!             throw (JMException)x.getException();
           }
        }
!       catch (JMException x)
!       {
!          throw new IOException("Cannot retrieve MBeanServer ID " + x.toString());
!       }
! 
!       deploy(url, environment);
! 
!       JMXServiceURL address = null;
!       if (existingID != null)
!       {
!          address = url;
!       }
!       else
!       {
!          String path = url.getURLPath();
!          if (path == null) path = "";
!          if (!path.startsWith("/")) path = "/" + path;
!          if (path.endsWith("/")) path = path.substring(0, path.length() - 1);
!          address = new JMXServiceURL(url.getProtocol(), url.getHost(), url.getPort(), path + ID_CONTEXT + connectorID);
!       }
!       return address;
     }
  
     private void deploy(JMXServiceURL address, Map environment) throws IOException
     {
!       String deployPath = environment == null ? null : (String)environment.get(SOAPConnectorServer.AXIS_DEPLOY_URL);
!       if (deployPath == null || deployPath.length() == 0) deployPath = SOAPConnectorServer.DEFAULT_AXIS_DEPLOY_URL;
  
        JMXServiceURL temp = new JMXServiceURL(address.getProtocol(), address.getHost(), address.getPort(), deployPath);
--- 109,166 ----
     public Object createServer(JMXServiceURL url, Map environment) throws IOException
     {
!       WebContainer result = null;
!       boolean useExternalWebContainer = environment == null ? false : Boolean.valueOf(String.valueOf(environment.get(SOAPConnectorServer.USE_EXTERNAL_WEB_CONTAINER))).booleanValue();
!       if (!useExternalWebContainer)
!       {
!          // Create and start an embedded web container
!          String webContainerClassName = environment == null ? null : (String)environment.get(SOAPConnectorServer.EMBEDDED_WEB_CONTAINER_CLASS);
!          // Not present, by default use Jetty
!          if (webContainerClassName == null || webContainerClassName.length() == 0) webContainerClassName = "mx4j.tools.remote.soap.web.jetty.JettyWebContainer";
  
!          result = findWebContainer(url, webContainerClassName);
!          if (result == null)
!          {
!             result = createWebContainer(url, webContainerClassName, environment);
!             if (result != null) result.start(url, environment);
!          }
  
!          // Nothing present, give up
!          if (result == null) throw new IOException("Could not start embedded web container");
!       }
!       return result;
     }
  
!    private WebContainer findWebContainer(JMXServiceURL url, String webContainerClassName)
     {
!       String key = createWebContainerKey(url, webContainerClassName);
!       return (WebContainer)webContainers.get(key);
     }
  
!    private String createWebContainerKey(JMXServiceURL url, String webContainerClassName)
     {
!       return new StringBuffer(webContainerClassName).append("|").append(url.getHost()).append("|").append(url.getPort()).toString();
     }
  
     public JMXServiceURL bindServer(Object server, JMXServiceURL url, Map environment) throws IOException
     {
!       WebContainer webContainer = (WebContainer)server;
!       if (webContainer != null && !isDeployed(webContainer, url))
        {
!          webContainer.deploy(AxisServlet.class.getName(), url, environment);
!          if (!hasDeployed(webContainer))
           {
!             // Axis has never been deployed, deploy it now
!             deploy(url, environment);
           }
+          addDeployed(webContainer, url);
        }
!       return url;
     }
  
     private void deploy(JMXServiceURL address, Map environment) throws IOException
     {
!       String path = address.getURLPath();
!       if (!path.endsWith("/")) path += "/";
!       String deployPath = path + AXIS_DEPLOY_SERVICE;
  
        JMXServiceURL temp = new JMXServiceURL(address.getProtocol(), address.getHost(), address.getPort(), deployPath);
***************
*** 199,228 ****
     }
  
-    private String generateConnectorID()
-    {
-       synchronized (SOAPResolver.class)
-       {
-          return String.valueOf(++connectorID);
-       }
-    }
- 
     public void unbindServer(Object server, JMXServiceURL address, Map environment) throws IOException
     {
!       String connectorID = findConnectorID(address);
!       if (connectorID == null) throw new IOException("Unknown SOAPConnectorServer ID: " + address);
!       synchronized (mbeanServerIds)
        {
!          mbeanServerIds.remove(connectorID);
        }
- 
-       undeploy(address, environment);
     }
  
     private void undeploy(JMXServiceURL address, Map environment) throws IOException
     {
!       String deployPath = environment == null ? null : (String)environment.get(SOAPConnectorServer.AXIS_DEPLOY_URL);
!       if (deployPath == null || deployPath.length() == 0) deployPath = SOAPConnectorServer.DEFAULT_AXIS_DEPLOY_URL;
  
!       JMXServiceURL temp = new JMXServiceURL(address.getProtocol(), address.getHost(), address.getPort(), deployPath);
        String undeployEndpoint = getEndpoint(temp, environment);
  
--- 188,213 ----
     }
  
     public void unbindServer(Object server, JMXServiceURL address, Map environment) throws IOException
     {
!       WebContainer webContainer = (WebContainer)server;
!       if (webContainer != null && isDeployed(webContainer, address))
        {
!          // First undeploy the service, then undeploy the webContainer: otherwise the service cannot be undeployed
!          removeDeployed(webContainer, address);
!          if (!hasDeployed(webContainer))
!          {
!             undeploy(address, environment);
!          }
!          webContainer.undeploy(AxisServlet.class.getName(), address, environment);
        }
     }
  
     private void undeploy(JMXServiceURL address, Map environment) throws IOException
     {
!       String path = address.getURLPath();
!       if (!path.endsWith("/")) path += "/";
!       String undeployPath = path + AXIS_DEPLOY_SERVICE;
  
!       JMXServiceURL temp = new JMXServiceURL(address.getProtocol(), address.getHost(), address.getPort(), undeployPath);
        String undeployEndpoint = getEndpoint(temp, environment);
  
***************
*** 233,237 ****
           options.setDefaultURL(undeployEndpoint);
           InputStream wsdd = getClass().getResourceAsStream(SERVER_UNDEPLOY_WSDD);
!          if (wsdd == null) throw new IOException("Could not find AXIS deployment descriptor");
           deployer.process(options, wsdd);
        }
--- 218,222 ----
           options.setDefaultURL(undeployEndpoint);
           InputStream wsdd = getClass().getResourceAsStream(SERVER_UNDEPLOY_WSDD);
!          if (wsdd == null) throw new IOException("Could not find AXIS deployment descriptor " + SERVER_UNDEPLOY_WSDD);
           deployer.process(options, wsdd);
        }
***************
*** 239,244 ****
        {
           Logger logger = getLogger();
!          if (logger.isEnabledFor(Logger.INFO)) logger.info("Exception while deploying AXIS service", x);
!          throw new IOException("Could not deploy SOAPConnectorServer to AXIS " + x.toString());
        }
     }
--- 224,299 ----
        {
           Logger logger = getLogger();
!          if (logger.isEnabledFor(Logger.INFO)) logger.info("Exception while undeploying AXIS service", x);
!          throw new IOException("Could not undeploy SOAPConnectorServer " + x.toString());
!       }
!    }
! 
!    public void destroyServer(Object server, JMXServiceURL url, Map environment) throws IOException
!    {
!       WebContainer webContainer = (WebContainer)server;
!       if (webContainer != null && !hasDeployed(webContainer))
!       {
!          // No more deployed stuff here, shutdown also the web container
!          String key = createWebContainerKey(url, server.getClass().getName());
!          WebContainer container = (WebContainer)webContainers.remove(key);
!          if (webContainer != container) throw new IOException("Trying to stop the wrong web container: " + server + " should be: " + container);
!          webContainer.stop();
!       }
!    }
! 
!    private WebContainer createWebContainer(JMXServiceURL url, String webContainerClassName, Map environment)
!    {
!       ClassLoader loader = Thread.currentThread().getContextClassLoader();
!       if (environment != null)
!       {
!          Object cl = environment.get(JMXConnectorServerFactory.PROTOCOL_PROVIDER_CLASS_LOADER);
!          if (cl instanceof ClassLoader) loader = (ClassLoader)cl;
!       }
! 
!       try
!       {
!          WebContainer webContainer = (WebContainer)loader.loadClass(webContainerClassName).newInstance();
!          String key = createWebContainerKey(url, webContainerClassName);
!          webContainers.put(key, webContainer);
!          return webContainer;
!       }
!       catch (Exception x)
!       {
!       }
!       return null;
!    }
! 
!    private boolean isDeployed(WebContainer webContainer, JMXServiceURL url)
!    {
!       Set urls = (Set)deployedURLs.get(webContainer);
!       if (urls == null) return false;
!       return urls.contains(url);
!    }
! 
!    private boolean hasDeployed(WebContainer webContainer)
!    {
!       Set urls = (Set)deployedURLs.get(webContainer);
!       if (urls == null) return false;
!       return !urls.isEmpty();
!    }
! 
!    private void addDeployed(WebContainer webContainer, JMXServiceURL url)
!    {
!       Set urls = (Set)deployedURLs.get(webContainer);
!       if (urls == null)
!       {
!          urls = new HashSet();
!          deployedURLs.put(webContainer, urls);
!       }
!       urls.add(url);
!    }
! 
!    private void removeDeployed(WebContainer webContainer, JMXServiceURL url)
!    {
!       Set urls = (Set)deployedURLs.get(webContainer);
!       if (urls != null)
!       {
!          urls.remove(url);
!          if (urls.isEmpty()) deployedURLs.remove(webContainer);
        }
     }



-------------------------------------------------------
This SF.Net email is sponsored by BEA Weblogic Workshop
FREE Java Enterprise J2EE developer tools!
Get your free copy of BEA WebLogic Workshop 8.1 today.
http://ads.osdn.com/?ad_id=4721&alloc_id=10040&op=click
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.