View Javadoc

1   /*
2    * Copyright (c) 2003 Peter Antman, Teknik i Media  <peter.antman@tim.se>
3    *
4    * $Id: MBeanProxyProvider.java,v 1.1.1.1 2004/05/19 12:26:42 pra Exp $
5    *
6    * This library is free software; you can redistribute it and/or
7    * modify it under the terms of the GNU Lesser General Public
8    * License as published by the Free Software Foundation; either
9    * version 2 of the License, or (at your option) any later version
10   * 
11   * This library is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14   * Lesser General Public License for more details.
15   * 
16   * You should have received a copy of the GNU Lesser General Public
17   * License along with this library; if not, write to the Free Software
18   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19   */
20  package org.backsource.axis;
21  
22  import java.util.Iterator;
23  // axis package
24  import org.apache.axis.AxisFault;
25  import org.apache.axis.Handler;
26  import org.apache.axis.MessageContext;
27  import org.apache.axis.EngineConfiguration;
28  import org.apache.axis.message.SOAPEnvelope;
29  import org.apache.axis.description.ServiceDesc;
30  import org.apache.axis.enum.Style;
31  import org.apache.axis.handlers.soap.SOAPService;
32  import org.apache.axis.providers.java.RPCProvider;
33  import org.apache.axis.providers.java.MsgProvider;
34  import org.apache.axis.providers.java.JavaProvider;
35  
36  // Jboss
37  //import org.jboss.util.jmx.MBeanProxy;
38  import org.backsource.jmx.MBeanProxyFactory;
39  
40  // log4j
41  import org.apache.log4j.Category;
42  // jmx
43  import javax.management.MBeanServerFactory;
44  import javax.management.MBeanServer;
45  import javax.management.MBeanException;
46  import javax.management.ReflectionException;
47  import javax.management.InstanceNotFoundException;
48  import javax.management.MalformedObjectNameException;
49  import javax.management.ObjectName;
50  import javax.management.Attribute;
51  import javax.management.MBeanInfo;
52  import javax.management.MBeanAttributeInfo;
53  import javax.management.AttributeNotFoundException;
54  import javax.management.InvalidAttributeValueException;
55  import javax.management.InvalidAttributeValueException;
56  import javax.management.IntrospectionException;
57  import javax.management.ReflectionException;
58  import javax.management.MBeanOperationInfo;
59  import javax.management.OperationsException;
60  
61  import javax.naming.NamingException;
62  /***
63   * An axis mbean invoker provider.
64   *
65   * <p>This may be used as an Axis provider/handler to delegate the incomming
66   * soap request to an MBean given by the service propery <code>ObjectName</code>. An interface class must also be specifyed, since a proxy to the mbean is
67   create with that interface, and since all operations are basically done through introspection.</p>
68   *<p>Currently it is possible to use this hanlder both for RPC and message style invocations. Here is a minimal configuration for an rpc service: </p>
69  <pre>   &lt;service name="DeliverEvents" provider="Handler"&gt;
70            &lt;parameter name="handlerClass" value="org.backsource.axis.MBeanProxyProvider"/&gt;
71            &lt;parameter name="ObjectName" value="ProtocolHandler:handlerName=vvWs"/&gt;
72            &lt;parameter name="InterfaceName" value="org.backsource.amsterdam.plugins.axis.AxisEntrance"/&gt;
73            &lt;parameter name="allowedMethods" value="handleMessage"/&gt;
74          &lt;/service&gt;
75  </pre>
76  <p>And here is one with a message style:</p>
77  <pre>   &lt;service name="DeliverDocument" style="message" provider="Handler"&gt;
78            &lt;parameter name="handlerClass" value="org.backsource.axis.MBeanProxyProvider"/&gt;
79            &lt;parameter name="ObjectName" value="ProtocolHandler:handlerName=vvWs"/&gt;
80            &lt;parameter name="InterfaceName" value="org.backsource.amsterdam.plugins.axis.AxisEntrance"/&gt;
81            &lt;parameter name="allowedMethods" value="handleDocument"/&gt;
82  
83          &lt;/service&gt;
84  </pre>
85   *
86   * @author <a href="mailto:pra@tim.se">Peter Antman</a>
87   * @version $Revision: 1.1.1.1 $
88   */
89  
90  public class MBeanProxyProvider extends RPCProvider {
91     /*** Object name of the MBean to proxy */
92     static final String OBJECTNAME_PROPERTY = "ObjectName";
93     
94     /*** Service property of mbean server id, may/should be null */
95     static final String MBEAN_SERVER_ID_PROPERTY = "MBeanServerId";
96     
97     /*** service property of interface */
98     static final String INTF_PROPERTY = "InterfaceName";
99     
100    /*** stores meta-data about mbean */
101    protected MBeanInfo info;
102 
103    /*** the server which we are tight to */
104    protected MBeanServer server;
105    
106    /*** the objectName which we are running into */
107    protected ObjectName name;
108    
109    /*** whether this provider has been already initialized */
110    protected boolean initialized;
111 
112    protected Class intfClass;
113 
114    protected Object targetObject;
115 
116    protected JavaProvider delegate;
117    
118    public MBeanProxyProvider (){
119       
120    }
121    
122    /*** 
123     * initialize the meta-data 
124     * @see org.apache.axis.providers.BasicProvider#initServiceDesc(SOAPService, MessageContext)
125     * 1.0
126     */
127    public void initServiceDesc(SOAPService service, MessageContext msgCtx)
128       throws AxisFault {
129       // include the JMX objectname
130       String objectName=
131          (String) service.getOption(OBJECTNAME_PROPERTY);
132       // and the server id (maybe)
133       String serverId=
134          (String) service.getOption(MBEAN_SERVER_ID_PROPERTY);
135          
136       // process server id
137       Iterator allServers=
138          MBeanServerFactory.findMBeanServer(serverId).iterator();
139       if (!allServers.hasNext())
140          throw new AxisFault("Could not find the associated MBeanServer.");
141       else
142          server= (MBeanServer) allServers.next();
143       
144       // process objectname
145       try {
146          name= new ObjectName(objectName);
147       } catch (MalformedObjectNameException e) {
148          throw new AxisFault("ObjectName could not be converted to a javax.management.ObjectName.", e);
149       }
150       try {
151          info= server.getMBeanInfo(name);
152       } catch (InstanceNotFoundException e) {
153          throw new AxisFault("Could not find MBean instance.", e);
154       } catch (IntrospectionException e) {
155          throw new AxisFault("Could not introspect mbean.", e);
156       } catch (ReflectionException e) {
157          throw new AxisFault("Could not introspect mbean.", e);
158       }
159       
160       // Get interface name
161       String intfName = (String)service.getOption(INTF_PROPERTY);
162       if ( intfName == null) {
163          intfName = info.getClassName();
164       } // end of if ()
165       try {
166          
167          ClassLoader cl     = getClassLoader(msgCtx);
168          // Make shure it loads
169          intfClass = cl.loadClass(intfName);
170          //targetObject = MBeanProxy.create( intfClass, name, server);
171          targetObject = MBeanProxyFactory.create(intfClass,
172                                                  name.toString());
173          
174       } catch (ClassNotFoundException e) {
175          throw new AxisFault("Could not load interface class " + intfName, e);
176       } catch (OperationsException e) {
177          throw new AxisFault("Could not create proxy " + intfName, e);
178       }  catch (NamingException e) {
179          throw new AxisFault("Could not lookup remote mbean server " + intfName, e);
180       } // end of try-catch
181       super.initServiceDesc(service,msgCtx);
182 
183       // Check style
184       ServiceDesc serviceDesc = service.getServiceDescription();
185       if ( serviceDesc.getStyle().equals(Style.MESSAGE) ) {
186          log.debug("Setting up delegate for message style");
187          delegate = new MsgProvider();
188          // Just in case
189          //delegate.initServiceDesc(service, msgCtx);
190       } // end of if ()
191       
192    }
193 
194    public void processMessage (MessageContext msgContext,
195                                 SOAPEnvelope reqEnv,
196                                 SOAPEnvelope resEnv,
197                                 Object obj)
198         throws Exception
199     {
200        if ( delegate != null) {
201           delegate.processMessage(msgContext,reqEnv,resEnv,obj);
202        } else {
203           super.processMessage(msgContext,reqEnv,resEnv,obj);
204        } // end of else
205        
206        
207     }
208 
209 
210    protected Object makeNewServiceObject(MessageContext msgContext, java.lang.String clsName) {
211 
212       return targetObject;
213    }
214 
215    /***
216     * Return the class name of the service
217     */
218    protected String getServiceClassName(Handler service)
219    {
220 
221       return intfClass.getName();
222    }
223    protected Class getServiceClass(MessageContext msgContext, String clsName) throws Exception {
224       //initialize(msgContext);
225       return intfClass;
226    }
227    protected ClassLoader getClassLoader(MessageContext msgContext) {
228       ClassLoader  cl = null;;
229       if (msgContext != null) {
230             cl = msgContext.getClassLoader();
231         } else {
232             cl = Thread.currentThread().getContextClassLoader();
233         }
234       return cl;
235    }
236 }// MBeanProxyProvider