001: /*
002: * This file is part of the WfMOpen project.
003: * Copyright (C) 2001-2005 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: Instance.java,v 1.13 2007/07/15 22:01:39 mlipp Exp $
021: *
022: * $Log: Instance.java,v $
023: * Revision 1.13 2007/07/15 22:01:39 mlipp
024: * Added test case.
025: *
026: * Revision 1.12 2007/03/29 11:45:41 schnelle
027: * Code cleanup.
028: *
029: * Revision 1.11 2007/03/27 21:59:42 mlipp
030: * Fixed lots of checkstyle warnings.
031: *
032: * Revision 1.10 2007/03/01 12:29:30 schnelle
033: * Enhanced Instance.SetProperties to process ContextData.
034: *
035: * Revision 1.9 2007/02/02 08:18:29 schnelle
036: * Prepared tests with an Umlaut.
037: *
038: * Revision 1.8 2007/02/01 13:45:37 schnelle
039: * Using namespace for factory schemas that do not contain '&'.
040: *
041: * Revision 1.7 2007/02/01 12:39:13 schnelle
042: * Use of receiver toool to keep the first activity running.
043: *
044: * Revision 1.6 2007/02/01 08:49:23 drmlipp
045: * Fixed.
046: *
047: * Revision 1.5 2007/01/31 15:13:20 schnelle
048: * Unified method to create the base url.
049: *
050: * Revision 1.4 2007/01/31 13:39:45 schnelle
051: * Implemented setUp of test cases.
052: *
053: * Revision 1.3 2007/01/31 10:57:36 schnelle
054: * Adapted to change in receiver key.
055: *
056: * Revision 1.2 2007/01/30 11:56:16 drmlipp
057: * Merged Wf-XML branch.
058: *
059: * Revision 1.1.2.4 2007/01/10 14:17:21 schnelle
060: * Implemented unsubscribe.
061: *
062: * Revision 1.1.2.3 2006/12/20 14:38:33 schnelle
063: * Implemented Factory GetDefinition.
064: *
065: * Revision 1.1.2.2 2006/12/14 08:51:05 schnelle
066: * Implemented CompleteActivity.
067: *
068: * Revision 1.1.2.1 2006/12/12 09:35:19 schnelle
069: * Implemented ChangeState for Instance.
070: *
071: * Revision 1.1.2.2 2006/12/11 12:22:31 schnelle
072: * Support of process creation with a later start.
073: *
074: * Revision 1.1.2.1 2006/12/01 15:31:28 schnelle
075: * Separation of test cases dependend on the role.
076: *
077: * Revision 1.4.6.7 2006/12/01 14:18:00 schnelle
078: * Added support for schema type for data in create process
079: *
080: * Revision 1.4.6.6 2006/12/01 12:50:11 schnelle
081: * Basic import of context data for process creation.
082: *
083: * Revision 1.4.6.5 2006/11/30 12:45:20 schnelle
084: * Basic implementation of Factory CreateInstance.
085: *
086: * Revision 1.4.6.4 2006/11/30 10:38:21 schnelle
087: * Implementation of Factory ListInstance.
088: *
089: * Revision 1.4.6.3 2006/11/29 14:13:03 schnelle
090: * Take respect to namespaces of asap requests and responses.
091: *
092: * Revision 1.4.6.2 2006/11/29 11:05:40 schnelle
093: * Full implementation of the request and response headers.
094: *
095: * Revision 1.4.6.1 2006/11/28 15:32:35 schnelle
096: * Proper selection of the response generator.
097: *
098: * Revision 1.4 2006/09/29 12:32:11 drmlipp
099: * Consistently using WfMOpen as projct name now.
100: *
101: * Revision 1.3 2005/01/24 21:11:39 mlipp
102: * Extended.
103: *
104: * Revision 1.2 2005/01/24 20:26:01 mlipp
105: * Reverted saaj back to 1.1 to fit Axis version.
106: *
107: * Revision 1.1 2005/01/23 21:44:23 mlipp
108: * Initial version.
109: *
110: */
111: package wfxml;
112:
113: import java.io.IOException;
114: import java.io.OutputStream;
115: import java.util.Enumeration;
116: import java.util.Iterator;
117: import java.util.StringTokenizer;
118:
119: import javax.servlet.GenericServlet;
120: import javax.servlet.ServletConfig;
121: import javax.servlet.ServletException;
122: import javax.servlet.http.HttpServlet;
123: import javax.servlet.http.HttpServletRequest;
124: import javax.servlet.http.HttpServletResponse;
125: import javax.xml.soap.MessageFactory;
126: import javax.xml.soap.MimeHeaders;
127: import javax.xml.soap.Name;
128: import javax.xml.soap.SOAPBodyElement;
129: import javax.xml.soap.SOAPElement;
130: import javax.xml.soap.SOAPException;
131: import javax.xml.soap.SOAPMessage;
132:
133: import org.apache.xmlrpc.webserver.ServletWebServer;
134:
135: import junit.framework.Test;
136: import junit.framework.TestCase;
137: import junit.framework.TestSuite;
138: import de.danet.an.util.XMLUtil;
139:
140: /**
141: * Test WfXML Instance resource.
142: * @author Dirk Schnelle
143: * @author Michael Lipp
144: */
145: public class Instance extends TestCase {
146: /** The factory resource. */
147: private String instance;
148:
149: private String timestamp;
150:
151: /**
152: * Constructor of this TestCase.
153: * @param name name of this test case.
154: */
155: public Instance(String name) {
156: super (name);
157: }
158:
159: /**
160: * Creates this test suite.
161: * @return created test suite.
162: */
163: public static Test suite() {
164: TestSuite suite = new TestSuite();
165: suite.addTest(new Instance("listActivities"));
166: suite.addTest(new Instance("getProperties"));
167: suite.addTest(new Instance("setProperties"));
168: suite.addTest(new Instance("subscribe"));
169: suite.addTest(new Instance("unsubscribe"));
170: suite.addTest(new Instance("changeState"));
171: suite.addTest(new Instance("receiveEvent"));
172:
173: return suite;
174: }
175:
176: /* (non-Javadoc)
177: * @see junit.framework.TestCase#setUp()
178: */
179: protected void setUp() throws Exception {
180: timestamp = XMLUtil.toXsdLocalDateTime(new java.util.Date());
181:
182: String sender = Factory.class.getName() + "/setUp";
183: String id = "43";
184:
185: ServiceRegistry.importDefinition(sender, id);
186: String factory = ServiceRegistry.getTestProcessFactory();
187: instance = Factory.startTestProcess(factory,
188: "wfxmltest instance " + timestamp);
189:
190: super .setUp();
191: }
192:
193: /**
194: * Test Factory ListInstances.
195: * @exception Exception
196: * Test failed.
197: */
198: public void changeState() throws Exception {
199: String sender = Instance.class.getName() + "/changeState";
200: String id = "instance42";
201:
202: SOAPMessage message = Basic.createMessage();
203: Basic.fillRequestHeadet(message, instance, sender, id);
204: SOAPElement action = Basic.createActionElement(message,
205: "ChangeStateRq");
206:
207: SOAPElement name = action.addChildElement("State", "as");
208: String requestedState = "open.notrunning.suspended";
209: name.addTextNode(requestedState);
210:
211: SOAPMessage response = Basic.call(message);
212:
213: Basic.checkNoFault(response);
214:
215: assertEquals(sender, Basic.getHeaderValue(response,
216: "ReceiverKey"));
217: assertEquals(instance, Basic.getHeaderValue(response,
218: "SenderKey"));
219: assertEquals(id, Basic.getHeaderValue(response, "RequestID"));
220:
221: SOAPBodyElement responseNode = Basic
222: .getFirstBodyElement(response);
223: Name answerName = responseNode.getElementName();
224: assertEquals(Basic.ASAP_NS, answerName.getURI());
225: assertEquals("ChangeStateRs", answerName.getLocalName());
226: Iterator processIterator = responseNode.getChildElements();
227: assertTrue(processIterator.hasNext());
228: SOAPElement child = (SOAPElement) processIterator.next();
229: Name stateName = child.getElementName();
230: assertEquals("as", stateName.getPrefix());
231: assertEquals("State", stateName.getLocalName());
232:
233: String newState = XMLUtil.getFirstLevelTextContent(child);
234: assertEquals(requestedState, newState);
235: }
236:
237: /**
238: * Test Factory ListInstances.
239: * @exception Exception
240: * Test failed.
241: */
242: public void listActivities() throws Exception {
243: String sender = Instance.class.getName() + "/listActivities";
244: String id = "instance43";
245:
246: SOAPMessage message = Basic.createMessage();
247: Basic.fillRequestHeadet(message, instance, sender, id);
248: Basic.createActionElement(message, "ListActivitiesRq");
249:
250: SOAPMessage response = Basic.call(message);
251:
252: Basic.checkNoFault(response);
253:
254: assertEquals(sender, Basic.getHeaderValue(response,
255: "ReceiverKey"));
256: assertEquals(instance, Basic.getHeaderValue(response,
257: "SenderKey"));
258: assertEquals(id, Basic.getHeaderValue(response, "RequestID"));
259:
260: SOAPBodyElement activitylist = Basic
261: .getFirstBodyElement(response);
262: Name answerName = activitylist.getElementName();
263: assertEquals(Basic.WFXML_NS, answerName.getURI());
264: assertEquals("ListActivitiesRs", answerName.getLocalName());
265: for (Iterator activityIterator = activitylist
266: .getChildElements(); activityIterator.hasNext();) {
267:
268: SOAPElement child = (SOAPElement) activityIterator.next();
269: Name childName = child.getElementName();
270: assertEquals("wfxml", childName.getPrefix());
271: assertEquals("ActivityInfo", childName.getLocalName());
272:
273: String activityKey = Basic.getChildTextContent(child,
274: "ActivityKey");
275: assertFalse(activityKey.equals(""));
276: }
277: }
278:
279: /**
280: * Test Instance getProperties.
281: * @exception Exception
282: * Test failed.
283: */
284: public void getProperties() throws Exception {
285: String sender = Instance.class.getName() + "/getProperties";
286: String id = "instance44";
287:
288: SOAPMessage message = Basic.createMessage();
289: Basic.fillRequestHeadet(message, instance, sender, id);
290: Basic.createActionElement(message, "GetPropertiesRq");
291:
292: SOAPMessage response = Basic.call(message);
293:
294: Basic.checkNoFault(response);
295:
296: assertEquals(sender, Basic.getHeaderValue(response,
297: "ReceiverKey"));
298: assertEquals(instance, Basic.getHeaderValue(response,
299: "SenderKey"));
300: assertEquals(id, Basic.getHeaderValue(response, "RequestID"));
301:
302: SOAPBodyElement processlist = Basic
303: .getFirstBodyElement(response);
304: Name answerName = processlist.getElementName();
305: assertEquals(Basic.ASAP_NS, answerName.getURI());
306: assertEquals("GetPropertiesRs", answerName.getLocalName());
307: }
308:
309: /**
310: * Test Instance setProperties.
311: * @exception Exception
312: * Test failed.
313: */
314: public void setProperties() throws Exception {
315: String sender = Instance.class.getName() + "/getProperties";
316: String id = "instance45";
317:
318: SOAPMessage message = Basic.createMessage();
319: Basic.fillRequestHeadet(message, instance, sender, id);
320: SOAPElement action = Basic.createActionElement(message,
321: "SetPropertiesRq");
322:
323: SOAPElement cd = action.addChildElement("Data", "as");
324: cd.addNamespaceDeclaration("pd",
325: "http://localhost:8080/wfxml/dummy-pd.xsd");
326:
327: SOAPElement stringdata = cd.addChildElement(
328: "newpkg_wp1_string", "pd");
329: stringdata.addTextNode("text content " + timestamp);
330: SOAPElement intdata = cd.addChildElement("newpkg_wp1_integer",
331: "pd");
332: intdata.addTextNode("45");
333: SOAPElement floatdata = cd.addChildElement("newpkg_wp1_float",
334: "pd");
335: floatdata.addTextNode("45.45");
336: SOAPElement booldata = cd.addChildElement("newpkg_wp1_boolean",
337: "pd");
338: booldata.addTextNode("true");
339: SOAPElement datedata = cd.addChildElement("newpkg_wp1_date",
340: "pd");
341: datedata.addTextNode(timestamp);
342: SOAPElement schemadata = cd.addChildElement(
343: "newpkg_wp1_schema", "pd");
344: SOAPElement order = schemadata.addChildElement("order");
345: order.setAttribute("id", "08/17");
346: SOAPElement position1 = order.addChildElement("position");
347: position1.setAttribute("pos", "3");
348: SOAPElement position2 = order.addChildElement("position");
349: position2.setAttribute("pos", "4");
350:
351: SOAPMessage response = Basic.call(message);
352:
353: Basic.checkNoFault(response);
354:
355: assertEquals(sender, Basic.getHeaderValue(response,
356: "ReceiverKey"));
357: assertEquals(instance, Basic.getHeaderValue(response,
358: "SenderKey"));
359: assertEquals(id, Basic.getHeaderValue(response, "RequestID"));
360:
361: SOAPBodyElement processlist = Basic
362: .getFirstBodyElement(response);
363: Name answerName = processlist.getElementName();
364: assertEquals(Basic.ASAP_NS, answerName.getURI());
365: assertEquals("SetPropertiesRs", answerName.getLocalName());
366: }
367:
368: /**
369: * Test Instance subscribe.
370: * @exception Exception
371: * Test failed.
372: */
373: public void subscribe() throws Exception {
374: String sender = Instance.class.getName() + "/subscribe";
375: String id = "instance46";
376:
377: SOAPMessage message = Basic.createMessage();
378: Basic.fillRequestHeadet(message, instance, sender, id);
379: SOAPElement action = Basic.createActionElement(message,
380: "SubscribeRq");
381:
382: SOAPElement observer = action.addChildElement("ObserverKey",
383: "as");
384: observer.addTextNode(sender);
385:
386: SOAPMessage response = Basic.call(message);
387:
388: Basic.checkNoFault(response);
389:
390: assertEquals(sender, Basic.getHeaderValue(response,
391: "ReceiverKey"));
392: assertEquals(instance, Basic.getHeaderValue(response,
393: "SenderKey"));
394: assertEquals(id, Basic.getHeaderValue(response, "RequestID"));
395:
396: SOAPBodyElement processlist = Basic
397: .getFirstBodyElement(response);
398: Name answerName = processlist.getElementName();
399: assertEquals(Basic.ASAP_NS, answerName.getURI());
400: assertEquals("SubscribeRs", answerName.getLocalName());
401: }
402:
403: /**
404: * Test Instance unsubscribe.
405: * @exception Exception
406: * Test failed.
407: */
408: public void unsubscribe() throws Exception {
409: String sender = Instance.class.getName() + "/unsubscribe";
410: String id = "instance46";
411:
412: SOAPMessage message = Basic.createMessage();
413: Basic.fillRequestHeadet(message, instance, sender, id);
414: SOAPElement action = Basic.createActionElement(message,
415: "UnsubscribeRq");
416:
417: SOAPElement observer = action.addChildElement("ObserverKey",
418: "as");
419: observer.addTextNode(Instance.class.getName() + "/subscribe");
420:
421: SOAPMessage response = Basic.call(message);
422:
423: Basic.checkNoFault(response);
424:
425: assertEquals(sender, Basic.getHeaderValue(response,
426: "ReceiverKey"));
427: assertEquals(instance, Basic.getHeaderValue(response,
428: "SenderKey"));
429: assertEquals(id, Basic.getHeaderValue(response, "RequestID"));
430:
431: SOAPBodyElement processlist = Basic
432: .getFirstBodyElement(response);
433: Name answerName = processlist.getElementName();
434: assertEquals(Basic.ASAP_NS, answerName.getURI());
435: assertEquals("UnsubscribeRs", answerName.getLocalName());
436: }
437:
438: /**
439: * Receive an event
440: */
441: public void receiveEvent() throws Exception {
442: EventReceiver evtRec = new EventReceiver();
443: ServletWebServer server = new ServletWebServer(evtRec, 18080);
444: server.start();
445: try {
446: String instanceKey = createProcess();
447: subscribeToProcess(instanceKey, "http://localhost:18080");
448: startProcess(instanceKey);
449: for (int i = 15; i > 0; i--) {
450: if (evtRec.isCalled()) {
451: break;
452: }
453: Thread.sleep(1000);
454: }
455: assertTrue(evtRec.isCalled());
456: } finally {
457: server.shutdown();
458: }
459: }
460:
461: public class EventReceiver extends HttpServlet {
462: private boolean called = false;
463:
464: /* (non-Javadoc)
465: * Comment copied from interface or superclass.
466: */
467: public void init(ServletConfig arg0) throws ServletException {
468: }
469:
470: /* (non-Javadoc)
471: * Comment copied from interface or superclass.
472: */
473: protected void doPost(HttpServletRequest request,
474: HttpServletResponse response) throws ServletException,
475: IOException {
476: MessageFactory messageFactory = null;
477: try {
478: messageFactory = MessageFactory.newInstance();
479: } catch (SOAPException e) {
480: response.sendError(
481: HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
482: "Unable to access SOAP subsystem: "
483: + e.getMessage());
484: return;
485: }
486:
487: SOAPMessage respMsg = null;
488: MimeHeaders mimeHeaders = new MimeHeaders();
489: for (Enumeration en = request.getHeaderNames(); en
490: .hasMoreElements();) {
491: String headerName = (String) en.nextElement();
492: String headerVal = request.getHeader(headerName);
493: StringTokenizer tk = new StringTokenizer(headerVal, ",");
494: while (tk.hasMoreTokens()) {
495: mimeHeaders.addHeader(headerName, tk.nextToken()
496: .trim());
497: }
498: }
499:
500: // build request message from headers and stream
501: try {
502: SOAPMessage reqMsg = messageFactory.createMessage(
503: mimeHeaders, request.getInputStream());
504: respMsg = messageFactory.createMessage();
505: OutputStream os = response.getOutputStream();
506: respMsg.writeTo(os);
507: os.flush();
508: } catch (SOAPException e) {
509: throw new ServletException(e);
510: }
511:
512: called = true;
513: }
514:
515: /**
516: * @return Returns the called.
517: */
518: public boolean isCalled() {
519: return called;
520: }
521: }
522:
523: private String createProcess() throws Exception {
524: String factory = ServiceRegistry.getTestProcessFactory();
525: String sender = Factory.class.getName() + "/createProcInstance";
526: String id = "43";
527:
528: SOAPMessage message = Basic.createMessage();
529: Basic.fillRequestHeadet(message, factory, sender, id);
530: SOAPElement action = Basic.createActionElement(message,
531: "CreateInstanceRq");
532: SOAPElement start = action.addChildElement("StartImmediately",
533: "as");
534: start.addTextNode("NO");
535:
536: SOAPElement cd = action.addChildElement("ContextData", "as");
537: cd.addNamespaceDeclaration("pd",
538: "http://localhost:8080/wfxml/dummy-pd.xsd");
539:
540: SOAPElement name = action.addChildElement("Name", "as");
541: name.addTextNode("wfxmltest factory " + timestamp);
542: SOAPElement stringdata = cd.addChildElement(
543: "newpkg_wp1_string", "pd");
544: stringdata.addTextNode("text content " + timestamp);
545: SOAPElement intdata = cd.addChildElement("newpkg_wp1_integer",
546: "pd");
547: intdata.addTextNode("43");
548: SOAPElement floatdata = cd.addChildElement("newpkg_wp1_float",
549: "pd");
550: floatdata.addTextNode("43.43");
551: SOAPElement booldata = cd.addChildElement("newpkg_wp1_boolean",
552: "pd");
553: booldata.addTextNode("true");
554: SOAPElement datedata = cd.addChildElement("newpkg_wp1_date",
555: "pd");
556: datedata.addTextNode(timestamp);
557: SOAPElement schemadata = cd.addChildElement(
558: "newpkg_wp1_schema", "pd");
559: SOAPElement order = schemadata.addChildElement("order");
560: order.setAttribute("id", "08/16");
561: SOAPElement position1 = order.addChildElement("position");
562: position1.setAttribute("pos", "1");
563: SOAPElement position2 = order.addChildElement("position");
564: position2.setAttribute("pos", "2");
565:
566: SOAPMessage response = Basic.call(message);
567:
568: Basic.checkNoFault(response);
569:
570: SOAPBodyElement processlist = Basic
571: .getFirstBodyElement(response);
572: Name answerName = processlist.getElementName();
573: Iterator processIterator = processlist.getChildElements();
574: SOAPElement child = (SOAPElement) processIterator.next();
575: Name childName = child.getElementName();
576:
577: return XMLUtil.getFirstLevelTextContent(child);
578: }
579:
580: public void subscribeToProcess(String instance, String obsEPR)
581: throws Exception {
582: String sender = Instance.class.getName() + "/subscribe";
583: String id = "instance46";
584:
585: SOAPMessage message = Basic.createMessage();
586: Basic.fillRequestHeadet(message, instance, sender, id);
587: SOAPElement action = Basic.createActionElement(message,
588: "SubscribeRq");
589:
590: SOAPElement observer = action.addChildElement("ObserverKey",
591: "as");
592: observer.addTextNode(obsEPR);
593:
594: SOAPMessage response = Basic.call(message);
595:
596: Basic.checkNoFault(response);
597: }
598:
599: public void startProcess(String instance) throws Exception {
600: String sender = Instance.class.getName() + "/changeState";
601: String id = "instance42";
602:
603: SOAPMessage message = Basic.createMessage();
604: Basic.fillRequestHeadet(message, instance, sender, id);
605: SOAPElement action = Basic.createActionElement(message,
606: "ChangeStateRq");
607:
608: SOAPElement name = action.addChildElement("State", "as");
609: String requestedState = "open.running";
610: name.addTextNode(requestedState);
611:
612: SOAPMessage response = Basic.call(message);
613:
614: Basic.checkNoFault(response);
615: }
616:
617: /**
618: * retrieves the first activity of the given process instance.
619: * @param testInstance the instance
620: * @return key of the first activity.
621: * @throws SOAPException
622: * Error in the SOAP message.
623: */
624: static String getFirstActivity(String testInstance)
625: throws SOAPException {
626: String sender = Instance.class.getName() + "/getFirstActivity";
627: String id = "instance43";
628:
629: SOAPMessage message = Basic.createMessage();
630: Basic.fillRequestHeadet(message, testInstance, sender, id);
631: Basic.createActionElement(message, "ListActivitiesRq");
632:
633: SOAPMessage response = Basic.call(message);
634:
635: SOAPBodyElement activitylist = Basic
636: .getFirstBodyElement(response);
637: Iterator activityIterator = activitylist.getChildElements();
638: SOAPElement child = (SOAPElement) activityIterator.next();
639:
640: return Basic.getChildTextContent(child, "ActivityKey");
641: }
642: }
|