Overview
Camel services allow you to leverage the core routing engine inside of Apache Camel to route between services in SwitchYard. All of the EIP and core routing support in Camel is available to your service implementation. Each Camel route is exposed as a service within SwitchYard, which means it has a well-defined contract and can be injected into any other service in the runtime.
Creating a Camel Service
The first thing you need to decide when you create a Camel routing service is whether you want to use the Java DSL or XML dialect for the route. Functionally, they are more or less equivalent, so it's more a choice of how you want to express your routing logic. If you want create a Java DSL route, select the "Camel (Java)" implementation type. For XML, use the "Camel (XML)" type. Regardless of which language you choose, the following information is required:
-
Name : the name of the Java class or XML file for your bean service.
-
Service Name : the name of the service your bean will provide.
-
Interface : the contract for the service being provided. Camel supports Java, WSDL, and ESB contract types.
For details on each type of Camel route, see the Java DSL Routes and XML Routes sections below. You can have multiple routing services per application, each with it's own routing language (e.g. an application can have two Java DSL routes and one XML route). There are some general guidelines to keep in mind with both types of routes:
-
There is only one route per service.
-
The consumer or "from" endpoint in a route is always a "switchyard" endpoint and the endpoint name must equal the service name. This is default behavior in the tooling.
-
To consume other services from within your route, only use "switchyard" consumer (i.e. "to") endpoints. This keeps your routing logic independent of the binding details for consumed services.
Java DSL Routes
A newly created Java DSL route looks like this:
package com.example.switchyard.docs;
import org.apache.camel.builder.RouteBuilder;
public class CamelServiceRoute extends RouteBuilder {
/**
* The Camel route is configured via this method. The from:
* endpoint is required to be a SwitchYard service.
*/
public void configure() {
// TODO Auto-generated method stub
from("switchyard://Example").log(
"Received message for 'Example' : ${body}");
}
}
There are no SwitchYard-specific classes or APIs used for Java DSL routes; the route class is identical in signature to what you would use with Apache Camel directly. Since there is one route per service, you will have one RouteBuilder class for each Camel routing service in your application. To add logic to your routing service, simply add additional logic to the configure() method. For background and details on what you can do with the Java DSL, please consult the Apache Camel documentation.
XML Routes
A newly created XML route looks like this:
<?xml version="1.0" encoding="ASCII"?>
<route xmlns="http://camel.apache.org/schema/spring">
<from uri="switchyard://Example"/>
<log message="Example - message received: ${body}"/>
</route>
Like Java DSL routes, the XML routing syntax is identical to what you would use with Apache Camel directly and conforms to the Camel schema for <route> definitions. There will be one file containing a route definition for each XML routing service in your application.
Consuming Services From Camel Routes
Invoking another service from within your Camel route can be done by using the SwitchYard producer endpoint (switchyard://) within your route. Endpoint configuration is very straightforward:
switchyard://[service-name]?operationName=[operation-name]
-
service-name : name of the SwitchYard service. This value needs to match the name of a service reference defined on the service component for the route.
-
operation-name : name of the service operation to be invoked. This is only used on references and is optional if the target service only has a single operation.
A modified version of the default XML route which invokes a SwitchYard service can be found below:
<?xml version="1.0" encoding="ASCII"?>
<route xmlns="http://camel.apache.org/schema/spring">
<from uri="switchyard://Example"/>
<log message="Example - message received: ${body}"/>
<!-- Invoke hasItem operation on WarehouseService -->
<to uri="switchyard://WarehouseService?operationName=hasItem"/>
</route>
Scripting languages
Camel supports dynamic languages inside route logic in both XML and Java form. As the support for dynamic languages is built in JDK any language which provides javax.script.ScriptEngineManager may be used. However, because of 3rd party dependencies by default SwitchYard supports only following languages:
-
BeanShell
-
JavaScript
-
Groovy
-
Ruby
-
Python
To use these script languages you have couple of options. They are available in expression-aware places like filter:
public class ScriptingBuilder extends RouteBuilder {
public void configure() {
from("switchyard://Inbound")
.filter().javaScript("request.getHeader('myHeader') != null")
.to("switchyard://Outbound");
}
}
If you would like use dynamic language to implement your service you may use transform element:
public class ScriptingImplementationBuilder extends RouteBuilder {
public void configure() {
from("switchyard://Inbound")
.transform().groovy("classpath:script.groovy"); // classpath resource
from("switchyard://InboundBsh")
.transform().language("beanshell", "file:script.bsh"); // file system resource
}
}
Inside your script you will have access to predefined variables like request, response or exchange which will let you generate response.
CDI Integration
SwitchYard integrates the CDI Bean Manager with the Camel Bean Registry to allow you to reference CDI Beans in your Camel routes. Any Java class annotated with @Named in your application will be available through Camel's Bean registry.
Consider an example of where you have the following CDI bean:
@Named("StringSupport")
@ApplicationScoped
public class StringUtil {
public String trim(String string) {
return string.trim();
}
}
This bean can be used inside your SwitchYard Camel Routes as follows:
public class ExampleBuilder extends RouteBuilder {
public void configure() {
from("switchyard://ExampleBuilder")
.split(body(String.class).tokenize("\n"))
.filter(body(String.class).startsWith("sally:"))
.to("bean:StringSupport");
}
}
See Camel's Bean Binding documentation for more details.
Implementation Property Injection
SwitchYard integrates with the Properties Component in Camel to make system and application properties available inside your route definitions. You can inject properties into your camel route using "{{propertyName}}" expression where "propertyName" is the name of the property. The following camel route expects the "user.name" property to be injected in the last <log> statement:
<route xmlns="http://camel.apache.org/schema/spring" id="CamelTestRoute">
<log message="ItemId [${body}]"/>
<to uri="switchyard://WarehouseService?operationName=hasItem"/>
<log message="Title Name [${body}]"/>
<log message="Properties [{{user.name}}]"/>
</route>
See the Properties section of the User Guide for more details of SwitchYard property support.