1
2
3
4
5
6
7
8
9
10
11 package org.mule.transport.soap.axis;
12
13 import org.mule.api.MuleContext;
14 import org.mule.api.MuleException;
15 import org.mule.api.MuleRuntimeException;
16 import org.mule.api.construct.FlowConstruct;
17 import org.mule.api.context.notification.MuleContextNotificationListener;
18 import org.mule.api.endpoint.EndpointBuilder;
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.processor.MessageProcessor;
24 import org.mule.api.security.SecurityFilter;
25 import org.mule.api.service.Service;
26 import org.mule.api.source.CompositeMessageSource;
27 import org.mule.api.transport.MessageReceiver;
28 import org.mule.component.DefaultJavaComponent;
29 import org.mule.config.ExceptionHelper;
30 import org.mule.config.i18n.CoreMessages;
31 import org.mule.context.notification.MuleContextNotification;
32 import org.mule.endpoint.AbstractEndpointBuilder;
33 import org.mule.endpoint.EndpointURIEndpointBuilder;
34 import org.mule.model.seda.SedaService;
35 import org.mule.object.SingletonObjectFactory;
36 import org.mule.processor.SecurityFilterMessageProcessor;
37 import org.mule.routing.MessageFilter;
38 import org.mule.service.ServiceCompositeMessageSource;
39 import org.mule.transport.AbstractConnector;
40 import org.mule.transport.service.TransportFactory;
41 import org.mule.transport.servlet.ServletConnector;
42 import org.mule.transport.soap.axis.extensions.MuleConfigProvider;
43 import org.mule.transport.soap.axis.extensions.MuleTransport;
44 import org.mule.transport.soap.axis.extensions.WSDDFileProvider;
45 import org.mule.transport.soap.axis.extensions.WSDDJavaMuleProvider;
46 import org.mule.transport.soap.axis.i18n.AxisMessages;
47 import org.mule.util.ClassUtils;
48 import org.mule.util.CollectionUtils;
49 import org.mule.util.MuleUrlStreamHandlerFactory;
50
51 import java.lang.reflect.Field;
52 import java.util.ArrayList;
53 import java.util.HashMap;
54 import java.util.Iterator;
55 import java.util.List;
56 import java.util.Map;
57
58 import javax.xml.namespace.QName;
59
60 import org.apache.axis.AxisProperties;
61 import org.apache.axis.client.Call;
62 import org.apache.axis.configuration.SimpleProvider;
63 import org.apache.axis.deployment.wsdd.WSDDConstants;
64 import org.apache.axis.deployment.wsdd.WSDDProvider;
65 import org.apache.axis.encoding.TypeMappingRegistryImpl;
66 import org.apache.axis.encoding.ser.BeanDeserializerFactory;
67 import org.apache.axis.encoding.ser.BeanSerializerFactory;
68 import org.apache.axis.handlers.soap.SOAPService;
69 import org.apache.axis.server.AxisServer;
70 import org.apache.axis.wsdl.fromJava.Namespaces;
71 import org.apache.axis.wsdl.fromJava.Types;
72
73
74
75
76
77
78
79
80 public class AxisConnector extends AbstractConnector implements MuleContextNotificationListener<MuleContextNotification>
81 {
82
83 static
84 {
85 ExceptionHelper.registerExceptionReader(new AxisFaultExceptionReader());
86 }
87
88 public static final QName QNAME_MULE_PROVIDER = new QName(WSDDConstants.URI_WSDD_JAVA, "Mule");
89 public static final QName QNAME_MULE_TYPE_MAPPINGS = new QName("http://www.muleumo.org/ws/mappings",
90 "Mule");
91 public static final String DEFAULT_MULE_NAMESPACE_URI = "http://www.muleumo.org";
92
93 public static final String DEFAULT_MULE_AXIS_SERVER_CONFIG = "mule-axis-server-config.wsdd";
94 public static final String DEFAULT_MULE_AXIS_CLIENT_CONFIG = "mule-axis-client-config.wsdd";
95 public static final String AXIS_SERVICE_COMPONENT_NAME = "_axisServiceComponent";
96 public static final String AXIS_SERVICE_PROPERTY = "_axisService";
97 public static final String AXIS_CLIENT_CONFIG_PROPERTY = "clientConfig";
98
99 public static final String SERVICE_PROPERTY_COMPONENT_NAME = "componentName";
100 public static final String SERVICE_PROPERTY_SERVCE_PATH = "servicePath";
101
102 public static final String AXIS = "axis";
103
104
105 public static final String SOAP_METHODS = "soapMethods";
106 public static final String STYLE = "style";
107 public static final String USE = "use";
108
109 private String serverConfig = DEFAULT_MULE_AXIS_SERVER_CONFIG;
110
111 private AxisServer axis = null;
112 private SimpleProvider serverProvider = null;
113 private String clientConfig = DEFAULT_MULE_AXIS_CLIENT_CONFIG;
114 private SimpleProvider clientProvider = null;
115
116 private List beanTypes;
117 private Service axisComponent;
118
119
120
121
122
123
124
125
126
127 private Map axisTransportProtocols = null;
128
129
130
131
132
133
134
135 private List servletServices = new ArrayList();
136
137 private List supportedSchemes = null;
138
139 private boolean doAutoTypes = true;
140
141 private boolean treatMapAsNamedParams = true;
142
143 public AxisConnector(MuleContext context)
144 {
145 super(context);
146 this.registerProtocols();
147 }
148
149 protected void registerProtocols()
150 {
151 if (supportedSchemes == null)
152 {
153
154
155 supportedSchemes = new ArrayList();
156 supportedSchemes.add("http");
157 supportedSchemes.add("https");
158 supportedSchemes.add("servlet");
159 supportedSchemes.add("vm");
160 supportedSchemes.add("jms");
161 supportedSchemes.add("xmpp");
162 supportedSchemes.add("ssl");
163 supportedSchemes.add("tcp");
164 supportedSchemes.add("smtp");
165 supportedSchemes.add("smtps");
166 supportedSchemes.add("pop3");
167 supportedSchemes.add("pop3s");
168 supportedSchemes.add("imap");
169 supportedSchemes.add("imaps");
170 }
171
172 for (Iterator iterator = supportedSchemes.iterator(); iterator.hasNext();)
173 {
174 String s = (String) iterator.next();
175 registerSupportedProtocol(s);
176 }
177 }
178
179 @Override
180 protected void doInitialise() throws InitialisationException
181 {
182 axisTransportProtocols = new HashMap();
183
184
185 axisTransportProtocols = new HashMap();
186 try
187 {
188 for (Iterator iterator = supportedSchemes.iterator(); iterator.hasNext();)
189 {
190 String s = (String) iterator.next();
191 axisTransportProtocols.put(s, MuleTransport.getTransportClass(s));
192 registerSupportedProtocol(s);
193 }
194 muleContext.registerListener(this);
195 }
196 catch (Exception e)
197 {
198 throw new InitialisationException(e, this);
199 }
200
201
202 if (clientProvider == null)
203 {
204 clientProvider = createAxisProvider(clientConfig);
205 }
206 else
207 {
208 if (!DEFAULT_MULE_AXIS_CLIENT_CONFIG.equals(clientConfig))
209 {
210 logger.warn(AxisMessages.clientProviderAndClientConfigConfigured());
211 }
212 }
213
214 if (axis == null)
215 {
216 if (serverProvider == null)
217 {
218 serverProvider = this.createAxisProvider(serverConfig);
219 }
220 else
221 {
222 if (!DEFAULT_MULE_AXIS_SERVER_CONFIG.equals(serverConfig))
223 {
224 logger.warn(AxisMessages.serverProviderAndServerConfigConfigured());
225 }
226 }
227
228
229 axis = new AxisServer(serverProvider);
230
231 axis.setOption("axis.doAutoTypes", Boolean.valueOf(doAutoTypes));
232 }
233
234
235 WSDDProvider.registerProvider(QNAME_MULE_PROVIDER, new WSDDJavaMuleProvider(this));
236
237 try
238 {
239 registerTransportTypes();
240 }
241 catch (ClassNotFoundException e)
242 {
243 throw new InitialisationException(
244 CoreMessages.cannotLoadFromClasspath(e.getMessage()), e, this);
245 }
246
247
248
249
250 MuleUrlStreamHandlerFactory.registerHandler("jms", new org.mule.transport.soap.axis.transport.jms.Handler());
251 MuleUrlStreamHandlerFactory.registerHandler("pop3", new org.mule.transport.soap.axis.transport.pop3.Handler());
252 MuleUrlStreamHandlerFactory.registerHandler("smtp", new org.mule.transport.soap.axis.transport.smtp.Handler());
253 MuleUrlStreamHandlerFactory.registerHandler("vm", new org.mule.transport.soap.axis.transport.vm.Handler());
254
255 try
256 {
257 registerTypes((TypeMappingRegistryImpl) axis.getTypeMappingRegistry(), beanTypes);
258 }
259 catch (ClassNotFoundException e)
260 {
261 throw new InitialisationException(e, this);
262 }
263 }
264
265 protected void registerTransportTypes() throws ClassNotFoundException
266 {
267
268
269
270 for (Iterator iterator = getAxisTransportProtocols().keySet().iterator(); iterator.hasNext();)
271 {
272 String protocol = (String) iterator.next();
273 Object temp = getAxisTransportProtocols().get(protocol);
274 Class clazz;
275 if (temp instanceof String)
276 {
277 clazz = ClassUtils.loadClass(temp.toString(), getClass());
278 }
279 else
280 {
281 clazz = (Class) temp;
282 }
283 Call.setTransportForProtocol(protocol, clazz);
284 }
285 }
286
287 protected SimpleProvider createAxisProvider(String config) throws InitialisationException
288 {
289
290
291
292
293 WSDDFileProvider fileProvider = new WSDDFileProvider(config);
294 fileProvider.setSearchClasspath(true);
295
296
297
298
299
300 return new MuleConfigProvider(fileProvider);
301 }
302
303 public String getProtocol()
304 {
305 return AXIS;
306 }
307
308
309
310
311
312
313
314
315
316 @Override
317 protected Object getReceiverKey(FlowConstruct flowConstruct, InboundEndpoint endpoint)
318 {
319 if (endpoint.getEndpointURI().getPort() == -1)
320 {
321 return flowConstruct.getName();
322 }
323 else
324 {
325 return endpoint.getEndpointURI().getAddress() + "/" + flowConstruct.getName();
326 }
327 }
328
329 protected void unregisterReceiverWithMuleService(MessageReceiver receiver, EndpointURI ep)
330 throws MuleException
331 {
332 String endpointKey = getCounterEndpointKey(receiver.getEndpointURI());
333
334 for (Iterator iterator = ((ServiceCompositeMessageSource) axisComponent.getMessageSource()).getEndpoints().iterator(); iterator.hasNext();)
335 {
336 ImmutableEndpoint endpoint = (ImmutableEndpoint) iterator.next();
337 if (endpointKey.startsWith(endpoint.getEndpointURI().getAddress()))
338 {
339 logger.info("Unregistering Axis endpoint: " + endpointKey + " for service: "
340 + ((AxisMessageReceiver) receiver).getSoapService().getName());
341 }
342 try
343 {
344 endpoint.getConnector()
345 .unregisterListener(receiver.getEndpoint(), axisComponent);
346 }
347 catch (Exception e)
348 {
349 logger.error("Failed to unregister Axis endpoint: " + endpointKey + " for service: "
350 + receiver.getFlowConstruct().getName() + ". Error is: "
351 + e.getMessage(), e);
352 }
353 }
354 }
355
356 protected void registerReceiverWithMuleService(MessageReceiver receiver, EndpointURI ep)
357 throws MuleException
358 {
359
360
361
362
363
364 if (axisComponent == null)
365 {
366 axisComponent = getOrCreateAxisComponent();
367 }
368 else
369 {
370
371
372 muleContext.getRegistry().unregisterService(AXIS_SERVICE_PROPERTY + getName());
373 }
374
375 String serviceName = ((AxisMessageReceiver) receiver).getSoapService().getName();
376
377
378
379
380 String endpoint;
381 String scheme = ep.getScheme().toLowerCase();
382 if (scheme.equals("jms") || scheme.equals("vm") || scheme.equals("servlet"))
383 {
384 endpoint = ep.toString();
385 }
386 else
387 {
388 endpoint = receiver.getEndpointURI().getAddress() + "/" + serviceName;
389 }
390 if (logger.isDebugEnabled())
391 {
392 logger.debug("Modified endpoint with " + scheme + " scheme to " + endpoint);
393 }
394
395 EndpointBuilder serviceEndpointbuilder = new EndpointURIEndpointBuilder(endpoint, muleContext);
396 serviceEndpointbuilder.setExchangePattern(receiver.getEndpoint().getExchangePattern());
397 serviceEndpointbuilder.setName(ep.getScheme() + ":" + serviceName);
398
399 serviceEndpointbuilder.setTransformers(receiver.getEndpoint().getTransformers().isEmpty() ? null
400 : receiver.getEndpoint().getTransformers());
401 serviceEndpointbuilder.setResponseTransformers(receiver.getEndpoint().getResponseTransformers().isEmpty() ? null
402 : receiver.getEndpoint().getResponseTransformers());
403
404 serviceEndpointbuilder.addMessageProcessor(new MessageFilter(receiver.getEndpoint().getFilter()));
405
406
407 SecurityFilter securityFilter = receiver.getEndpoint().getSecurityFilter();
408 if (securityFilter != null)
409 {
410 serviceEndpointbuilder.addMessageProcessor(new SecurityFilterMessageProcessor(securityFilter));
411 }
412
413
414
415 AbstractEndpointBuilder receiverEndpointBuilder = new EndpointURIEndpointBuilder(receiver.getEndpoint());
416
417
418 List<MessageProcessor> procs = new ArrayList(receiverEndpointBuilder.getMessageProcessors());
419 CollectionUtils.removeType(procs, MessageFilter.class);
420 CollectionUtils.removeType(procs, SecurityFilterMessageProcessor.class);
421 receiverEndpointBuilder.setMessageProcessors(procs);
422
423 InboundEndpoint serviceEndpoint = muleContext.getEndpointFactory()
424 .getInboundEndpoint(serviceEndpointbuilder);
425
426 InboundEndpoint receiverEndpoint = muleContext.getEndpointFactory()
427 .getInboundEndpoint(receiverEndpointBuilder);
428
429 receiver.setEndpoint(receiverEndpoint);
430
431 ((CompositeMessageSource) axisComponent.getMessageSource()).addSource(serviceEndpoint);
432 }
433
434 private String getCounterEndpointKey(EndpointURI endpointURI)
435 {
436 StringBuffer endpointKey = new StringBuffer(64);
437
438 endpointKey.append(endpointURI.getScheme());
439 endpointKey.append("://");
440 endpointKey.append(endpointURI.getHost());
441 if (endpointURI.getPort() > -1)
442 {
443 endpointKey.append(":");
444 endpointKey.append(endpointURI.getPort());
445 }
446 return endpointKey.toString();
447 }
448
449
450
451
452
453
454 protected Service getOrCreateAxisComponent() throws MuleException
455 {
456 Service service = muleContext.getRegistry().lookupService(AXIS_SERVICE_PROPERTY + getName());
457
458 if (service == null)
459 {
460
461 service = new SedaService(muleContext);
462 service.setName(AXIS_SERVICE_PROPERTY + getName());
463 service.setModel(muleContext.getRegistry().lookupSystemModel());
464
465 Map props = new HashMap();
466 props.put(AXIS, axis);
467 SingletonObjectFactory of = new SingletonObjectFactory(AxisServiceComponent.class, props);
468 final DefaultJavaComponent component = new DefaultJavaComponent(of);
469 component.setMuleContext(muleContext);
470 service.setComponent(component);
471 }
472 return service;
473 }
474
475
476
477
478
479
480 @Override
481 protected void doStart() throws MuleException
482 {
483 axis.start();
484 }
485
486
487
488
489
490
491 @Override
492 protected void doStop() throws MuleException
493 {
494 axis.stop();
495
496
497 }
498
499 @Override
500 protected void doConnect() throws Exception
501 {
502
503 }
504
505 @Override
506 protected void doDisconnect() throws Exception
507 {
508
509 }
510
511 @Override
512 protected void doDispose()
513 {
514
515
516 try
517 {
518 Field field = AxisProperties.class.getDeclaredField("loaders");
519 field.setAccessible(true);
520 field.set(null, null);
521
522 field = AxisProperties.class.getDeclaredField("nameDiscoverer");
523 field.setAccessible(true);
524 field.set(null, null);
525 }
526 catch (Exception e)
527 {
528 logger.error(
529 "Error disposing AxisConnector, this may cause a memory leak. Error is: " + e.getMessage(), e);
530 }
531
532 }
533
534 public String getServerConfig()
535 {
536 return serverConfig;
537 }
538
539 public void setServerConfig(String serverConfig)
540 {
541 this.serverConfig = serverConfig;
542 }
543
544 public List getBeanTypes()
545 {
546 return beanTypes;
547 }
548
549 public void setBeanTypes(List beanTypes)
550 {
551 this.beanTypes = beanTypes;
552 }
553
554 public String getClientConfig()
555 {
556 return clientConfig;
557 }
558
559 public void setClientConfig(String clientConfig)
560 {
561 this.clientConfig = clientConfig;
562 }
563
564 public AxisServer getAxis()
565 {
566 return axis;
567 }
568
569 public void setAxis(AxisServer axisServer)
570 {
571 this.axis = axisServer;
572 }
573
574 public SimpleProvider getServerProvider()
575 {
576 return serverProvider;
577 }
578
579 public void setServerProvider(SimpleProvider serverProvider)
580 {
581 this.serverProvider = serverProvider;
582 }
583
584 public SimpleProvider getClientProvider()
585 {
586 return clientProvider;
587 }
588
589 public void setClientProvider(SimpleProvider clientProvider)
590 {
591 this.clientProvider = clientProvider;
592 }
593
594 public Map getAxisTransportProtocols()
595 {
596 return axisTransportProtocols;
597 }
598
599 public void setAxisTransportProtocols(Map axisTransportProtocols)
600 {
601 this.axisTransportProtocols.putAll(axisTransportProtocols);
602 }
603
604 void addServletService(SOAPService service)
605 {
606 servletServices.add(service);
607 }
608
609 public List getSupportedSchemes()
610 {
611 return supportedSchemes;
612 }
613
614 public void setSupportedSchemes(List supportedSchemes)
615 {
616 this.supportedSchemes = supportedSchemes;
617 }
618
619 public boolean isDoAutoTypes()
620 {
621 return doAutoTypes;
622 }
623
624 public void setDoAutoTypes(boolean doAutoTypes)
625 {
626 this.doAutoTypes = doAutoTypes;
627 }
628
629 void registerTypes(TypeMappingRegistryImpl registry, List types) throws ClassNotFoundException
630 {
631 if (types != null)
632 {
633 Class clazz;
634 for (Iterator iterator = types.iterator(); iterator.hasNext();)
635 {
636 clazz = ClassUtils.loadClass(iterator.next().toString(), getClass());
637 String localName = Types.getLocalNameFromFullName(clazz.getName());
638 QName xmlType = new QName(Namespaces.makeNamespace(clazz.getName()), localName);
639
640 registry.getDefaultTypeMapping().register(clazz, xmlType,
641 new BeanSerializerFactory(clazz, xmlType), new BeanDeserializerFactory(clazz, xmlType));
642 }
643 }
644 }
645
646 public boolean isTreatMapAsNamedParams()
647 {
648 return treatMapAsNamedParams;
649 }
650
651 public void setTreatMapAsNamedParams(boolean treatMapAsNamedParams)
652 {
653 this.treatMapAsNamedParams = treatMapAsNamedParams;
654 }
655
656 public void onNotification(MuleContextNotification notification)
657 {
658 try
659 {
660 if (notification.getAction() == MuleContextNotification.CONTEXT_STARTED)
661 {
662
663
664
665
666
667
668 if (muleContext.getRegistry().lookupService(AXIS_SERVICE_PROPERTY + getName()) == null)
669 {
670
671
672 if (axisComponent == null)
673 {
674 axisComponent = getOrCreateAxisComponent();
675 }
676 muleContext.getRegistry().registerService(axisComponent);
677
678
679
680
681 for (Iterator iterator = servletServices.iterator(); iterator.hasNext();)
682 {
683 SOAPService service = (SOAPService) iterator.next();
684 ServletConnector servletConnector = (ServletConnector) new TransportFactory(muleContext).getConnectorByProtocol("servlet");
685 String url = servletConnector.getServletUrl();
686 if (url != null)
687 {
688 service.getServiceDescription().setEndpointURL(url + "/" + service.getName());
689 }
690 else
691 {
692 logger.error("The servletUrl property on the ServletConntector has not been set this means that wsdl generation for service '"
693 + service.getName() + "' may be incorrect");
694 }
695 }
696 servletServices.clear();
697 }
698 }
699 }
700 catch (MuleException e)
701 {
702 throw new MuleRuntimeException(e);
703 }
704 }
705 }