1   /*
2    * $Id: ManagerTest.java,v 1.1 2004/12/15 14:18:22 patforna Exp $
3    *
4    * Copyright (c) 2004 Patric Fornasier, Pawel Kowalski
5    * Berne University of Applied Sciences
6    * School of Engineering and Information Technology
7    * All rights reserved.
8    */
9   package bexee.admin;
10  
11  import java.io.ByteArrayInputStream;
12  import java.io.File;
13  import java.io.FileOutputStream;
14  import java.io.InputStream;
15  import java.io.OutputStream;
16  import java.io.PrintWriter;
17  import java.net.URL;
18  
19  import javax.wsdl.Definition;
20  
21  import junit.framework.TestCase;
22  
23  import org.apache.axis.AxisFault;
24  import org.apache.axis.client.Call;
25  import org.apache.axis.configuration.XMLStringProvider;
26  import org.apache.axis.description.ServiceDesc;
27  import org.apache.axis.handlers.soap.SOAPService;
28  import org.apache.axis.server.AxisServer;
29  import org.apache.axis.transport.local.LocalTransport;
30  import org.apache.axis.utils.XMLUtils;
31  import org.apache.commons.logging.Log;
32  import org.apache.commons.logging.LogFactory;
33  import org.w3c.dom.Document;
34  
35  import bexee.dao.BPELProcessDAO;
36  import bexee.dao.DAOFactory;
37  import bexee.model.process.BPELProcess;
38  
39  /***
40   * This is a test class for both {@link bexee.admin.Admin}and
41   * {@link bexee.admin.Manager}.
42   * <p>
43   * The reason why both classes are tested in one test class is because
44   * <code>Manager</code> has to be invoked as a web service and thus we need to
45   * create a web service call which we do with the help of <code>Admin</code>.
46   * <p>
47   * The wsdl and bpel xml string contain only the very information necessary to
48   * perform the tests. As the <code>Manager</code> logic evolves we may need to
49   * extend the wsdl and bpel xml documents to more sophisticated versions.
50   * 
51   * @version $Revision: 1.1 $, $Date: 2004/12/15 14:18:22 $
52   * @author Patric Fornasier
53   */
54  public class ManagerTest extends TestCase {
55  
56      private static Log log = LogFactory.getLog(ManagerTest.class);
57  
58      // the web service deployment descriptor for axis
59      private static final String DEPLOY_DOC = ""
60              + "<deployment xmlns=\"http://xml.apache.org/axis/wsdd/\" "
61              + "    xmlns:java=\"http://xml.apache.org/axis/wsdd/providers/java\">"
62              + "  <service name=\"Manager\" provider=\"java:RPC\">"
63              + "    <parameter name=\"allowedMethods\" value=\"*\"/>"
64              + "    <parameter name=\"className\" value=\"bexee.admin.Manager\"/>"
65              + "  </service>" + "</deployment>";
66  
67      // the BPEL process document
68      private static final String BPEL_DOC = ""
69              + "<process name=\"TravelProcess\""
70              + "  targetNamespace=\"http://bexee.sourceforge.net/Travel\""
71              + "  suppressJoinFailure=\"yes\" xmlns:tns=\"http://bexee.sourceforge.net/Travel\""
72              + "  xmlns=\"http://schemas.xmlsoap.org/ws/2003/03/business-process/\""
73              + "  xmlns:services=\"http://bexee.sourceforge.net/Travel\""
74              + "  xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">"
75              + "  <partnerLinks>"
76              + "    <partnerLink name=\"client\""
77              + "      partnerLinkType=\"tns:BookTravel\" myRole=\"TravelProvider\"/>"
78              + "    <partnerLink name=\"HotelOfferService\""
79              + "      partnerLinkType=\"services:OfferTravelPLT\" partnerRole=\"OfferProvider\"/>"
80              + "    <partnerLink name=\"FlightOfferService\""
81              + "      partnerLinkType=\"services:OfferTravelPLT\" partnerRole=\"OfferProvider\"/>"
82              + "    <partnerLink name=\"HotelBookingService\""
83              + "      partnerLinkType=\"services:BookTravelPLT\" partnerRole=\"BookProvider\"/>"
84              + "    <partnerLink name=\"FlightBookingService\""
85              + "      partnerLinkType=\"services:BookTravelPLT\" partnerRole=\"BookProvider\"/>"
86              + "  </partnerLinks>"
87              + "  <variables>"
88              + "    <variable name=\"userName\" messageType=\"tns:TravelServiceRequestMessage\"/>"
89              + "    <variable name=\"response\" messageType=\"tns:TravelServiceResponseMessage\"/>"
90              + "    <variable name=\"offerRequest\" messageType=\"tns:getOfferRequest\"/>"
91              + "    <variable name=\"bookRequest\" messageType=\"tns:bookRequest\"/>"
92              + "    <variable name=\"hotelOffer\" messageType=\"tns:getOfferResponse\"/>"
93              + "    <variable name=\"flightOffer\" messageType=\"tns:getOfferResponse\"/>"
94              + "    <variable name=\"hotelBooking\" messageType=\"tns:bookResponse\"/>"
95              + "    <variable name=\"flightBooking\" messageType=\"tns:bookResponse\"/>"
96              + "  </variables>"
97              + "  <sequence name=\"root-activity\">"
98              + "    <receive name=\"startBooking\" partnerLink=\"client\""
99              + "      portType=\"services:InitTravel\" operation=\"initiate\" variable=\"userName\""
100             + "      createInstance=\"yes\"/>"
101             + "    <assign name=\"assignOffer\">"
102             + "      <copy>"
103             + "        <from variable=\"userName\" part=\"value\"/>"
104             + "        <to variable=\"offerRequest\" part=\"input\"/>"
105             + "      </copy>"
106             + "    </assign>"
107             + "    <flow name=\"offers\">"
108             + "      <!--  invoke hotel offer -->"
109             + "      <invoke name=\"invokeHotelOffer\" partnerLink=\"HotelOfferService\""
110             + "        portType=\"services:TravelService\" operation=\"getOffer\""
111             + "        inputVariable=\"offerRequest\" outputVariable=\"hotelOffer\"/>"
112             + "      <!--  invoke flight offer -->    "
113             + "      <invoke name=\"invokeFlightOffer\" partnerLink=\"FlightOfferService\""
114             + "        portType=\"services:TravelService\" operation=\"getOffer\""
115             + "        inputVariable=\"offerRequest\" outputVariable=\"flightOffer\"/>"
116             + "    </flow>"
117             + "    <assign name=\"assignBook\">"
118             + "      <copy>"
119             + "        <from variable=\"userName\" part=\"value\"/>"
120             + "        <to variable=\"bookRequest\" part=\"input\"/>"
121             + "      </copy>"
122             + "    </assign>"
123             + "    <flow name=\"bookings\">"
124             + "      <!--  invoke hotel booking -->"
125             + "      <invoke name=\"invokeHotelBooking\" partnerLink=\"HotelBookingService\""
126             + "        portType=\"services:TravelService\" operation=\"book\""
127             + "        inputVariable=\"bookRequest\" outputVariable=\"hotelBooking\"/>"
128             + "      <!--  invoke flight booking -->"
129             + "      <invoke name=\"invokeFlightBooking\" partnerLink=\"FlightBookingService\""
130             + "        portType=\"services:TravelService\" operation=\"book\""
131             + "        inputVariable=\"bookRequest\" outputVariable=\"flightBooking\"/>"
132             + "    </flow>"
133             + "    <assign name=\"assignResponse\">"
134             + "      <copy>"
135             + "        <from variable=\"userName\" part=\"value\"/>"
136             + "        <to variable=\"response\" part=\"value\"/>"
137             + "      </copy>"
138             + "    </assign>"
139             + "    <reply name=\"bookReply\" partnerLink=\"client\" portType=\"services:InitTravel\""
140             + "      operation=\"initiate\" variable=\"response\"/>"
141             + "  </sequence>" + "</process>";
142 
143     // the BPEL WSDL document
144     private static final String WSDL_DOC = ""
145             + "<?xml version=\"1.0\"?>"
146             + "<definitions name=\"Travel\""
147             + "        targetNamespace=\"http://bexee.sourceforge.net/Travel\""
148             + "        xmlns:tns=\"http://bexee.sourceforge.net/Travel\""
149             + "        xmlns:plnk=\"http://schemas.xmlsoap.org/ws/2003/05/partner-link/\""
150             + "        xmlns=\"http://schemas.xmlsoap.org/wsdl/\""
151             + "        xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">"
152             + "  <message name=\"TravelServiceRequestMessage\">"
153             + "    <part name=\"value\" type=\"xsd:string\"/>" + "  </message>"
154             + "  <message name=\"TravelServiceResponseMessage\">"
155             + "    <part name=\"value\" type=\"xsd:string\"/>" + "  </message>"
156             + "  <portType name=\"InitTravel\">"
157             + "    <operation name=\"initiate\">"
158             + "      <input message=\"tns:TravelServiceRequestMessage\"/>"
159             + "      <output message=\"tns:TravelServiceResponseMessage\"/>"
160             + "    </operation>" + "  </portType>"
161             + "  <plnk:partnerLinkType name=\"BookTravel\">"
162             + "    <plnk:role name=\"TravelProvider\">"
163             + "      <plnk:portType name=\"tns:InitTravel\"/>"
164             + "    </plnk:role>" + "  </plnk:partnerLinkType>"
165             + "</definitions>";
166 
167     // an extra partner WSDL
168     private static final String PARTNER_WSDL_DOC = ""
169             + "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
170             + "<wsdl:definitions name=\"BookTravel\""
171             + "  targetNamespace=\"http://bexee.sourceforge.net/Travel\""
172             + "  xmlns=\"http://schemas.xmlsoap.org/wsdl/\""
173             + "  xmlns:apachesoap=\"http://xml.apache.org/xml-soap\""
174             + "  xmlns:impl=\"http://bexee.sourceforge.net/Travel\""
175             + "  xmlns:intf=\"http://bexee.sourceforge.net/Travel\""
176             + "  xmlns:plnk=\"http://schemas.xmlsoap.org/ws/2003/05/partner-link/\""
177             + "  xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\""
178             + "  xmlns:tns=\"http://bexee.sourceforge.net/Travel\""
179             + "  xmlns:wsdl=\"http://schemas.xmlsoap.org/wsdl/\""
180             + "  xmlns:wsdlsoap=\"http://schemas.xmlsoap.org/wsdl/soap/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">"
181             + "  <wsdl:message name=\"getOfferRequest\">"
182             + "    <wsdl:part name=\"input\" type=\"xsd:string\"/>"
183             + "  </wsdl:message>"
184             + "  <wsdl:message name=\"bookRequest\">"
185             + "    <wsdl:part name=\"input\" type=\"xsd:string\"/>"
186             + "  </wsdl:message>"
187             + "  <wsdl:message name=\"getOfferResponse\">"
188             + "    <wsdl:part name=\"getOfferReturn\" type=\"xsd:string\"/>"
189             + "  </wsdl:message>"
190             + "  <wsdl:message name=\"bookResponse\">"
191             + "    <wsdl:part name=\"bookReturn\" type=\"xsd:string\"/>"
192             + "  </wsdl:message>"
193             + "  <wsdl:portType name=\"TravelService\">"
194             + "    <wsdl:operation name=\"book\" parameterOrder=\"input\">"
195             + "      <wsdl:input message=\"impl:bookRequest\" name=\"bookRequest\"/>"
196             + "      <wsdl:output message=\"impl:bookResponse\" name=\"bookResponse\"/>"
197             + "    </wsdl:operation>"
198             + "    <wsdl:operation name=\"getOffer\" parameterOrder=\"input\">"
199             + "      <wsdl:input message=\"impl:getOfferRequest\" name=\"getOfferRequest\"/>"
200             + "      <wsdl:output message=\"impl:getOfferResponse\" name=\"getOfferResponse\"/>"
201             + "    </wsdl:operation>"
202             + "  </wsdl:portType>"
203             + "  <wsdl:binding name=\"TravelServiceSoapBinding\" type=\"impl:TravelService\">"
204             + "    <wsdlsoap:binding style=\"rpc\" transport=\"http://schemas.xmlsoap.org/soap/http\"/>"
205             + "    <wsdl:operation name=\"book\">"
206             + "      <wsdlsoap:operation soapAction=\"\"/>"
207             + "      <wsdl:input name=\"bookRequest\">"
208             + "        <wsdlsoap:body encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\""
209             + "          namespace=\"http://bexee.sourceforge.net/Travel\" use=\"encoded\"/>"
210             + "      </wsdl:input>"
211             + "      <wsdl:output name=\"bookResponse\">"
212             + "        <wsdlsoap:body encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\""
213             + "          namespace=\"http://bexee.sourceforge.net/Travel\" use=\"encoded\"/>"
214             + "      </wsdl:output>"
215             + "    </wsdl:operation>"
216             + "    <wsdl:operation name=\"getOffer\">"
217             + "      <wsdlsoap:operation soapAction=\"\"/>"
218             + "      <wsdl:input name=\"getOfferRequest\">"
219             + "        <wsdlsoap:body encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\""
220             + "          namespace=\"http://bexee.sourceforge.net/Travel\" use=\"encoded\"/>"
221             + "      </wsdl:input>"
222             + "      <wsdl:output name=\"getOfferResponse\">"
223             + "        <wsdlsoap:body encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\""
224             + "          namespace=\"http://bexee.sourceforge.net/Travel\" use=\"encoded\"/>"
225             + "      </wsdl:output>"
226             + "    </wsdl:operation>"
227             + "  </wsdl:binding>"
228             + "  <wsdl:service name=\"TravelServiceService\">"
229             + "    <wsdl:port binding=\"impl:TravelServiceSoapBinding\" name=\"TravelService\">"
230             + "      <wsdlsoap:address location=\"http://localhost:8080/axis/services/TravelService\"/>"
231             + "    </wsdl:port>" + "  </wsdl:service>"
232             + "  <plnk:partnerLinkType name=\"OfferTravelPLT\">"
233             + "    <plnk:role name=\"OfferProvider\">"
234             + "      <plnk:portType name=\"tns:TravelService\"/>"
235             + "    </plnk:role>" + "  </plnk:partnerLinkType>"
236             + "  <plnk:partnerLinkType name=\"BookTravelPLT\">"
237             + "    <plnk:role name=\"BookProvider\">"
238             + "      <plnk:portType name=\"tns:TravelService\"/>"
239             + "    </plnk:role>" + "  </plnk:partnerLinkType>"
240             + "</wsdl:definitions>";
241 
242     private InputStream wsdl;
243 
244     private InputStream bpel;
245 
246     protected LocalTransport transport;
247 
248     private AxisServer axis;
249 
250     private Admin admin;
251 
252     private File file;
253 
254     private InputStream partnerWSDL;
255 
256     protected void setUp() throws Exception {
257         super.setUp();
258 
259         /*
260          * this is a bit of a hack, but we need to get the discovery file into
261          * the classpath, so that we can use our own WSDDProvider
262          */
263         URL url = getClass().getClassLoader().getResource("");
264         File classpath = new File(url.getFile());
265 
266         // create the discovery folders if necessary and then the file
267         File folder = new File(classpath, "META-INF/services/");
268         if (!folder.exists()) {
269             folder.mkdirs();
270         }
271         file = new File(folder, "org.apache.axis.deployment.wsdd.Provider");
272         // insert our mock wsdd provider class name
273         PrintWriter pw = new PrintWriter(new FileOutputStream(file));
274         pw.println("bexee.axis.BexeeWSDDProvider");
275         pw.close();
276 
277         // create axis server and local transport
278         XMLStringProvider provider = new XMLStringProvider(DEPLOY_DOC);
279         axis = new AxisServer(provider);
280         transport = new LocalTransport(axis);
281         transport.setRemoteService("Manager");
282 
283         // create mock admin object
284         admin = new MockAdmin();
285 
286         // create bpel and wsdl streams
287         bpel = new ByteArrayInputStream(BPEL_DOC.getBytes());
288         wsdl = new ByteArrayInputStream(WSDL_DOC.getBytes());
289         partnerWSDL = new ByteArrayInputStream(PARTNER_WSDL_DOC.getBytes());
290 
291     }
292 
293     protected void tearDown() throws Exception {
294         super.tearDown();
295 
296         // try to delete temporary file on exiting VM
297         file.deleteOnExit();
298         
299         // make sure that we don't leave garbage in the dao
300         DAOFactory.getInstance().createBPELProcessDAO().deleteAll();
301     }
302     
303     /***
304      * Test if we can deploy a BPEL process, that is it will be deployed to Axis
305      * and stored in the DAO.
306      */
307     public void testDeploy() throws Exception {
308                         
309         admin.deploy(bpel, wsdl, partnerWSDL);
310 
311         // check if the service has been deployed to Axis
312         SOAPService service = axis.getService("TravelProcess");
313         assertNotNull(service);
314 
315         // check if the operations have been deployed to Axis
316         ServiceDesc desc = service.getServiceDescription();
317         assertNotNull(desc.getOperationByName("initiate"));
318 
319         // uncomment the following line to print out the wsdd configuration
320         //outputWSDD(System.out);
321 
322         // check if the BPEL file has been stored
323         BPELProcessDAO dao = DAOFactory.getInstance().createBPELProcessDAO();
324         BPELProcess process = dao.find("TravelProcess");
325         assertNotNull(process);
326 
327         // check if the WSDL file has been stored
328         Definition wsdl = process.getWSDL();
329         assertNotNull(wsdl);
330         assertEquals("Travel", wsdl.getQName().getLocalPart());
331 
332         // check if the extra WSDL file has been stored
333         Definition extraWSDL = (Definition) process.getPartnerWSDL().get(0);
334         assertNotNull(extraWSDL);
335         assertEquals("BookTravel", extraWSDL.getQName().getLocalPart());
336     }
337 
338     /***
339      * Test if we can undeploy a process.
340      */
341     public void testUndeploy() throws Exception {
342 
343         admin.deploy(bpel, wsdl);
344 
345         // check if the service has been deployed to Axis
346         SOAPService service = axis.getService("TravelProcess");
347         assertNotNull(service);
348 
349         admin.undeploy("TravelProcess");
350         
351         // check if the service has been undeployed from Axis
352         service = axis.getService("TravelProcess");
353         assertNull(service);
354         
355         // check if the BPEL Process data has been deleted
356         BPELProcessDAO dao = DAOFactory.getInstance().createBPELProcessDAO();
357         BPELProcess process = dao.find("TravelProcess");
358         assertNull(process);
359     }
360 
361     /***
362      * Prints the current Axis wsdd configuration
363      */
364     private void outputWSDD(OutputStream out) throws AxisFault {
365         Document doc = org.apache.axis.utils.Admin.listConfig(axis);
366         PrintWriter writer = new PrintWriter(out);
367         XMLUtils.DocumentToWriter(doc, writer);
368         writer.close();
369     }
370 
371     /***
372      * Mock class extending the <code>Admin</code> class to add special
373      * functionality used for testing.
374      * 
375      * @version $Revision: 1.1 $, $Date: 2004/12/15 14:18:22 $
376      * @author Patric Fornasier
377      */
378     private class MockAdmin extends Admin {
379 
380         /***
381          * Overrides default behaviour of super class. In addition to calling
382          * the super class' method the local transport will be set on the call.
383          */
384         protected Call createCall(String operation) throws AdminException {
385             Call call = super.createCall(operation);
386             call.setTransport(transport);
387             return call;
388         }
389     }
390 
391 }