1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.backsource.axis;
21
22 import java.util.Iterator;
23
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
37
38 import org.backsource.jmx.MBeanProxyFactory;
39
40
41 import org.apache.log4j.Category;
42
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> <service name="DeliverEvents" provider="Handler">
70 <parameter name="handlerClass" value="org.backsource.axis.MBeanProxyProvider"/>
71 <parameter name="ObjectName" value="ProtocolHandler:handlerName=vvWs"/>
72 <parameter name="InterfaceName" value="org.backsource.amsterdam.plugins.axis.AxisEntrance"/>
73 <parameter name="allowedMethods" value="handleMessage"/>
74 </service>
75 </pre>
76 <p>And here is one with a message style:</p>
77 <pre> <service name="DeliverDocument" style="message" provider="Handler">
78 <parameter name="handlerClass" value="org.backsource.axis.MBeanProxyProvider"/>
79 <parameter name="ObjectName" value="ProtocolHandler:handlerName=vvWs"/>
80 <parameter name="InterfaceName" value="org.backsource.amsterdam.plugins.axis.AxisEntrance"/>
81 <parameter name="allowedMethods" value="handleDocument"/>
82
83 </service>
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
130 String objectName=
131 (String) service.getOption(OBJECTNAME_PROPERTY);
132
133 String serverId=
134 (String) service.getOption(MBEAN_SERVER_ID_PROPERTY);
135
136
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
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
161 String intfName = (String)service.getOption(INTF_PROPERTY);
162 if ( intfName == null) {
163 intfName = info.getClassName();
164 }
165 try {
166
167 ClassLoader cl = getClassLoader(msgCtx);
168
169 intfClass = cl.loadClass(intfName);
170
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 }
181 super.initServiceDesc(service,msgCtx);
182
183
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
189
190 }
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 }
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
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 }