1 /**
2 * Copyright 2005-2008 the original author or authors.
3 *
4 * Licensed under the Gnu General Pubic License, Version 2.0 (the
5 * "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.opensource.org/licenses/gpl-license.php
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 * See the Gnu General Public License for more details.
14 */
15 package org.figure8.join.control.action;
16
17 import org.figure8.join.control.JoinAction;
18 import org.figure8.join.control.form.ConsumerForm;
19 import org.figure8.join.core.Configurable;
20 import org.figure8.join.core.ContainerContextHandler;
21 import org.figure8.join.core.setup.BootstrapUtil;
22 import org.figure8.join.core.setup.BootstrapManager;
23 import org.figure8.join.core.messaging.JMSConsumerBeanInfo;
24 import org.figure8.join.core.messaging.JMSConsumerBeanManager;
25 import org.figure8.join.core.messaging.JMSConsumerBeanParameterInfo;
26 import org.figure8.join.services.remoting.MessagingService;
27 import org.figure8.join.services.remoting.services.BeansHelper;
28 import org.figure8.join.services.remoting.beans.RemoteJMSConsumerBeanInfo;
29 import org.figure8.join.services.security.InvalidLoginException;
30 import org.figure8.join.businessobjects.security.User;
31 import org.figure8.join.util.ScriptLogAccessorProxy;
32 import org.figure8.join.util.LogUtil;
33
34 import org.apache.commons.logging.Log;
35 import org.apache.commons.beanutils.PropertyUtils;
36 import org.apache.struts.action.ActionForm;
37 import org.apache.struts.action.ActionForward;
38 import org.apache.struts.action.ActionMapping;
39
40 import com.caucho.hessian.client.HessianProxyFactory;
41
42 import javax.servlet.http.HttpSession;
43 import javax.servlet.http.HttpServletRequest;
44 import javax.servlet.http.HttpServletResponse;
45
46 import java.rmi.RemoteException;
47 import java.util.List;
48 import java.util.Iterator;
49 /**
50 * This is a Struts action for managing the event consumers in Join application.
51 * @author <a href="mailto:laurent.broudoux@free.fr">Laurent Broudoux</a>
52 * @version $Revision: 1.4 $
53 *
54 * @struts.action path="/consumer" name="consumerForm"
55 * scope="request" parameter="op" validate="true"
56 * input="/pages/mainpage.jsp?body=/jsp/consumers.jsp"
57 * @struts.action-forward name="Consumers" path="/jsp/consumers.jsp"
58 * @struts.action-forward name="Details" path="/jsp/consumerdetails.jsp"
59 * @struts.action-forward name="Parameters" path="/jsp/configurableparameters.jsp"
60 */
61 public class ConsumerActions extends JoinAction{
62
63
64
65 /** Get a commons logger. */
66 private static final Log log = LogUtil.getLog(ConsumerActions.class);
67
68 /** Operation code for loading a message consumer infos */
69 public static final String LOAD_OP = "load";
70 /** Operation code for saving a message consumer infos */
71 public static final String SAVE_OP = "save";
72 /** Operation code for saving a message consumer parameters infos */
73 public static final String SAVE_PARAM_OP = "saveParameters";
74 /** Operation code for getting details on a message consumer infos */
75 public static final String DETAILS_OP = "details";
76
77 /**
78 * The session scope attribute under which the consumer object
79 * currently selected by our logged-in User is stored.
80 */
81 public static final String CONSUMER_KEY = "consumer";
82 /**
83 * The session scope attribute under which the retrieved consumers
84 * list is stored.
85 */
86 public static final String CONSUMERS_KEY = "consumers";
87 /**
88 * The request scope attribute under which is stored the Consumer that
89 * has raised a DuplicateEntityException during save of another one.
90 */
91 public static final String DUPLICATE_CONSUMER_KEY = "duplicate";
92
93
94
95
96 /** The remote messaging service to use if setup is dissociated */
97 protected MessagingService service = null;
98 /** The local consumers manager to use if setup is simple */
99 protected JMSConsumerBeanManager manager = null;
100
101
102
103
104 /** Creates a new instance of ConsumerActions. */
105 public ConsumerActions(){
106 }
107
108
109
110
111 /**
112 *
113 * @param operation String representing the operation to invoke on Action
114 * @param mapping Mapping between forwards name and path for this action
115 * @param form The form object containing request parameters
116 * @param request The servlet container request wrapper
117 * @param response The servlet container response wrapper
118 * @return A forward to the next view to render and display
119 * @throws Exception such as InfraStructureExceptions ...
120 */
121 public ActionForward doExecute(String operation, ActionMapping mapping, ActionForm form,
122 HttpServletRequest request, HttpServletResponse response)
123 throws Exception{
124
125 log.debug("doExecute() called for '" + operation + "' operation");
126
127
128 initializeManagerOrService();
129
130 if (request.getParameter("displayType") == null)
131 request.setAttribute("displayType", "all");
132
133 try{
134 if (LOAD_OP.equals(operation)){
135 return loadConsumer(mapping, form, request, response);
136 }
137 else if (SAVE_OP.equals(operation)){
138 return saveConsumer(mapping, form, request, response);
139 }
140 else if (SAVE_PARAM_OP.equals(operation)){
141 return saveConsumerParameters(mapping, form, request, response);
142 }
143 else if (DETAILS_OP.equals(operation)){
144 return getConsumerDetails(mapping, form, request, response);
145 }
146 else{
147
148 request.getSession().removeAttribute(CONSUMER_KEY);
149 updateConsumersInRequest(request);
150 return mapping.findForward("Consumers");
151 }
152 }
153 catch (InvalidLoginException ile){
154 log.error("");
155 return mapping.findForward("");
156 }
157 catch (RemoteException re){
158 log.error("");
159 return mapping.findForward("");
160 }
161 }
162
163
164
165
166 /**
167 * Load a specified consumer info from datastore and fill form with it.
168 * @return A forward to the next view to render and display
169 */
170 protected ActionForward loadConsumer(ActionMapping mapping, ActionForm form,
171 HttpServletRequest request, HttpServletResponse response)
172 throws Exception{
173
174 if (form instanceof ConsumerForm){
175
176 ConsumerForm cForm = (ConsumerForm)form;
177 HttpSession session = request.getSession();
178
179
180 if (manager != null){
181 log.debug("Retrieving consumer '" + cForm.getName() + "' from local manager");
182
183 JMSConsumerBeanInfo consumer = manager.getConsumerBeanInfo(cForm.getName());
184 session.setAttribute(CONSUMER_KEY, consumer);
185
186 PropertyUtils.copyProperties(cForm, consumer);
187 }
188 else if (service != null){
189 log.debug("Retrieving consumer '" + cForm.getName() + "' from remote service");
190
191 String token = loginToRemoteService(request);
192 RemoteJMSConsumerBeanInfo remoteConsumer = service.getConsumerBeanInfo(token, cForm.getName());
193 logoutFromRemoteService(token);
194
195 JMSConsumerBeanInfo consumer = BeansHelper.getLocalObject(remoteConsumer);
196 session.setAttribute(CONSUMER_KEY, consumer);
197
198 PropertyUtils.copyProperties(cForm, consumer);
199 }
200
201
202 updateConsumersInRequest(request);
203 return mapping.findForward("Consumers");
204 }
205
206 return null;
207 }
208
209 /**
210 * Save a consumer into datastore. The consumer may be an already existing one or a
211 * new one (this is indeed a create or update method).
212 * @return A forward to the next view to render and display
213 */
214 protected ActionForward saveConsumer(ActionMapping mapping, ActionForm form,
215 HttpServletRequest request, HttpServletResponse response)
216 throws Exception{
217
218 if (form instanceof ConsumerForm){
219
220 ConsumerForm cForm = (ConsumerForm)form;
221
222 HttpSession session = request.getSession();
223 JMSConsumerBeanInfo consumer = (JMSConsumerBeanInfo)session.getAttribute(CONSUMER_KEY);
224
225
226 if (consumer == null){
227 log.info("Creation of a new JMSConsumerBeanInfo with name: " + cForm.getName());
228 consumer = new JMSConsumerBeanInfo(cForm.getName(), cForm.getSelector(), cForm.getDestination(),
229 cForm.getConsumerBeanClass());
230 consumer.setActive(cForm.isActive());
231 consumer.setThreadSafe(cForm.isThreadSafe());
232 }
233 else{
234 log.info("Update of existing JMSConsumerBeanInfo having name: " + cForm.getName());
235 PropertyUtils.copyProperties(consumer, cForm);
236 }
237
238
239 if (manager != null){
240 log.debug("Saving consumer '" + cForm.getName() + "' using local manager");
241
242 manager.saveConsumerBeanInfo(consumer);
243 }
244 else if (service != null){
245 log.debug("Saving consumer '" + cForm.getName() + "' using remote service");
246
247 String token = loginToRemoteService(request);
248 service.saveConsumerBeanInfo(token, BeansHelper.getRemoteObject(consumer));
249 logoutFromRemoteService(token);
250 }
251
252
253 if (consumer.getJMSConsumerBean() instanceof Configurable){
254 session.setAttribute(CONSUMER_KEY, consumer);
255
256 request.setAttribute(OP_PARAMETER, SAVE_PARAM_OP);
257 request.setAttribute("configurableId", consumer.getName());
258 request.setAttribute("configurable", consumer.getJMSConsumerBean());
259 request.setAttribute("action", "consumer");
260
261
262 List parameters = consumer.getConsumerParameterInfos();
263 for (int i=0; i < parameters.size(); i++)
264 cForm.addParameter((JMSConsumerBeanParameterInfo)parameters.get(i));
265
266 return mapping.findForward("Parameters");
267 }
268
269
270 session.removeAttribute(CONSUMER_KEY);
271 updateConsumersInRequest(request);
272 removeObsoleteForm(mapping, request);
273 return mapping.findForward("Consumers");
274 }
275
276 return null;
277 }
278
279 /**
280 * Save a consumer parameters into datastore. The consumer is an already existing one.
281 * @return A forward to the next view to render and display
282 */
283 protected ActionForward saveConsumerParameters(ActionMapping mapping, ActionForm form,
284 HttpServletRequest request, HttpServletResponse response)
285 throws Exception{
286
287 if (form instanceof ConsumerForm){
288
289 ConsumerForm cForm = (ConsumerForm)form;
290
291 HttpSession session = request.getSession();
292 JMSConsumerBeanInfo consumer = (JMSConsumerBeanInfo)session.getAttribute(CONSUMER_KEY);
293
294 if (consumer != null){
295 log.info("Adding JMSConsumerBeanParameterInfo to consumer: " + consumer.getName());
296
297 consumer.getConsumerParameterInfos().clear();
298
299
300 Iterator parameters = cForm.getParameters().keySet().iterator();
301 while (parameters != null && parameters.hasNext()){
302
303 String name = (String)parameters.next();
304 String value = (String)cForm.getMappedParameter(name);
305 if (log.isDebugEnabled())
306 log.debug("Adding a consumer parameter: " + name + "=" + value);
307
308 JMSConsumerBeanParameterInfo paramInfo = new JMSConsumerBeanParameterInfo(name, value);
309 consumer.addConsumerParameterInfo(paramInfo);
310 }
311
312
313 if (manager != null){
314 log.debug("Saving consumer '" + cForm.getName() + "' parameters using local manager");
315
316 manager.saveConsumerBeanInfo(consumer);
317 }
318 else if (service != null){
319 log.debug("Saving consumer '" + cForm.getName() + "' parameters using remote service");
320
321 String token = loginToRemoteService(request);
322 service.saveConsumerBeanInfo(token, BeansHelper.getRemoteObject(consumer));
323 logoutFromRemoteService(token);
324 }
325 }
326
327
328 updateConsumersInRequest(request);
329
330 session.removeAttribute(CONSUMER_KEY);
331 removeObsoleteForm(mapping, request);
332 return mapping.findForward("Consumers");
333 }
334
335 return null;
336 }
337
338 /**
339 * Get all the details from registered consumer, including its parameters and execution log files
340 * @return A forward to the next view to render and display
341 */
342 protected ActionForward getConsumerDetails(ActionMapping mapping, ActionForm form,
343 HttpServletRequest request, HttpServletResponse response)
344 throws Exception{
345
346 if (form instanceof ConsumerForm){
347 ConsumerForm cForm = (ConsumerForm)form;
348
349
350 if (manager != null){
351 JMSConsumerBeanInfo consumer = manager.getConsumerBeanInfo(cForm.getName());
352 request.setAttribute(CONSUMER_KEY, consumer);
353 }
354 else if (service != null){
355 String token = loginToRemoteService(request);
356 RemoteJMSConsumerBeanInfo consumer = service.getConsumerBeanInfo(token, cForm.getName());
357 logoutFromRemoteService(token);
358 request.setAttribute(CONSUMER_KEY, consumer);
359 }
360
361 ScriptLogAccessorProxy proxy = ScriptLogAccessorProxy.getInstance();
362 List logInfos = proxy.getScriptLogInfos(cForm.getName(), "JMSAdapter");
363 request.setAttribute("scriptLogInfos", logInfos);
364
365
366 return mapping.findForward("Details");
367 }
368
369 return null;
370 }
371
372 /**
373 * Update the consumers definitions collection within request.
374 * @param request The servlet container request wrapper
375 * @throws Exception if consumers cannot be refreshed
376 */
377 protected void updateConsumersInRequest(HttpServletRequest request) throws Exception{
378 if (manager != null){
379
380 request.setAttribute(CONSUMERS_KEY, manager.getConsumerBeanInfos());
381 }
382 else if (service != null){
383
384 String token = loginToRemoteService(request);
385 request.setAttribute(CONSUMERS_KEY, service.getConsumerBeanInfos(token));
386 logoutFromRemoteService(token);
387 }
388 }
389
390 /**
391 * Initialize the local consumer manager or the remote service depending
392 * on the application setup and the application side we are on.
393 * @throws Exception if manager cannot be found or remote service is not available
394 */
395 protected void initializeManagerOrService() throws Exception{
396 if (manager == null && service == null){
397 BootstrapManager bootstrapManager = BootstrapUtil.getBootstrapManager();
398
399 if (bootstrapManager.isDissociatedSetup() && bootstrapManager.isSynchronousSide()){
400 String url = bootstrapManager.getOtherSideUrl() + "/remoting/hessian/MessagingService";
401 log.info("Connecting to remote MessagingService using url: " + url);
402 HessianProxyFactory proxyFactory = new HessianProxyFactory();
403 service = (MessagingService)proxyFactory.create(MessagingService.class, url);
404 }
405 else{
406
407 log.info("Looking up local JMSConsumerBeanManager using 'jmsConsumerBeanManager' component");
408 ContainerContextHandler handler = ContainerContextHandler.getInstance();
409 manager = (JMSConsumerBeanManager)handler.getComponent("jmsConsumerBeanManager");
410 }
411 }
412 }
413
414
415
416
417 /** Login for using remote service. */
418 private String loginToRemoteService(HttpServletRequest request) throws InvalidLoginException, RemoteException{
419
420 User user = getUserContainer(request).getView().getUser();
421 String pwd = getUserContainer(request).getView().getClearPassword();
422
423 String token = service.login(user.getLogin(), pwd);
424 return token;
425 }
426
427 /** Logout from remote service. */
428 private void logoutFromRemoteService(String token) throws RemoteException{
429 service.logout(token);
430 }
431 }