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