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