Chapter 41. Proxying a Web Service

Abstract

A common use case for the Camel CXF component is to use a route as a proxy for a Web service. That is, in order to perform additional processing of WS request and response messages, you interpose a route between the WS client and the original Web service.

41.1. Proxying with HTTP

Overview

The simplest way to proxy a SOAP/HTTP Web service is to treat the request and reply messages as HTTP packets. This type of proxying can be used where there is no requirement to read or modify the messages passing through the route. For example, you could use this kind of proxying to apply various patterns of flow control on the WS messges.
Figure 41.1, “Proxy Route with Message in HTTP Format” shows an overview of how to proxy a Web service using an Apache Camel route, where the route treats the messages as HTTP packets. The key feature of this route is that both the consumer endpoint (at the start of the route) and the producer endpoint (at the end of the route) must be compatible with the HTTP packet format.

Figure 41.1. Proxy Route with Message in HTTP Format

Proxy Route with Message in HTTP Format

Alternatives for the consumer endpoint

The following Apache Camel endpoints can be used as consumer endpoints for HTTP format messages:
  • Jetty endpoint—is a lightweight Web server. You can use Jetty to handle messages for any HTTP-based protocol, including the commonly-used Web service SOAP/HTTP protocol.
  • Camel CXF endpoint in MESSAGE mode—when a Camel CXF endpoint is used in MESSAGE mode, the body of the exchange message is the raw message received from the transport layer (which is HTTP). In other words, the Camel CXF endpoint in MESSAGE mode is equivalent to a Jetty endpoint in the case of HTTP-based protocols.

Consumer endpoint for HTTP

A Jetty endpoint has the general form, jetty:HttpAddress. To configure the Jetty endpoint to be a proxy for a Web service, use a HttpAddress value that is almost identical to the HTTP address the client connects to, except that Jetty's version of HttpAddress uses the special hostname, 0.0.0.0 (which matches all of the network interfaces on the current machine).
<route>
    <from uri="jetty:http://0.0.0.0:9093/Customers?matchOnUriPrefix=true"/>
    ...
</route>

matchOnUriPrefix option

Normally, a Jetty consumer endpoint accepts only an exact match on the context path. For example, a request that is sent to the address http://localhost:9093/Customers would be accepted, but a request sent to http://localhost:9093/Customers/Foo would be rejected. By setting matchOnUriPrefix to true, however, you enable a kind of wildcarding on the context path, so that any context path prefixed by /Customers is accepted.

Alternatives for the producer endpoint

The following Apache Camel endpoints can be used as producer endpoints for HTTP format messages:
  • Jetty HTTP client endpoint(recommended) the Jetty library implements a HTTP client. In particular, the Jetty HTTP client features support for HttpClient thread pools, which means that the Jetty implementation scales particularly well.
  • HTTP endpoint—the HTTP endpoint implements a HTTP client based on the HttpClient 3.x API.
  • HTTP4 endpoint—the HTTP endpoint implements a HTTP client based on the HttpClient 4.x API.

Producer endpoint for HTTP

To configure a Jetty HTTP endpoint to send HTTP requests to a remote SOAP/HTTP Web service, set the uri attribute of the to element at the end of the route to be the address of the remote Web service, as follows:
<route>
    ...
    <to uri="jetty:http://localhost:8083/Customers?bridgeEndpoint=true&amp;throwExceptionOnFailure=false"/>
</route>

bridgeEndpoint option

The HTTP component supports a bridgeEndpoint option, which you can enable on a HTTP producer endpoint to configure the endpoint appropriately for operating in a HTTP-to-HTTP bridge (as is the case in this demonstration). In particular, when bridgeEndpoint=true, the HTTP endpoint ignores the value of the Exchange.HTTP_URI header, using the HTTP address from the endpoint URI instead.

throwExceptionOnFailure option

Setting throwExceptionOnFailure to false ensures that any HTTP exceptions are relayed back to the original WS client, instead of being thrown within the route.

Handling message headers

When defining a HTTP bridge application, the CamelHttp* headers set by the consumer endpoint at the start of the route can affect the behavior of the producer endpoint. For this reason, in a bridge application it is advisable to remove the CamelHttp* headers before the message reaches the producer endpoint, as follows:
<route>
    <from uri="jetty:http:..."/>
    ...
    <removeHeaders pattern="CamelHttp*"/>
    <to uri="jetty:http:..."/>
</route>

Outgoing HTTP headers

By default, any headers in the exchange that are not prefixed by Camel will be converted into HTTP headers and sent out over the wire by the HTTP producer endpoint. This could have adverse consequences on the behavior of your application, so it is important to be aware of any headers that are set in the exchange object and to remove them, if necessary.
For more details about dealing with headers, see Section 41.4, “Handling HTTP Headers”.