View Javadoc

1   /*
2    * $Id: DefaultReplyToHandler.java 19191 2010-08-25 21:05:23Z tcarlson $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
5    *
6    * The software in this package is published under the terms of the CPAL v1.0
7    * license, a copy of which has been included with this distribution in the
8    * LICENSE.txt file.
9    */
10  
11  package org.mule.transport;
12  
13  import org.mule.DefaultMuleEvent;
14  import org.mule.DefaultMuleMessage;
15  import org.mule.api.MuleContext;
16  import org.mule.api.MuleEvent;
17  import org.mule.api.MuleException;
18  import org.mule.api.MuleMessage;
19  import org.mule.api.config.MuleProperties;
20  import org.mule.api.endpoint.EndpointBuilder;
21  import org.mule.api.endpoint.EndpointFactory;
22  import org.mule.api.endpoint.ImmutableEndpoint;
23  import org.mule.api.endpoint.OutboundEndpoint;
24  import org.mule.api.transformer.Transformer;
25  import org.mule.api.transport.DispatchException;
26  import org.mule.api.transport.ReplyToHandler;
27  import org.mule.config.i18n.CoreMessages;
28  import org.mule.service.AbstractService;
29  
30  import java.util.HashMap;
31  import java.util.List;
32  import java.util.Map;
33  
34  import org.apache.commons.logging.Log;
35  import org.apache.commons.logging.LogFactory;
36  
37  /**
38   * <code>DefaultReplyToHandler</code> is responsible for processing a message
39   * replyTo header.
40   */
41  
42  public class DefaultReplyToHandler implements ReplyToHandler
43  {
44      /**
45       * logger used by this class
46       */
47      protected transient final Log logger = LogFactory.getLog(getClass());
48  
49      private volatile List<Transformer> transformers;
50      private final Map<String, ImmutableEndpoint> endpointCache = new HashMap<String, ImmutableEndpoint>();
51      protected MuleContext muleContext;
52  
53      public DefaultReplyToHandler(List<Transformer> transformers, MuleContext muleContext)
54      {
55          this.transformers = transformers;
56          this.muleContext = muleContext;
57      }
58  
59      public void processReplyTo(MuleEvent event, MuleMessage returnMessage, Object replyTo) throws MuleException
60      {
61          if (logger.isDebugEnabled())
62          {
63              logger.debug("sending reply to: " + replyTo);
64          }
65          String replyToEndpoint = replyTo.toString();
66  
67          // get the endpoint for this url
68          OutboundEndpoint endpoint = getEndpoint(event, replyToEndpoint);
69  
70          // make sure remove the replyTo property as not cause a a forever
71          // replyto loop
72          returnMessage.removeProperty(MuleProperties.MULE_REPLY_TO_PROPERTY);
73  
74          // MULE-4617. This is fixed with MULE-4620, but lets remove this property
75          // anyway as it should never be true from a replyTo dispatch
76          returnMessage.removeProperty(MuleProperties.MULE_REMOTE_SYNC_PROPERTY);
77  
78          // Create a new copy of the message so that response MessageProcessors don't end up screwing up the reply
79          returnMessage = new DefaultMuleMessage(returnMessage.getPayload(), returnMessage, muleContext);
80  
81          // Create the replyTo event asynchronous
82          MuleEvent replyToEvent = new DefaultMuleEvent(returnMessage, endpoint, event.getSession());
83  
84          // carry over properties
85          List<String> responseProperties = endpoint.getResponseProperties();
86          for (String propertyName : responseProperties)
87          {
88              Object propertyValue = event.getMessage().getInboundProperty(propertyName);
89              if (propertyValue != null)
90              {
91                  replyToEvent.getMessage().setOutboundProperty(propertyName, propertyValue);
92              }
93          }
94  
95          // dispatch the event
96          try
97          {
98              ((AbstractService) event.getFlowConstruct()).getStatistics().incSentReplyToEvent();
99              endpoint.process(replyToEvent);
100             if (logger.isInfoEnabled())
101             {
102                 logger.info("reply to sent: " + endpoint);
103             }
104         }
105         catch (Exception e)
106         {
107             throw new DispatchException(CoreMessages.failedToDispatchToReplyto(endpoint),
108                 replyToEvent, endpoint, e);
109         }
110 
111     }
112 
113     protected synchronized OutboundEndpoint getEndpoint(MuleEvent event, String endpointUri) throws MuleException
114     {
115         OutboundEndpoint endpoint = (OutboundEndpoint) endpointCache.get(endpointUri);
116         if (endpoint == null)
117         {
118             EndpointFactory endpointFactory = muleContext.getRegistry().lookupEndpointFactory();
119             EndpointBuilder endpointBuilder = endpointFactory.getEndpointBuilder(endpointUri);
120             if (transformers == null)
121             {
122                 endpointBuilder.setTransformers(event.getEndpoint().getResponseTransformers());
123             }
124             endpoint = endpointFactory.getOutboundEndpoint(endpointBuilder);
125             endpointCache.put(endpointUri, endpoint);
126         }
127         return endpoint;
128     }
129 
130     public List<Transformer> getTransformers()
131     {
132         return transformers;
133     }
134 
135     public void setTransformers(List<Transformer> transformers)
136     {
137         this.transformers = transformers;
138     }
139 }