Chinmoy
Chinmoy

Reputation: 1754

How to consume a SOAP web service in a Mule Flow?

I am beginning with Mule flows and have seen the I have seen this page http://www.mulesoft.org/documentation/display/MULE3CONCEPTS/Using+Mule+with+Web+Services and http://www.mulesoft.org/documentation/display/MULEWS/Consuming+SOAP+Web+Services+in+Mule this oe too. They were not of much help. Currently, I have a simple mule flow as shown below.

Flow definition

<?xml version="1.0" encoding="UTF-8"?>

<mule xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:http="http://www.mulesoft.org/schema/mule/http"
    xmlns:cxf="http://www.mulesoft.org/schema/mule/cxf" xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
    xmlns:spring="http://www.springframework.org/schema/beans" xmlns:core="http://www.mulesoft.org/schema/mule/core"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="CE-3.2.1"
    xsi:schemaLocation="
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://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd ">
    <flow name="EchoFlow" doc:name="EchoFlow">
        <http:inbound-endpoint exchange-pattern="request-response"
            host="localhost" port="8081" path="service/echoflow" doc:name="HTTP" />
        <cxf:jaxws-client operation="" serviceClass="com.myapp.demo.ServiceAImplService" 
            doc:name="SOAP"/>
        <outbound-endpoint address="http://localhost:8080/ServiceA/services/" doc:name="Generic"/>
    </flow>
</mule>

I am using Mule studio. There is an HTTP inbound endpoint that expects a response. I tried configuring a jax-ws client which will call the actual web service. The WSDL for the service is:

wsdl file

<?xml version='1.0' encoding='UTF-8'?><wsdl:definitions name="ServiceAImplService" targetNamespace="http://service.demo.myapp.com/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://service.demo.myapp.com/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <wsdl:types>
<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://service.demo.myapp.com/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<import namespace="http://service.demo.myapp.com/" schemaLocation="http://localhost:8080/ServiceA/services/ServiceAImplPort?xsd=serviceaimpl_schema1.xsd"/>
</schema>
  </wsdl:types>
  <wsdl:message name="helloResponse">
    <wsdl:part element="tns:helloResponse" name="parameters">
    </wsdl:part>
  </wsdl:message>
  <wsdl:message name="hello">
    <wsdl:part element="tns:hello" name="parameters">
    </wsdl:part>
  </wsdl:message>
  <wsdl:portType name="IServiceA">
    <wsdl:operation name="hello">
      <wsdl:input message="tns:hello" name="hello">
    </wsdl:input>
      <wsdl:output message="tns:helloResponse" name="helloResponse">
    </wsdl:output>
    </wsdl:operation>
  </wsdl:portType>
  <wsdl:binding name="ServiceAImplServiceSoapBinding" type="tns:IServiceA">
    <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
    <wsdl:operation name="hello">
      <soap:operation soapAction="urn:Hello" style="document"/>
      <wsdl:input name="hello">
        <soap:body use="literal"/>
      </wsdl:input>
      <wsdl:output name="helloResponse">
        <soap:body use="literal"/>
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:service name="ServiceAImplService">
    <wsdl:port binding="tns:ServiceAImplServiceSoapBinding" name="ServiceAImplPort">
      <soap:address location="http://localhost:8080/ServiceA/services/ServiceAImplPort"/>
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>

I am not too sure about configuring a jax-ws client as you can see. So, how exactly do I consume a SOAP web service in this flow.


My second question: How do I transform the payload to make a call from one web-service to another web-service (both SOAP). What will be the flow?


And finally, how do I merge payloads? Say, I have three web services called in parallel and their responses all return together. How do I merge the payloads so that I can read it in another service (after combining the responses from multiple services called in parallel)?



What is the equivalent implementation of

       <pattern:web-service-proxy name="ex-proxy"
        inboundAddress="http://localhost:8081/xxx"
        outboundAddress="http://xx.xx.com/XXX_WS/xxxWService.asmx" /> 

using CXF proxy service/client? And that brings me to another question, when to use CXF-service and when to use CXF-client? And lastly, is there a detailed documentation or example/tutorial for Mule Flow Orchestration?

Upvotes: 3

Views: 23210

Answers (3)

Petter Nordlander
Petter Nordlander

Reputation: 22279

Try using a CXF proxy (service and client). In this case, you will get the raw XML into the flow. Of course you can deserialize it to java if you need to, for instance via XML-To-Object transformer (XStream).

http://www.mulesoft.org/documentation/display/MULE3USER/Proxying+Web+Services+with+CXF

From there, there are several ways to do transform the payload in the middle. Either go through java (as mentioned above) and transform java layer objects or write an XSLT sheet that does the transformation.Or transform the XML using Java and/or the other tools Mule provides (scripting, xpath etc).

You might want to explain the aggregation case once more in details. Do you want to merge the responses for future use or have one web service call -> fan out -> aggregate -> response?

Upvotes: 2

Pascal
Pascal

Reputation: 11

If you have access to the Service Endpoint Interface of the Web-Service, you can easily consume the Web-Service in a simple Java-Component like this:

public class CityServiceComponent {

    public String process(String input) {

        // list of cities
        StringBuilder output = new StringBuilder();

        // create service factory
        JaxWsProxyFactoryBean serviceFactory = new JaxWsProxyFactoryBean();
        // set service endpoint interface
        serviceFactory.setServiceClass(CityService.class);
        // set wsdl location
        serviceFactory.setAddress("http://localhost:8080/city-service-provider/CityService?wsdl");
        // init city service
        CityService cityService = (CityService) serviceFactory.create();

        // call city service and get all available cities
        List<City> cities = cityService.findAll();

        // build list of cities
        for (City city : cities) {

            output.append(city.toString());
            output.append("\n");
        }

        // forward output message
        return output.toString();

    }

}

Hope this helps...

Upvotes: 1

babybug
babybug

Reputation: 15

1) Generally, you should use "Proxy Service" instead of "JAX-WS" to consume a remote web service.

2) Use chaining routers to pass responses between multiple endpoints.

Upvotes: 1

Related Questions