1
2
3
4
5
6
7
8
9
10
11 package org.mule.transport.rmi;
12
13 import org.mule.api.MessagingException;
14 import org.mule.api.MuleContext;
15 import org.mule.api.MuleEvent;
16 import org.mule.api.MuleException;
17 import org.mule.api.config.MuleProperties;
18 import org.mule.api.construct.FlowConstruct;
19 import org.mule.api.endpoint.EndpointURI;
20 import org.mule.api.endpoint.ImmutableEndpoint;
21 import org.mule.api.endpoint.InboundEndpoint;
22 import org.mule.api.lifecycle.InitialisationException;
23 import org.mule.api.transformer.TransformerException;
24 import org.mule.api.transport.MessageReceiver;
25 import org.mule.api.transport.PropertyScope;
26 import org.mule.config.i18n.CoreMessages;
27 import org.mule.transport.AbstractJndiConnector;
28 import org.mule.transport.rmi.i18n.RmiMessages;
29 import org.mule.util.ArrayUtils;
30 import org.mule.util.ClassUtils;
31 import org.mule.util.IOUtils;
32
33 import java.io.IOException;
34 import java.lang.reflect.Method;
35 import java.net.InetAddress;
36 import java.net.URL;
37 import java.rmi.NotBoundException;
38 import java.rmi.RMISecurityManager;
39 import java.rmi.Remote;
40 import java.util.Arrays;
41 import java.util.Collection;
42 import java.util.Iterator;
43 import java.util.List;
44
45 import javax.naming.NamingException;
46
47 import org.apache.commons.collections.MapUtils;
48
49
50
51
52 public class RmiConnector extends AbstractJndiConnector
53 {
54
55 public static final String RMI = "rmi";
56 public static final int DEFAULT_RMI_muleRegistry_PORT = 1099;
57 public static final String PROPERTY_RMI_SECURITY_POLICY = "securityPolicy";
58 public static final String PROPERTY_RMI_SERVER_CODEBASE = "serverCodebase";
59 public static final String PROPERTY_SERVER_CLASS_NAME = "serverClassName";
60
61
62
63
64
65
66
67
68 public static final String PROPERTY_SERVICE_METHOD_PARAM_TYPES = "methodArgumentTypes";
69
70
71
72
73
74 public static final String PROPERTY_SERVICE_METHOD_PARAMS_LIST = "methodArgumentsList";
75
76 private String securityPolicy = null;
77
78 private String serverCodebase = null;
79
80 private String serverClassName = null;
81
82 protected long pollingFrequency = 1000L;
83
84 private SecurityManager securityManager = new RMISecurityManager();
85
86 public RmiConnector(MuleContext context)
87 {
88 super(context);
89 }
90
91 @Override
92 protected void doInitialise() throws InitialisationException
93 {
94
95 if (securityPolicy != null)
96 {
97 System.setProperty("java.security.policy", securityPolicy);
98 }
99
100
101 if (securityManager != null)
102 {
103 System.setSecurityManager(securityManager);
104 }
105
106 initJndiContext();
107 }
108
109 @Override
110 protected void doDispose()
111 {
112
113 }
114
115 @Override
116 protected void doConnect() throws Exception
117 {
118
119 }
120
121 @Override
122 protected void doDisconnect() throws Exception
123 {
124
125 }
126
127 @Override
128 protected void doStart() throws MuleException
129 {
130
131 }
132
133 @Override
134 protected void doStop() throws MuleException
135 {
136
137 }
138
139 public String getProtocol()
140 {
141 return RMI;
142 }
143
144 public String getSecurityPolicy()
145 {
146 return securityPolicy;
147 }
148
149 public void setSecurityPolicy(String path)
150 {
151
152 if (path != null)
153 {
154 URL url = IOUtils.getResourceAsUrl(path, RmiConnector.class);
155 if (url == null)
156 {
157 throw new IllegalArgumentException(
158 "Error on initialization, RMI security policy does not exist");
159 }
160 this.securityPolicy = url.toString();
161 }
162 }
163
164 public String getServerCodebase()
165 {
166 return (this.serverCodebase);
167 }
168
169 public void setServerCodebase(String serverCodebase)
170 {
171 this.serverCodebase = serverCodebase;
172 }
173
174 public String getServerClassName()
175 {
176 return (this.serverClassName);
177 }
178
179 public void setServerClassName(String serverClassName)
180 {
181 this.serverClassName = serverClassName;
182 }
183
184 public SecurityManager getSecurityManager()
185 {
186 return securityManager;
187 }
188
189 public void setSecurityManager(SecurityManager securityManager)
190 {
191 this.securityManager = securityManager;
192 }
193
194 @Override
195 public MessageReceiver createReceiver(FlowConstruct flowConstruct, InboundEndpoint endpoint) throws Exception
196 {
197 final Object[] args = new Object[]{new Long(pollingFrequency)};
198 return getServiceDescriptor().createMessageReceiver(this, flowConstruct, endpoint, args);
199 }
200
201
202
203
204
205
206
207
208
209
210
211 public Method getMethodObject(Remote remoteObject, MuleEvent event)
212 throws MuleException, NoSuchMethodException, ClassNotFoundException
213 {
214 EndpointURI endpointUri = event.getEndpoint().getEndpointURI();
215 String methodName = MapUtils.getString(endpointUri.getParams(), MuleProperties.MULE_METHOD_PROPERTY,
216 null);
217
218 if (null == methodName)
219 {
220 methodName = (String)event.getMessage().removeProperty(MuleProperties.MULE_METHOD_PROPERTY, PropertyScope.INVOCATION);
221
222 if (null == methodName)
223 {
224 throw new MessagingException(RmiMessages.messageParamServiceMethodNotSet(), event);
225 }
226 }
227
228 Class[] argTypes = getArgTypes(event.getMessage().getInvocationProperty(RmiConnector.PROPERTY_SERVICE_METHOD_PARAM_TYPES), event);
229
230 try
231 {
232 return remoteObject.getClass().getMethod(methodName, argTypes);
233 }
234 catch (NoSuchMethodException e)
235 {
236 throw new NoSuchMethodException(
237 CoreMessages.methodWithParamsNotFoundOnObject(methodName, ArrayUtils.toString(argTypes),
238 remoteObject.getClass()).toString());
239 }
240 catch (SecurityException e)
241 {
242 throw e;
243 }
244 }
245
246 protected Class[] stringsToClasses(Collection strings) throws ClassNotFoundException
247 {
248 Class[] classes = new Class[strings.size()];
249 int index = 0;
250 Iterator string = strings.iterator();
251 while (string.hasNext())
252 {
253 classes[index++] = ClassUtils.loadClass((String) string.next(), getClass());
254 }
255 return classes;
256 }
257
258 protected Object getRemoteRef(ImmutableEndpoint endpoint)
259 throws IOException, NotBoundException, NamingException, InitialisationException
260 {
261
262 EndpointURI endpointUri = endpoint.getEndpointURI();
263
264 String serviceName = endpointUri.getPath();
265 try
266 {
267
268 return getJndiContext().lookup(serviceName);
269 }
270 catch (NamingException e)
271 {
272
273 }
274
275 try
276 {
277 serviceName = serviceName.substring(1);
278 return getJndiContext().lookup(serviceName);
279 }
280 catch (NamingException e)
281 {
282
283 }
284
285 int port = endpointUri.getPort();
286 if (port < 1)
287 {
288 if (logger.isWarnEnabled())
289 {
290 logger.warn("RMI port not set on URI: " + endpointUri + ". Using default port: "
291 + RmiConnector.DEFAULT_RMI_muleRegistry_PORT);
292 }
293 port = RmiConnector.DEFAULT_RMI_muleRegistry_PORT;
294 }
295
296 InetAddress inetAddress = InetAddress.getByName(endpointUri.getHost());
297
298 return getJndiContext(inetAddress.getHostAddress() + ":" + port).lookup(serviceName);
299 }
300
301 public Remote getRemoteObject(ImmutableEndpoint endpoint)
302 throws IOException, NotBoundException, NamingException, InitialisationException
303 {
304 return (Remote)getRemoteRef(endpoint);
305 }
306
307 public long getPollingFrequency()
308 {
309 return pollingFrequency;
310 }
311
312 public void setPollingFrequency(long pollingFrequency)
313 {
314 this.pollingFrequency = pollingFrequency;
315 }
316
317 protected Class[] getArgTypes(Object args, MuleEvent fromEvent)
318 throws ClassNotFoundException, TransformerException
319 {
320 Class<?>[] argTypes = null;
321
322 if (args instanceof List)
323 {
324
325
326 argTypes = stringsToClasses((List) args);
327 }
328 else if (args instanceof String)
329 {
330 argTypes = stringsToClasses(Arrays.asList(((String) args).split(",")));
331 }
332 else
333 {
334 argTypes = ClassUtils.getClassTypes(fromEvent.getMessage().getPayload());
335 }
336
337 return argTypes;
338 }
339 }