From 10b1237c09ad151c3391d2300ed30f99009d9014 Mon Sep 17 00:00:00 2001 From: Daniel Luebke Date: Mon, 7 Apr 2014 15:34:28 +0200 Subject: [PATCH] Create a BPTS skeleton from a BPEL file --- .../main/java/net/bpelunit/util/XMLUtil.java | 33 ++++ .../java/net/bpelunit/util/XMLUtilTest.java | 38 ++++ .../functions/create/CreateFunction.java | 175 +++++++++++++++--- .../create/NamespacePrefixGenerator.java | 20 ++ .../functions/create/CreateFunctionTest.java | 22 ++- 5 files changed, 264 insertions(+), 24 deletions(-) create mode 100644 net.bpelunit.utils.bptstool/src/main/java/net/bpelunit/utils/bptstool/functions/create/NamespacePrefixGenerator.java diff --git a/net.bpelunit.util/src/main/java/net/bpelunit/util/XMLUtil.java b/net.bpelunit.util/src/main/java/net/bpelunit/util/XMLUtil.java index 4c433943..5a178b80 100644 --- a/net.bpelunit.util/src/main/java/net/bpelunit/util/XMLUtil.java +++ b/net.bpelunit.util/src/main/java/net/bpelunit/util/XMLUtil.java @@ -315,4 +315,37 @@ public static String getTextContent(Node e) { return sb.toString(); } + public static QName resolveQName(String qNameWithPrefix, Element element) { + String nsPrefix; + String localName; + if(qNameWithPrefix.contains(":")) { + String[] parts = qNameWithPrefix.split(":"); + nsPrefix = parts[0]; + localName = parts[1]; + } else { + nsPrefix = ""; + localName = qNameWithPrefix; + } + + return new QName(resolveNamespacePrefix(nsPrefix, element), localName); + } + + public static String resolveNamespacePrefix(String prefix, Element element) { + String namespace = null; + + if("".equals(prefix)) { + namespace = element.getAttribute("xmlns"); + } else { + namespace = element.getAttribute("xmlns:" + prefix); + } + if(namespace != null && !"".equals(namespace)) { + return namespace; + } + + if(element.getParentNode() instanceof Element) { + return resolveNamespacePrefix(prefix, (Element)element.getParentNode()); + } else { + throw new RuntimeException("Cannot resolve prefix " + prefix); + } + } } diff --git a/net.bpelunit.util/src/test/java/net/bpelunit/util/XMLUtilTest.java b/net.bpelunit.util/src/test/java/net/bpelunit/util/XMLUtilTest.java index a53e5c4f..b2c579c1 100644 --- a/net.bpelunit.util/src/test/java/net/bpelunit/util/XMLUtilTest.java +++ b/net.bpelunit.util/src/test/java/net/bpelunit/util/XMLUtilTest.java @@ -4,6 +4,7 @@ */ package net.bpelunit.util; +import static org.junit.Assert.*; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; @@ -268,6 +269,43 @@ public void testGetPosition() throws Exception { assertEquals(4, XMLUtil.getPosition(children.get(3))); } + @Test + public void testResolveNamespacePrefix_NormalPrefix() throws Exception { + Document xml = XMLUtil.parseXML("ns:b"); + String namespace = XMLUtil.resolveNamespacePrefix("ns", xml.getDocumentElement()); + assertEquals("ns1", namespace); + } + + @Test + public void testResolveNamespacePrefix_NormalPrefixInHierarchy() throws Exception { + Document xml = XMLUtil.parseXML("ns:b"); + String namespace = XMLUtil.resolveNamespacePrefix("ns", (Element)xml.getDocumentElement().getChildNodes().item(0)); + assertEquals("ns1", namespace); + } + + @Test + public void testResolveNamespacePrefix_DefaultNamespace() throws Exception { + Document xml = XMLUtil.parseXML("b"); + String namespace = XMLUtil.resolveNamespacePrefix("", xml.getDocumentElement()); + assertEquals("ns1", namespace); + } + + @Test + public void testResolveQName_NormalPrefix() throws Exception { + Document xml = XMLUtil.parseXML("ns:b"); + QName qname = XMLUtil.resolveQName("ns:a", xml.getDocumentElement()); + assertEquals("ns1", qname.getNamespaceURI()); + assertEquals("a", qname.getLocalPart()); + } + + @Test + public void testResolveQName_DefaultNamespace() throws Exception { + Document xml = XMLUtil.parseXML("b"); + QName qname = XMLUtil.resolveQName("a", xml.getDocumentElement()); + assertEquals("ns1", qname.getNamespaceURI()); + assertEquals("a", qname.getLocalPart()); + } + private static class NodeListMock implements NodeList { Node[] nodes; diff --git a/net.bpelunit.utils.bptstool/src/main/java/net/bpelunit/utils/bptstool/functions/create/CreateFunction.java b/net.bpelunit.utils.bptstool/src/main/java/net/bpelunit/utils/bptstool/functions/create/CreateFunction.java index 7b8a93bb..295a0b1b 100644 --- a/net.bpelunit.utils.bptstool/src/main/java/net/bpelunit/utils/bptstool/functions/create/CreateFunction.java +++ b/net.bpelunit.utils.bptstool/src/main/java/net/bpelunit/utils/bptstool/functions/create/CreateFunction.java @@ -3,22 +3,31 @@ import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; +import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; +import javax.wsdl.Binding; +import javax.wsdl.Definition; +import javax.wsdl.Import; +import javax.wsdl.Port; +import javax.wsdl.Service; import javax.wsdl.WSDLException; +import javax.wsdl.extensions.soap.SOAPAddress; import javax.wsdl.factory.WSDLFactory; import javax.wsdl.xml.WSDLReader; -import javax.xml.bind.JAXBException; +import javax.wsdl.xml.WSDLWriter; import javax.xml.namespace.QName; import javax.xml.parsers.ParserConfigurationException; import net.bpelunit.framework.xml.suite.XMLDeploymentSection; import net.bpelunit.framework.xml.suite.XMLPUTDeploymentInformation; import net.bpelunit.framework.xml.suite.XMLPartnerDeploymentInformation; +import net.bpelunit.framework.xml.suite.XMLTestCase; import net.bpelunit.framework.xml.suite.XMLTestSuite; import net.bpelunit.framework.xml.suite.XMLTestSuiteDocument; import net.bpelunit.model.bpel.BpelFactory; @@ -50,7 +59,9 @@ public class CreateFunction implements IFunction { private Options options; private String testSuiteDir; private String bpelFileName; - private Map wsdlFilesByNamespace = new HashMap(); + private WSDLFactory wsdlFactory; + private WSDLWriter wsdlWriter; + private WSDLReader wsdlReader; public CreateFunction() { createOptions(); @@ -114,14 +125,10 @@ private void showHelpAndExit() { public void execute(String[] params) { parseOptionsFromCommandLine(params); - WSDLReader wsdlReader = null; - try { - wsdlReader = WSDLFactory.newInstance().newWSDLReader(); - } catch (WSDLException e) { - throw new RuntimeException(e); - } File bpelFile = new File(bpelFileName); File bptsFile = getBptsFile(bpelFile, testSuiteDir); + Map wsdlFilesByNamespace = new HashMap(); + new File(bptsFile.getParentFile(), "wsdl").mkdir(); // TODO Check parameters // checkExistsFile(bpelFile); @@ -151,22 +158,18 @@ public void execute(String[] params) { processUnderTest.setName(bpel.getName()); processUnderTest.setType(deployerType); - List partnerLinks = bpel.getPartnerLinks(); - for (IPartnerLink pl : partnerLinks) { - if(pl.getPartnerRole() != null) { - XMLPartnerDeploymentInformation partner = deployment - .addNewPartner(); - partner.setName(pl.getName()); - - QName plt = pl.getPartnerLinkType(); - String pltNS = plt.getNamespaceURI(); - File wsdlFile = wsdlFilesByNamespace.get(pltNS); - Document wsdlXml = XMLUtil.parseXML(new FileInputStream(wsdlFile)); - List partnerLinkTypeDefinitions = XMLUtil.getChildElementsByName(wsdlXml.getDocumentElement(), "partnerLinkType"); - } - } + addPartners(bptsFile, wsdlFilesByNamespace, bpel, deployment); - System.out.println(bptsFile); + // required by schema although it won't be used with the generated structure + processUnderTest.setWsdl(deployment.getPartnerArray(0).getWsdl()); + + XMLTestCase dummyTestCase = testSuite.getTestCases().addNewTestCase(); + dummyTestCase.setName("TODO"); + dummyTestCase.addNewClientTrack(); + for(XMLPartnerDeploymentInformation p : deployment.getPartnerList()) { + dummyTestCase.addNewPartnerTrack().setName(p.getName()); + } + testSuiteDoc.save(bptsFile); } catch (FileNotFoundException e) { @@ -181,9 +184,135 @@ public void execute(String[] params) { } catch (ParserConfigurationException e) { // TODO Auto-generated catch block e.printStackTrace(); + } catch (WSDLException e) { + // TODO Auto-generated catch block + e.printStackTrace(); } } + private void addPartners(File bptsFile, + Map wsdlFilesByNamespace, IProcess bpel, + XMLDeploymentSection deployment) throws SAXException, IOException, + ParserConfigurationException, FileNotFoundException, WSDLException { + + wsdlFactory = WSDLFactory.newInstance(); + wsdlWriter = wsdlFactory.newWSDLWriter(); + wsdlReader = wsdlFactory.newWSDLReader(); + List partnerLinks = bpel.getPartnerLinks(); + for (IPartnerLink pl : partnerLinks) { + NamespacePrefixGenerator namespacePrefixGenerator = new NamespacePrefixGenerator(); + XMLPartnerDeploymentInformation partner = deployment + .addNewPartner(); + partner.setName(pl.getName()); + + String partnerWsdlFileName = "wsdl/" + + FileUtil.getFileNameWithoutSuffix(bptsFile.getName()) + + "_" + pl.getName() + ".wsdl"; + File partnerWsdlFile = new File(bptsFile.getParentFile(), + partnerWsdlFileName); + partner.setWsdl(partnerWsdlFileName); + + Definition partnerWsdl = wsdlFactory.newDefinition(); + partnerWsdl.setTargetNamespace(ensureTrailingSlash(bpel + .getTargetNamespace()) + pl.getName()); + partnerWsdl.setExtensionRegistry(wsdlFactory.newPopulatedExtensionRegistry()); + partnerWsdl.addNamespace("soap", "http://schemas.xmlsoap.org/wsdl/soap/"); + + QName plt = pl.getPartnerLinkType(); + String pltNS = plt.getNamespaceURI(); + File pltWsdlFile = wsdlFilesByNamespace.get(pltNS); + Document pltWsdlXml = XMLUtil.parseXML(new FileInputStream( + pltWsdlFile)); + Definition pltWsdl = wsdlReader.readWSDL( + pltWsdlFile.getAbsolutePath(), pltWsdlXml); + Import pltWsdlImport = partnerWsdl.createImport(); + partnerWsdl.addImport(pltWsdlImport); + pltWsdlImport.setDefinition(pltWsdl); + pltWsdlImport.setNamespaceURI(pltWsdl.getTargetNamespace()); + pltWsdlImport.setLocationURI(pltWsdlFile.getAbsolutePath()); // TODO + // Relative + // Path + List partnerLinkTypeDefinitions = XMLUtil + .getChildElementsByName(pltWsdlXml.getDocumentElement(), + "partnerLinkType"); + Element partnerLinkType = getElementWithNameAttribute( + partnerLinkTypeDefinitions, plt.getLocalPart()); + List roleElements = XMLUtil.getChildElementsByName( + partnerLinkType, "role"); + + if (pl.getMyRole() != null) { + createServiceForRoleInPartnerLink(pl, partnerWsdl, + roleElements, "Process", pl.getMyRole(), + namespacePrefixGenerator, "TODO"); + } + if (pl.getPartnerRole() != null) { + createServiceForRoleInPartnerLink(pl, partnerWsdl, + roleElements, "Mock", pl.getPartnerRole(), + namespacePrefixGenerator, ensureTrailingSlash(baseUrl) + partner.getName()); + } + wsdlWriter.writeWSDL(partnerWsdl, new FileOutputStream( + partnerWsdlFile)); + } + } + + private void createServiceForRoleInPartnerLink(IPartnerLink pl, + Definition partnerWsdl, List roleElements, + String serviceName, String roleName, + NamespacePrefixGenerator namespacePrefixGenerator, + String endpointURL) throws WSDLException { + Element role = getElementWithNameAttribute(roleElements, roleName); + QName portTypeQName = XMLUtil.resolveQName( + role.getAttribute("portType"), role); + Binding binding = findBindingForPortType(portTypeQName, partnerWsdl); + + if (binding == null) { + binding = partnerWsdl.createBinding(); + partnerWsdl.addBinding(binding); + binding.setPortType(partnerWsdl.getPortType(portTypeQName)); + } else { + String bindingNS = binding.getQName().getNamespaceURI(); + partnerWsdl.addNamespace( + namespacePrefixGenerator.getNamespacePrefix(bindingNS), + bindingNS); + } + + Service service = partnerWsdl.createService(); + service.setQName(new QName(partnerWsdl.getTargetNamespace(), + serviceName)); + Port port = partnerWsdl.createPort(); + port.setName(roleName); + port.setBinding(binding); + SOAPAddress soapAddress = (SOAPAddress)partnerWsdl.getExtensionRegistry().createExtension(Port.class, new QName("http://schemas.xmlsoap.org/wsdl/soap/", "address")); + soapAddress.setLocationURI(endpointURL); + port.addExtensibilityElement(soapAddress); + service.addPort(port); + partnerWsdl.addService(service); + } + + @SuppressWarnings("unchecked") + private Binding findBindingForPortType(QName resolveQName, Definition d) { + for (Binding b : (Collection) (d.getAllBindings().values())) { + if (b.getPortType().getQName().equals(resolveQName)) { + return b; + } + } + return null; + } + + private String ensureTrailingSlash(String ns) { + return ns.endsWith("/") ? ns : ns + "/"; + } + + private Element getElementWithNameAttribute(List elements, + String name) { + for (Element e : elements) { + if (name.equals(e.getAttribute("name"))) { + return e; + } + } + return null; + } + File getBptsFile(File bpelFile, String testSuiteDir) { File bptsFile; diff --git a/net.bpelunit.utils.bptstool/src/main/java/net/bpelunit/utils/bptstool/functions/create/NamespacePrefixGenerator.java b/net.bpelunit.utils.bptstool/src/main/java/net/bpelunit/utils/bptstool/functions/create/NamespacePrefixGenerator.java new file mode 100644 index 00000000..d3ca3cb3 --- /dev/null +++ b/net.bpelunit.utils.bptstool/src/main/java/net/bpelunit/utils/bptstool/functions/create/NamespacePrefixGenerator.java @@ -0,0 +1,20 @@ +package net.bpelunit.utils.bptstool.functions.create; + +import java.util.HashMap; +import java.util.Map; + +public class NamespacePrefixGenerator { + + private int counter = 1; + private static final String NSPREFIX = "ns"; + + private Map namespaceMap = new HashMap(); + + public synchronized String getNamespacePrefix(String namespace) { + if(!namespaceMap.containsKey(namespace)) { + namespaceMap.put(namespace, NSPREFIX + (counter++)); + } + return namespaceMap.get(namespace); + } + +} diff --git a/net.bpelunit.utils.bptstool/src/test/java/net/bpelunit/utils/bptstool/functions/create/CreateFunctionTest.java b/net.bpelunit.utils.bptstool/src/test/java/net/bpelunit/utils/bptstool/functions/create/CreateFunctionTest.java index a085771c..71bec68d 100644 --- a/net.bpelunit.utils.bptstool/src/test/java/net/bpelunit/utils/bptstool/functions/create/CreateFunctionTest.java +++ b/net.bpelunit.utils.bptstool/src/test/java/net/bpelunit/utils/bptstool/functions/create/CreateFunctionTest.java @@ -4,12 +4,28 @@ import static org.junit.Assert.assertTrue; import java.io.File; +import java.util.HashMap; + +import net.bpelunit.framework.base.BPELUnitBaseRunner; +import net.bpelunit.framework.exception.ConfigurationException; +import net.bpelunit.framework.model.test.TestSuite; +import net.bpelunit.framework.model.test.report.ArtefactStatus; import org.junit.Test; public class CreateFunctionTest { + private final class TestTestRunner extends BPELUnitBaseRunner { + public TestTestRunner() throws ConfigurationException { + initialize(new HashMap()); + } + + @Override + public void configureLogging() throws ConfigurationException { + } + } + private CreateFunction createFunction = new CreateFunction();; @Test @@ -23,6 +39,11 @@ public void testExecute() throws Exception { assertTrue(new File("target/test").exists()); assertTrue(new File("target/test").isDirectory()); assertTrue(new File("target/test/Test.bpts").isFile()); + + BPELUnitBaseRunner r = new TestTestRunner(); + TestSuite testSuite = r.loadTestSuite(new File("target/test/Test.bpts")); + testSuite.run(); + assertEquals(ArtefactStatus.StatusCode.PASSED, testSuite.getStatus().getCode()); } @Test @@ -45,5 +66,4 @@ public void testGetBptsFile() throws Exception { assertEquals(expectedBptsFile.getAbsoluteFile(), createFunction.getBptsFile(bpelFile, "/test")); } } - }