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