Page 1 of 2 12 LastLast
Results 1 to 10 of 12

Thread: How to implement the web-service-proxy pattern

  1. #1
    Join Date
    May 2011
    Posts
    8

    Default How to implement the web-service-proxy pattern

    Hi guys,

    It is possible to implement the web-service-proxy pattern in Spring Integration ?

    See the figure below.

    The caller invoke a service locate in a web service proxy, the web servie proxy redirect the request to remote web service and send the response back to the caller.

    The caller known nothing about the web service. In fact, the calle think that the web service is located in the web service proxy.


    web-service-proxy-pattern.jpg

  2. #2
    Join Date
    Mar 2010
    Location
    Gtr Philadelphia, PA
    Posts
    2,142

    Default

    Yes

    Code:
    ws:inbound-gateway->transformRequestIfNecessary->ws:outbound-gateway->transformResponseIfNecessary
    Gary P. Russell
    Spring Integration Team
    SpringSource, a division of VMware

  3. #3
    Join Date
    May 2011
    Posts
    8

    Default

    Hi Gary,

    There is a sample for this case ?

    I'am trying the configuration below (based in the ws-inbound-gateway and ws-outbound-gateway samples):

    Code:
    <int-ws:inbound-gateway id="ws-inbound-gateway" request-channel="wsRequestChannel" extract-payload="false" />
    <int-ws:outbound-gateway id="ws-outbound-gateway" uri="http://www.w3schools.com/webservices/tempconvert.asmx" request-channel="wsRequestChannel"/>
    <int:channel id="wsRequestChannel" />
    <int:channel id="wsResponseChannel" />
    But, this configuration does not work because:

    1. It is missing a transformer (What operations would need to do this transformer?)
    2. Doen not undestand a WSDL request (example: http://server/service?wsdl)

    I understand that it is possible to do a web-service-proxy using the Spring Integration. However, for a novice user (like me , these settings are difficult to do at first. More examples would be helpful.

    Thanks,

    Fabio

  4. #4
    Join Date
    Mar 2010
    Location
    Gtr Philadelphia, PA
    Posts
    2,142

    Default

    I only suggested a transformer if the proxy wanted to change the data in any way.

    If you want full-blown WS support on the client side, including WSDL, security, etc, you can use Spring-WS on the inbound side

    http://static.springsource.org/spring-ws/site/

    The Spring WS documentation shows how to expose the WSDL.

    Then, from the @Endpoint, inject a messaging gateway and send the message to the outbound gateway.


    Code:
    SpringWSEndpoint->gw->ws:outbound-gateway
    Gary P. Russell
    Spring Integration Team
    SpringSource, a division of VMware

  5. #5
    Join Date
    May 2011
    Posts
    8

    Default

    Hi Gary,

    Quote Originally Posted by Gary Russell View Post
    Code:
    SpringWSEndpoint->gw->ws:outbound-gateway
    The quote above is exactly what I already do: In the ESB (Enterprise Service Bus), I have an SOAP Web Service (web-service-proxy) that redirect the income request to real web service.

    But, to add new Web Services in the ESB is very costly:

    1. Use the WSDL of the real WS to generate the artifacts that will be used in the ESB
    2. Add this generated code in the ESB
    3. Compile and deploy the new version of ESB


    I would like to use a better approach: Simply redirect the SOAP messages to the real web service. No generation of code neither compilation it is necessary.

    I could to do this using the MULE pattern:web-service-proxy, as shown below

    Code:
    <pattern:web-service-proxy name="productLine-ws-proxy"
    		inboundAddress="http://inbound-address/MyWebService"
    		outboundAddress="http://outbound-address/MyWebService"
    		/>
    With only this three lines of configuration, all requests to inbound-address was redirect to outbound-address.

    This is true to consume a service (SOAP messages send via POST) and also to access the service WSDL (http://inbound-address/MyWebService?WSDL)

    Is there something equivalent in the Spring Integration ?

    sorry for the insistence.

    My preference is to use the Spring Integration rather than migrate my current solution for the MULE. My current application is based on the Spring and I would like to continue.

    Thanks again,
    Fabio.

  6. #6
    Join Date
    Mar 2010
    Location
    Gtr Philadelphia, PA
    Posts
    2,142

    Default

    Well, my first suggestion will work

    Code:
    ws:inbound-gateway->ws:outbound-gateway
    for normal requests/responses, but it won't proxy the request for the WSDL. You could still deploy the WSDL statically as described in WS documentation.
    Gary P. Russell
    Spring Integration Team
    SpringSource, a division of VMware

  7. #7
    Join Date
    Mar 2010
    Location
    Gtr Philadelphia, PA
    Posts
    2,142

    Default

    I just ran a test and everything worked as expected.

    Code:
    <int-ws:inbound-gateway id="proxy" request-channel="toOutbound"/>
    
    <int:channel id="toOutbound" />
    
    <int-ws:outbound-gateway 
    	request-channel="toOutbound"
    	uri="http://localhost:18080/ws-inbound-gateway/echoservice" />
    To publish the wsdl from the proxied service on the proxy, download the wsdl, fix up the locationURI to point to the proxy, put it on the classpath, and add this bean to the servlet context...

    Code:
    <ws:static-wsdl id="thewebservice" location="classpath:my.wsdl"/>
    It's then available as

    Code:
    http://.../thewebservice.wsdl
    HTH
    Gary P. Russell
    Spring Integration Team
    SpringSource, a division of VMware

  8. #8
    Join Date
    May 2011
    Posts
    8

    Default

    Hi Gary,

    Thanks for the help.

    Using a SOAP remote web service like temperature converter, instead of POX approch (http://localhost:18080/ws-inbound-gateway/echoservice), result in the error below:

    Code:
    <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
       <SOAP-ENV:Header/>
       <SOAP-ENV:Body>
          <SOAP-ENV:Fault>
             <faultcode>SOAP-ENV:Server</faultcode>
             <faultstring xml:lang="en">Server did not recognize the value of HTTP Header SOAPAction: .</faultstring>
          </SOAP-ENV:Fault>
       </SOAP-ENV:Body>
    </SOAP-ENV:Envelope>
    This could be fixed using a <int-ws:header-enrich inside> inside a <int-chain> to add the soap-action. But, This should not be automatic (ws-outbound add the soap-action http, if any) ?

    Furthermore, using the <ws:static-wsdl> result in a non standard wsdl url. The default URL to download the WSDL follows the form http://<server>/webservice?wsdl instead of http://<server>/webservice.wsdl

    Of course this can also be corrected, but adds an additional overhead in the overall process.

    Finnaly, in the code below

    Code:
     <int-ws:inbound-gateway id="proxy" request-channel="toOutbound"/>
    it will be necessary to add a filter to redirect only the desired service.

    It would be possible to create a namespace that solves these problems, as shown below?

    Code:
    <int-ws:soap-proxy 
       wsdl-service-name="<wsdl:service@name>"  
       target-web-service="http://<server>/serviceName" 
       wsdl-location="classpath:META-INF/wsdl/serviceName.wsdl" 
       wsdl-ulr-pattern="?|." 
    />
    Where:

    1. wsdl-service-name --> [optional] The name of the service that could be accepted by this endpoint. If not specified, all income request will be accepteds;
    2. target-web-service --> The url of the proxied web service
    3. wsdl-location --> The local copy of the target-web-service WSDL
    4. wsdl-ulr-pattern --> specify if the wsdl url is in the form http://../serviceName.wsdl or http://../serviceName?wsdl

    Explanation:

    A - The spring servlet MessageDispatcherServlet dispatch all requests to org.springframework.integration.ws.SimpleWebServic eInboundGateway;

    B - The attribute wsdl-service-name allows that the endpoint only accept the requests of the expected services (It checks the attribute wsdl:service@name of the income requests). This attribute also allows a modular programming: new proxied web services could be stored in the modules themselves, because it only accept the specified requests;

    C - The attribute wsdl-location turn the ESB (Enterprise Service Bus) independent of the remote wsdl;

    D - The attribute wsdl-ulr-pattern alow two common wsdl url: "?wsdl" or ".wsdl"

    Thank you very much,
    Fabio.
    Last edited by lisboa; Mar 9th, 2012 at 06:35 AM. Reason: fix and add some clarification about the <int-ws:soap-proxy> proposal

  9. #9
    Join Date
    Mar 2010
    Location
    Gtr Philadelphia, PA
    Posts
    2,142

    Default

    You raise some interesting points.

    We do have access to the Http header (soap action), so we could propagate it, if we decide to raise the support of a ws proxy to a first class citizen.

    I don't believe ...?wsdl is a "standard" per se. In fact, there are lots of examples on the web using the .wsdl format...

    http://developer.ebay.com/devzone/sh...tOverview.html

    Please go ahead and open a new feature JIRA here https://jira.springsource.org/browse/INT and we'll consider being more friendly to WS proxying for an upcoming release.

    Thanks.
    Gary P. Russell
    Spring Integration Team
    SpringSource, a division of VMware

  10. #10
    Join Date
    May 2011
    Posts
    8

    Default

    Hello Gary,

    beyond soap-action, the (1) caller IP (Internet Protocol of the caller), the (2) requested URI and the (3) wsdl:service@name would also be useful.

    (1) The path of the requested URI is commonly used as web service selector. For example

    http://server/service1
    http://server/service2

    If the requested URI is present in the Spring Integration WS-Message, then it is possible to use a publish-subcribe-channel + filters to redirect the income messages to the appropriate ws-outbound-gateway (in fact, the appropriate target-web-services).

    Probably this could be made using the UriEndpointMapping.mapping properties, but it seems to me that this is not very modular, because new web-services-proxy requires modification in a centralized repository (the mapping) and, possibly, a server restart.

    Using the publish-subcribe-channel + filters approch, allow the adition of new web service proxy in its own module (i.e. add a new spring configurarion file with the new filter + ws-outbound-gateway) in a OSGI module (perhaps ..).

    (2) and (3) The caller IP and wsdl:service@name together with web service failure/success information turn easy to create usefull auditing:

    (2.a) The Caller IP-A accessed the wsdl:service@name resulting in a success (or failure)
    (2.b) The IP A could access the target-web-service-A, but could not access the target-web-service-B. This could be made using a servlet filter. In this case, it would be necessary to check if a income request is or is not a web service call, but that is exactly what is done by int-ws namespace...

    Using a servlet filter I have access to requested URI and caller IP, but the status (success, failure) of the web service invokation is not available (At least, not as accessible as a Spring Integration SOAPMessage);

    Note: In fact, the "?wsdl" is not a standard. I meant it is a common use for wsdl url (excuse me for my lack of precision).

    Thanks!
    Last edited by lisboa; Mar 9th, 2012 at 11:18 PM.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •