MuleSoft: Contract-First Web Service Development
Learn the quick and easy steps on how to develop and expose a WSDL-first and contract-first web service by using Anypoint studio.
Join the DZone community and get the full member experience.
Join For FreeLearn about how to develop a WSDL-first web service using Anypoint studio.
In short, the steps required to expose a contract-first web service are:
- Define contract (WSDL and XML schema files).
- Create Mule project in Anypoint studio and place the contract files.
- Create a flow with an HTTP endpoint.
- Configure a CXF component.
- Implement Service Endpoint Interface (SEI) and configure the implementation as a Java component.
- Test the component using SOAP UI.
1. Define Contract (WSDL and XML Schema Files)
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<wsdl:definitions
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:mov="http://ss.com/ws/MovieService/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="MovieService"
targetNamespace="http://ss.com/ws/MovieService/">
<wsdl:types>
<xsd:schema targetNamespace="http://ss.com/ws/MovieService/" attributeFormDefault="unqualified" elementFormDefault="qualified">
<xsd:element name="movieSearch" type="mov:movieSearchRequestType" />
<xsd:element name="movieSearchResponse" type="mov:movieSearchResponseType"/>
<xsd:complexType name="movieSearchRequestType">
<xsd:sequence>
<xsd:element name="location" type="xsd:string" />
<xsd:element name="date" type="xsd:date" />
<xsd:element name="movieName" type="xsd:string" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="movieSearchResponseType">
<xsd:sequence>
<xsd:element name="showDetails" type="mov:showType" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="showType">
<xsd:sequence>
<xsd:element name="cinemaName" type="xsd:string" />
<xsd:element name="showTimes" type="xsd:string" minOccurs="1" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
</wsdl:types>
<wsdl:message name="movieSearchRequest">
<wsdl:part element="mov:movieSearch" name="parameters" />
</wsdl:message>
<wsdl:message name="movieSearchResponse">
<wsdl:part element="mov:movieSearchResponse" name="parameters" />
</wsdl:message>
<wsdl:portType name="MovieService">
<wsdl:operation name="movieSearch">
<wsdl:input message="mov:movieSearchRequest" />
<wsdl:output message="mov:movieSearchResponse" />
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="MovieServiceSOAP" type="mov:MovieService">
<soap:binding style="document"
transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="movieSearch">
<soap:operation soapAction="http://ss.com/ws/MovieService/movieSearch" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="MovieService">
<wsdl:port binding="mov:MovieServiceSOAP" name="MovieServiceSOAP">
<soap:address location="http://www.example.org/" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
2. Create Mule Project in Anypoint Studio and Place Contract Files
Create a Mule project in Anypoint Studio and place the defined WSDL to the location src/main/wsdl as demonstrated below.
3. Create a Flow With an HTTP Endpoint
I configured the HTTP endpoint port as 9090 and path as /contract.
4. Configure CXF Component
Mule has a CXF component in the Component palette for configuring JAX-WS-based web services. CXF framework is the implementation of the JAX-WS specification. Drag and drop CXF component from the Component palette.
Configure the CXF component as follows:
The sources are generated from the WSDL document by the CXF framework:
5. Implement SEI and Configure the Implementation as a Java Component
Create a package for placing the implementation class:
Here is the implementation for the generated Service Endpoint Interface (SEI). For the sake of simplicity, we hard coded the implementation.
package com.ss.source.impl;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.datatype.XMLGregorianCalendar;
import javax.xml.ws.RequestWrapper;
import javax.xml.ws.ResponseWrapper;
import com.ss.source.MovieService;
import com.ss.source.ObjectFactory;
import com.ss.source.ShowType;
@WebService(targetNamespace = "http://ss.com/ws/MovieService/", name = "MovieService")
@XmlSeeAlso({
ObjectFactory.class
})
public class MovieServiceImpl implements MovieService {
@Override
@WebMethod(action = "http://ss.com/ws/MovieService/movieSearch")
@RequestWrapper(localName = "movieSearch", targetNamespace = "http://ss.com/ws/MovieService/", className = "com.ss.ws.MovieSearchRequestType")
@ResponseWrapper(localName = "movieSearchResponse", targetNamespace = "http://ss.com/ws/MovieService/", className = "com.ss.ws.MovieSearchResponseType")
@WebResult(name = "showDetails", targetNamespace = "")
public List < ShowType > movieSearch(
@WebParam(name = "location", targetNamespace = "") java.lang.String location,
@WebParam(name = "date", targetNamespace = "") javax.xml.datatype.XMLGregorianCalendar date,
@WebParam(name = "movieName", targetNamespace = "") java.lang.String movieName
) {
List < ShowType > shows = new ArrayList < ShowType > ();
if (movieName.equalsIgnoreCase("Logan") && location.equalsIgnoreCase("hyderabad")) {
ShowType showType = new ShowType();
showType.setCinemaName("INOX Multiplex");
showType.setShowTimes(Arrays.asList("10:00 AM", "2:00 PM", "7:00 PM"));
shows.add(showType);
}
return shows;
}
}
Drag and drop the Java component from the Component palette and configure as demonstrated below:
The flow after all configurations:
< ? xml version = "1.0"
encoding = "UTF-8" ? >
< mule xmlns : http = "http://www.mulesoft.org/schema/mule/http"
xmlns: cxf = "http://www.mulesoft.org/schema/mule/cxf"
xmlns = "http://www.mulesoft.org/schema/mule/core"
xmlns: doc = "http://www.mulesoft.org/schema/mule/documentation"
xmlns: spring = "http://www.springframework.org/schema/beans"
xmlns: xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi: schemaLocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http: //www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http: //www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd
http: //www.mulesoft.org/schema/mule/cxf http://www.mulesoft.org/schema/mule/cxf/current/mule-cxf.xsd">
< http: listener - config name = "HTTP_Listener_Configuration"
host = "localhost"
port = "9090"
doc: name = "HTTP Listener Configuration" / >
< cxf: configuration name = "CXF_Configuration"
enableMuleSoapHeaders = "true"
initializeStaticBusInstance = "true"
doc: name = "CXF Configuration" / >
< flow name = "contract_firstFlow" >
< http: listener config - ref = "HTTP_Listener_Configuration"
path = "/contract"
doc: name = "HTTP" / >
< cxf: jaxws - service configuration - ref = "CXF_Configuration"
serviceClass = "com.ss.source.MovieService"
doc: name = "CXF" / >
< component class = "com.ss.source.impl.MovieServiceImpl"
doc: name = "Java" / >
< /flow> < /mule>
Run the flow from Anypoint studio.
Test the Service using http://localhost:9090/contract?wsdl.
Open the SOAP UI and create the new SOAP project using the above WSDL URL.
Test the project using the new request as demonstrated below:
Congrats! You got the response as per the implementation.
Opinions expressed by DZone contributors are their own.
Comments