| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| package org.apache.axis2.description; |
| |
| import java.io.File; |
| import java.io.FileInputStream; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| |
| import javax.wsdl.xml.WSDLLocator; |
| import javax.xml.namespace.QName; |
| |
| import org.apache.axis2.engine.AxisConfiguration; |
| import org.apache.axis2.wsdl.WSDLConstants; |
| import org.apache.ws.commons.schema.XmlSchema; |
| import org.apache.ws.commons.schema.XmlSchemaElement; |
| import org.apache.ws.commons.schema.XmlSchemaObject; |
| import org.xml.sax.InputSource; |
| |
| import junit.framework.TestCase; |
| |
| public class WSDL11ToAxisServiceBuilderTest extends TestCase { |
| /** |
| * Tests processing of an operation that declares multiple faults referring to the same message. |
| * In this case, {@link WSDL11ToAxisServiceBuilder} must correctly populate the |
| * {@link AxisMessage} object for both faults. In particular, |
| * {@link AxisMessage#getElementQName()} must return consistent information. This is a |
| * regression test for AXIS2-4533. |
| * |
| * @throws Exception |
| */ |
| public void testMultipleFaultsWithSameMessage() throws Exception { |
| InputStream in = new FileInputStream("test-resources/wsdl/faults.wsdl"); |
| try { |
| AxisService service = new WSDL11ToAxisServiceBuilder(in).populateService(); |
| AxisOperation operation = service.getOperation(new QName("urn:test", "test")); |
| assertNotNull(operation); |
| List<AxisMessage> faultMessages = operation.getFaultMessages(); |
| assertEquals(2, faultMessages.size()); |
| AxisMessage error1 = faultMessages.get(0); |
| AxisMessage error2 = faultMessages.get(1); |
| assertEquals("errorMessage", error1.getName()); |
| assertEquals("errorMessage", error2.getName()); |
| assertEquals(new QName("urn:test", "error"), error1.getElementQName()); |
| assertEquals(new QName("urn:test", "error"), error2.getElementQName()); |
| } finally { |
| in.close(); |
| } |
| } |
| |
| public void testNonDuplicatedElementsHttpBinding() throws Exception { |
| final String wsdlPath = "test-resources/wsdl/nonduplicatedElements.wsdl"; |
| InputStream in = new FileInputStream(wsdlPath); |
| final String targetNamespace = "http://www.example.org"; |
| final QName serviceName = new QName(targetNamespace, "FooService"); |
| final String portName = "FooHttpGetPort"; |
| |
| AxisService service = new WSDL11ToAxisServiceBuilder(in, serviceName, portName).populateService(); |
| List<XmlSchema> schemaDocuments = service.getSchema(); |
| List<QName> duplicatedGlobalElements = findDuplicatedGlobalElements(schemaDocuments); |
| // NO duplicated element should exists |
| assertTrue("Duplicated global element declarations found in '" + wsdlPath, |
| duplicatedGlobalElements.isEmpty()); |
| } |
| |
| protected List<QName> findDuplicatedGlobalElements(List<XmlSchema> schemaDocuments) { |
| List<QName> duplicatedGlobalElementDeclarations = new ArrayList<QName>(); |
| Set<QName> globalElementDeclarations = new HashSet<QName>(); |
| // Iterate over all schema documents |
| for (XmlSchema schemaDocument : schemaDocuments) { |
| for (XmlSchemaObject xmlSchemaObject : schemaDocument.getItems()) { |
| // Check only XML schema elements |
| if (xmlSchemaObject instanceof XmlSchemaElement) { |
| QName elementName = ((XmlSchemaElement)xmlSchemaObject).getQName(); |
| /* Was another element with the same name found in this or |
| other XML schema document? */ |
| if (globalElementDeclarations.contains(elementName)) { |
| duplicatedGlobalElementDeclarations.add(elementName); |
| } else { |
| globalElementDeclarations.add(elementName); |
| } |
| } |
| } |
| } |
| return duplicatedGlobalElementDeclarations; |
| } |
| |
| private AxisService populateAxisService(AxisConfiguration axisConf, File wsdlFile) throws IOException { |
| InputStream in = null; |
| try { |
| in = new FileInputStream(wsdlFile); |
| WSDL11ToAxisServiceBuilder wsdl11Builder = new WSDL11ToAxisServiceBuilder(in); |
| if (axisConf != null) { |
| wsdl11Builder.useAxisConfiguration(axisConf); |
| } |
| AxisService service = wsdl11Builder.populateService(); |
| assertNotNull("Could not load AxisService from wsdl: " + wsdlFile.getAbsolutePath(), service); |
| |
| return service; |
| } finally { |
| if (in != null) { |
| in.close(); |
| } |
| } |
| } |
| |
| private void checkOperationActions(AxisService service, AxisOperation operation, String expectedInputAction, String expectedOutputAction, String expectedFaultAction) { |
| assertEquals(String.format("Expected that operation '%s' of service '%s' defines an input action of '%s' but it defines '%s' instead.", operation.getName(), service.getName(), expectedInputAction, operation.getInputAction()), expectedInputAction, operation.getInputAction()); |
| assertEquals(String.format("Expected that operation '%s' of service '%s' defines an output action of '%s' but it defines '%s' instead.", operation.getName(), service.getName(), expectedOutputAction, operation.getOutputAction()), expectedOutputAction, operation.getOutputAction()); |
| assertEquals(String.format("Expected that operation '%s' of service '%s' defines an input action of '%s' but it defines '%s' instead.", operation.getName(), service.getName(), expectedFaultAction, operation.getFaultAction()), expectedFaultAction, operation.getFaultAction()); |
| |
| ArrayList<String> wsaMappingList = operation.getWSAMappingList(); |
| assertEquals(String.format("Expected that operation '%s' of service '%s' has a 'wsaMappingList' of size '%d' but size is '%d' instead.", operation.getName(), service.getName(), 1, wsaMappingList.size()), 1, wsaMappingList.size()); |
| assertTrue(String.format("Expected that the 'wsaMappingList' of operation '%s' of service '%s' contains an entry of '%s' but it does not.", operation.getName(), service.getName(), expectedInputAction), wsaMappingList.contains(expectedInputAction)); |
| |
| assertSame(String.format("Expected that 'operationsAliasesMap' of service '%s' contains a '%s' operation for action '%s'.", service.getName(), operation.getName(), expectedInputAction), service.getOperationByAction(expectedInputAction), operation); |
| } |
| |
| public void testGetVersionActions() throws IOException { |
| AxisConfiguration axisConf = new AxisConfiguration(); |
| AxisService service = populateAxisService(axisConf, new File("test-resources/wsdl/Version.wsdl")); |
| |
| String[] operationNames = new String[] { |
| "getVersionWSAW", "getVersionWSA", "getVersionWSAM", "getVersionWSAWSubmission", |
| "getVersionWSAWURI", "getVersionWSAURI", "getVersionWSAMURI", "getVersionWSAWSubmissionURI" |
| }; |
| |
| for (String operationName : operationNames) { |
| QName operationQName = new QName("http://axisversion.sample", operationName); |
| AxisOperation operation = service.getOperation(operationQName); |
| assertNotNull(String.format("Could not find AxisOperation '%s' in service: %s", operationQName.toString(), service.getName()), operation); |
| |
| String prefix = operationName.endsWith("URI") ? "ns:Version" : "http://axisversion.sample"; |
| String expectedInputAction = String.format("%s/VersionPortType/%sRequest", prefix, operationQName.getLocalPart()); |
| String expectedOutputAction = String.format("%s/VersionPortType/%sResponse", prefix, operationQName.getLocalPart()); |
| String expectedFaultAction = String.format("%s/VersionPortType/Fault/%sException", prefix, operationQName.getLocalPart()); |
| |
| checkOperationActions(service, operation, expectedInputAction,expectedOutputAction,expectedFaultAction); |
| } |
| } |
| |
| /** |
| * Tests parsing of <code>EchoService.wsdl</code> into an AxisService instance. The <code>EchoService.wsdl</code> |
| * imports <code>EchoBindings.wsdl</code>, which contains the binding definitions (note that it does not reverse-import the EchoService.wsdl). |
| * Parsing the wsdl should cause neither a "There is no port type associated with the binding" exception, nor a "Cannot determine the MEP" exception, |
| * provided that Axis2 does not recursively search the port type in all imported wsdls, but looks it up via {@link javax.wsdl.Definition#getPortType(QName)}, |
| * falling back to {@link javax.wsdl.Binding#getPortType()} if not available (will be the case when port type is imported through another document but not directly) |
| * |
| * The test verifies that no exceptions are thrown and additionally checks that the endpoint, binding, operation and its in/out messages are correctly populated from the WSDL definition. |
| * @throws IOException |
| */ |
| public void testImportedBindings() throws IOException { |
| AxisConfiguration axisConf = new AxisConfiguration(); |
| WSDLLocator wsdlLocator = new CustomWSDLLocator("test-resources/wsdl/imports/binding/", "EchoService.wsdl"); |
| AxisService service = populateAxisService(axisConf, new File(wsdlLocator.getBaseURI()), wsdlLocator); |
| assertValidEchoService(service, wsdlLocator); |
| } |
| |
| /** |
| * Tests parsing of <code>EchoService.wsdl</code> into an AxisService instance. The <code>EchoService.wsdl</code> |
| * imports <code>EchoBindings.wsdl</code>, which reverse-imports the EchoService.wsdl (i.e. we have a circular import). |
| * Parsing the wsdl should cause neither a "There is no port type associated with the binding" exception, nor a "Cannot determine the MEP" exception, |
| * provided that Axis2 does not recursively search the port type in all imported wsdls, but looks it up via {@link javax.wsdl.Definition#getPortType(QName)}, |
| * falling back to {@link javax.wsdl.Binding#getPortType()} if not available (will be the case when port type is imported through another document but not directly) |
| * |
| * The test verifies that no exceptions are thrown and additionally checks that the endpoint, binding, operation and its in/out messages are correctly populated from the WSDL definition. |
| * @throws IOException |
| */ |
| public void testCircularImportedBindings() throws IOException { |
| AxisConfiguration axisConf = new AxisConfiguration(); |
| WSDLLocator wsdlLocator = new CustomWSDLLocator("test-resources/wsdl/imports/binding_recursive/", "EchoService.wsdl"); |
| AxisService service = populateAxisService(axisConf, new File(wsdlLocator.getBaseURI()), wsdlLocator); |
| assertValidEchoService(service, wsdlLocator); |
| } |
| |
| /** |
| * Tests parsing of <code>EchoService.wsdl</code> into an AxisService instance. The <code>EchoService.wsdl</code> |
| * imports <code>EchoBindings.wsdl</code>, which in turn imports the <code>EchoPortType.wsdl</code>. |
| * Parsing the wsdl should cause neither a "There is no port type associated with the binding" exception, nor a "Cannot determine the MEP" exception, |
| * provided that Axis2 does not recursively search the port type in all imported wsdls, but looks it up via {@link javax.wsdl.Definition#getPortType(QName)}, |
| * falling back to {@link javax.wsdl.Binding#getPortType()} if not available (will be the case when port type is imported through another document but not directly) |
| * |
| * The test verifies that no exceptions are thrown and additionally checks that the endpoint, binding, operation and its in/out messages are correctly populated from the WSDL definition. |
| * @throws IOException |
| */ |
| public void testImportedPortType() throws IOException { |
| AxisConfiguration axisConf = new AxisConfiguration(); |
| WSDLLocator wsdlLocator = new CustomWSDLLocator("test-resources/wsdl/imports/portType/", "EchoService.wsdl"); |
| AxisService service = populateAxisService(axisConf, new File(wsdlLocator.getBaseURI()), wsdlLocator); |
| assertValidEchoService(service, wsdlLocator); |
| } |
| |
| private void assertValidEchoService(AxisService echoService, WSDLLocator wsdlLocator) { |
| //check soap12 endpoint and binding are available |
| String endpointName = "EchoServiceHttpSoap12Endpoint"; |
| AxisEndpoint soap12Endpoint = echoService.getEndpoint(endpointName); |
| assertNotNull(String.format("Cannot find %s endpoint in wsdl definition: %s", endpointName, wsdlLocator.getBaseURI()), soap12Endpoint); |
| |
| AxisBinding soap12Binding = soap12Endpoint.getBinding(); |
| assertNotNull(String.format("Binding not set on %s endpoint in wsdl definition: %s", endpointName, wsdlLocator.getBaseURI()), soap12Binding); |
| |
| //check that policy reference is present on the binding subject |
| String bindingPolicyRefId = "#basicAuthPolicy"; |
| assertNotNull(String.format("Cannot find policy reference %s on binding %s", bindingPolicyRefId, soap12Binding.getName()), |
| soap12Binding.getPolicySubject().getAttachedPolicyComponent(bindingPolicyRefId)); |
| |
| //check that binding operation and respective operation are available |
| QName echoBindingOpName = new QName("http://tempuri.org/bindings", "echo"); |
| AxisBindingOperation echoBindingOp = (AxisBindingOperation) soap12Binding.getChild(echoBindingOpName); |
| assertNotNull(String.format("Cannot find %s binding operation on binding %s", echoBindingOpName, soap12Binding), echoBindingOp); |
| |
| AxisOperation echoOp = echoBindingOp.getAxisOperation(); |
| assertNotNull(String.format("Operation not set on binding operation %s", echoBindingOp.getName()), echoOp); |
| |
| //check that operation style is correctly identified and an operation with respective mep is created |
| assertTrue(String.format("Operation %s is not an instance of %s", echoOp.getName(), InOutAxisOperation.class.getName()), echoOp instanceof InOutAxisOperation); |
| assertEquals(String.format("Operation %s specifies an unexpected MEP uri: %s", echoOp.getName(), echoOp.getMessageExchangePattern()), |
| WSDL2Constants.MEP_URI_IN_OUT, echoOp.getMessageExchangePattern()); |
| |
| //check in/out messages |
| AxisMessage inMessage = echoOp.getMessage(WSDLConstants.MESSAGE_LABEL_IN_VALUE); |
| assertNotNull(String.format("No input message set on operation %s", echoOp.getName()), inMessage); |
| QName echoInMessageName = new QName("http://tempuri.org/types", "echo"); |
| assertEquals(String.format("Unexpected input message QName set on operation %s", echoOp.getName()), echoInMessageName, inMessage.getElementQName()); |
| //message name is 'echoRequest' whereas the QName's local name is simply 'echo' |
| assertEquals(String.format("Unexpected input message name set on operation %s", echoOp.getName()), "echoRequest", inMessage.getName()); |
| |
| AxisMessage outMessage = echoOp.getMessage(WSDLConstants.MESSAGE_LABEL_OUT_VALUE); |
| assertNotNull(String.format("No output message set on operation %s", echoOp.getName()), outMessage); |
| QName echoOutMessageName = new QName("http://tempuri.org/types", "echoResponse"); |
| assertEquals(String.format("Unexpected output message QName set on operation %s", echoOp.getName()), echoOutMessageName, outMessage.getElementQName()); |
| assertEquals(String.format("Unexpected output message name set on operation %s", echoOp.getName()), echoOutMessageName.getLocalPart(), outMessage.getName()); |
| } |
| |
| private AxisService populateAxisService(AxisConfiguration axisConf, File wsdlFile, WSDLLocator wsdlLocator) throws IOException { |
| InputStream in = null; |
| try { |
| in = new FileInputStream(wsdlFile); |
| WSDL11ToAxisServiceBuilder wsdl11Builder = new WSDL11ToAxisServiceBuilder(in); |
| if (wsdlLocator != null) { |
| wsdl11Builder.setCustomWSDLResolver(wsdlLocator); |
| } |
| wsdl11Builder.setDocumentBaseUri(wsdlFile.getParentFile().toURI().toString()); |
| if (axisConf != null) { |
| wsdl11Builder.useAxisConfiguration(axisConf); |
| } |
| AxisService service = wsdl11Builder.populateService(); |
| assertNotNull("Could not load AxisService from wsdl: " + wsdlFile.getAbsolutePath(), service); |
| |
| return service; |
| } finally { |
| if (in != null) { |
| in.close(); |
| } |
| } |
| } |
| |
| //custom locator that can located imported wsdls relative to the base wsdl uri (code borrowed from wsdl4j) |
| class CustomWSDLLocator implements WSDLLocator { |
| private String wsdlURI; |
| |
| private InputSource baseInputSource; |
| private Map<String, InputSource> importInputSources = new HashMap<String, InputSource>(); |
| private boolean closed = false; |
| private String baseURI; |
| private String lastImportURI; |
| |
| public CustomWSDLLocator(String baseURI, String wsdlURI) { |
| this.baseURI = baseURI; |
| this.wsdlURI = wsdlURI; |
| } |
| |
| public InputSource getBaseInputSource() { |
| if (baseInputSource == null) { |
| lastImportURI = baseURI + wsdlURI; |
| baseInputSource = new InputSource(lastImportURI); |
| } |
| return baseInputSource; |
| } |
| |
| public InputSource getImportInputSource(String parentLocation, String importLocation) { |
| InputSource inSource = (InputSource) importInputSources.get(importLocation); |
| if (inSource == null) { |
| lastImportURI = baseURI + importLocation; |
| inSource = new InputSource(lastImportURI); |
| importInputSources.put(importLocation, inSource); |
| } |
| return inSource; |
| } |
| |
| public String getBaseURI() { |
| return baseURI + wsdlURI; |
| } |
| |
| public String getLatestImportURI() { |
| return lastImportURI; |
| } |
| |
| public void close() { |
| closed = true; |
| } |
| |
| public boolean isClosed() { |
| return closed; |
| } |
| } |
| } |