001: /*
002: * This file is part of the WfMOpen project.
003: * Copyright (C) 2001-2004 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: Chabacc.java,v 1.6 2007/02/16 20:58:37 mlipp Exp $
021: *
022: * $Log: Chabacc.java,v $
023: * Revision 1.6 2007/02/16 20:58:37 mlipp
024: * Extended test case.
025: *
026: * Revision 1.5 2007/02/15 13:52:37 drmlipp
027: * Fixed channel release problem.
028: *
029: * Revision 1.4 2007/02/07 16:48:36 mlipp
030: * Fixed test case.
031: *
032: * Revision 1.3 2006/11/03 22:09:26 mlipp
033: * Added test.
034: *
035: * Revision 1.2 2006/09/29 12:32:07 drmlipp
036: * Consistently using WfMOpen as projct name now.
037: *
038: * Revision 1.1.1.1 2004/08/18 15:18:47 drmlipp
039: * Update to 1.2
040: *
041: * Revision 1.8 2004/03/21 12:38:24 lipp
042: * Added test cases for mimic as requester process.
043: *
044: * Revision 1.7 2004/03/18 09:13:23 lipp
045: * Added special XML test.
046: *
047: * Revision 1.6 2004/02/13 08:25:29 lipp
048: * Changed channel message data type to Map which is more appropriate.
049: *
050: * Revision 1.5 2004/02/12 13:27:46 lipp
051: * Renamed openChannel to getChannel (channels have no open state).
052: *
053: * Revision 1.4 2004/02/06 13:37:35 lipp
054: * Added channel close notification.
055: *
056: * Revision 1.3 2004/02/06 10:25:46 lipp
057: * Finshed Receiver.
058: *
059: * Revision 1.2 2004/01/30 14:36:30 lipp
060: * Partial implementation of message receipt.
061: *
062: * Revision 1.1 2004/01/28 16:11:38 lipp
063: * Re-implementation of chabacc, Sender working.
064: *
065: */
066: package tools;
067:
068: import java.io.BufferedReader;
069: import java.io.InputStream;
070: import java.io.InputStreamReader;
071:
072: import java.util.Collection;
073: import java.util.HashMap;
074: import java.util.Iterator;
075: import java.util.Map;
076:
077: import javax.security.auth.login.LoginException;
078: import javax.xml.parsers.DocumentBuilderFactory;
079: import javax.xml.transform.Transformer;
080: import javax.xml.transform.TransformerFactory;
081: import javax.xml.transform.dom.DOMSource;
082: import javax.xml.transform.sax.SAXResult;
083:
084: import org.w3c.dom.Document;
085: import org.w3c.dom.DocumentFragment;
086: import org.w3c.dom.Node;
087:
088: import de.danet.an.util.EJBUtil;
089: import de.danet.an.util.XMLUtil;
090: import de.danet.an.util.junit.EJBClientTest;
091: import de.danet.an.util.sax.SAXContentBuffer;
092:
093: import de.danet.an.workflow.omgcore.ProcessData;
094: import de.danet.an.workflow.omgcore.WfActivity;
095: import de.danet.an.workflow.omgcore.WfProcess;
096: import de.danet.an.workflow.omgcore.WfRequester;
097: import de.danet.an.workflow.util.SAXEventBufferImpl;
098:
099: import de.danet.an.workflow.api.Activity;
100: import de.danet.an.workflow.api.Channel;
101: import de.danet.an.workflow.api.DefaultRequester;
102: import de.danet.an.workflow.api.FactoryConfigurationError;
103: import de.danet.an.workflow.api.Process;
104: import de.danet.an.workflow.api.ProcessDefinitionDirectory;
105: import de.danet.an.workflow.api.ProcessDirectory;
106: import de.danet.an.workflow.api.ProcessMgr;
107: import de.danet.an.workflow.api.SAXEventBuffer;
108: import de.danet.an.workflow.api.WorkflowService;
109: import de.danet.an.workflow.api.WorkflowServiceFactory;
110:
111: import common.UTLoginContext;
112: import junit.framework.Test;
113: import junit.framework.TestCase;
114: import junit.framework.TestSuite;
115:
116: /**
117: * Test Cahbacc
118: */
119: public class Chabacc extends TestCase {
120: private static UTLoginContext plc = null;
121: static {
122: try {
123: plc = new UTLoginContext();
124: plc.login();
125: } catch (LoginException e) {
126: throw new IllegalStateException(e.getMessage());
127: }
128: }
129:
130: /**
131: * A process directory reference.
132: */
133: private ProcessDirectory pdd = null;
134:
135: /**
136: * Constructor of this TestCase
137: */
138: public Chabacc(String name) {
139: super (name);
140: }
141:
142: /**
143: * Stellt diese TestSuite zusammen.
144: */
145: public static Test suite() {
146: TestSuite suite = new TestSuite();
147: suite.addTest(new Chabacc("importProcessDefinitions"));
148: suite.addTest(new Chabacc("receiveMessage"));
149: suite.addTest(new Chabacc("sendMessageAfter"));
150: suite.addTest(new Chabacc("sendMessageBefore"));
151: suite.addTest(new Chabacc("sendXMLMessage"));
152: suite.addTest(new Chabacc("sendSelf"));
153: suite.addTest(new Chabacc("echo"));
154: suite.addTest(new Chabacc("echoIndirect"));
155: suite.addTest(new Chabacc("closeNotification"));
156: suite.addTest(new Chabacc("testInEJB"));
157: suite.addTest(new Chabacc("testInEJBWithTimeout"));
158: return new EJBClientTest(plc, suite);
159: }
160:
161: private WorkflowService workflowService = null;
162:
163: /**
164: * Initialisierung.
165: */
166: protected void setUp() throws Exception {
167: try {
168: WorkflowServiceFactory wfsf = WorkflowServiceFactory
169: .newInstance();
170: workflowService = wfsf.newWorkflowService();
171: } catch (FactoryConfigurationError e) {
172: throw new IllegalStateException(e.getMessage());
173: }
174: }
175:
176: protected void tearDown() throws Exception {
177: workflowService.release(workflowService);
178: workflowService = null;
179: }
180:
181: /**
182: * Import the process definitions from a XPDL file
183: * unsing the ProcessDefinitionDirectory bean.
184: */
185: public void importProcessDefinitions() throws Exception {
186: // Create process definition directory bean
187: ProcessDefinitionDirectory pdd = workflowService
188: .processDefinitionDirectory();
189:
190: InputStream is = getClass().getResourceAsStream(
191: "/tools/chabacc.xml");
192: assertTrue(is != null);
193: BufferedReader br = new BufferedReader(new InputStreamReader(
194: is, "ISO-8859-1"));
195: StringBuffer sb = new StringBuffer();
196: String st;
197: while ((st = br.readLine()) != null) {
198: sb.append(st + "\n");
199: }
200: pdd.importProcessDefinitions(sb.toString());
201: Collection processDefinitions = pdd.processDefinitions();
202: assertTrue(processDefinitions.size() > 0);
203:
204: }
205:
206: /**
207: * Test.
208: */
209: public void receiveMessage() throws Exception {
210: ProcessDefinitionDirectory procDefDir = null;
211: ProcessDirectory procDir = null;
212: Channel chan = null;
213: try {
214: procDefDir = workflowService.processDefinitionDirectory();
215: procDir = workflowService.processDirectory();
216: ProcessMgr pmgr = procDefDir.processMgr("chabacc",
217: "chabacc_test_sender");
218: WfProcess process = pmgr
219: .createProcess(new DefaultRequester(workflowService));
220: chan = workflowService.getChannel(process, "test_channel");
221: WfActivity sleepAct = null;
222: for (Iterator i = process.steps().iterator(); i.hasNext();) {
223: sleepAct = (WfActivity) i.next();
224: if (sleepAct.name().equals("Wait")) {
225: break;
226: }
227: }
228: process.start();
229: assertTrue(stateReached(sleepAct, "open.running"));
230: Map pd = chan.receiveMessage();
231: assertTrue("Hello world!".equals(pd.get("message")));
232: assertTrue(stateReached(process, "closed.completed"));
233: procDir.removeProcess(process);
234: } finally {
235: workflowService.release(chan);
236: workflowService.release(procDefDir);
237: workflowService.release(procDir);
238: }
239: }
240:
241: /**
242: * Test.
243: */
244: public void sendMessageAfter() throws Exception {
245: ProcessDefinitionDirectory procDefDir = null;
246: ProcessDirectory procDir = null;
247: Channel chan = null;
248: try {
249: procDefDir = workflowService.processDefinitionDirectory();
250: procDir = workflowService.processDirectory();
251: ProcessMgr pmgr = procDefDir.processMgr("chabacc",
252: "chabacc_test_receiver");
253: WfProcess process = pmgr
254: .createProcess(new DefaultRequester(workflowService));
255: chan = workflowService.getChannel(process, "test_channel");
256: WfActivity recAct = null;
257: for (Iterator i = process.steps().iterator(); i.hasNext();) {
258: recAct = (WfActivity) i.next();
259: if (recAct.name().equals("Receive")) {
260: break;
261: }
262: }
263: assertTrue(recAct != null);
264: process.start();
265: assertTrue(stateReached(recAct, "open.running"));
266: Thread.sleep(500);
267: Map pd = new HashMap();
268: pd.put("message", "Hello world!");
269: chan.sendMessage(pd);
270: assertTrue(stateReached(recAct, "closed.completed"));
271: pd = process.processContext();
272: assertTrue("Hello world!".equals(pd.get("lastMessage")));
273: assertTrue(stateReached(process, "closed.completed"));
274: procDir.removeProcess(process);
275: } finally {
276: workflowService.release(chan);
277: workflowService.release(procDefDir);
278: workflowService.release(procDir);
279: }
280: }
281:
282: /**
283: * Test.
284: */
285: public void sendMessageBefore() throws Exception {
286: ProcessDefinitionDirectory procDefDir = null;
287: ProcessDirectory procDir = null;
288: Channel chan = null;
289: try {
290: procDefDir = workflowService.processDefinitionDirectory();
291: procDir = workflowService.processDirectory();
292: ProcessMgr pmgr = procDefDir.processMgr("chabacc",
293: "chabacc_test_receiver");
294: WfProcess process = pmgr
295: .createProcess(new DefaultRequester(workflowService));
296: chan = workflowService.getChannel(process, "test_channel");
297: Map pd = new HashMap();
298: pd.put("message", "Hello world!");
299: chan.sendMessage(pd);
300: Thread.sleep(500);
301: process.start();
302: assertTrue(stateReached(process, "closed.completed"));
303: pd = process.processContext();
304: assertTrue("Hello world!".equals(pd.get("lastMessage")));
305: procDir.removeProcess(process);
306: } finally {
307: workflowService.release(chan);
308: workflowService.release(procDefDir);
309: workflowService.release(procDir);
310: }
311: }
312:
313: /**
314: * Test.
315: */
316: public void sendXMLMessage() throws Exception {
317: ProcessDefinitionDirectory procDefDir = null;
318: ProcessDirectory procDir = null;
319: Channel chan = null;
320: try {
321: procDefDir = workflowService.processDefinitionDirectory();
322: procDir = workflowService.processDirectory();
323: ProcessMgr pmgr = procDefDir.processMgr("chabacc",
324: "chabacc_test_xml_receiver");
325: WfProcess process = pmgr
326: .createProcess(new DefaultRequester(workflowService));
327: chan = workflowService.getChannel(process, "test_channel");
328: DocumentBuilderFactory df = DocumentBuilderFactory
329: .newInstance();
330: Document doc = df.newDocumentBuilder().newDocument();
331: DocumentFragment frag = doc.createDocumentFragment();
332: frag.appendChild(doc.createElement("root"));
333: TransformerFactory tf = TransformerFactory.newInstance();
334: Transformer t = tf.newTransformer();
335: SAXEventBufferImpl b = new SAXEventBufferImpl();
336: t.transform(new DOMSource(frag), new SAXResult(b));
337: b.pack();
338: Map pd = new HashMap();
339: pd.put("message", b);
340: chan.sendMessage(pd);
341: Thread.sleep(500);
342: process.start();
343: assertTrue(stateReached(process, "closed.completed"));
344: pd = process.processContext();
345: Object o = pd.get("lastXMLMessage");
346: assertTrue(o != null);
347: assertTrue(o instanceof SAXContentBuffer);
348: Node recDoc = ((SAXContentBuffer) o).toW3cDom();
349: assertTrue(recDoc instanceof Document);
350: assertTrue(((Document) recDoc).getDocumentElement()
351: .getLocalName().equals("root"));
352: procDir.removeProcess(process);
353: } finally {
354: workflowService.release(chan);
355: workflowService.release(procDefDir);
356: workflowService.release(procDir);
357: }
358: }
359:
360: /**
361: * Test.
362: */
363: public void sendSelf() throws Exception {
364: ProcessDefinitionDirectory procDefDir = null;
365: ProcessDirectory procDir = null;
366: try {
367: procDefDir = workflowService.processDefinitionDirectory();
368: procDir = workflowService.processDirectory();
369: ProcessMgr pmgr = procDefDir.processMgr("chabacc",
370: "chabacc_test_send_self");
371: WfProcess process = pmgr
372: .createProcess(new DefaultRequester(workflowService));
373: process.start();
374: assertTrue(stateReached(process, "closed.completed"));
375: ProcessData pd = process.processContext();
376: assertTrue("Hello world!".equals(pd.get("lastMessage")));
377: procDir.removeProcess(process);
378: } finally {
379: workflowService.release(procDefDir);
380: workflowService.release(procDir);
381: }
382: }
383:
384: /**
385: * Test.
386: */
387: public void echo() throws Exception {
388: ProcessDefinitionDirectory procDefDir = null;
389: ProcessDirectory procDir = null;
390: Channel chan = null;
391: try {
392: procDefDir = workflowService.processDefinitionDirectory();
393: procDir = workflowService.processDirectory();
394: ProcessMgr pmgr = procDefDir.processMgr("chabacc",
395: "chabacc_test_rec_send");
396: WfProcess process = pmgr
397: .createProcess(new DefaultRequester(workflowService));
398: chan = workflowService.getChannel(process, "test_channel");
399: Map pd = new HashMap();
400: pd.put("message", "Do you echo?");
401: chan.sendMessage(pd);
402: process.start();
403: pd = chan.receiveMessage();
404: assertTrue("Got: " + pd.get("message"), "Do you echo?"
405: .equals(pd.get("message")));
406: assertTrue(stateReached(process, "closed.completed"));
407: procDir.removeProcess(process);
408: } finally {
409: workflowService.release(chan);
410: workflowService.release(procDefDir);
411: workflowService.release(procDir);
412: }
413: }
414:
415: /**
416: * Test.
417: */
418: public void echoIndirect() throws Exception {
419: ProcessDefinitionDirectory procDefDir = null;
420: ProcessDirectory procDir = null;
421: Channel chan = null;
422: try {
423: procDefDir = workflowService.processDefinitionDirectory();
424: procDir = workflowService.processDirectory();
425: ProcessMgr pmgr = procDefDir.processMgr("chabacc",
426: "chabacc_test_rec_send_indirect");
427: WfProcess process = pmgr
428: .createProcess(new DefaultRequester(workflowService));
429: chan = workflowService.getChannel(process, "test_channel");
430: Map pd = new HashMap();
431: pd.put("message", "Do you echo?");
432: chan.sendMessage(pd);
433: process.start();
434: pd = chan.receiveMessage();
435: assertTrue("Got: " + pd.get("message"), "Do you echo?"
436: .equals(pd.get("message")));
437: assertTrue(stateReached(process, "closed.completed"));
438: pd = process.processContext();
439: assertTrue(pd.get("feedback").equals("Got message"));
440: // cleanup
441: Iterator acts = process.activitiesInState("closed")
442: .iterator();
443: assertTrue(acts.hasNext());
444: Activity act = null;
445: while (true) {
446: act = (Activity) acts.next();
447: if (act.name().equals("Run subflow")) {
448: break;
449: }
450: }
451: Iterator subs = act.performers().iterator();
452: assertTrue(subs.hasNext());
453: Process sub = (Process) subs.next();
454: procDir.removeProcess(sub);
455: procDir.removeProcess(process);
456: } finally {
457: workflowService.release(chan);
458: workflowService.release(procDefDir);
459: workflowService.release(procDir);
460: }
461: }
462:
463: /**
464: * Test.
465: */
466: public void closeNotification() throws Exception {
467: ProcessDefinitionDirectory procDefDir = null;
468: ProcessDirectory procDir = null;
469: Channel chan = null;
470: try {
471: procDefDir = workflowService.processDefinitionDirectory();
472: procDir = workflowService.processDirectory();
473: ProcessMgr pmgr = procDefDir.processMgr("chabacc",
474: "chabacc_test_close_notification");
475: WfProcess process = pmgr
476: .createProcess(new DefaultRequester(workflowService));
477: chan = workflowService.getChannel(process, "test_channel");
478: process.start();
479: Map pd = chan.receiveMessage();
480: assertTrue(pd == null);
481: assertTrue(stateReached(process, "closed.completed"));
482: procDir.removeProcess(process);
483: } finally {
484: workflowService.release(chan);
485: workflowService.release(procDefDir);
486: workflowService.release(procDir);
487: }
488: }
489:
490: /**
491: * Test.
492: */
493: public void testInEJB() throws Exception {
494: de.danet.an.wfdemo.testejb.Test test = (de.danet.an.wfdemo.testejb.Test) EJBUtil
495: .createSession(
496: de.danet.an.wfdemo.testejb.TestHome.class,
497: "ejb/WfMOpenTestEJB");
498: Map pd = test.startAndWait();
499: assertTrue("Hello world!".equals(pd.get("message")));
500: }
501:
502: /**
503: * Test.
504: */
505: public void testInEJBWithTimeout() throws Exception {
506: de.danet.an.wfdemo.testejb.Test test = (de.danet.an.wfdemo.testejb.Test) EJBUtil
507: .createSession(
508: de.danet.an.wfdemo.testejb.TestHome.class,
509: "ejb/WfMOpenTestEJB");
510: Map pd = test.startAndWait(1000);
511: assertTrue("Hello world!".equals(pd.get("message")));
512: }
513:
514: private WfProcess createProcess(String pkgId, String prcId,
515: WfRequester req) throws Exception {
516: ProcessDefinitionDirectory procDir = null;
517: try {
518: procDir = workflowService.processDefinitionDirectory();
519: ProcessMgr pmgr = procDir.processMgr(pkgId, prcId);
520: return pmgr.createProcess(req);
521: } finally {
522: workflowService.release(procDir);
523: }
524: }
525:
526: private boolean stateReached(WfProcess proc, String procState)
527: throws Exception {
528: boolean test = true;
529: boolean stateReached = false;
530: int maxRetries = 100;
531: while (test) {
532: if (maxRetries-- > 0) {
533: if (proc.state().startsWith(procState)) {
534: stateReached = true;
535: test = false;
536: } else {
537: Thread.sleep(500);
538: }
539: } else {
540: test = false;
541: }
542: }
543: return stateReached;
544: }
545:
546: private boolean stateReached(WfActivity act, String actState)
547: throws Exception {
548: boolean test = true;
549: boolean stateReached = false;
550: int maxRetries = 100;
551: while (test) {
552: if (maxRetries-- > 0) {
553: if (act.state().startsWith(actState)) {
554: stateReached = true;
555: test = false;
556: } else {
557: Thread.sleep(500);
558: }
559: } else {
560: test = false;
561: }
562: }
563: return stateReached;
564: }
565: }
|