Book Image

Instant Apache Camel Message Routing

By : Bilgin Ibryam
Book Image

Instant Apache Camel Message Routing

By: Bilgin Ibryam

Overview of this book

With new APIs and technologies emerging every day, the need for integrating applications is greater than ever before. With the right tools, integrating applications is not hard. Apache Camel is the leading open source integration and message orchestration framework. Apache Camel, which has a variety of connectors and features numerous well-known integration patterns, has an enormous advantage over home grown integration solutions. Instant Apache Camel Message Routing helps you to get started using the Camel routing engine and Enterprise Integration Patterns. This book will show you how to create integration applications using Apache Camel. You will learn how Camel works and how to leverage the Enterprise Integration Patterns for message routing. Instant Apache Camel Message Routing is a practical and step-by-step guide to Apache Camel and integration patterns. This book will show you how Apache Camel works and how it integrates disparate systems using Enterprise Integration Patterns. The book starts with a high level overview of the Camel architecture before diving into message routing principles. Then, it introduces a number of patterns, complete with diagrams, common use cases, and examples about how to use them with Camel. The book also shows you how to test and monitor Camel applications and cope with failure scenarios.
Table of Contents (7 chapters)

Using components (Simple)


As of this writing Camel has around 150 components with support for many protocols and technologies. The full list of components is available at http://camel.apache.org/components.html with links to each component's details page where all the configuration options are explained. A component represents an adapter for a specific API and allows Camel to exchange messages with external applications. The following diagram depicts how components enable external applications sending data to a messaging channel using components' endpoints and also receive data from it:

In this tutorial, we will demonstrate how to leverage Camel components by creating an HTTP endpoint, and calling external services with the Jetty component.

Getting ready

The complete source code for this tutorial is located under the project camel-message-routing-examples/using-components.

How to do it...

Camel-core contains a dozen components which are always available with Camel. These include bean, direct, vm, file, log, mock, seda, timer, xslt, and a few more. All of the other components used for routing have to be retrieved and added additionally to the classpath.

  1. In this tutorial, we will use the jetty component, so the following camel-jetty dependency will be needed:

    <dependency>
        <groupId>org.apache.camel</groupId>
        <artifactId>camel-jetty</artifactId>
        <version>${camel-version}</version>
    </dependency>
  2. Next, we will create a route with Jetty consumer and log the messages using log component. Finally, we use a Jetty producer to make external HTTP calls to Google.

    from("jetty:http://localhost:8181?matchOnUriPrefix=true")
        .to("log://org.apache.camel.howto?showAll=true")
    .to("jetty:http://www.google.co.uk?bridgeEndpoint=true&throwExceptionOnFailure=false");

When this route is started, it will start a Jetty web server listening on localhost port 8080. If we use a web browser and try to access http://localhost:8080, the route will log the request, make an HTTP call to http://www.google.co.uk, and return the result to the requestor. And, what we should see in our browser (if all works fine) is Google's home page. So this route is in fact an HTTP proxy that logs all requests.

How it works...

Routes in Camel consist of EIPs and components. EIPs transform the messages inside the routes, whereas components usually allow messages to reach external systems. Components can be added to Camel runtime (CamelContext) in two ways. The less popular way is manually instantiating a component and adding it to the context:

camelContext.addComponent("jetty", new JettyHttpComponent());

The second way of adding components to Camel runtime is through the auto-discovery mechanism. In this mode, when a component is needed as part of the routing process and it is not available to CamelContext, Camel will scan the classpath and look at META-INF/services/org/apache/camel/component for a file matching the component name. The jetty component's file META-INF/services/org/apache/camel/component/jetty contains the following:

class=org.apache.camel.component.jetty.JettyHttpComponent

The content of the file shows the actual component class, so that Camel can instantiate it, and add it to CamelContext. A component is in essence an endpoint factory, it creates endpoints based on URLs. The Endpoint interface models the end of channel through which systems can send and receive messages. Camel endpoints are usually referenced using URLs. URLs provide a unified way for describing endpoints for various systems. The Camel URL has the following structure: schema:context path:options. For example, the Jetty URL from the previous route looks like:

jetty://http://www.google.co.uk?bridgeEndpoint=true&throwExceptionOnFailure=false

Its schema is jetty, which tells Camel what is the component class name, that the context path is http://www.google.co.uk and it has two options bridgeEndpoint=true&throwExceptionOnFailure=false. The context path is endpoint specific; it means different things for different endpoints. For example, the context path of the log endpoint used above org.apache.camel.howto represents the logging category, whereas in Jetty it is the host and port name. Options are also endpoint specific, and each endpoint has different options for the underlying technology. Once an endpoint is instantiated for a specific URL, then it is responsible for creating consumers and producers.

At a very high level, the process of using a component in a Camel route goes through the following steps: when a URI is used in a route, based on the URI schema, a component is instantiated. The component uses the context path and the options to create an endpoint. Then the endpoint creates a consumer or producer depending on what is needed in the route. When the consumer receives a message from the external system, it transforms the message to an exchange and starts routing it in Camel. The producer, on the other hand, receives an exchange as part of the routing, and delivers it to the external system using the external API.

There's more...

We saw how to pass primitive types and string literals as Endpoint options. Next, we will see how Camel offers a unified access to the environment it is running on, and how to pass complex objects from its environment as options in the URLs.

Accessing the Registry

Camel Registry provides a unified interface for accessing Java beans on the runtime environment. There are different Registry implementations and depending on our DSL choice, one is always in use. If we use the Java DSL, by default the Registry will be JndiRegistry. This Registry uses Java Naming and Directory Interface (JNDI) to lookup beans. There is also a simpler Map based Registry available to use with Java DSL. With SimpleRegistry, we can manually add bean instances to make them available during routing:

SimpleRegistry registry = new SimpleRegistry();
registry.put("myHttpClient", new HttpClient());
CamelContext context = new DefaultCamelContext(registry);

Once a bean is available in the Registry, we can pass it as an option to an endpoint by prefixing its key with #. For example, the Jetty producer has an option called httpClient for setting a custom HttpClient, and we can pass our instance from the SimpleRegistry, as shown in the following code:

.to("jetty:http://www.google.co.uk?bridgeEndpoint=true&httpClient=#myHttpClient");

Options are usually fields on the concrete Endpoint implementation, and to set the httpClient field of JettyHttpEndpoint, Camel will look up the Registry using myHttpClient as the key.

When Spring XML DSL is used, the Registry implementation is provided by the ApplicationContextRegistry class, which gives access to the beans from the Spring ApplicationContext. So, if we have a Spring bean declaration like the following line of code, we can access it as Endpoint options with the same syntax as the previous #myHttpClient:

<bean id="myHttpClient" class="org.eclipse.jetty.client.HttpClient"/>

There is also an OsgiServiceRegistry implementation used when running Camel in the OSGI container and giving access to the beans from the OSGI service registry.