/* * JBoss, Home of Professional Open Source * Copyright 2009-11, Red Hat Middleware LLC, and others contributors as indicated * by the @authors tag. All rights reserved. * See the copyright.txt in the distribution for a * full listing of individual contributors. * This copyrighted material is made available to anyone wishing to use, * modify, copy, or redistribute it subject to the terms and conditions * of the GNU Lesser General Public License, v. 2.1. * This program is distributed in the hope that it will be useful, but WITHOUT A * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License, * v.2.1 along with this distribution; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301, USA. */ package org.riftsaw.engine; import static org.junit.Assert.*; import java.util.Map; import javax.xml.namespace.QName; import org.apache.ode.bpel.evt.BpelEvent; import org.apache.ode.utils.DOMUtils; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; import org.riftsaw.engine.internal.BPELEngineImpl; import org.w3c.dom.Element; public class BPELEngineTest { private static BPELEngine m_engine=null; private static TestServiceLocator m_locator=new TestServiceLocator(); @BeforeClass public static void runBeforeClass() { try { m_engine = BPELEngineFactory.createEngine(); java.util.Properties props=new java.util.Properties(); java.io.InputStream is=BPELEngineImpl.class.getClassLoader().getResourceAsStream("bpel.properties"); props.load(is); m_engine.init(m_locator, props); } catch (Exception e) { fail("Failed to initialize the engine: "+e); } } @AfterClass public static void runAfterClass() { try { m_engine.close(); } catch (Exception e) { fail("Failed to close down the engine: "+e); } } public DeploymentRef deploy(String descriptor) throws Exception { java.net.URL url=BPELEngineImpl.class.getResource(descriptor); java.io.File deployFile=new java.io.File(url.getFile()); // Deploy the process java.io.File deployment=deployFile.getParentFile(); return (m_engine.deploy(deployment.getName(), deployment)); } public void invoke(QName serviceName, String portName, String operation, String reqFile, String respFile, QName faultName) throws Exception { java.net.URL url=BPELEngineImpl.class.getResource(reqFile); java.io.InputStream is=url.openStream(); byte[] b=new byte[is.available()]; is.read(b); is.close(); org.w3c.dom.Element mesgElem=DOMUtils.stringToDOM(new String(b)); // invoke ODE Element resp=null; try { resp = m_engine.invoke(serviceName, portName, operation, mesgElem, null); } catch (Fault fault) { if (faultName == null) { fail("Unexpected fault '"+fault.getFaultName()+"' has occurred"); } else if (faultName.equals(fault.getFaultName()) == false) { fail("Fault has occurred, but has different name. Expecting '"+ faultName+"' but got '"+fault.getFaultName()+"'"); } else { resp = fault.getFaultMessage(); } } if (resp != null) { if (respFile == null) { fail("Response received but no file to verify it against"); } String respText=DOMUtils.domToString(resp); url = BPELEngineImpl.class.getResource(respFile); is = url.openStream(); b = new byte[is.available()]; is.read(b); is.close(); String respFileText=new String(b); if (respFileText.equals(respText) == false) { fail("Responses differ: file="+respFileText+" message="+respText); } } } @Test public void testLoanApprovalDocLit1() { TestBPELEngineListener l=new TestBPELEngineListener(); m_engine.register(l); m_locator.clear(); m_locator.addService(new QName("http://example.com/loan-approval/riskAssessment/","riskAssessor"), "riskAssessor_Port", new Service() { public Element invoke(String operationName, Element mesg, Map<String, Object> headers) throws Exception { // TODO Auto-generated method stub return DOMUtils.stringToDOM( "<checkResponse xmlns=\"http://example.com/loan-approval/riskAssessment/\">"+ " <level>low</level>"+ " </checkResponse>"); } }); DeploymentRef ref1=null; try { ref1=deploy("/loan_approval_doclit/deploy.xml"); invoke(new QName("http://example.com/loan-approval/loanService/","loanService"), "loanService_Port", "request", "/loan_approval_doclit/loanreq1.xml", "/loan_approval_doclit/loanresp1.xml", null); } catch (Exception e) { fail("Failed: "+e); } finally { try { m_engine.undeploy(ref1); } catch (Exception e) { fail("Failed to undeploy: "+e); } } if (l.getEvents().size() == 0) { fail("Expecting events"); } } @Test public void testLoanApprovalDocLit2() { m_locator.clear(); m_locator.addService(new QName("http://example.com/loan-approval/riskAssessment/","riskAssessor"), "riskAssessor_Port", new Service() { public Element invoke(String operationName, Element mesg, Map<String, Object> headers) throws Exception { Fault f=new Fault(new QName("http://example.com/loan-approval/riskAssessment/","loanProcessFault"), DOMUtils.stringToDOM( "<message><errorCode><ns1:integer xmlns:ns1=\"http://example.com/loan-approval/xsd/error-messages/\">21000</ns1:integer></errorCode></message>")); throw f; } }); DeploymentRef ref1=null; try { ref1=deploy("/loan_approval_doclit/deploy.xml"); invoke(new QName("http://example.com/loan-approval/loanService/","loanService"), "loanService_Port", "request", "/loan_approval_doclit/loanreq2.xml", "/loan_approval_doclit/loanresp2.xml", new QName("http://example.com/loan-approval/loanService/","unableToHandleRequest")); } catch (Exception e) { fail("Failed: "+e); } finally { try { m_engine.undeploy(ref1); } catch (Exception e) { fail("Failed to undeploy: "+e); } } } @Test public void testLoanApprovalUndeclaredFault() { m_locator.clear(); m_locator.addService(new QName("http://example.com/loan-approval/riskAssessment/","riskAssessor"), "riskAssessor_Port", new Service() { public Element invoke(String operationName, Element mesg, Map<String, Object> headers) throws Exception { Fault f=new Fault(new QName("http://example.com/loan-approval/riskAssessment/","loanProcessFault"), DOMUtils.stringToDOM( "<ns1:integer xmlns:ns1=\"http://example.com/loan-approval/xsd/error-messages/\">21000</ns1:integer>")); throw f; } }); DeploymentRef ref1=null; try { ref1=deploy("/loan_approval_undeclaredfault/deploy.xml"); invoke(new QName("http://example.com/loan-approval/loanService/","loanService"), "loanService_Port", "request", "/loan_approval_undeclaredfault/loanreq2.xml", "/loan_approval_undeclaredfault/loanresp2.xml", new QName("http://example.com/loan-approval/loanService/","unableToHandleRequest")); } catch (Exception e) { fail("Failed: "+e); } finally { try { m_engine.undeploy(ref1); } catch (Exception e) { fail("Failed to undeploy: "+e); } } } @Test public void testHelloWorldRedeploy() { try { DeploymentRef ref1=deploy("/hello_world/deploy.xml"); m_engine.undeploy(ref1); DeploymentRef ref2=deploy("/hello_world/deploy.xml"); m_engine.undeploy(ref2); } catch (Exception e) { fail("Failed: "+e); } } @Test public void testHelloWorld() { try { DeploymentRef ref1=deploy("/hello_world/deploy.xml"); invoke(new QName("http://www.jboss.org/bpel/examples/wsdl","HelloService"), "HelloPort", "hello", "/hello_world/hello_request1.xml", "/hello_world/hello_response1.xml", null); m_engine.undeploy(ref1); } catch (Exception e) { fail("Failed: "+e); } } @Test public void testHelloWorldWithListener() { TestBPELEngineListener l=new TestBPELEngineListener(); m_engine.register(l); try { DeploymentRef ref1=deploy("/hello_world/deploy.xml"); invoke(new QName("http://www.jboss.org/bpel/examples/wsdl","HelloService"), "HelloPort", "hello", "/hello_world/hello_request1.xml", "/hello_world/hello_response1.xml", null); m_engine.undeploy(ref1); } catch (Exception e) { fail("Failed: "+e); } if (l.getEvents().size() == 0) { fail("Expecting events"); } } @Test public void testHelloWorldWithRemovedListener() { TestBPELEngineListener l=new TestBPELEngineListener(); m_engine.register(l); // Remove, and run a process instance, to ensure listener no longer registered m_engine.unregister(l); try { DeploymentRef ref1=deploy("/hello_world/deploy.xml"); invoke(new QName("http://www.jboss.org/bpel/examples/wsdl","HelloService"), "HelloPort", "hello", "/hello_world/hello_request1.xml", "/hello_world/hello_response1.xml", null); m_engine.undeploy(ref1); } catch (Exception e) { fail("Failed: "+e); } if (l.getEvents().size() != 0) { fail("Not expecting any events"); } } @Test public void testHelloWorldInvalid() { try { deploy("/hello_world_invalid/deploy.xml"); fail("Should have thrown an exception"); } catch (Exception e) { // Ignore } } @Test public void testHelloWorldVersioned() { try { DeploymentRef ref1=deploy("/hello_world_versioned/deploy.xml"); invoke(new QName("http://www.jboss.org/bpel/examples/wsdl","HelloService"), "HelloPort", "hello", "/hello_world_versioned/hello_request1.xml", "/hello_world_versioned/hello_response1.xml", null); m_engine.undeploy(ref1); } catch (Exception e) { fail("Failed: "+e); } } @Test public void testHelloWorldVersionedInvalid() { try { deploy("/hello_world_versioned_invalid/deploy.xml"); fail("Should have thrown an exception"); } catch (Exception e) { // Ignore } } @Test public void testSimpleCorrelation() { TestBPELEngineListener l=new TestBPELEngineListener(); m_engine.register(l); try { DeploymentRef ref1=deploy("/simple_correlation/deploy.xml"); invoke(new QName("http://www.jboss.org/bpel/examples/wsdl","HelloGoodbyeService"), "HelloGoodbyePort", "hello", "/simple_correlation/hello_request1.xml", "/simple_correlation/hello_response1.xml", null); invoke(new QName("http://www.jboss.org/bpel/examples/wsdl","HelloGoodbyeService"), "HelloGoodbyePort", "goodbye", "/simple_correlation/goodbye_request1.xml", "/simple_correlation/goodbye_response1.xml", null); m_engine.undeploy(ref1); } catch (Exception e) { fail("Failed: "+e); } if (l.getEvents().size() == 0) { fail("Expecting events"); } } @Test public void testSimpleCorrelationVersioned() { try { deploy("/version1/simple_correlation/deploy.xml"); // Start process instance 1 invoke(new QName("http://www.jboss.org/bpel/examples/wsdl","HelloGoodbyeService"), "HelloGoodbyePort", "hello", "/version1/simple_correlation/hello_request1.xml", "/version1/simple_correlation/hello_response1.xml", null); DeploymentRef ref2=deploy("/version2/simple_correlation/deploy.xml"); // Start process instance 2 invoke(new QName("http://www.jboss.org/bpel/examples/wsdl","HelloGoodbyeService"), "HelloGoodbyePort", "hello", "/version2/simple_correlation/hello_request2.xml", "/version2/simple_correlation/hello_response2.xml", null); // Complete process instance 2 invoke(new QName("http://www.jboss.org/bpel/examples/wsdl","HelloGoodbyeService"), "HelloGoodbyePort", "goodbye", "/version2/simple_correlation/goodbye_request2.xml", "/version2/simple_correlation/goodbye_response2.xml", null); // Complete process instance 1 invoke(new QName("http://www.jboss.org/bpel/examples/wsdl","HelloGoodbyeService"), "HelloGoodbyePort", "goodbye", "/version2/simple_correlation/goodbye_request1.xml", "/version2/simple_correlation/goodbye_response1.xml", null); m_engine.undeploy(ref2); } catch (Exception e) { fail("Failed: "+e); } } @Test public void testSimpleInvoke() { m_locator.clear(); m_locator.addService(new QName("http://simple_invoke/helloworld","HelloWorldWSService"), "HelloWorldPort", new Service() { public Element invoke(String operationName, Element mesg, Map<String, Object> headers) throws Exception { // TODO Auto-generated method stub return DOMUtils.stringToDOM( "<message><sayHelloResponse><ns2:sayHelloResponse xmlns:ns2=\"http://simple_invoke/helloworld\">"+ " <return>Hello Joe Bloggs. Sincerely, JBossWS</return>"+ "</ns2:sayHelloResponse></sayHelloResponse></message>"); } }); try { DeploymentRef ref1=deploy("/simple_invoke/deploy.xml"); invoke(new QName("http://www.jboss.org/bpel/examples/wsdl","SimpleInvoke_Service"), "SimpleInvoke_Port", "sayHelloTo", "/simple_invoke/hello_request1.xml", "/simple_invoke/hello_response1.xml", null); m_engine.undeploy(ref1); } catch (Exception e) { fail("Failed: "+e); } } @Test public void testLoanApproval1() { m_locator.clear(); m_locator.addService(new QName("http://example.com/loan-approval/wsdl/","loanApprover"), "loanApprover_Port", new Service() { public Element invoke(String operationName, Element mesg, Map<String, Object> headers) throws Exception { fail("Should not be contacting the loan approver"); return null; } }); m_locator.addService(new QName("http://example.com/loan-approval/wsdl/","riskAssessor"), "riskAssessor_Port", new Service() { public Element invoke(String operationName, Element mesg, Map<String, Object> headers) throws Exception { // TODO Auto-generated method stub return DOMUtils.stringToDOM( "<wsdl:checkResponse xmlns:wsdl=\"http://example.com/loan-approval/wsdl/\">"+ " <level>low</level>"+ " </wsdl:checkResponse>"); } }); DeploymentRef ref1=null; try { ref1=deploy("/loan_approval/deploy.xml"); invoke(new QName("http://example.com/loan-approval/wsdl/","loanService"), "loanService_Port", "request", "/loan_approval/loanreq1.xml", "/loan_approval/loanresp1.xml", null); } catch (Exception e) { fail("Failed: "+e); } finally { try { m_engine.undeploy(ref1); } catch (Exception e) { fail("Failed to undeploy: "+e); } } } @Test public void testLoanApproval2() { m_locator.clear(); m_locator.addService(new QName("http://example.com/loan-approval/wsdl/","loanApprover"), "loanApprover_Port", new Service() { public Element invoke(String operationName, Element mesg, Map<String, Object> headers) throws Exception { // TODO Auto-generated method stub return DOMUtils.stringToDOM( "<wsdl:approveResponse xmlns:wsdl=\"http://example.com/loan-approval/wsdl/\">"+ "<accept>Evaluated and Approved</accept>"+ "</wsdl:approveResponse>"); } }); m_locator.addService(new QName("http://example.com/loan-approval/wsdl/","riskAssessor"), "riskAssessor_Port", new Service() { public Element invoke(String operationName, Element mesg, Map<String, Object> headers) throws Exception { // TODO Auto-generated method stub return DOMUtils.stringToDOM( "<wsdl:checkResponse xmlns:wsdl=\"http://example.com/loan-approval/wsdl/\">"+ " <level>high</level>"+ " </wsdl:checkResponse>"); } }); DeploymentRef ref1=null; try { ref1=deploy("/loan_approval/deploy.xml"); invoke(new QName("http://example.com/loan-approval/wsdl/","loanService"), "loanService_Port", "request", "/loan_approval/loanreq2.xml", "/loan_approval/loanresp2.xml", null); } catch (Exception e) { fail("Failed: "+e); } finally { try { m_engine.undeploy(ref1); } catch (Exception e) { fail("Failed to undeploy: "+e); } } } @Test public void testLoanApproval3() { m_locator.clear(); m_locator.addService(new QName("http://example.com/loan-approval/wsdl/","loanApprover"), "loanApprover_Port", new Service() { public Element invoke(String operationName, Element mesg, Map<String, Object> headers) throws Exception { Fault f=new Fault(new QName("http://example.com/loan-approval/wsdl/","loanProcessFault"), DOMUtils.stringToDOM( "<message><errorCode><ns1:integer xmlns:ns1=\"http://example.com/loan-approval/xsd/error-messages/\">21000</ns1:integer></errorCode></message>")); throw f; } }); m_locator.addService(new QName("http://example.com/loan-approval/wsdl/","riskAssessor"), "riskAssessor_Port", new Service() { public Element invoke(String operationName, Element mesg, Map<String, Object> headers) throws Exception { // TODO Auto-generated method stub return DOMUtils.stringToDOM( "<wsdl:checkResponse xmlns:wsdl=\"http://example.com/loan-approval/wsdl/\">"+ " <level>high</level>"+ " </wsdl:checkResponse>"); } }); DeploymentRef ref1=null; try { ref1=deploy("/loan_approval/deploy.xml"); invoke(new QName("http://example.com/loan-approval/wsdl/","loanService"), "loanService_Port", "request", "/loan_approval/loanreq3.xml", "/loan_approval/loanresp3.xml", new QName("http://example.com/loan-approval/wsdl/","unableToHandleRequest")); } catch (Exception e) { fail("Failed: "+e); } finally { try { m_engine.undeploy(ref1); } catch (Exception e) { fail("Failed to undeploy: "+e); } } } @Test public void testLoanApproval4() { m_locator.clear(); m_locator.addService(new QName("http://example.com/loan-approval/wsdl/","loanApprover"), "loanApprover_Port", new Service() { public Element invoke(String operationName, Element mesg, Map<String, Object> headers) throws Exception { fail("Should not be contacting the loan approver"); return null; } }); m_locator.addService(new QName("http://example.com/loan-approval/wsdl/","riskAssessor"), "riskAssessor_Port", new Service() { public Element invoke(String operationName, Element mesg, Map<String, Object> headers) throws Exception { fail("Should not be contacting the loan assessor"); return null; } }); DeploymentRef ref1=null; try { ref1=deploy("/loan_approval/deploy.xml"); invoke(new QName("http://example.com/loan-approval/wsdl/","loanService"), "loanService_Port", "request", "/loan_approval/loanreq4.xml", "/loan_approval/loanresp4.xml", new QName("http://example.com/loan-approval/wsdl/","unableToHandleRequest")); } catch (Exception e) { e.printStackTrace(); fail("Failed: "+e); } finally { try { m_engine.undeploy(ref1); } catch (Exception e) { fail("Failed to undeploy: "+e); } } } public static class TestServiceLocator implements ServiceLocator { private java.util.Map<String,Service> m_services=new java.util.HashMap<String, Service>(); public void addService(QName serviceName, String portName, Service service) { m_services.put(serviceName.toString()+"-"+portName, service); } public Service getService(QName processName, QName serviceName, String portName) { return (m_services.get(serviceName.toString()+"-"+portName)); } public void clear() { m_services.clear(); } } public class TestBPELEngineListener implements BPELEngineListener { private java.util.List<BpelEvent> _events=new java.util.ArrayList<BpelEvent>(); public void onEvent(BpelEvent bpelEvent) { _events.add(bpelEvent); } public java.util.List<BpelEvent> getEvents() { return (_events); } } }