Web service proxying

The proxying of requests through to backend services is a common use case for Camel. Decoupling the web service client from the backend service allows you to more easily move or change the backend, as you only need to update the proxy code, as opposed to all of the client systems that would otherwise use the backend directly. This technique is known as endpoint virtualization.

A proxy may also be used to impose a security or auditing layer, for use cases such as exposing the original service to new types of clients, for example, ones external to your company.

This recipe will show you the basics of creating a simple web service proxy in Camel.

Getting ready

This recipe assumes that you have a project with JAX-WS artifacts created as described in the Generating the service stubs from a WSDL recipe. To use the generated API, you need to include a dependency to that project in your build:

<dependency>
  <groupId>org.camelcookbook.examples</groupId>
  <artifactId>ws-payments-api</artifactId>
  <version>1.0-SNAPSHOT</version>
</dependency>

This recipe's example is based on paymentService.wsdl. For this example, we are assuming that the proxy and backend service have identical WSDL interfaces. If they were different, you would need to generate the JAX-WS artifacts for both WSDLs in separate projects.

All source files for this recipe are located in the ws-camel-routes project in the camel-cookbook-web-services module. The Java code for this recipe is located in the org.camelcookbook.ws.proxy package. The Spring XML files are located under src/main/resources/META-INF/spring and prefixed with proxy.

How to do it...

There are two main steps to this recipe: configure the frontend and backend Camel CXF endpoints, and specify a route from one to the other.

  1. Configure the endpoints.

    In the XML DSL, within the Spring beans element, configure two cxfEndpoints; one for the frontend proxy, and the other for the backend service:

    <cxf:cxfEndpoint
        id="paymentServiceProxy"
        address="http://host1:port1/paymentService"
        serviceClass="org.camelcookbook.ws.payment_service.Payment"/>
    
    <cxf:cxfEndpoint
        id="paymentServiceBackend"
        address="http://host2:port2/paymentService"
        serviceClass="org.camelcookbook.ws.payment_service.Payment"/>

    In the Java DSL, we create endpoint URI strings for each of the endpoints:

    final String paymentServiceProxyUri =
        "cxf:http://host1:port1/paymentService" +
        "?serviceClass=" +
        Payment.class.getCanonicalName());
    
    final String paymentServiceBackendUri =
        "cxf:http://host2:port2/paymentService" +
        "?serviceClass=" +
        Payment.class.getCanonicalName());
  2. Create the proxy route.

    In the XML DSL, this is defined as:

    <route id="wsProxy">
      <from uri=
          "cxf:bean:paymentServiceProxy?dataFormat=PAYLOAD"/>
      <log message="request = ${body}"/>
      <to uri=
          "cxf:bean:paymentServiceBackend?dataFormat=PAYLOAD"/>
      <log message="response = ${body}"/>
    </route>

    In the Java DSL, the same route is expressed as:

    from(paymentServiceProxyUri + "&dataFormat=PAYLOAD")
        .id("wsProxy")
      .log("request = ${body}")
      .to(paymentServiceBackendUri + "&dataFormat=PAYLOAD")
      .log("response = ${body}");

Note

We have used the dataFormat=PAYLOAD option to process the body of the SOAP message as XML. This isn't strictly necessary, but it can help improve throughput as the Camel CXF Component won't convert the message body from XML to POJO and back to XML.

How it works...

This recipe is effectively combining two previous recipes; the Invoking a remote web service from Camel recipe, and the Implementing a web service with a Camel route recipe into one with the difference being that the Camel route does not process the message, but rather relays it to the backend service.

Our recipe's example assumes that both frontend and backend services have identical WSDL interfaces. If they are different, you can update the endpoint configuration appropriately, specifically setting the serviceClass option to reference the correct JAX-WS WebService artifact. You can then perform any necessary transformations of the body in your proxy Camel route in order to bridge the two interfaces.

You may also need to remove or modify certain exchange headers, as headers set by Camel CXF from the consuming (from) endpoint may interfere with the behavior of the producing endpoint by overriding the default behavior specified by the endpoint URI. For example, if your backend has a different operation name from that of the proxy web service, you would need to update the operationName header before invoking the backend service.

There's more...

You can explicitly add an Error Handler to allow you to specify redelivery settings. Redelivery can be useful to deal with situations such as your backend service becoming temporarily unavailable due to normal maintenance or an upgrade. Camel can attempt to redeliver the message after a delay providing the appearance of continuous availability.

See also

  • Camel CXF Component: http://camel.apache.org/cxf
  • Apache CXF: http://cxf.apache.org
  • The Retrying an operation recipe in Chapter 7, Error Handling and Compensation
  • The Generating the service stubs from a WSDL recipe
  • The Invoking a remote web service from Camel recipe
  • The Implementing a web service with a Camel route recipe
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.19.243