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