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