KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > opencrx > kernel > workflow > servlet > WorkflowHandlerServlet


1 /*
2  * ====================================================================
3  * Project: opencrx, http://www.opencrx.org/
4  * Name: $Id: WorkflowHandlerServlet.java,v 1.2 2006/04/02 00:34:25 wfro Exp $
5  * Description: AsynchWorkflowExecutor Servlet
6  * Revision: $Revision: 1.2 $
7  * Owner: CRIXP AG, Switzerland, http://www.crixp.com
8  * Date: $Date: 2006/04/02 00:34:25 $
9  * ====================================================================
10  *
11  * This software is published under the BSD license
12  * as listed below.
13  *
14  * Copyright (c) 2004-2005, CRIXP Corp., Switzerland
15  * All rights reserved.
16  *
17  * Redistribution and use in source and binary forms, with or without
18  * modification, are permitted provided that the following conditions
19  * are met:
20  *
21  * * Redistributions of source code must retain the above copyright
22  * notice, this list of conditions and the following disclaimer.
23  *
24  * * Redistributions in binary form must reproduce the above copyright
25  * notice, this list of conditions and the following disclaimer in
26  * the documentation and/or other materials provided with the
27  * distribution.
28  *
29  * * Neither the name of CRIXP Corp. nor the names of the contributors
30  * to openCRX may be used to endorse or promote products derived
31  * from this software without specific prior written permission
32  *
33  *
34  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
35  * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
36  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
37  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
38  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
39  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
40  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
41  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
42  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
43  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
44  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
45  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
46  * POSSIBILITY OF SUCH DAMAGE.
47  *
48  * ------------------
49  *
50  * This product includes software developed by the Apache Software
51  * Foundation (http://www.apache.org/).
52  *
53  * This product includes software developed by contributors to
54  * openMDX (http://www.openmdx.org/)
55  */

56 package org.opencrx.kernel.workflow.servlet;
57
58 import java.io.IOException JavaDoc;
59 import java.lang.reflect.Constructor JavaDoc;
60 import java.lang.reflect.InvocationTargetException JavaDoc;
61 import java.util.ArrayList JavaDoc;
62 import java.util.Date JavaDoc;
63 import java.util.Iterator JavaDoc;
64 import java.util.List JavaDoc;
65
66 import javax.naming.Context JavaDoc;
67 import javax.naming.InitialContext JavaDoc;
68 import javax.naming.NamingException JavaDoc;
69 import javax.servlet.ServletConfig JavaDoc;
70 import javax.servlet.ServletException JavaDoc;
71 import javax.servlet.http.HttpServlet JavaDoc;
72 import javax.servlet.http.HttpServletRequest JavaDoc;
73 import javax.servlet.http.HttpServletResponse JavaDoc;
74
75 import org.opencrx.kernel.home1.cci.WfProcessInstance;
76 import org.opencrx.kernel.home1.cci.WfProcessInstanceFilter;
77 import org.opencrx.kernel.workflow.ASynchWorkflow_1_0;
78 import org.openmdx.application.log.AppLog;
79 import org.openmdx.base.accessor.generic.view.Manager_1;
80 import org.openmdx.base.accessor.jmi.cci.JmiServiceException;
81 import org.openmdx.base.accessor.jmi.cci.RefPackage_1_0;
82 import org.openmdx.base.accessor.jmi.spi.RefRootPackage_1;
83 import org.openmdx.base.exception.ServiceException;
84 import org.openmdx.compatibility.application.dataprovider.transport.ejb.cci.Dataprovider_1ConnectionFactoryImpl;
85 import org.openmdx.compatibility.base.dataprovider.cci.QualityOfService;
86 import org.openmdx.compatibility.base.dataprovider.cci.RequestCollection;
87 import org.openmdx.compatibility.base.dataprovider.cci.ServiceHeader;
88 import org.openmdx.compatibility.base.dataprovider.transport.adapter.Provider_1;
89 import org.openmdx.compatibility.base.dataprovider.transport.cci.Dataprovider_1_1Connection;
90 import org.openmdx.compatibility.base.dataprovider.transport.cci.Provider_1_0;
91 import org.openmdx.compatibility.base.dataprovider.transport.delegation.Connection_1;
92 import org.openmdx.compatibility.base.query.FilterOperators;
93 import org.openmdx.compatibility.kernel.application.cci.Classes;
94 import org.openmdx.model1.accessor.basic.spi.Model_1;
95
96 /**
97  * The AsynchWorkflowHandlerServlet periodically scans for non-executed
98  * asynchronous workflows. Non-executed workflows are executed and
99  * marked as executed. The workflows to be executed must implement
100  * the interface org.opencrx.kernel.workflow.AsynchWorkflow_1_0. The
101  * workflow implementation classes must be on the classpath of the
102  * client application.
103  */

104 public class WorkflowHandlerServlet
105     extends HttpServlet JavaDoc {
106
107     //-----------------------------------------------------------------------
108
public void init(
109         ServletConfig JavaDoc config
110     ) throws ServletException JavaDoc {
111
112         super.init(config);
113         
114         // initialize model repository
115
int i = 0;
116         List JavaDoc modelPackages = new ArrayList JavaDoc();
117         while(getInitParameter("modelPackage[" + i + "]") != null) {
118             modelPackages.add(
119               getInitParameter("modelPackage[" + i + "]")
120             );
121             i++;
122         }
123         try {
124             new Model_1().addModels(modelPackages);
125         }
126         catch(Exception JavaDoc e) {
127             System.out.println("Can not initialize model repository " + e.getMessage());
128             System.out.println(new ServiceException(e).getCause());
129         }
130
131         Context JavaDoc initialContext;
132         try {
133             initialContext = new InitialContext JavaDoc();
134         } catch (NamingException JavaDoc e) {
135             throw new ServletException JavaDoc("Can not get the initial context", e);
136         }
137       
138         // data connection
139
try {
140             this.connectionData = Dataprovider_1ConnectionFactoryImpl.createGenericConnection(
141                 initialContext.lookup("java:comp/env/ejb/data")
142             );
143         }
144         catch(Exception JavaDoc e) {
145             throw new ServletException JavaDoc("Can not get connection to data provider", e);
146         }
147
148     }
149
150     //-----------------------------------------------------------------------
151
private boolean executeAsynchWorkflow(
152         WfProcessInstance wfProcessInstance
153     ) {
154         AppLog.info("Execute", wfProcessInstance.getProcess().getName());
155         try {
156             String JavaDoc workflowName = wfProcessInstance.getProcess().getName();
157         
158             ASynchWorkflow_1_0 workflow = null;
159             Class JavaDoc workflowClass = null;
160             try {
161                 workflowClass = Classes.getApplicationClass(
162                     workflowName
163                 );
164             }
165             catch(ClassNotFoundException JavaDoc e) {
166                 AppLog.error("Implementation for workflow " + workflowName + " not found");
167                 return false;
168             }
169             // Look up constructor
170
Constructor JavaDoc workflowConstructor = null;
171             try {
172                 workflowConstructor = workflowClass.getConstructor(new Class JavaDoc[]{});
173             }
174             catch(NoSuchMethodException JavaDoc e) {
175                 AppLog.error("No constructor found for workflow " + workflowName);
176             }
177             // Instantiate workflow
178
try {
179                 workflow = (ASynchWorkflow_1_0)workflowConstructor.newInstance(new Object JavaDoc[]{});
180             }
181             catch(InstantiationException JavaDoc e) {
182                 AppLog.error("Can not create workflow (can not instantiate)", workflowName);
183                 return false;
184             }
185             catch(IllegalAccessException JavaDoc e) {
186                 AppLog.error("Can not create workflow (illegal access)", workflowName);
187                 return false;
188             }
189             catch(IllegalArgumentException JavaDoc e) {
190                 AppLog.error("Can not create workflow (illegal argument)", workflowName);
191                 return false;
192             }
193             catch(InvocationTargetException JavaDoc e) {
194                 AppLog.error("Can not create workflow (can not invoke target)", workflowName + "(" + e.getTargetException().getMessage() + ")");
195                 return false;
196             }
197             workflow.execute(
198                 wfProcessInstance
199             );
200             AppLog.info("SUCCESS");
201             return true;
202         }
203         catch(Exception JavaDoc e) {
204             new ServiceException(e).log();
205             System.out.println(" FAILED (Reason=" + e.getMessage() + ")");
206             AppLog.info("FAILED");
207             return false;
208         }
209     }
210     
211     //-------------------------------------------------------------------------
212
private RefPackage_1_0 createDataPkg(
213         ServiceHeader header
214     ) throws ServiceException {
215         Provider_1_0 provider = new Provider_1(
216           new RequestCollection(
217             header,
218             this.connectionData
219           ),
220           false
221         );
222         Manager_1 manager = new Manager_1(
223           new Connection_1(
224             provider,
225             false
226           )
227         );
228         RefPackage_1_0 rootPkg = new RefRootPackage_1(manager);
229         return rootPkg;
230     }
231
232     //-----------------------------------------------------------------------
233
private void handleAsynchWorkflows(
234         String JavaDoc providerName,
235         String JavaDoc segmentName,
236         HttpServletRequest JavaDoc req,
237         HttpServletResponse JavaDoc res
238     ) throws IOException JavaDoc {
239             
240         // TODO: should be configurable
241
int maxNumberOfRetries = 5;
242         
243         System.out.println(new Date JavaDoc().toString() + ": openCRX/WorkflowHandler: " + providerName + "/" + segmentName);
244         
245         try {
246             RefPackage_1_0 rootPkg = this.createDataPkg(
247                 new ServiceHeader("admin-" + segmentName, null, false, new QualityOfService())
248             );
249             WorkflowControllerServlet.initWorkflows(
250                 rootPkg,
251                 providerName,
252                 segmentName
253             );
254             
255             // Get activity segment
256
org.opencrx.kernel.home1.cci.home1Package userHomePkg =
257                 (org.opencrx.kernel.home1.cci.home1Package)rootPkg.refPackage(
258                     org.opencrx.kernel.home1.cci.home1Package.class.getName()
259                 );
260             org.opencrx.kernel.home1.cci.Segment userHomeSegment =
261                 (org.opencrx.kernel.home1.cci.Segment)rootPkg.refObject(
262                     "xri:@openmdx:org.opencrx.kernel.home1/provider/" + providerName + "/segment/" + segmentName
263                 );
264     
265             WfProcessInstanceFilter filter = userHomePkg.createWfProcessInstanceFilter();
266             filter.thereExistsIdentity(
267                 FilterOperators.IS_LIKE,
268                 new String JavaDoc[]{
269                     userHomeSegment.refMofId() + "/userHome/:*/wfProcessInstance/:*"
270                 }
271             );
272             filter.forAllStartedOn(
273                 FilterOperators.IS_IN,
274                 new Date JavaDoc[]{}
275             );
276             List JavaDoc wfProcessInstances = userHomeSegment.getExtent(filter);
277             AppLog.info("Executing workflows");
278             int jj = 0;
279             for(
280                 Iterator JavaDoc j = wfProcessInstances.iterator();
281                 j.hasNext() && (jj < 200);
282                 jj++
283             ) {
284                 WfProcessInstance wfProcessInstance = (WfProcessInstance)j.next();
285                 if(
286                     (wfProcessInstance.getStepCounter() == null) ||
287                     (wfProcessInstance.getStepCounter().intValue() < maxNumberOfRetries)
288                 ) {
289                     boolean success = false;
290                     try {
291                         success = this.executeAsynchWorkflow(
292                             wfProcessInstance
293                         );
294                     }
295                     catch(JmiServiceException e) {
296                         e.log();
297                         try {
298                             rootPkg.refRollback();
299                         } catch(Exception JavaDoc e0) {}
300                     }
301                     if(success) {
302                         try {
303                             userHomePkg.refBegin();
304                             wfProcessInstance.setStartedOn(new Date JavaDoc());
305                             wfProcessInstance.setLastActivityOn(new Date JavaDoc());
306                             wfProcessInstance.setStepCounter(
307                                 new Integer JavaDoc(wfProcessInstance.getStepCounter().intValue() + 1)
308                             );
309                             userHomePkg.refCommit();
310                         }
311                         catch(Exception JavaDoc e) {
312                             new ServiceException(e).log();
313                             try {
314                                 userHomePkg.refRollback();
315                             } catch(Exception JavaDoc e0) {}
316                         }
317                     }
318                     else {
319                         try {
320                             userHomePkg.refBegin();
321                             wfProcessInstance.setStepCounter(
322                                 new Integer JavaDoc(wfProcessInstance.getStepCounter().intValue() + 1)
323                             );
324                             userHomePkg.refCommit();
325                         }
326                         catch(Exception JavaDoc e) {
327                             new ServiceException(e).log();
328                             try {
329                                 userHomePkg.refRollback();
330                             } catch(Exception JavaDoc e0) {}
331                         }
332                     }
333                 }
334                 // Mark as executed if retry count is reached
335
else {
336                     userHomePkg.refBegin();
337                     wfProcessInstance.setStartedOn(new Date JavaDoc());
338                     wfProcessInstance.setLastActivityOn(new Date JavaDoc());
339                     userHomePkg.refCommit();
340                 }
341             }
342         }
343         catch(ServiceException e) {
344             System.out.println("Exception occured " + e.getMessage() + ". Continuing");
345             new ServiceException(e).log();
346         }
347         catch(JmiServiceException e) {
348             System.out.println("Exception occured " + e.getMessage() + ". Continuing");
349             new ServiceException(e).log();
350         }
351         catch(Exception JavaDoc e) {
352             System.out.println("Exception occured " + e.getMessage() + ". Continuing");
353             new ServiceException(e).log();
354         }
355     }
356
357     //-----------------------------------------------------------------------
358
protected void handleRequest(
359         HttpServletRequest JavaDoc req,
360         HttpServletResponse JavaDoc res
361     ) throws ServletException JavaDoc, IOException JavaDoc {
362         String JavaDoc segmentName = req.getParameter("segment");
363         String JavaDoc providerName = req.getParameter("provider");
364         String JavaDoc id = providerName + "/" + segmentName;
365         // run
366
if(
367             COMMAND_EXECUTE.equals(req.getPathInfo()) &&
368             !this.runningSegments.contains(id)
369         ) {
370             try {
371                 this.runningSegments.add(id);
372                 this.handleAsynchWorkflows(
373                     providerName,
374                     segmentName,
375                     req,
376                     res
377                 );
378             } catch(Exception JavaDoc e) {
379                 new ServiceException(e).log();
380             }
381             finally {
382                 this.runningSegments.remove(id);
383             }
384         }
385     }
386
387     //-----------------------------------------------------------------------
388
protected void doGet(
389         HttpServletRequest JavaDoc req,
390         HttpServletResponse JavaDoc res
391     ) throws ServletException JavaDoc, IOException JavaDoc {
392         res.setStatus(HttpServletResponse.SC_OK);
393         res.flushBuffer();
394         this.handleRequest(
395             req,
396             res
397         );
398     }
399         
400     //-----------------------------------------------------------------------
401
protected void doPost(
402         HttpServletRequest JavaDoc req,
403         HttpServletResponse JavaDoc res
404     ) throws ServletException JavaDoc, IOException JavaDoc {
405         res.setStatus(HttpServletResponse.SC_OK);
406         res.flushBuffer();
407         this.handleRequest(
408             req,
409             res
410         );
411     }
412         
413     //-----------------------------------------------------------------------
414
// Members
415
//-----------------------------------------------------------------------
416
private static final long serialVersionUID = 1260441904508971604L;
417
418     private static final String JavaDoc COMMAND_EXECUTE = "/execute";
419     
420     private Dataprovider_1_1Connection connectionData = null;
421     private final List JavaDoc runningSegments = new ArrayList JavaDoc();
422 }
423
424 //--- End of File -----------------------------------------------------------
425
Popular Tags