001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.servicemix.cxfbc;
018
019 import java.io.IOException;
020 import java.util.ArrayList;
021 import java.util.Iterator;
022 import java.util.List;
023 import java.util.Map;
024 import java.util.ResourceBundle;
025 import java.util.Set;
026 import java.util.concurrent.ConcurrentHashMap;
027 import java.util.concurrent.CopyOnWriteArrayList;
028
029 import javax.activation.DataHandler;
030 import javax.jbi.JBIException;
031 import javax.jbi.component.ComponentContext;
032 import javax.jbi.management.DeploymentException;
033 import javax.jbi.messaging.ExchangeStatus;
034 import javax.jbi.messaging.MessageExchange;
035 import javax.jbi.messaging.NormalizedMessage;
036 import javax.jbi.servicedesc.ServiceEndpoint;
037 import javax.transaction.TransactionManager;
038 import javax.wsdl.WSDLException;
039 import javax.wsdl.extensions.soap.SOAPBinding;
040 import javax.xml.namespace.QName;
041 import javax.xml.transform.Source;
042
043 import org.w3c.dom.Element;
044 import org.w3c.dom.Node;
045 import org.w3c.dom.NodeList;
046 import com.ibm.wsdl.extensions.soap.SOAPAddressImpl;
047 import com.ibm.wsdl.extensions.soap.SOAPBindingImpl;
048
049 import org.apache.cxf.Bus;
050 import org.apache.cxf.BusFactory;
051 import org.apache.cxf.attachment.AttachmentImpl;
052 import org.apache.cxf.binding.soap.SoapFault;
053 import org.apache.cxf.binding.soap.SoapMessage;
054 import org.apache.cxf.binding.soap.interceptor.MustUnderstandInterceptor;
055 import org.apache.cxf.binding.soap.interceptor.ReadHeadersInterceptor;
056 import org.apache.cxf.binding.soap.interceptor.SoapOutInterceptor;
057 import org.apache.cxf.binding.soap.interceptor.SoapPreProtocolOutInterceptor;
058 import org.apache.cxf.bus.CXFBusImpl;
059 import org.apache.cxf.bus.spring.SpringBusFactory;
060 import org.apache.cxf.catalog.OASISCatalogManager;
061 import org.apache.cxf.continuations.Continuation;
062 import org.apache.cxf.continuations.ContinuationProvider;
063 import org.apache.cxf.endpoint.Endpoint;
064 import org.apache.cxf.endpoint.EndpointImpl;
065 import org.apache.cxf.endpoint.Server;
066 import org.apache.cxf.endpoint.ServerImpl;
067 import org.apache.cxf.feature.AbstractFeature;
068 import org.apache.cxf.helpers.DOMUtils;
069 import org.apache.cxf.interceptor.AttachmentInInterceptor;
070 import org.apache.cxf.interceptor.AttachmentOutInterceptor;
071 import org.apache.cxf.interceptor.BareOutInterceptor;
072 import org.apache.cxf.interceptor.Fault;
073 import org.apache.cxf.interceptor.Interceptor;
074 import org.apache.cxf.interceptor.OneWayProcessorInterceptor;
075 import org.apache.cxf.interceptor.OutgoingChainInterceptor;
076 import org.apache.cxf.interceptor.StaxInInterceptor;
077 import org.apache.cxf.interceptor.StaxOutInterceptor;
078 import org.apache.cxf.interceptor.InterceptorChain.State;
079 import org.apache.cxf.message.Attachment;
080 import org.apache.cxf.message.Exchange;
081 import org.apache.cxf.message.Message;
082 import org.apache.cxf.message.MessageContentsList;
083 import org.apache.cxf.phase.AbstractPhaseInterceptor;
084 import org.apache.cxf.phase.Phase;
085 import org.apache.cxf.phase.PhaseInterceptorChain;
086 import org.apache.cxf.service.Service;
087 import org.apache.cxf.service.invoker.Invoker;
088 import org.apache.cxf.service.model.BindingFaultInfo;
089 import org.apache.cxf.service.model.BindingOperationInfo;
090 import org.apache.cxf.service.model.EndpointInfo;
091 import org.apache.cxf.service.model.FaultInfo;
092 import org.apache.cxf.service.model.MessagePartInfo;
093 import org.apache.cxf.service.model.ServiceInfo;
094 import org.apache.cxf.transport.ChainInitiationObserver;
095 import org.apache.cxf.transport.Destination;
096 import org.apache.cxf.transport.http_jetty.JettyHTTPDestination;
097 import org.apache.cxf.transport.http_jetty.JettyHTTPServerEngine;
098 import org.apache.cxf.transport.jms.JMSConfiguration;
099 import org.apache.cxf.transport.jms.JMSDestination;
100 import org.apache.cxf.ws.addressing.AddressingProperties;
101 import org.apache.cxf.ws.addressing.ContextUtils;
102 import org.apache.cxf.ws.rm.Servant;
103 import org.apache.cxf.wsdl.WSDLManager;
104 import org.apache.cxf.wsdl11.WSDLServiceFactory;
105 import org.apache.servicemix.common.endpoints.ConsumerEndpoint;
106 import org.apache.servicemix.common.security.AuthenticationService;
107 import org.apache.servicemix.cxfbc.interceptors.ExtractHeaderPartIntercepor;
108 import org.apache.servicemix.cxfbc.interceptors.JbiInInterceptor;
109 import org.apache.servicemix.cxfbc.interceptors.JbiInWsdl1Interceptor;
110 import org.apache.servicemix.cxfbc.interceptors.JbiJAASInterceptor;
111 import org.apache.servicemix.cxfbc.interceptors.JbiOperationInterceptor;
112 import org.apache.servicemix.cxfbc.interceptors.JbiOutWsdl1Interceptor;
113 import org.apache.servicemix.cxfbc.interceptors.MtomCheckInterceptor;
114 import org.apache.servicemix.cxfbc.interceptors.JbiFault;
115 import org.apache.servicemix.cxfbc.interceptors.SchemaValidationInInterceptor;
116 import org.apache.servicemix.cxfbc.interceptors.SchemaValidationOutInterceptor;
117 import org.apache.servicemix.cxfbc.interceptors.SetStatusInterceptor;
118 import org.apache.servicemix.jbi.jaxp.SourceTransformer;
119 import org.apache.servicemix.soap.util.DomUtil;
120 import org.eclipse.jetty.server.Handler;
121 import org.springframework.core.io.Resource;
122 import org.springframework.transaction.PlatformTransactionManager;
123
124 /**
125 *
126 * @author gnodet
127 * @org.apache.xbean.XBean element="consumer" description="a consumer endpoint that is capable of using SOAP/HTTP or SOAP/JMS"
128 */
129 public class CxfBcConsumer extends ConsumerEndpoint implements
130 CxfBcEndpointWithInterceptor {
131
132 List<Interceptor<? extends Message>> in = new CopyOnWriteArrayList<Interceptor<? extends Message>>();
133
134 List<Interceptor<? extends Message>> out = new CopyOnWriteArrayList<Interceptor<? extends Message>>();
135
136 List<Interceptor<? extends Message>> outFault = new CopyOnWriteArrayList<Interceptor<? extends Message>>();
137
138 List<Interceptor<? extends Message>> inFault = new CopyOnWriteArrayList<Interceptor<? extends Message>>();
139
140 private Resource wsdl;
141
142 private Endpoint ep;
143
144 private ChainInitiationObserver chain;
145
146 private Server server;
147
148 private Map<String, Message> messages = new ConcurrentHashMap<String, Message>();
149
150 private boolean synchronous;
151
152 private boolean isOneway;
153
154 private String busCfg;
155
156 private BindingFaultInfo faultWanted;
157
158 private Bus bus;
159
160 private Bus providedBus;
161
162 private boolean mtomEnabled;
163
164 private String locationURI;
165
166 private long timeout = 0; // default is NO_TIMEOUT
167
168 private boolean useJBIWrapper = true;
169
170 private boolean useSOAPEnvelope = true;
171
172 private EndpointInfo ei;
173
174 private boolean started;
175
176 private List<AbstractFeature> features = new CopyOnWriteArrayList<AbstractFeature>();
177
178 private boolean transactionEnabled;
179
180 private boolean isSTFlow;
181
182 private ClassLoader suClassLoader;
183
184 private boolean x509;
185
186 private boolean schemaValidationEnabled;
187
188 private boolean delegateToJaas = true;
189
190 private Map<String, Object> properties = new ConcurrentHashMap<String, Object>();
191
192 /**
193 * @return the wsdl
194 */
195 public Resource getWsdl() {
196 return wsdl;
197 }
198
199 /**
200 * Specifies the location of the WSDL defining the endpoint's interface.
201 *
202 * @param wsdl the location of the WSDL contract as a <code>Resource</code> object
203 * @org.apache.xbean.Property description="the location of the WSDL document defining the endpoint's interface"
204 **/
205 public void setWsdl(Resource wsdl) {
206 this.wsdl = wsdl;
207 }
208
209 /**
210 * Returns the list of interceptors used to process fault messages being
211 * sent to the provider.
212 *
213 * @return a list of <code>Interceptor</code> objects
214 * */
215 public List<Interceptor<? extends Message>> getOutFaultInterceptors() {
216 return outFault;
217 }
218
219 /**
220 * Returns the list of interceptors used to process fault messages being
221 * recieved by the endpoint.
222 *
223 * @return a list of <code>Interceptor</code> objects
224 * */
225 public List<Interceptor<? extends Message>> getInFaultInterceptors() {
226 return inFault;
227 }
228
229 /**
230 * Returns the list of interceptors used to process responses being
231 * recieved by the endpoint.
232 *
233 * @return a list of <code>Interceptor</code> objects
234 * */
235 public List<Interceptor<? extends Message>> getInInterceptors() {
236 return in;
237 }
238
239 /**
240 * Returns the list of interceptors used to process requests being
241 * sent to the provider.
242 *
243 * @return a list of <code>Interceptor</code> objects
244 * */
245 public List<Interceptor<? extends Message>> getOutInterceptors() {
246 return out;
247 }
248
249 /**
250 * Specifies a list of interceptors used to process responses recieved
251 * by the endpoint.
252 *
253 * @param interceptors a list of <code>Interceptor</code> objects
254 * @org.apache.xbean.Property description="a list of beans configuring interceptors that process incoming responses"
255 * */
256 public void setInInterceptors(List<Interceptor<? extends Message>> interceptors) {
257 in.addAll(interceptors);
258 }
259
260 /**
261 * Specifies a list of interceptors used to process faults recieved by
262 * the endpoint.
263 *
264 * @param interceptors a list of <code>Interceptor</code> objects
265 * @org.apache.xbean.Property description="a list of beans configuring interceptors that process incoming faults"
266 * */
267 public void setInFaultInterceptors(List<Interceptor<? extends Message>> interceptors) {
268 inFault.addAll(interceptors);
269 }
270
271 /**
272 * Specifies a list of interceptors used to process requests sent by
273 * the endpoint.
274 *
275 * @param interceptors a list of <code>Interceptor</code> objects
276 * @org.apache.xbean.Property description="a list of beans configuring interceptors that process requests"
277 * */
278 public void setOutInterceptors(List<Interceptor<? extends Message>> interceptors) {
279 out.addAll(interceptors);
280 }
281
282 /**
283 * Specifies a list of interceptors used to process faults sent by
284 * the endpoint.
285 *
286 * @param interceptors a list of <code>Interceptor</code> objects
287 * @org.apache.xbean.Property description="a list of beans configuring interceptors that process fault messages being returned to the consumer"
288 * */
289 public void setOutFaultInterceptors(List<Interceptor<? extends Message>> interceptors) {
290 outFault.addAll(interceptors);
291 }
292
293 public void process(MessageExchange exchange) throws Exception {
294 if (exchange.getStatus() == ExchangeStatus.DONE) {
295 Message message = messages.get(exchange.getExchangeId());
296 if (message == null) {
297 return;
298 }
299 boolean oneway = message.getExchange().get(BindingOperationInfo.class)
300 .getOperationInfo().isOneWay();
301 if (oneway) {
302 //ensure remove message if oneway to avoid memory leak
303 messages.remove(exchange.getExchangeId());
304 }
305 return;
306 }
307 Message message = messages.remove(exchange.getExchangeId());
308 message.setContent(MessageExchange.class, exchange);
309 message.put("needSetDone", Boolean.TRUE);
310
311 boolean oneway = message.getExchange().get(BindingOperationInfo.class)
312 .getOperationInfo().isOneWay();
313 if (!isSynchronous() && !oneway) {
314 if (isNativeAsyn(message)) {
315 message.getInterceptorChain().resume();
316 } else {
317 ContinuationProvider continuationProvider = (ContinuationProvider) message
318 .get(ContinuationProvider.class.getName());
319 Continuation continuation = continuationProvider
320 .getContinuation();
321 if (continuation.isPending()) {
322 continuation.resume();
323 isSTFlow = false;
324 } else {
325 isSTFlow = true;
326 }
327 }
328 }
329 }
330
331 @Override
332 public void activate() throws Exception {
333 super.activate();
334 try {
335 registerListServiceHandler();
336 applyFeatures();
337 checkJmsTransportTransaction();
338 } catch (Exception ex){
339 super.deactivate();
340 throw ex;
341 }
342 }
343
344 private void checkJmsTransportTransaction() {
345 Destination destination = server.getDestination();
346 if (destination instanceof JMSDestination) {
347 JMSDestination jmsDestination = (JMSDestination)destination;
348 JMSConfiguration jmsConfig = jmsDestination.getJmsConfig();
349 if (jmsConfig.isSessionTransacted()) {
350 TransactionManager tm = (TransactionManager) getContext().getTransactionManager();
351 if (tm == null) {
352 throw new IllegalStateException("No TransactionManager available");
353 } else if (tm instanceof PlatformTransactionManager) {
354 jmsConfig.setSessionTransacted(true);
355 jmsConfig.setTransactionManager((PlatformTransactionManager)tm);
356 jmsConfig.setUseJms11(false);
357 setSynchronous(true);
358 transactionEnabled = true;
359 }
360 }
361 }
362
363 }
364
365 private void applyFeatures() {
366 if (getFeatures() != null) {
367 for (AbstractFeature feature : getFeatures()) {
368 feature.initialize(server, getBus());
369 }
370 }
371 }
372
373
374
375 private void registerListServiceHandler() {
376 if (server.getDestination() instanceof JettyHTTPDestination) {
377 JettyHTTPDestination jettyDest = (JettyHTTPDestination) server.getDestination();
378 JettyHTTPServerEngine jettyEng = (JettyHTTPServerEngine) jettyDest.getEngine();
379 List<Handler> handlers = jettyEng.getHandlers();
380 if (handlers == null) {
381 handlers = new ArrayList<Handler>();
382 jettyEng.setHandlers(handlers);
383 }
384 handlers.add(new ListServiceHandler(((CxfBcComponent) getServiceUnit().getComponent()).getAllBuses()));
385 }
386 }
387
388 @Override
389 public void start() throws Exception {
390 server.start();
391 super.start();
392 this.started = true;
393 }
394
395 @Override
396 public void stop() throws Exception {
397 this.started = false;
398 getBus().getExtension(WSDLManager.class).removeDefinition(definition);
399 super.stop();
400 }
401
402 @Override
403 public void deactivate() throws Exception {
404 server.stop();
405 if (!isComponentBus()) {
406 Map<String, Bus> allBuses = ((CxfBcComponent) getServiceUnit().getComponent()).getAllBuses();
407 //if use the endpoint own bus, then shutdown it
408 if (providedBus != null) {
409 if (allBuses.keySet().contains(providedBus.getId())) {
410 allBuses.remove(providedBus.getId());
411 }
412 providedBus.shutdown(true);
413 providedBus = null;
414 } else {
415 if (allBuses.keySet().contains(bus.getId())) {
416 allBuses.remove(bus.getId());
417 }
418 bus.shutdown(true);
419 bus = null;
420 }
421 }
422 super.deactivate();
423 }
424
425 @Override
426 public void validate() throws DeploymentException {
427 try {
428 suClassLoader = Thread.currentThread().getContextClassLoader();
429 if (definition == null) {
430
431 retrieveWSDL();
432 }
433 if (service == null) {
434 // looking for the servicename according to targetServiceName
435 // first
436 if (definition.getServices().containsKey(getTargetService())) {
437 service = getTargetService();
438 } else {
439 service = (QName) definition.getServices().keySet()
440 .iterator().next();
441 }
442 }
443 WSDLServiceFactory factory = new WSDLServiceFactory(getBus(),
444 definition, service);
445
446 Service cxfService = factory.create();
447
448 ei = cxfService.getServiceInfos().iterator().next()
449 .getEndpoints().iterator().next();
450 for (ServiceInfo serviceInfo : cxfService.getServiceInfos()) {
451 if (serviceInfo.getName().equals(service)
452 && getEndpoint() != null
453 && serviceInfo.getEndpoint(new QName(serviceInfo
454 .getName().getNamespaceURI(), getEndpoint())) != null) {
455 ei = serviceInfo.getEndpoint(new QName(serviceInfo
456 .getName().getNamespaceURI(), getEndpoint()));
457
458 }
459 }
460
461 if (endpoint == null) {
462 endpoint = ei.getName().getLocalPart();
463 }
464
465 if (locationURI != null) {
466 ei.setAddress(locationURI);
467 }
468 cxfService.getInInterceptors().add(new AbstractPhaseInterceptor<Message>(Phase.PRE_PROTOCOL) {
469 public void handleMessage(Message message) throws Fault {
470 if (!started) {
471 throw new Fault(new Exception("Endpoint is stopped"));
472 }
473 }
474 });
475 cxfService.getInInterceptors().add(new MustUnderstandInterceptor());
476 cxfService.getInInterceptors().add(new AttachmentInInterceptor());
477 cxfService.getInInterceptors().add(new StaxInInterceptor());
478 cxfService.getInInterceptors().add(new OneWayProcessorInterceptor());
479 cxfService.getInInterceptors().add(
480 new ReadHeadersInterceptor(getBus()));
481 cxfService.getInInterceptors().add(
482 new JbiOperationInterceptor());
483 cxfService.getInInterceptors().add(
484 new JbiInWsdl1Interceptor(isUseJBIWrapper(), isUseSOAPEnvelope()));
485 if (isSchemaValidationEnabled()) {
486 cxfService.getInInterceptors().add(new SchemaValidationInInterceptor(
487 isUseJBIWrapper(), isUseSOAPEnvelope()));
488 }
489 if (isSchemaValidationEnabled()) {
490 cxfService.getOutInterceptors().add(new SchemaValidationOutInterceptor(
491 isUseJBIWrapper(), isUseSOAPEnvelope()));
492 }
493 cxfService.getInInterceptors().add(new JbiInInterceptor());
494 cxfService.getInInterceptors().add(new JbiJAASInterceptor(
495 AuthenticationService.Proxy.create(
496 ((CxfBcComponent)this.getServiceUnit().getComponent())
497 .getAuthenticationService()), isX509(), isDelegateToJaas()));
498 cxfService.getInInterceptors().add(new JbiInvokerInterceptor());
499 cxfService.getInInterceptors().add(new JbiPostInvokerInterceptor());
500
501 cxfService.getInInterceptors().add(new OutgoingChainInterceptor());
502
503 cxfService.getOutInterceptors().add(
504 new JbiOutWsdl1Interceptor(isUseJBIWrapper(), isUseSOAPEnvelope()));
505 cxfService.getOutInterceptors().add(
506 new ExtractHeaderPartIntercepor());
507 cxfService.getOutInterceptors().add(
508 new SetStatusInterceptor());
509
510 cxfService.getOutInterceptors().add(new AttachmentOutInterceptor());
511 cxfService.getOutInterceptors().add(
512 new MtomCheckInterceptor(isMtomEnabled()));
513 cxfService.getOutInterceptors().add(new StaxOutInterceptor());
514 /*cxfService.getOutInterceptors().add(
515 new SoapPreProtocolOutInterceptor());
516 cxfService.getOutInterceptors().add(
517 new SoapOutInterceptor(getBus()));*/
518 cxfService.getOutFaultInterceptors().add(
519 new SoapOutInterceptor(getBus()));
520
521
522 ep = new EndpointImpl(getBus(), cxfService, ei);
523 getInInterceptors().addAll(getBus().getInInterceptors());
524 getInFaultInterceptors().addAll(getBus().getInFaultInterceptors());
525 getOutInterceptors().addAll(getBus().getOutInterceptors());
526 getOutFaultInterceptors()
527 .addAll(getBus().getOutFaultInterceptors());
528
529 cxfService.getInInterceptors().addAll(getInInterceptors());
530 cxfService.getInFaultInterceptors()
531 .addAll(getInFaultInterceptors());
532 cxfService.getOutInterceptors().addAll(getOutInterceptors());
533 cxfService.getOutFaultInterceptors().addAll(
534 getOutFaultInterceptors());
535
536 ep.getInInterceptors().addAll(getInInterceptors());
537 ep.getInFaultInterceptors().addAll(getInFaultInterceptors());
538 ep.getOutInterceptors().addAll(getOutInterceptors());
539 ep.getOutFaultInterceptors().addAll(getOutFaultInterceptors());
540
541 ep.getOutInterceptors().add(new AttachmentOutInterceptor());
542 ep.getOutInterceptors().add(new StaxOutInterceptor());
543 ep.getOutInterceptors().add(new SoapOutInterceptor(getBus()));
544 ep.putAll(this.getProperties());
545
546 cxfService.getInInterceptors().addAll(getBus().getInInterceptors());
547 cxfService.getInFaultInterceptors().addAll(
548 getBus().getInFaultInterceptors());
549 cxfService.getOutInterceptors().addAll(
550 getBus().getOutInterceptors());
551 cxfService.getOutFaultInterceptors().addAll(
552 getBus().getOutFaultInterceptors());
553
554 chain = new JbiChainInitiationObserver(ep, getBus());
555 removeDatabindingInterceptprs();
556 addRMFeatureRequiredInterceptors();
557 server = new ServerImpl(getBus(), ep, null, chain);
558 super.validate();
559 } catch (DeploymentException e) {
560 throw e;
561 } catch (Exception e) {
562 throw new DeploymentException(e);
563 }
564 }
565
566 private void addRMFeatureRequiredInterceptors() {
567 CXFBusImpl bus = (CXFBusImpl) getBus();
568 if (bus.getFeatures() != null) {
569 for (AbstractFeature feature : bus.getFeatures()){
570 if (feature.getClass().getName().equals("org.apache.cxf.ws.rm.feature.RMFeature")) {
571 bus.getOutInterceptors().add(new BareOutInterceptor());
572 }
573 }
574 }
575 }
576
577 private void removeDatabindingInterceptprs() {
578 for (Interceptor interceptor : ep.getBinding().getInInterceptors()) {
579 if (interceptor.getClass().getName().equals("org.apache.cxf.interceptor.DocLiteralInInterceptor")
580 || interceptor.getClass().getName().equals("org.apache.cxf.binding.soap.interceptor.SoapHeaderInterceptor")
581 || interceptor.getClass().getName().equals("org.apache.cxf.binding.soap.interceptor.RPCInInterceptor")) {
582 ep.getBinding().getInInterceptors().remove(interceptor);
583 }
584 }
585
586 for (Interceptor interceptor : ep.getBinding().getOutInterceptors()) {
587 if (interceptor.getClass().getName().equals("org.apache.cxf.interceptor.WrappedOutInterceptor")
588 || interceptor.getClass().getName().equals("org.apache.cxf.interceptor.BareOutInterceptor")) {
589 ep.getBinding().getOutInterceptors().remove(interceptor);
590 }
591 }
592 }
593
594
595 private boolean isNativeAsyn(Message message) {
596 boolean ret = false;
597 AddressingProperties addressingProperties = (AddressingProperties) message.get(WSAUtils.WSA_HEADERS_INBOUND);
598 if (addressingProperties != null
599 && !ContextUtils.isGenericAddress(addressingProperties.getReplyTo())) {
600 //it's decoupled endpoint, so already switch thread and
601 //use executors, which means underlying transport won't
602 //be block, so we shouldn't rely on continuation in
603 //this case, as the SuspendedInvocationException can't be
604 //caught by underlying transport. We just need pause/resume InterceptorChain
605 //before/after send/receive MessageExchange for async
606 return true;
607 }
608 return ret;
609 }
610
611 private void retrieveWSDL() throws JBIException, WSDLException, DeploymentException, IOException {
612 if (wsdl == null) {
613 ServiceEndpoint targetEndpoint = null;
614 // the user has provided the targetService and targetEndpoint attributes
615 if (getTargetService() != null && getTargetEndpoint() != null) {
616 targetEndpoint = getServiceUnit().getComponent().getComponentContext().getEndpoint(getTargetService(), getTargetEndpoint());
617 }
618 // the user has provided only the targetService attribute
619 if (getTargetService() != null && getTargetEndpoint() == null) {
620 ServiceEndpoint[] endpoints = getServiceUnit().getComponent().getComponentContext().getEndpointsForService(getTargetService());
621 if (endpoints != null && endpoints.length > 0) {
622 targetEndpoint = endpoints[0];
623 }
624 }
625 // the user has provided only the targetInterfaceName attribute
626 if (getTargetEndpoint() == null && getTargetInterface() != null) {
627 ServiceEndpoint[] endpoints = getServiceUnit().getComponent().getComponentContext().getEndpoints(getTargetInterface());
628 if (endpoints != null && endpoints.length > 0) {
629 targetEndpoint = endpoints[0];
630 }
631 }
632
633 if (targetEndpoint == null) {
634 throw new DeploymentException("The target endpoint is not found.");
635 }
636
637 description = this.getServiceUnit().getComponent().getComponentContext().getEndpointDescriptor(targetEndpoint);
638 definition = getBus().getExtension(WSDLManager.class).getDefinition((Element)description.getFirstChild());
639 List address = definition.getService(getTargetService()).getPort(getTargetEndpoint()).getExtensibilityElements();
640 if (address == null || address.size() == 0) {
641 SOAPAddressImpl soapAddress = new SOAPAddressImpl();
642 //specify default transport if there is no one in the internal wsdl
643 soapAddress.setLocationURI("http://localhost");
644 definition.getService(getTargetService()).getPort(getTargetEndpoint()).addExtensibilityElement(soapAddress);
645 }
646 List binding = definition.getService(getTargetService()).getPort(getTargetEndpoint()).getBinding().getExtensibilityElements();
647 if (binding == null || binding.size() == 0) {
648 //no binding info in the internal wsdl so we need add default soap11 binding
649 SOAPBinding soapBinding = new SOAPBindingImpl();
650 soapBinding.setTransportURI("http://schemas.xmlsoap.org/soap/http");
651 soapBinding.setStyle("document");
652 definition.getService(getTargetService()).getPort(getTargetEndpoint()).getBinding().
653 addExtensibilityElement(soapBinding);
654 }
655 } else {
656 description = DomUtil.parse(wsdl.getInputStream());
657 try {
658 //ensure the jax-ws-catalog is loaded
659 OASISCatalogManager.getCatalogManager(getBus()).loadContextCatalogs();
660 // use wsdl manager to parse wsdl or get cached
661 // definition
662 definition = getBus().getExtension(WSDLManager.class)
663 .getDefinition(wsdl.getURL());
664 } catch (WSDLException ex) {
665 // throw new ServiceConstructionException(new
666 // Message("SERVICE_CREATION_MSG", LOG), ex);
667 }
668 }
669 }
670
671 protected Bus getBus() {
672 Bus ret = null;
673 if (providedBus != null) {
674 ret = providedBus;
675 } else if (getBusCfg() != null) {
676 if (bus == null) {
677 SpringBusFactory bf = new SpringBusFactory();
678 bus = bf.createBus(getBusCfg());
679 if (locationURI != null && locationURI.startsWith("/")) {
680 //it's in the servlet container
681 //set this bus so that it could be used in CXFManagerServlet
682 BusFactory.setDefaultBus(bus);
683 }
684 }
685 ret = bus;
686 } else {
687 bus = ((CxfBcComponent) getServiceUnit().getComponent()).getBus();
688 ret = bus;
689 }
690 Map<String, Bus> allBuses = ((CxfBcComponent) getServiceUnit().getComponent()).getAllBuses();
691 if (!allBuses.keySet().contains(ret.getId())) {
692 allBuses.put(ret.getId(), ret);
693 }
694 return ret;
695 }
696
697 private boolean isComponentBus() {
698 return getBus() == ((CxfBcComponent) getServiceUnit().getComponent()).getBus();
699 }
700
701 /**
702 * Specifies the HTTP address to which requests are sent. This value
703 * will overide any value specified in the WSDL.
704 *
705 * @param locationURI the URI as a string
706 * @org.apache.xbean.Property description="the HTTP address to which requests are sent. This value will overide any value specified in the WSDL."
707 **/
708 public void setLocationURI(String locationURI) {
709 this.locationURI = locationURI;
710 }
711
712 public String getLocationURI() {
713 return locationURI;
714 }
715
716 protected class JbiChainInitiationObserver extends ChainInitiationObserver {
717
718 public JbiChainInitiationObserver(Endpoint endpoint, Bus bus) {
719 super(endpoint, bus);
720 }
721
722 protected void setExchangeProperties(Exchange exchange, Message m) {
723 super.setExchangeProperties(exchange, m);
724 exchange.put(ComponentContext.class, CxfBcConsumer.this
725 .getContext());
726 exchange.put(CxfBcConsumer.class, CxfBcConsumer.this);
727 }
728
729 public void onMessage(Message m) {
730 m.put("suClassloader", suClassLoader);
731 ClassLoader oldCl = Thread.currentThread().getContextClassLoader();
732 if (oldCl != suClassLoader) {
733 try {
734 Thread.currentThread().setContextClassLoader(suClassLoader);
735 super.onMessage(m);
736 } finally {
737 Thread.currentThread().setContextClassLoader(oldCl);
738 }
739 } else {
740 super.onMessage(m);
741 }
742 }
743
744 }
745
746 public class JbiInvokerInterceptor extends
747 AbstractPhaseInterceptor<Message> {
748
749 public JbiInvokerInterceptor() {
750 super(Phase.INVOKE);
751 }
752
753 private Object getInvokee(Message message) {
754 Object invokee = message.getContent(List.class);
755 if (invokee == null) {
756 invokee = message.getContent(Object.class);
757 }
758 return invokee;
759 }
760
761 private void copyJaxwsProperties(Message inMsg, Message outMsg) {
762 outMsg.put(Message.WSDL_OPERATION, inMsg
763 .get(Message.WSDL_OPERATION));
764 outMsg.put(Message.WSDL_SERVICE, inMsg.get(Message.WSDL_SERVICE));
765 outMsg.put(Message.WSDL_INTERFACE, inMsg
766 .get(Message.WSDL_INTERFACE));
767 outMsg.put(Message.WSDL_PORT, inMsg.get(Message.WSDL_PORT));
768 outMsg.put(Message.WSDL_DESCRIPTION, inMsg
769 .get(Message.WSDL_DESCRIPTION));
770 }
771
772 public void handleMessage(final Message message) throws Fault {
773
774 final Exchange cxfExchange = message.getExchange();
775 final Endpoint endpoint = cxfExchange.get(Endpoint.class);
776 final Service service = endpoint.getService();
777 final Invoker invoker = service.getInvoker();
778
779
780
781 if (invoker instanceof Servant) {
782 // it's rm request, run the invocation directly in bc, not send
783 // to se.
784
785 Exchange runableEx = message.getExchange();
786
787 Object result = invoker.invoke(runableEx, getInvokee(message));
788 if (!cxfExchange.isOneWay()) {
789 Endpoint end = cxfExchange.get(Endpoint.class);
790
791 Message outMessage = runableEx.getOutMessage();
792 if (outMessage == null) {
793 outMessage = end.getBinding().createMessage();
794 cxfExchange.setOutMessage(outMessage);
795 }
796 copyJaxwsProperties(message, outMessage);
797 if (result != null) {
798 MessageContentsList resList = null;
799 if (result instanceof MessageContentsList) {
800 resList = (MessageContentsList) result;
801 } else if (result instanceof List) {
802 resList = new MessageContentsList((List) result);
803 } else if (result.getClass().isArray()) {
804 resList = new MessageContentsList((Object[]) result);
805 } else {
806 outMessage.setContent(Object.class, result);
807 }
808 if (resList != null) {
809 outMessage.setContent(List.class, resList);
810 }
811 }
812 }
813
814 return;
815 }
816
817 MessageExchange exchange = message
818 .getContent(MessageExchange.class);
819 ComponentContext context = message.getExchange().get(
820 ComponentContext.class);
821 CxfBcConsumer.this.configureExchangeTarget(exchange);
822 CxfBcConsumer.this.isOneway = message.getExchange().get(
823 BindingOperationInfo.class).getOperationInfo().isOneWay();
824 message.getExchange().setOneWay(CxfBcConsumer.this.isOneway);
825
826 try {
827 if (CxfBcConsumer.this.isOneway) {
828 CxfBcConsumer.this.messages.put(exchange.getExchangeId(), message);
829 context.getDeliveryChannel().send(exchange);
830 } else if (CxfBcConsumer.this.isSynchronous()
831 && !CxfBcConsumer.this.isOneway) {
832 CxfBcConsumer.this.messages.put(exchange.getExchangeId(), message);
833 context.getDeliveryChannel().sendSync(exchange,
834 timeout * 1000);
835 process(exchange);
836 } else {
837 if (isNativeAsyn(message)) {
838 synchronized (message) {
839
840 if (!((PhaseInterceptorChain)message.getInterceptorChain()).getState()
841 .equals(State.PAUSED)) {
842 CxfBcConsumer.this.messages.put(exchange
843 .getExchangeId(), message);
844 context.getDeliveryChannel().send(exchange);
845 message.getInterceptorChain().pause();
846 } else {
847 // retry or timeout
848 if (!((PhaseInterceptorChain)message.getInterceptorChain()).getState()
849 .equals(State.EXECUTING)) {
850 messages.remove(exchange.getExchangeId());
851 // exchange timeout
852 throw new Exception("Exchange timed out: "
853 + exchange.getExchangeId());
854 }
855
856 }
857
858 }
859 } else {
860 synchronized (((ContinuationProvider) message
861 .get(ContinuationProvider.class.getName()))
862 .getContinuation()) {
863
864 ContinuationProvider continuationProvider = (ContinuationProvider) message
865 .get(ContinuationProvider.class.getName());
866 Continuation continuation = continuationProvider
867 .getContinuation();
868 if (continuation.isNew()) {
869 CxfBcConsumer.this.messages.put(exchange
870 .getExchangeId(), message);
871 context.getDeliveryChannel().send(exchange);
872 if (!isSTFlow) {
873 continuation.suspend(timeout * 1000);
874 }
875 } else if (!continuation.isResumed()) {
876 if (!continuation.isPending()) {
877 messages.remove(exchange.getExchangeId());
878 // exchange timeout
879 throw new Exception("Exchange timed out: "
880 + exchange.getExchangeId());
881 } else {
882 //retry
883 throw new org.apache.cxf.continuations.SuspendedInvocationException();
884 }
885 }
886 }
887 }
888 }
889 } catch (org.apache.cxf.continuations.SuspendedInvocationException e) {
890 throw e;
891 } catch (Exception e) {
892 throw new Fault(e);
893 }
894 }
895
896 }
897
898 protected class JbiPostInvokerInterceptor extends
899 AbstractPhaseInterceptor<Message> {
900 public JbiPostInvokerInterceptor() {
901 super(Phase.POST_INVOKE);
902 addBefore(OutgoingChainInterceptor.class.getName());
903 }
904
905 public void handleMessage(final Message message) throws Fault {
906 MessageExchange exchange = message
907 .getContent(MessageExchange.class);
908 Exchange ex = message.getExchange();
909 if (exchange.getStatus() == ExchangeStatus.ERROR) {
910 throw new Fault(exchange.getError());
911 }
912 if (!ex.isOneWay()) {
913 if (exchange.getFault() != null) {
914 Fault f = null;
915 if (isUseJBIWrapper()) {
916 f = new JbiFault(
917 new org.apache.cxf.common.i18n.Message(
918 "Fault occured", (ResourceBundle) null));
919 if (exchange.getProperty("faultstring") != null) {
920 f.setMessage((String)exchange.getProperty("faultstring"));
921 }
922 if (exchange.getProperty("faultcode") != null) {
923 f.setFaultCode((QName) exchange
924 .getProperty("faultcode"));
925 }
926 if (exchange.getProperty("hasdetail") == null) {
927 Element details = toElement(exchange.getFault()
928 .getContent());
929 f.setDetail(details);
930 }
931
932
933 } else {
934 Element details = toElement(exchange.getFault()
935 .getContent());
936
937 if (isUseSOAPEnvelope()) {
938 details = (Element) details.getElementsByTagNameNS(
939 details.getNamespaceURI(), "Body").item(0);
940 assert details != null;
941 details = (Element) details.getElementsByTagNameNS(
942 details.getNamespaceURI(), "Fault").item(0);
943 }
944 assert details != null;
945 if (exchange.getProperty("faultstring") != null) {
946 details = (Element) details.getElementsByTagName("faultstring").item(0);
947 } else {
948 details = (Element) details.getElementsByTagName("detail").item(0) == null ?
949 (Element) details.getElementsByTagName("soap:Detail").item(0):
950 (Element) details.getElementsByTagName("detail").item(0);
951
952 }
953
954 assert details != null;
955 f = new SoapFault(
956 new org.apache.cxf.common.i18n.Message(
957 "Fault occured", (ResourceBundle) null),
958 new QName(details.getNamespaceURI(), "detail"));
959 f.setDetail(details);
960 if (exchange.getProperty("faultstring") != null) {
961 f.setMessage((String)exchange.getProperty("faultstring"));
962 }
963
964 if (exchange.getProperty("faultcode") != null) {
965 f.setFaultCode((QName) exchange
966 .getProperty("faultcode"));
967 }
968
969 }
970 processFaultDetail(f, message);
971 message.put(BindingFaultInfo.class, faultWanted);
972
973
974 throw f;
975 } else if (exchange.getMessage("out") != null) {
976 Endpoint endpoint = ex.get(Endpoint.class);
977 Message outMessage = ex.getOutMessage();
978 if (outMessage == null) {
979 outMessage = endpoint.getBinding().createMessage();
980 ex.setOutMessage(outMessage);
981 }
982 outMessage.setContent(MessageExchange.class, exchange);
983 outMessage.put("needSetDone", message.get("needSetDone"));
984 NormalizedMessage norMessage = (NormalizedMessage) exchange
985 .getMessage("out");
986
987 if (outMessage instanceof SoapMessage) {
988 AddressingProperties addressingProperties = WSAUtils
989 .getCXFAddressingPropertiesFromMap((Map<String, String>) norMessage
990 .getProperty(WSAUtils.WSA_HEADERS_OUTBOUND));
991 outMessage.put(WSAUtils.WSA_HEADERS_OUTBOUND,
992 addressingProperties);
993 }
994 List<Attachment> attachmentList = new ArrayList<Attachment>();
995 outMessage.setContent(Source.class, exchange.getMessage(
996 "out").getContent());
997 Set attachmentNames = norMessage.getAttachmentNames();
998
999 Iterator iter = attachmentNames.iterator();
1000 while (iter.hasNext()) {
1001 String id = (String)iter.next();
1002 DataHandler dh = norMessage.getAttachment(id);
1003 attachmentList.add(new AttachmentImpl(id, dh));
1004 }
1005
1006 outMessage.setAttachments(attachmentList);
1007 }
1008
1009 }
1010
1011 }
1012
1013 public void handleFault(Message message) {
1014 if (transactionEnabled) {
1015 //detect if the fault is defined in the wsdl, which means need return to client and
1016 //jms transactionManger just commit
1017 Exchange ex = message.getExchange();
1018 BindingOperationInfo boi = ex.get(BindingOperationInfo.class);
1019 for (BindingFaultInfo bfi : boi.getFaults()) {
1020 FaultInfo fi = bfi.getFaultInfo();
1021 //get fault details
1022 MessagePartInfo mpi = fi.getMessageParts().get(0);
1023 if (mpi != null) {
1024 Fault fault = (Fault) message.getContent(Exception.class);
1025 Element detail = fault.getDetail();
1026 if (detail != null
1027 && detail.getFirstChild().getLocalName().equals(mpi.getName().getLocalPart())) {
1028 //it's fault defined in the wsdl, so let it go back to the client
1029 return;
1030 }
1031 }
1032 }
1033 //this exception is undefined in the wsdl, so tell the transactionManager injected into
1034 //jms transport need rollback
1035 throw new Error("rollback");
1036 }
1037 }
1038
1039 // this method is used for ws-policy to set BindingFaultInfo
1040 protected void processFaultDetail(Fault fault, Message msg) {
1041 if (fault.getDetail() == null) {
1042 return;
1043 }
1044 Element exDetail = (Element) DOMUtils.getChild(fault.getDetail(),
1045 Node.ELEMENT_NODE);
1046 if (exDetail == null) {
1047 return;
1048 }
1049
1050 QName qname = new QName(exDetail.getNamespaceURI(), exDetail
1051 .getLocalName());
1052
1053 faultWanted = null;
1054 BindingOperationInfo boi = msg.getExchange().get(
1055 BindingOperationInfo.class);
1056 if (boi.isUnwrapped()) {
1057 boi = boi.getWrappedOperation();
1058 }
1059 for (BindingFaultInfo bfi : boi.getFaults()) {
1060 for (MessagePartInfo mpi : bfi.getFaultInfo().getMessageParts()) {
1061 if (qname.equals(mpi.getConcreteName())) {
1062 faultWanted = bfi;
1063 msg.put(BindingFaultInfo.class, faultWanted);
1064 break;
1065 }
1066 }
1067 if (faultWanted != null) {
1068 break;
1069 }
1070 }
1071
1072 }
1073
1074 }
1075
1076 private static Element toElement(Source src) throws Fault {
1077 try {
1078 SourceTransformer transformer = new SourceTransformer();
1079 Element ret = transformer.toDOMElement(src);
1080 ret = removeEmptyDefaultTns(ret);
1081 return ret;
1082 } catch (Exception e) {
1083 throw new Fault(e);
1084 }
1085 }
1086
1087 private static Element removeEmptyDefaultTns(Element ret) {
1088 // to make unquailied fault work
1089 if (ret.hasAttribute("xmlns")
1090 && ret.getAttribute("xmlns").length() == 0) {
1091 ret.removeAttribute("xmlns");
1092 }
1093 NodeList nodes = ret.getChildNodes();
1094 for (int i = 0; i < nodes.getLength(); i++) {
1095 if (nodes.item(i) instanceof Element) {
1096 Element ele = (Element) nodes.item(i);
1097 ele = removeEmptyDefaultTns(ele);
1098
1099 }
1100 }
1101 return ret;
1102 }
1103
1104 /**
1105 * Specifies the location of the CXF configuraiton file used to configure
1106 * the CXF bus. This allows you to access features like JMS runtime
1107 * behavior and WS-RM.
1108 *
1109 * @param busCfg a string containing the relative path to the configuration file
1110 * @org.apache.xbean.Property description="the location of the CXF configuration file used to configure the CXF bus. This allows you to configure features like WS-RM and JMS runtime behavior."
1111 **/
1112 public void setBusCfg(String busCfg) {
1113 this.busCfg = busCfg;
1114 }
1115
1116 public String getBusCfg() {
1117 return busCfg;
1118 }
1119
1120 /**
1121 * Specifies if the endpoint can support binnary attachments.
1122 *
1123 * @param mtomEnabled a boolean
1124 * @org.apache.xbean.Property description="Specifies if MTOM / attachment support is enabled. Default is <code>false</code>."
1125 **/
1126 public void setMtomEnabled(boolean mtomEnabled) {
1127 this.mtomEnabled = mtomEnabled;
1128 }
1129
1130 public boolean isMtomEnabled() {
1131 return mtomEnabled;
1132 }
1133
1134 /**
1135 * Specifies the interval for which the endpoint will wait for a
1136 * response, This is specified in seconds.
1137 *
1138 * @param timeout the number of second to wait for a response
1139 * @org.apache.xbean.Property description="the number of second the endpoint will wait for a response. The default is unlimited."
1140 **/
1141 public void setTimeout(long timeout) {
1142 this.timeout = timeout;
1143 }
1144
1145 public long getTimeout() {
1146 return timeout;
1147 }
1148
1149 /**
1150 * Specifies if the endpoint expects messages to use the JBI wrapper
1151 * for SOAP messages.
1152 *
1153 * @param useJBIWrapper a boolean
1154 * @org.apache.xbean.Property description="Specifies if the JBI wrapper is sent in the body of the message. Default is <code>true</code>.
1155 * Ignore the value of useSOAPEnvelope if useJBIWrapper is true"
1156 **/
1157 public void setUseJBIWrapper(boolean useJBIWrapper) {
1158 this.useJBIWrapper = useJBIWrapper;
1159 }
1160
1161 public boolean isUseJBIWrapper() {
1162 return useJBIWrapper;
1163 }
1164
1165 /**
1166 * Specifies if the endpoint expects soap messages when useJBIWrapper is false,
1167 * if useJBIWrapper is true then ignore useSOAPEnvelope
1168 *
1169 * @org.apache.xbean.Property description="Specifies if the endpoint expects soap messages when useJBIWrapper is false,
1170 * if useJBIWrapper is true then ignore useSOAPEnvelope. The default is <code>true</code>.
1171 * */
1172 public void setUseSOAPEnvelope(boolean useSOAPEnvelope) {
1173 this.useSOAPEnvelope = useSOAPEnvelope;
1174 }
1175
1176 public boolean isUseSOAPEnvelope() {
1177 return useSOAPEnvelope;
1178 }
1179
1180 /**
1181 * Specifies if the endpoint expects send messageExchange by sendSync
1182 * @param synchronous a boolean
1183 * @org.apache.xbean.Property description="Specifies if the endpoint expects send messageExchange by sendSync .
1184 * Default is <code>true</code>."
1185 **/
1186 public void setSynchronous(boolean synchronous) {
1187 this.synchronous = synchronous;
1188 }
1189
1190 public boolean isSynchronous() {
1191 return synchronous;
1192 }
1193
1194 /**
1195 * Specifies the cxf features set for this endpoint
1196 *
1197 * @param features a list of <code>AbstractFeature</code> objects
1198 * @org.apache.xbean.Property description="Specifies the cxf features set for this endpoint"
1199 **/
1200 public void setFeatures(List<AbstractFeature> features) {
1201 this.features = features;
1202 }
1203
1204 public List<AbstractFeature> getFeatures() {
1205 return features;
1206 }
1207
1208 /**
1209 * Specifies if the endpoint use X.509 Certificate to do the authentication.
1210 *
1211 * @param x509
1212 * a boolean
1213 * @org.apache.xbean.Property description="Specifies if the endpoint use X.509 Certificate to do the authentication.
1214 * Default is <code>false</code>.
1215 */
1216 public void setX509(boolean x509) {
1217 this.x509 = x509;
1218 }
1219
1220 public boolean isX509() {
1221 return x509;
1222 }
1223
1224 public boolean isSchemaValidationEnabled() {
1225 return schemaValidationEnabled;
1226 }
1227
1228 /**
1229 * Specifies if the endpoint use schemavalidation for the incoming/outgoing message.
1230 *
1231 * @param schemaValidationEnabled
1232 * a boolean
1233 * @org.apache.xbean.Property description="Specifies if the endpoint use schemavalidation for the incoming/outgoing message.
1234 * Default is <code>false</code>.
1235 */
1236
1237 public void setSchemaValidationEnabled(boolean schemaValidationEnabled) {
1238 this.schemaValidationEnabled = schemaValidationEnabled;
1239 }
1240
1241 /**
1242 * Specifies a preconfigured CXF bus to use.
1243 *
1244 * @param providedBus
1245 * @org.apache.xbean.Property description="a preconfigured CXF Bus object to use; overrides busCfg"
1246 * */
1247 public void setProvidedBus(Bus providedBus) {
1248 this.providedBus = providedBus;
1249 }
1250
1251 public Bus getProvidedBus() {
1252 return this.providedBus;
1253 }
1254
1255 /**
1256 * Specifies if the endpoint delegate to JAASAuthenticationService to do the authentication.
1257 *
1258 * @param delegateToJaas
1259 * a boolean
1260 * @org.apache.xbean.Property description="Specifies if the endpoint delegate to JAASAuthenticationService to do the authentication.
1261 * Default is <code>true</code>.
1262 */
1263 public void setDelegateToJaas(boolean delegateToJaas) {
1264 this.delegateToJaas = delegateToJaas;
1265 }
1266
1267 public boolean isDelegateToJaas() {
1268 return delegateToJaas;
1269 }
1270
1271 /**
1272 * Sets arbitrary properties that are added to the CXF context at
1273 * the Endpoint level.
1274 *
1275 * @param properties
1276 * the properties to add
1277 * @org.apache.xbean.Property description="Sets arbitrary properties that are added to the CXF context at the Endpoint level"
1278 */
1279 public void setProperties(Map<String, Object> properties) {
1280 this.properties.putAll(properties);
1281 }
1282
1283 public Map<String, Object> getProperties() {
1284 return this.properties;
1285 }
1286 }