1
2
3
4
5
6
7
8
9
10
11 package org.mule.transport.jms;
12
13 import org.mule.api.MuleContext;
14 import org.mule.api.MuleEvent;
15 import org.mule.api.MuleException;
16 import org.mule.api.MuleMessage;
17 import org.mule.api.endpoint.EndpointBuilder;
18 import org.mule.api.endpoint.OutboundEndpoint;
19 import org.mule.api.service.Service;
20 import org.mule.api.transformer.Transformer;
21 import org.mule.api.transport.DispatchException;
22 import org.mule.endpoint.EndpointURIEndpointBuilder;
23 import org.mule.management.stats.ServiceStatistics;
24 import org.mule.transport.DefaultReplyToHandler;
25 import org.mule.transport.jms.i18n.JmsMessages;
26 import org.mule.transport.jms.transformers.ObjectToJMSMessage;
27 import org.mule.util.StringMessageUtils;
28 import org.mule.util.StringUtils;
29
30 import java.util.List;
31
32 import javax.jms.Destination;
33 import javax.jms.JMSException;
34 import javax.jms.Message;
35 import javax.jms.MessageProducer;
36 import javax.jms.Queue;
37 import javax.jms.Session;
38 import javax.jms.Topic;
39
40
41
42
43
44
45
46
47
48
49
50 public class JmsReplyToHandler extends DefaultReplyToHandler
51 {
52
53
54
55 private static final long serialVersionUID = 1L;
56
57 private transient JmsConnector jmsConnector;
58 private transient ObjectToJMSMessage toJmsMessage;
59
60 public JmsReplyToHandler(JmsConnector connector)
61 {
62 super(connector.getMuleContext());
63 this.connector = this.jmsConnector = connector;
64 toJmsMessage = new ObjectToJMSMessage();
65 }
66
67 @Override
68 public void processReplyTo(MuleEvent event, MuleMessage returnMessage, Object replyTo) throws MuleException
69 {
70 Destination replyToDestination = null;
71 MessageProducer replyToProducer = null;
72 Session session = null;
73 try
74 {
75
76 if (replyTo instanceof Destination)
77 {
78 replyToDestination = (Destination)replyTo;
79 }
80 if (replyToDestination == null)
81 {
82 super.processReplyTo(event, returnMessage, replyTo);
83 return;
84 }
85
86 Class srcType = returnMessage.getPayload().getClass();
87 EndpointBuilder endpointBuilder = new EndpointURIEndpointBuilder(String.format("%s://temporary",connector.getProtocol()), muleContext);
88 endpointBuilder.setConnector(jmsConnector);
89 OutboundEndpoint tempEndpoint = muleContext.getEndpointFactory().getOutboundEndpoint(endpointBuilder);
90
91 List<Transformer> defaultTransportTransformers = ((org.mule.transport.AbstractConnector) jmsConnector).getDefaultOutboundTransformers(tempEndpoint);
92
93 returnMessage.applyTransformers(event, defaultTransportTransformers);
94
95 Object payload = returnMessage.getPayload();
96
97 if (replyToDestination instanceof Topic && replyToDestination instanceof Queue
98 && jmsConnector.getJmsSupport() instanceof Jms102bSupport)
99 {
100 logger.error(StringMessageUtils.getBoilerPlate("ReplyTo destination implements both Queue and Topic "
101 + "while complying with JMS 1.0.2b specification. "
102 + "Please report your application server or JMS vendor name and version "
103 + "to dev<_at_>mule.codehaus.org or http://mule.mulesoft.org/jira"));
104 }
105
106 final boolean topic = jmsConnector.getTopicResolver().isTopic(replyToDestination);
107 session = jmsConnector.getSession(false, topic);
108
109
110
111 Message replyToMessage = JmsMessageUtils.toMessage(payload, session);
112 toJmsMessage.setJmsProperties(returnMessage, replyToMessage);
113
114 processMessage(replyToMessage, event);
115 if (logger.isDebugEnabled())
116 {
117 logger.debug("Sending jms reply to: " + replyToDestination + " ("
118 + replyToDestination.getClass().getName() + ")");
119 }
120 replyToProducer = jmsConnector.getJmsSupport().createProducer(session, replyToDestination, topic);
121
122
123 MuleMessage eventMsg = event.getMessage();
124 String ttlString = (String)eventMsg.getOutboundProperty(JmsConstants.TIME_TO_LIVE_PROPERTY);
125 String priorityString = (String)eventMsg.getOutboundProperty(JmsConstants.PRIORITY_PROPERTY);
126 String persistentDeliveryString = (String)eventMsg.getOutboundProperty(JmsConstants.PERSISTENT_DELIVERY_PROPERTY);
127
128 String correlationIDString = replyToMessage.getJMSCorrelationID();
129 if (StringUtils.isBlank(correlationIDString))
130 {
131 correlationIDString = eventMsg.getInboundProperty(JmsConstants.JMS_MESSAGE_ID);
132 replyToMessage.setJMSCorrelationID(correlationIDString);
133 }
134
135 if (event.getFlowConstruct() instanceof Service)
136 {
137 ServiceStatistics stats = ((Service) event.getFlowConstruct()).getStatistics();
138 if (stats.isEnabled())
139 {
140 stats.incSentReplyToEvent();
141 }
142 }
143
144 if (ttlString == null && priorityString == null && persistentDeliveryString == null)
145 {
146 jmsConnector.getJmsSupport().send(replyToProducer, replyToMessage, topic, null);
147 }
148 else
149 {
150 long ttl = Message.DEFAULT_TIME_TO_LIVE;
151 int priority = Message.DEFAULT_PRIORITY;
152
153 if (ttlString != null)
154 {
155 ttl = Long.parseLong(ttlString);
156 }
157 if (priorityString != null)
158 {
159 priority = Integer.parseInt(priorityString);
160 }
161 boolean persistent = StringUtils.isNotBlank(persistentDeliveryString)
162 ? Boolean.valueOf(persistentDeliveryString)
163 : jmsConnector.isPersistentDelivery();
164
165 jmsConnector.getJmsSupport().send(replyToProducer, replyToMessage, persistent, priority, ttl,
166 topic, null);
167 }
168
169 if (logger.isInfoEnabled())
170 {
171 logger.info(String.format("Reply Message sent to: %s with correlationID:%s", replyToDestination, correlationIDString));
172 }
173 }
174 catch (Exception e)
175 {
176 throw new DispatchException(
177 JmsMessages.failedToCreateAndDispatchResponse(replyToDestination), event, null, e);
178 }
179 finally
180 {
181 jmsConnector.closeQuietly(replyToProducer);
182 jmsConnector.closeSessionIfNoTransactionActive(session);
183 }
184 }
185
186 protected void processMessage(Message replyToMessage, MuleEvent event) throws JMSException
187 {
188 replyToMessage.setJMSReplyTo(null);
189
190
191
192 MuleMessage eventMsg = event.getMessage();
193 String jmsCorrelationId = eventMsg.getInboundProperty("JMSCorrelationID");
194 if (jmsCorrelationId == null)
195 {
196 jmsCorrelationId = eventMsg.getInboundProperty("JMSMessageID");
197 }
198 if (jmsCorrelationId != null)
199 {
200 replyToMessage.setJMSCorrelationID(jmsCorrelationId);
201 }
202 if (logger.isDebugEnabled())
203 {
204 logger.debug("replyTo message is " + replyToMessage);
205 }
206 }
207
208 @Override
209 public void initAfterDeserialisation(MuleContext muleContext) throws MuleException
210 {
211 super.initAfterDeserialisation(muleContext);
212 this.toJmsMessage = new ObjectToJMSMessage();
213 this.jmsConnector = (JmsConnector) this.connector;
214 }
215 }