1 /***
2 *
3 * Copyright 2004 Protique Ltd
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 **/
18
19 package org.codehaus.activemq.web;
20
21 import org.apache.commons.logging.Log;
22 import org.apache.commons.logging.LogFactory;
23 import org.codehaus.activemq.message.ActiveMQDestination;
24
25 import javax.jms.Destination;
26 import javax.jms.JMSException;
27 import javax.jms.Message;
28 import javax.jms.MessageConsumer;
29 import javax.jms.ObjectMessage;
30 import javax.jms.TextMessage;
31 import javax.servlet.ServletConfig;
32 import javax.servlet.ServletException;
33 import javax.servlet.http.HttpServletRequest;
34 import javax.servlet.http.HttpServletResponse;
35 import java.io.IOException;
36
37 /***
38 * A servlet for sending and receiving messages to/from JMS destinations
39 * using HTTP POST for sending and HTTP GET for receiving.
40 * <p/>
41 * You can specify the destination and whether it is a topic or queue
42 * via configuration details on the servlet or as request parameters.
43 * <p/>
44 * For reading messages you can specify a readTimeout parameter to determine
45 * how long the servlet should block for.
46 *
47 * @version $Revision: 1.7 $
48 */
49 public class MessageServlet extends MessageServletSupport {
50 private static final Log log = LogFactory.getLog(MessageServlet.class);
51
52 private String readTimeoutParameter = "readTimeout";
53 private long defaultReadTimeout = -1;
54 private long maximumReadTimeout = 30000;
55
56 public void init() throws ServletException {
57 ServletConfig servletConfig = getServletConfig();
58 String name = servletConfig.getInitParameter("defaultReadTimeout");
59 if (name != null) {
60 defaultReadTimeout = asLong(name);
61 }
62 name = servletConfig.getInitParameter("maximumReadTimeout");
63 if (name != null) {
64 maximumReadTimeout = asLong(name);
65 }
66 }
67
68 /***
69 * Sends a message to a destination
70 *
71 * @param request
72 * @param response
73 * @throws ServletException
74 * @throws IOException
75 */
76 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
77
78 try {
79 WebClient client = getWebClient(request);
80
81 String text = getPostedMessageBody(request);
82
83
84 Destination destination = getDestination(client, request);
85
86 log.info("Sending message to: " + ActiveMQDestination.inspect(destination) + " with text: " + text);
87
88 TextMessage message = client.getSession().createTextMessage(text);
89 appendParametersToMessage(request, message);
90 client.send(destination, message);
91
92
93 response.setHeader("messageID", message.getJMSMessageID());
94 response.setStatus(HttpServletResponse.SC_OK);
95 }
96 catch (JMSException e) {
97 throw new ServletException("Could not post JMS message: " + e, e);
98 }
99 }
100
101 /***
102 * Reads a message from a destination up to some specific timeout period
103 *
104 * @param request
105 * @param response
106 * @throws ServletException
107 * @throws IOException
108 */
109 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
110 try {
111 WebClient client = getWebClient(request);
112
113
114 Destination destination = getDestination(client, request);
115
116 long timeout = getReadTimeout(request);
117
118 log.info("Receiving message from: " + ActiveMQDestination.inspect(destination) + " with timeout: " + timeout);
119
120 MessageConsumer consumer = client.getConsumer(destination);
121
122 Message message = null;
123
124 synchronized (consumer) {
125 if (timeout == 0) {
126 message = consumer.receiveNoWait();
127 }
128 else {
129 message = consumer.receive(timeout);
130 }
131 }
132
133 log.info("HTTP GET servlet done! message: " + message);
134
135 sendMessageResponse(request, response, message);
136 }
137 catch (JMSException e) {
138 throw new ServletException("Could not post JMS message: " + e, e);
139 }
140
141 }
142
143 /***
144 * Supports a HTTP DELETE to be equivlanent of consuming a message from a queue
145 */
146 protected void doDelete(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
147 try {
148 WebClient client = getWebClient(request);
149
150
151 Destination destination = getDestination(client, request);
152
153 MessageConsumer consumer = client.getConsumer(destination);
154
155 Message message = null;
156
157 synchronized (consumer) {
158 message = consumer.receiveNoWait();
159 }
160
161 sendMessageResponse(request, response, message);
162 }
163 catch (JMSException e) {
164 throw new ServletException("Could not post JMS message: " + e, e);
165 }
166 }
167
168 protected void sendMessageResponse(HttpServletRequest request, HttpServletResponse response, Message message) throws JMSException, IOException {
169 if (message == null) {
170 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
171 }
172 else {
173 String type = getContentType(request);
174 if (type != null) {
175 response.setContentType(type);
176 }
177 setResponseHeaders(response, message);
178 if (message instanceof TextMessage) {
179 TextMessage textMsg = (TextMessage) message;
180 response.getWriter().print(textMsg.getText());
181 }
182 else if (message instanceof ObjectMessage) {
183 ObjectMessage objectMsg = (ObjectMessage) message;
184 Object object = objectMsg.getObject();
185 response.getWriter().print(object.toString());
186 }
187 response.setStatus(HttpServletResponse.SC_OK);
188 }
189 }
190
191 protected String getContentType(HttpServletRequest request) {
192
193
194
195
196
197
198
199
200 String value = request.getParameter("xml");
201 if (value != null && "true".equalsIgnoreCase(value)) {
202 return "text/xml";
203 }
204 return null;
205 }
206
207 protected void setResponseHeaders(HttpServletResponse response, Message message) throws JMSException {
208 response.setHeader("destination", message.getJMSDestination().toString());
209 response.setHeader("id", message.getJMSMessageID());
210 }
211
212 /***
213 * @return the timeout value for read requests which is always >= 0
214 * and <= maximumReadTimeout to avoid DoS attacks
215 */
216 protected long getReadTimeout(HttpServletRequest request) {
217 long answer = defaultReadTimeout;
218
219 String name = request.getParameter(readTimeoutParameter);
220 if (name != null) {
221 answer = asLong(name);
222 }
223 if (answer < 0 || answer > maximumReadTimeout) {
224 answer = maximumReadTimeout;
225 }
226 return answer;
227 }
228
229 }