1
2
3
4
5
6
7
8
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.transport.Connector;
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 import org.mule.transport.service.TransportFactory;
31 import org.mule.util.ObjectNameHelper;
32 import org.mule.util.store.DeserializationPostInitialisable;
33
34 import java.io.IOException;
35 import java.io.ObjectInputStream;
36 import java.io.ObjectOutputStream;
37 import java.io.Serializable;
38 import java.util.HashMap;
39 import java.util.List;
40 import java.util.Map;
41
42 import org.apache.commons.logging.Log;
43 import org.apache.commons.logging.LogFactory;
44
45
46
47
48
49
50 public class DefaultReplyToHandler implements ReplyToHandler, Serializable, DeserializationPostInitialisable
51 {
52
53
54
55 private static final long serialVersionUID = 1L;
56
57
58
59
60 protected transient Log logger = LogFactory.getLog(getClass());
61
62 private transient Map<String, ImmutableEndpoint> endpointCache = new HashMap<String, ImmutableEndpoint>();
63 protected transient MuleContext muleContext;
64 protected transient Connector connector;
65 private transient Map<String, Object> serializedData = null;
66
67 public DefaultReplyToHandler(MuleContext muleContext)
68 {
69 this.muleContext = muleContext;
70 }
71
72 public void processReplyTo(MuleEvent event, MuleMessage returnMessage, Object replyTo) throws MuleException
73 {
74 if (logger.isDebugEnabled())
75 {
76 logger.debug("sending reply to: " + replyTo);
77 }
78 String replyToEndpoint = replyTo.toString();
79
80
81 OutboundEndpoint endpoint = getEndpoint(event, replyToEndpoint);
82
83
84
85 returnMessage.removeProperty(MuleProperties.MULE_REPLY_TO_PROPERTY);
86
87
88
89 returnMessage.removeProperty(MuleProperties.MULE_REMOTE_SYNC_PROPERTY);
90
91
92 returnMessage = new DefaultMuleMessage(returnMessage.getPayload(), returnMessage, muleContext);
93
94
95 MuleEvent replyToEvent = new DefaultMuleEvent(returnMessage, event);
96
97
98 List<String> responseProperties = endpoint.getResponseProperties();
99 for (String propertyName : responseProperties)
100 {
101 Object propertyValue = event.getMessage().getInboundProperty(propertyName);
102 if (propertyValue != null)
103 {
104 replyToEvent.getMessage().setOutboundProperty(propertyName, propertyValue);
105 }
106 }
107
108
109 try
110 {
111 if (event.getFlowConstruct() instanceof Service)
112 {
113 ServiceStatistics stats = ((Service) event.getFlowConstruct()).getStatistics();
114 if (stats.isEnabled())
115 {
116 stats.incSentReplyToEvent();
117 }
118 }
119 endpoint.process(replyToEvent);
120 if (logger.isInfoEnabled())
121 {
122 logger.info("reply to sent: " + endpoint);
123 }
124 }
125 catch (Exception e)
126 {
127 throw new DispatchException(CoreMessages.failedToDispatchToReplyto(endpoint),
128 replyToEvent, endpoint, e);
129 }
130
131 }
132
133 protected synchronized OutboundEndpoint getEndpoint(MuleEvent event, String endpointUri) throws MuleException
134 {
135 OutboundEndpoint endpoint = (OutboundEndpoint) endpointCache.get(endpointUri);
136 if (endpoint == null)
137 {
138 EndpointFactory endpointFactory = muleContext.getEndpointFactory();
139 EndpointBuilder endpointBuilder = endpointFactory.getEndpointBuilder(endpointUri);
140 endpoint = endpointFactory.getOutboundEndpoint(endpointBuilder);
141 endpointCache.put(endpointUri, endpoint);
142 }
143 return endpoint;
144 }
145
146 @SuppressWarnings({"unused", "unchecked"})
147 public void initAfterDeserialisation(MuleContext muleContext) throws MuleException
148 {
149
150
151 if (serializedData == null)
152 {
153 return;
154 }
155 this.muleContext = muleContext;
156 logger = LogFactory.getLog(getClass());
157 endpointCache = new HashMap<String, ImmutableEndpoint>();
158 connector = findConnector();
159 serializedData = null;
160 }
161
162 public Connector getConnector()
163 {
164 return connector;
165 }
166
167 protected Connector findConnector()
168 {
169 String connectorName = (String) serializedData.get("connectorName");
170 String connectorType = (String) serializedData.get("connectorType");
171 Connector found = null;
172
173 if (connectorName != null)
174 {
175 found = muleContext.getRegistry().get(connectorName);
176 }
177 else if (connectorType != null)
178 {
179 found = new TransportFactory(muleContext).getDefaultConnectorByProtocol(connectorType);
180 }
181 return found;
182 }
183
184 private void writeObject(ObjectOutputStream out) throws IOException
185 {
186 out.defaultWriteObject();
187
188 String connectorName = null;
189 String connectorType = null;
190
191
192 if (serializedData != null)
193 {
194 connectorName = (String) serializedData.get("connectorName");
195 connectorType = (String) serializedData.get("connectorType");
196 }
197 else
198 {
199 if (connector != null)
200 {
201 if (!ObjectNameHelper.isDefaultAutoGeneratedConnector(connector))
202 {
203 connectorName = connector.getName();
204 }
205 connectorType = connector.getProtocol();
206 }
207 }
208 out.writeObject(connectorName);
209 out.writeObject(connectorType);
210 }
211
212 private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException
213 {
214 in.defaultReadObject();
215 serializedData = new HashMap<String, Object>();
216
217 serializedData.put("connectorName", in.readObject());
218 serializedData.put("connectorType", in.readObject());
219 }
220 }