1
2
3
4
5
6
7
8
9
10
11 package org.mule.transport.jms;
12
13 import org.mule.api.MuleEvent;
14 import org.mule.api.MuleException;
15 import org.mule.api.MuleMessage;
16 import org.mule.api.endpoint.ImmutableEndpoint;
17 import org.mule.api.service.Service;
18 import org.mule.api.transformer.Transformer;
19 import org.mule.api.transport.DispatchException;
20 import org.mule.management.stats.ServiceStatistics;
21 import org.mule.transformer.types.DataTypeFactory;
22 import org.mule.transport.DefaultReplyToHandler;
23 import org.mule.transport.jms.i18n.JmsMessages;
24 import org.mule.transport.jms.transformers.ObjectToJMSMessage;
25 import org.mule.util.StringMessageUtils;
26 import org.mule.util.StringUtils;
27
28 import java.util.List;
29
30 import javax.jms.Destination;
31 import javax.jms.JMSException;
32 import javax.jms.Message;
33 import javax.jms.MessageProducer;
34 import javax.jms.Queue;
35 import javax.jms.Session;
36 import javax.jms.Topic;
37
38
39
40
41
42
43
44
45
46
47
48 public class JmsReplyToHandler extends DefaultReplyToHandler
49 {
50 private final JmsConnector connector;
51 private ObjectToJMSMessage toJmsMessage;
52
53 public JmsReplyToHandler(JmsConnector connector, List<Transformer> transformers)
54 {
55 super(transformers, connector.getMuleContext());
56 this.connector = connector;
57 toJmsMessage = new ObjectToJMSMessage();
58 }
59
60 @Override
61 public void processReplyTo(MuleEvent event, MuleMessage returnMessage, Object replyTo) throws MuleException
62 {
63 Destination replyToDestination = null;
64 MessageProducer replyToProducer = null;
65 Session session = null;
66 try
67 {
68
69 if (replyTo instanceof Destination)
70 {
71 replyToDestination = (Destination)replyTo;
72 }
73 if (replyToDestination == null)
74 {
75 super.processReplyTo(event, returnMessage, replyTo);
76 return;
77 }
78
79
80
81 Class srcType = returnMessage.getPayload().getClass();
82 for (Transformer t : getTransformers())
83 {
84 if (t.isSourceDataTypeSupported(DataTypeFactory.create(srcType)))
85 {
86 if (t.getEndpoint() == null)
87 {
88 t.setEndpoint(getEndpoint(event, "jms://temporary"));
89 break;
90 }
91 }
92 }
93 returnMessage.applyTransformers(event, getTransformers());
94 Object payload = returnMessage.getPayload();
95
96 if (replyToDestination instanceof Topic && replyToDestination instanceof Queue
97 && connector.getJmsSupport() instanceof Jms102bSupport)
98 {
99 logger.error(StringMessageUtils.getBoilerPlate("ReplyTo destination implements both Queue and Topic "
100 + "while complying with JMS 1.0.2b specification. "
101 + "Please report your application server or JMS vendor name and version "
102 + "to dev<_at_>mule.codehaus.org or http://mule.mulesoft.org/jira"));
103 }
104
105 final boolean topic = connector.getTopicResolver().isTopic(replyToDestination);
106 session = connector.getSession(false, topic);
107
108
109
110 Message replyToMessage = JmsMessageUtils.toMessage(payload, session);
111 toJmsMessage.setJmsProperties(returnMessage, replyToMessage);
112
113 processMessage(replyToMessage, event);
114 if (logger.isDebugEnabled())
115 {
116 logger.debug("Sending jms reply to: " + replyToDestination + " ("
117 + replyToDestination.getClass().getName() + ")");
118 }
119 replyToProducer = connector.getJmsSupport().createProducer(session, replyToDestination, topic);
120
121
122 MuleMessage eventMsg = event.getMessage();
123 String ttlString = (String)eventMsg.getOutboundProperty(JmsConstants.TIME_TO_LIVE_PROPERTY);
124 String priorityString = (String)eventMsg.getOutboundProperty(JmsConstants.PRIORITY_PROPERTY);
125 String persistentDeliveryString = (String)eventMsg.getOutboundProperty(JmsConstants.PERSISTENT_DELIVERY_PROPERTY);
126
127 String correlationIDString = replyToMessage.getJMSCorrelationID();
128 if (StringUtils.isBlank(correlationIDString))
129 {
130 correlationIDString = eventMsg.getInboundProperty(JmsConstants.JMS_MESSAGE_ID);
131 replyToMessage.setJMSCorrelationID(correlationIDString);
132 }
133
134 if (event.getFlowConstruct() instanceof Service)
135 {
136 ServiceStatistics stats = ((Service) event.getFlowConstruct()).getStatistics();
137 if (stats.isEnabled())
138 {
139 stats.incSentReplyToEvent();
140 }
141 }
142
143 final ImmutableEndpoint endpoint = event.getEndpoint();
144 if (ttlString == null && priorityString == null && persistentDeliveryString == null)
145 {
146 connector.getJmsSupport().send(replyToProducer, replyToMessage, topic, endpoint);
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 : connector.isPersistentDelivery();
164
165 connector.getJmsSupport().send(replyToProducer, replyToMessage, persistent, priority, ttl,
166 topic, endpoint);
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 connector.closeQuietly(replyToProducer);
182 connector.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 }