Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 3 Next »

We will go through creating and implementating web services in our openhub-example module.

WSDL and XSD implementation

  • WSDL and XSD is defined in Contract-First design approach - firstly define web service interfaces, secondly implement them in specific language.
  • there are two files (in package resources/org.openhubframework.openhub.modules.in.hello.ws.v1_0): 
    • WSDL definition (e.g. hello-v1.0.wsdl
    • XSD with requests/responses definition (helloOperations-v1.0.xsd). XSD contains request definitions, imports commonTypes-v1.0.xsd with common types from openhub-core module

Versioning

Use versions in format <major>.<minor>

Minor version is for compatible changes, major version indicates non-compatible changes.

Versioning should be explicit - it means to present version number in elements, URLs etc.:

If there is change in WSDL's version then change versions of XSDs as well.

See Best practices for more development tips.

hello-v1.0.wsdl:

  • traceHeader is mandatory for asynchronnous messages
  • it's good practice to adhere some name conventions, for example those presented in Best practices


<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
                  xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
                  xmlns:xs="http://www.w3.org/2001/XMLSchema"
                  xmlns:cc="http://openhubframework.org/ws/Common-v1"
                  xmlns:tns="http://openhubframework.org/ws/HelloService-v1"
                  targetNamespace="http://openhubframework.org/ws/HelloService-v1">

    <wsdl:types>
        <xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified">
            <xs:import namespace="http://openhubframework.org/ws/HelloService-v1" schemaLocation="helloOperations-v1.0.xsd"/>
        </xs:schema>
    </wsdl:types>

    <wsdl:message name="traceHeaderMsg">
        <wsdl:part element="cc:traceHeader" name="traceHeader"/>
    </wsdl:message>

    <wsdl:message name="syncHelloRequestMsg">
        <wsdl:part element="tns:syncHelloRequest" name="syncHelloRequest">
        </wsdl:part>
    </wsdl:message>
    <wsdl:message name="syncHelloResponseMsg">
        <wsdl:part element="tns:syncHelloResponse" name="syncHelloResponse">
        </wsdl:part>
    </wsdl:message>
    <wsdl:message name="asyncHelloRequestMsg">
        <wsdl:part element="tns:asyncHelloRequest" name="asyncHelloRequest">
        </wsdl:part>
    </wsdl:message>
    <wsdl:message name="asyncHelloResponseMsg">
        <wsdl:part element="tns:asyncHelloResponse" name="asyncHelloResponse">
        </wsdl:part>
    </wsdl:message>


    <wsdl:portType name="hello-v1.0">
        <wsdl:operation name="syncHello">
            <wsdl:input message="tns:syncHelloRequestMsg" name="syncHelloRequest">
            </wsdl:input>
            <wsdl:output message="tns:syncHelloResponseMsg" name="syncHelloResponse">
            </wsdl:output>
        </wsdl:operation>
        <wsdl:operation name="asyncHello">
            <wsdl:input message="tns:asyncHelloRequestMsg" name="asyncHelloRequest">
            </wsdl:input>
            <wsdl:output message="tns:asyncHelloResponseMsg" name="asyncHelloResponse">
            </wsdl:output>
        </wsdl:operation>
    </wsdl:portType>


    <wsdl:binding name="helloBindingSoap11-v1.0" type="tns:hello-v1.0">
        <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>

        <wsdl:operation name="syncHello">
            <soap:operation soapAction=""/>
            <wsdl:input name="syncHelloRequest">
                <soap:body use="literal"/>
            </wsdl:input>
            <wsdl:output name="syncHelloResponse">
                <soap:body use="literal"/>
            </wsdl:output>
        </wsdl:operation>
        <wsdl:operation name="asyncHello">
            <soap:operation soapAction=""/>
            <wsdl:input name="asyncHelloRequest">
                <soap:header message="tns:traceHeaderMsg" part="traceHeader" use="literal"/>
                <soap:body use="literal"/>
            </wsdl:input>
            <wsdl:output name="asyncHelloResponse">
                <soap:body use="literal"/>
            </wsdl:output>
        </wsdl:operation>
    </wsdl:binding>


    <wsdl:service name="helloService-v1.0">
        <wsdl:port binding="tns:helloBindingSoap11-v1.0" name="helloSoap11-v1.0">
            <soap:address location="/ws/hello/v1"/>
        </wsdl:port>
    </wsdl:service>

</wsdl:definitions>

helloOperations-v1.0.xsd:

  • this XSD contains requests and responses for each operation
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified"
           xmlns:cc="http://openhubframework.org/ws/Common-v1"
           xmlns:xs="http://www.w3.org/2001/XMLSchema"
           targetNamespace="http://openhubframework.org/ws/HelloService-v1">

    <!--
        Note: all XSD/WSDL files are copied together at one place during XJC (Maven) code generation
    -->
    <xs:import namespace="http://openhubframework.org/ws/Common-v1" schemaLocation="commonTypes-v1.0.xsd"/>

    <!-- syncHello -->
    <xs:element name="syncHelloRequest">
        <xs:annotation>
            <xs:documentation>Synchronous calling of hello service</xs:documentation>
        </xs:annotation>

        <xs:complexType>
            <xs:sequence>
                <xs:element name="name" type="xs:string">
                    <xs:annotation>
                        <xs:documentation>Greeting's name</xs:documentation>
                    </xs:annotation>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:element name="syncHelloResponse">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="greeting" type="xs:string"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>


    <!-- asyncHello -->
    <xs:element name="asyncHelloRequest">
        <xs:annotation>
            <xs:documentation>Asynchronous calling of hello service</xs:documentation>
        </xs:annotation>

        <xs:complexType>
            <xs:sequence>
                <xs:element name="name" type="xs:string">
                    <xs:annotation>
                        <xs:documentation>Greeting's name</xs:documentation>
                    </xs:annotation>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:element name="asyncHelloResponse">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="confirmAsyncHello" type="cc:callbackResponse"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>

</xs:schema>

Generating Java sources from WSDL/XSD

We use jaxws-maven-plugin plugin for generating Java classes from WSDL/XSD:

  • see pom.xml in openhub-example module for more details
  • we use two more plugins before generating Java classes
    • maven-dependency-plugin: copies resources (xjb, xsd) from other modules
    • maven-resources-plugin: copies all xjb, wsdl and xsd files to a single directory for generating Java model from WSDL/XSD,allowing WSDL/XSD files to reference each other easily with a simple relative path.
  • we defined two XJB binding files for use (both from core-api module)
    • jaxb_global_bindings.xjb: global Java type bindings, for example org.joda.time.DateTime vs xs:dateTime
    • jaxb_common_bindings.xjb: bindings of common types defined in commonTypes-v1.0.xsd


<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>jaxws-maven-plugin</artifactId>
    <configuration>
        <sourceDestDir>${modules.output.directory}</sourceDestDir>
        <wsdlDirectory>${modules.import.directory}</wsdlDirectory>
        <bindingDirectory>${modules.import.directory}</bindingDirectory>
        <bindingFiles>
            <bindingFile>jaxb_global_bindings.xjb</bindingFile>
        </bindingFiles>
    </configuration>
    <executions>
        <execution>
            <id>WSDL-import-in-hello-model</id>
            <goals>
                <goal>wsimport</goal>
            </goals>
            <configuration>
                <staleFile>${project.build.directory}/jaxws/.in.hello.model</staleFile>
                <packageName>org.openhubframework.openhub.modules.in.hello.model</packageName>
                <wsdlFiles>
                    <wsdlFile>hello-v1.0.wsdl</wsdlFile>
                </wsdlFiles>
                <bindingFiles>
                    <bindingFile>jaxb_global_bindings.xjb</bindingFile>
                    <bindingFile>jaxb_common_bindings.xjb</bindingFile>
                </bindingFiles>
            </configuration>
        </execution>
    </executions>
</plugin>

Publishing WSDL/XSD

sw

Route implementations

sw


publish WSDL/XSD files - add configuration to /META-INF/sp_ws_wsdl.xml. sws:static-wsdl is used for publishing WSDL, XSD files have to be published separately. See Spring Web Services reference manual where you find more information because Spring WS is underlying library for web service communication.

  • register XSD schemas for validation incoming/outgoing messages in configuration of "validatingInterceptor" (class HeaderAndPayloadValidatingInterceptor)
    • traceHeader is mandatory for asynchronous requests only - set synchronnous requests in ignoreRequests property to ignore this validation
  • configure conversion to Java classes - use jaxws-maven-plugin Maven plugin for conversion from WSDL or jaxb2-maven-plugin for conversion from XSD



  • No labels