001: /*
002: * This file is part of the WfMOpen project.
003: * Copyright (C) 2001-2003 Danet GmbH (www.danet.de), GS-AN.
004: * All rights reserved.
005: *
006: * This program is free software; you can redistribute it and/or modify
007: * it under the terms of the GNU General Public License as published by
008: * the Free Software Foundation; either version 2 of the License, or
009: * (at your option) any later version.
010: *
011: * This program is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014: * GNU General Public License for more details.
015: *
016: * You should have received a copy of the GNU General Public License
017: * along with this program; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
019: *
020: * $Id: EventHandlerEJB.java,v 1.9 2007/06/10 05:55:30 drmlipp Exp $
021: *
022: * $Log: EventHandlerEJB.java,v $
023: * Revision 1.9 2007/06/10 05:55:30 drmlipp
024: * Using local interface for optimization.
025: *
026: * Revision 1.8 2006/12/20 10:58:09 drmlipp
027: * Incremented requeue limit in response to an issue reported for a laptop
028: * (much CPU, slow disks/RDBMS).
029: *
030: * Revision 1.7 2006/10/10 09:23:58 drmlipp
031: * Made queue and topic names "generic".
032: *
033: * Revision 1.6 2006/09/29 12:32:12 drmlipp
034: * Consistently using WfMOpen as projct name now.
035: *
036: * Revision 1.5 2006/09/25 20:08:28 mlipp
037: * Merged changes from 1.3.4p1.
038: *
039: * Revision 1.4 2005/04/08 11:28:05 drmlipp
040: * Merged changes from 1.3 branch up to 1.3p6.
041: *
042: * Revision 1.2.6.3 2005/04/07 15:54:23 drmlipp
043: * Fixed problem with process not being started. Removed fix that handled
044: * special case of subprocess only.
045: *
046: * Revision 1.2.6.2 2005/04/04 20:09:19 drmlipp
047: * Changed WLS transaction isolation.
048: *
049: * Revision 1.3 2005/02/04 14:25:27 drmlipp
050: * Synchronized with 1.3rc2.
051: *
052: * Revision 1.2.6.1 2005/02/03 15:45:06 drmlipp
053: * Optimized execution.
054: *
055: * Revision 1.2 2004/09/10 12:44:30 drmlipp
056: * Enabled call by reference for weblogic by default.
057: *
058: * Revision 1.1.1.4 2004/08/18 15:17:38 drmlipp
059: * Update to 1.2
060: *
061: * Revision 1.41 2004/07/04 17:36:03 lipp
062: * Added JOnAS support.
063: *
064: * Revision 1.40 2004/02/21 21:31:01 lipp
065: * Some more refactoring to resolve cyclic dependencies.
066: *
067: * Revision 1.39 2004/01/14 07:59:45 lipp
068: * Added transaction isolation attribute for WLS.
069: *
070: * Revision 1.38 2003/12/02 16:00:10 lipp
071: * Added debug message.
072: *
073: * Revision 1.37 2003/11/21 14:56:12 lipp
074: * Adapted wls queue names.
075: *
076: * Revision 1.36 2003/11/18 14:32:12 lipp
077: * Removed tool invocation optimization (may be re-introduced later).
078: *
079: * Revision 1.35 2003/11/04 15:05:34 lipp
080: * Changed ActivityProxy representation in queue to avoid JBoss
081: * ClassCastException when retrieving message.
082: *
083: * Revision 1.34 2003/11/04 10:08:22 lipp
084: * Removed queuing optimization.
085: *
086: * Revision 1.33 2003/11/03 16:32:52 lipp
087: * Fixed event saving.
088: *
089: * Revision 1.32 2003/10/29 14:56:02 lipp
090: * Limit number of event handlers.
091: *
092: * Revision 1.31 2003/10/27 20:41:29 lipp
093: * Made application undeployable again.
094: *
095: * Revision 1.30 2003/10/27 13:31:16 lipp
096: * Cleaned up usage of static attributes.
097: *
098: * Revision 1.29 2003/10/25 21:00:15 lipp
099: * Made AuditEventQueuer the general queuer.
100: *
101: * Revision 1.28 2003/10/24 11:08:49 lipp
102: * Made AuditEventQueuer an EJB.
103: *
104: * Revision 1.27 2003/10/23 19:38:56 lipp
105: * Removed unnecessary start methods.
106: *
107: * Revision 1.26 2003/10/06 15:32:58 lipp
108: * More WebLogic adaptations.
109: *
110: * Revision 1.25 2003/09/26 12:52:01 lipp
111: * Changed role names.
112: *
113: * Revision 1.24 2003/08/27 14:41:54 lipp
114: * Clarified names/use of queues and queue definition files.
115: *
116: * Revision 1.23 2003/06/27 08:51:45 lipp
117: * Fixed copyright/license information.
118: *
119: * Revision 1.22 2003/06/04 13:15:51 lipp
120: * Optimized resource allocation/caching.
121: *
122: * Revision 1.21 2003/05/06 13:21:30 lipp
123: * Resolved cyclic dependency.
124: *
125: * Revision 1.20 2003/05/02 14:55:58 lipp
126: * Resolved some more package dependencies.
127: *
128: * Revision 1.19 2003/04/11 07:12:55 ott
129: * Some JNDI-Names for Weblogic changed
130: *
131: * Revision 1.18 2003/03/31 16:50:28 huaiyang
132: * Logging using common-logging.
133: *
134: * Revision 1.17 2003/02/28 15:03:33 lipp
135: * Re-persisting activity reference in event handling.
136: *
137: * Revision 1.16 2003/02/12 11:57:30 lipp
138: * Improved deadlock (RemoteException) handling for tools. Imroved debug
139: * information.
140: *
141: * Revision 1.15 2003/01/09 14:47:21 ott
142: * changes to use with weblogic 7.0
143: *
144: * Revision 1.14 2002/11/26 11:23:29 lipp
145: * Modified RemoteException comment.
146: *
147: * Revision 1.13 2002/11/21 11:37:12 montag
148: * xdoclet for wfcore finished.
149: *
150: * Revision 1.12 2002/11/20 14:32:41 montag
151: * begin generation of home and remote interfaces.
152: *
153: * Revision 1.11 2002/11/18 09:34:10 lipp
154: * Removed sophisticated cache handling (not necessary, silly me).
155: *
156: * Revision 1.10 2002/11/05 12:47:20 lipp
157: * Fixes to local invocation queue and ToolInvocationFailedAuditEvent.
158: *
159: * Revision 1.9 2002/10/31 16:27:14 lipp
160: * Fixed bug in moving events from local to JMS queue.
161: *
162: * Revision 1.8 2002/10/24 08:48:40 lipp
163: * Activated event queue optimization.
164: *
165: * Revision 1.7 2002/10/22 13:34:57 lipp
166: * Event handling now includes process in transaction as soon as possible
167: * in order to avoid deadlocks.
168: *
169: * Revision 1.6 2002/10/08 13:52:36 lipp
170: * Merged branch new-state-handling.
171: *
172: * Revision 1.5.2.1 2002/10/08 13:04:35 lipp
173: * Reimplementing state handling, activity start to complete cycle.
174: *
175: * Revision 1.5 2002/10/03 19:02:26 lipp
176: * New handling of tool invocation errors.
177: *
178: * Revision 1.4 2002/10/02 20:54:40 lipp
179: * Event handling partially reorganized.
180: *
181: * Revision 1.3 2002/10/02 15:08:32 lipp
182: * New event handling.
183: *
184: * Revision 1.2 2002/10/01 16:06:00 lipp
185: * Event queue activated.
186: *
187: * Revision 1.1 2002/09/30 13:05:41 lipp
188: * Introducing internal event queue.
189: *
190: */
191: package de.danet.an.workflow.ejbs.util;
192:
193: import java.util.Map;
194:
195: import java.rmi.RemoteException;
196:
197: import javax.ejb.EJBException;
198: import javax.ejb.MessageDrivenBean;
199: import javax.ejb.MessageDrivenContext;
200: import javax.jms.JMSException;
201: import javax.jms.Message;
202: import javax.jms.MessageListener;
203: import javax.jms.ObjectMessage;
204:
205: import de.danet.an.util.EJBUtil;
206: import de.danet.an.util.ResourceNotAvailableException;
207:
208: import de.danet.an.workflow.omgcore.WfAuditEvent;
209:
210: import de.danet.an.workflow.domain.DefaultAuditEvent;
211:
212: import de.danet.an.workflow.ejbs.WorkflowEngine;
213: import de.danet.an.workflow.ejbs.WorkflowEngineHome;
214: import de.danet.an.workflow.ejbs.admin.WorkflowEngineLocal;
215: import de.danet.an.workflow.ejbs.admin.WorkflowEngineLocalHome;
216:
217: /**
218: * This class provides the MDB that handles the
219: * <code>WfAuditEvent</code>s throws by the
220: * <code>WfExecutionObject</code>s.
221: *
222: * @author <a href="mailto:lipp@danet.de"></a>
223: * @version $Revision: 1.9 $
224: *
225: * @ejb.bean name="EventHandler" transaction-type="Container"
226: * destination-type="javax.jms.Queue"
227: * @jonas.bean ejb-name="EventHandler"
228: * @ejb.security-identity run-as="WfMOpenAdmin"
229: * @weblogic.run-as-identity-principal WfMOpenPrincipalForAdmin
230: * @ejb.ejb-ref ejb-name="WorkflowEngine" view-type="local"
231: * @ejb.ejb-ref ejb-name="Queuer" view-type="local"
232: * @ejb.transaction type="Required"
233: * @ejb.permission role-name="WfMOpenAdmin"
234: * @jboss.destination-jndi-name
235: * name="queue/@@@_JNDI_Name_Prefix_@@@InternalEventQueue"
236: * @jonas.message-driven-destination
237: * jndi-name="queue/@@@_JNDI_Name_Prefix_@@@InternalEventQueue"
238: * @weblogic.enable-call-by-reference True
239: * @weblogic.message-driven
240: * destination-jndi-name="queue/@@@_JNDI_Name_Prefix_@@@InternalEventQueue"
241: * @jboss.container-configuration name="EventHandler Message Driven Bean"
242: */
243:
244: public class EventHandlerEJB implements MessageDrivenBean,
245: MessageListener {
246:
247: private static final org.apache.commons.logging.Log logger = org.apache.commons.logging.LogFactory
248: .getLog(EventHandlerEJB.class);
249:
250: private MessageDrivenContext ctx;
251:
252: private QueuerLocal queuerCache = null;
253:
254: /** The workflow engine. */
255: private WorkflowEngineLocal engineCache = null;
256:
257: /**
258: * The queuer must be created lazily as we need permissions that
259: * we have in onMessage only.
260: */
261: private QueuerLocal queuer() {
262: if (queuerCache == null) {
263: try {
264: queuerCache = (QueuerLocal) EJBUtil.createSession(
265: QueuerLocalHome.class,
266: "java:comp/env/ejb/Queuer");
267: } catch (RemoteException e) {
268: throw new EJBException(e);
269: }
270: }
271: return queuerCache;
272: }
273:
274: /**
275: * The workflow engine.
276: * @return home interface of the workflow engine.
277: */
278: private WorkflowEngineLocal engine()
279: throws ResourceNotAvailableException {
280: if (engineCache == null) {
281: engineCache = (WorkflowEngineLocal) EJBUtil.createSession(
282: WorkflowEngineLocalHome.class,
283: "java:comp/env/ejb/WorkflowEngineLocal");
284: }
285: return engineCache;
286: }
287:
288: /**
289: * Called by container to set context.
290: * @param context the context.
291: */
292: public void setMessageDrivenContext(MessageDrivenContext context) {
293: ctx = context;
294: engineCache = null;
295: }
296:
297: /**
298: * Called by container to create EJB.
299: */
300: public void ejbCreate() {
301: logger.debug("Created.");
302: }
303:
304: /**
305: * Called by container to remove EJB.
306: */
307: public void ejbRemove() {
308: // TODO: unsure if this is a JBoss bug, but ejbRemove is
309: // called without a principal although run-as has been
310: // specified. Anyway, not removing the Queuer is not that bad.
311: // EJBUtil.removeSession(queuerCache);
312: queuerCache = null;
313: engineCache = null;
314: logger.debug("Removed.");
315: }
316:
317: /**
318: * Called by container when a new message is to be processed.
319: * @param message the message.
320: */
321: public void onMessage(Message message) {
322: WorkflowEngine wfe = null;
323: try {
324: Map args = (Map) ((ObjectMessage) message).getObject();
325: WfAuditEvent evt = (DefaultAuditEvent) args.get("event");
326: try {
327: engine().processEvent(evt);
328: } catch (RedeliveryRequiredException e) {
329: int requeued = 1;
330: if (message.propertyExists("requeuedCount")) {
331: requeued = message.getIntProperty("requeuedCount") + 1;
332: }
333: if (requeued > 20) {
334: logger
335: .error("Event discarded, redelivery limit exceeded: "
336: + e.getMessage());
337: return;
338: }
339: queuer().queue((DefaultAuditEvent) evt, requeued);
340: } catch (RemoteException e) {
341: // we have to retry at a later time
342: logger.debug(
343: "Temporary Problem handling event (repeated): "
344: + e.getMessage(), e);
345: // WLS seems to have problems with invoking
346: // setRollbackOnly twice
347: if (!ctx.getRollbackOnly()) {
348: ctx.setRollbackOnly();
349: }
350: } catch (Throwable t) {
351: // can't do anything reasonable
352: logger.error("Error handling event (discarded): "
353: + t.getMessage(), t);
354: }
355: } catch (JMSException e) {
356: // no use repeating this
357: logger.error(e.getMessage(), e);
358: } catch (Throwable t) {
359: // unsolvable error condition
360: logger.error(
361: "Event discarded due to error during handling: "
362: + t.getMessage(), t);
363: }
364: }
365:
366: }
|