Chapter 40. 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.
40.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 40.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 40.1. 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&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 40.4, “Handling HTTP Headers”.