1 /*
2 * ========================================================================
3 *
4 * Licensed to the Apache Software Foundation (ASF) under one or more
5 * contributor license agreements. See the NOTICE file distributed with
6 * this work for additional information regarding copyright ownership.
7 * The ASF licenses this file to You under the Apache License, Version 2.0
8 * (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 * ========================================================================
20 */
21 package org.apache.cactus.internal.server;
22
23 import javax.jms.JMSException;
24 import javax.jms.Message;
25
26 import org.apache.cactus.internal.HttpServiceDefinition;
27 import org.apache.cactus.internal.ServiceEnumeration;
28 import org.apache.cactus.spi.server.ImplicitObjects;
29 import org.apache.cactus.spi.server.MessageDrivenBeanImplicitObjects;
30 import org.apache.cactus.spi.server.TestController;
31 import org.apache.commons.logging.Log;
32 import org.apache.commons.logging.LogFactory;
33
34 /**
35 * MDB Controller that extracts the requested service from the
36 * JMS request and executes the request by calling a
37 * <code>MessageDrivenBeanTestCaller</code>. There are 2 services available :
38 * one for executing the test and one for returning the test result.
39 *
40 * @version $Id: MessageDrivenBeantestController.java 238991 2004-05-22 11:34:50Z ptahchiev $
41 */
42 public class MessageDrivenBeanTestController implements TestController
43 {
44
45 /**
46 * The logger.
47 */
48 private static final Log LOGGER =
49 LogFactory.getLog(MessageDrivenBeanTestController.class);
50
51 /**
52 * {@inheritDoc}
53 * @see AbstractWebTestController#getTestCaller(WebImplicitObjects)
54 */
55 protected MessageDrivenBeanTestCaller getTestCaller(MessageDrivenBeanImplicitObjects theObjects)
56 {
57 return new MessageDrivenBeanTestCaller(theObjects);
58 }
59
60 /**
61 * This method is supposed to handle the request from the Redirector.
62 *
63 * @param theObjects
64 * @throws JMSException
65 */
66 public void handleRequest(ImplicitObjects theObjects) throws JMSException
67 {
68 MessageDrivenBeanImplicitObjects mdbImplicitObjects = (MessageDrivenBeanImplicitObjects) theObjects;
69
70 // If the Cactus user has forgotten to put a needed jar on the server
71 // classpath (i.e. in WEB-INF/lib), then the servlet engine Webapp
72 // class loader will throw a NoClassDefFoundError exception. As this
73 // method is the entry point of the webapp, we'll catch all
74 // NoClassDefFoundError exceptions and report a nice error message
75 // for the user so that he knows he has forgotten to put a jar in the
76 // classpath. If we don't do this, the error will be trapped by the
77 // container and may not result in an ... err ... understandable error
78 // message (like in Tomcat) ...
79 try
80 {
81 String serviceName =
82 getServiceName(mdbImplicitObjects.getMessage());
83
84 MessageDrivenBeanTestCaller caller = getTestCaller(mdbImplicitObjects);
85
86 // TODO: will need a factory here real soon...
87
88 ServiceEnumeration service =
89 ServiceEnumeration.valueOf(serviceName);
90
91 // Is it the call test method service ?
92 if (service == ServiceEnumeration.CALL_TEST_SERVICE)
93 {
94 caller.doTest();
95 }
96 // Is it the get test results service ?
97 else if (service == ServiceEnumeration.GET_RESULTS_SERVICE)
98 {
99 caller.doGetResults();
100 }
101 // Is it the test connection service ?
102 // This service is only used to verify that connection between
103 // client and server is working fine
104 else if (service == ServiceEnumeration.RUN_TEST_SERVICE)
105 {
106 caller.doRunTest();
107 }
108 // Is it the service to create an HTTP session?
109 else if (service == ServiceEnumeration.CREATE_SESSION_SERVICE)
110 {
111 caller.doCreateSession();
112 }
113 else if (service == ServiceEnumeration.GET_VERSION_SERVICE)
114 {
115 caller.doGetVersion();
116 }
117 else
118 {
119 String message = "Unknown service [" + serviceName
120 + "] in HTTP request.";
121
122 LOGGER.error(message);
123 throw new JMSException(message);
124 }
125 }
126 catch (NoClassDefFoundError e)
127 {
128 // try to display messages as descriptive as possible !
129 if (e.getMessage().startsWith("junit/framework"))
130 {
131 String message = "You must put the JUnit jar in "
132 + "your server classpath (in WEB-INF/lib for example)";
133
134 LOGGER.error(message, e);
135 throw new JMSException(message);
136 }
137 else
138 {
139 String message = "You are missing a jar in your "
140 + "classpath (class [" + e.getMessage()
141 + "] could not " + "be found";
142
143 LOGGER.error(message, e);
144 throw new JMSException(message);
145 }
146 }
147 }
148
149 /**
150 * @param theRequest the JMS message
151 * @return the service name of the service to call (there are 2 services
152 * "do test" and "get results"), extracted from the JMS message
153 * @exception JMSException if the service to execute is missing from
154 * the JMS message
155 */
156 private String getServiceName(Message theRequest)
157 throws JMSException
158 {
159 // Call the correct Service method
160 String serviceName = theRequest.getStringProperty(HttpServiceDefinition.SERVICE_NAME_PARAM);
161
162
163 //String serviceName = ServletUtil.getQueryStringParameter(queueName,
164 // HttpServiceDefinition.SERVICE_NAME_PARAM);
165
166 if (serviceName == null)
167 {
168 String message = "Missing service name parameter ["
169 + HttpServiceDefinition.SERVICE_NAME_PARAM
170 + "] in HTTP request. Received query string is ["
171 + serviceName + "].";
172
173 LOGGER.debug(message);
174 throw new JMSException(message);
175 }
176
177 LOGGER.debug("Service to call = " + serviceName);
178
179 return serviceName;
180 }
181
182 }