View Javadoc

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