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