Camel services allow you to leverage the core routing engine inside of Apache Camel to route between services in SwitchYard. The route itself 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. The routing logic can be expressed in XML and included directly in the service component configuration, or you can use the Java DSL to define the route in an annotated Java class.
Java DSL Routes
SwitchYard provides an
@Route
annotation which can be used to declare that a class contains a Camel route which should be represented as a service in SwitchYard. The @Route annotation has a single required element which identifies the service interface to be used by the route. Aside from this annotation, the class looks exactly like a route that you would define in Camel alone.
@Route(JavaDSL.class)
public class JavaDSLBuilder extends RouteBuilder {
public void configure() {
from("switchyard://JavaDSL")
.log("Message received in Java DSL Route")
.log("${body}")
.split(body(String.class).tokenize("\n"))
.filter(body(String.class).startsWith("sally:"))
.to("switchyard://XMLService?operationName=acceptMessage");
}
}
When an application containing one or more Java DSL routes is built, the SwitchYard Maven plugin will automatically generate the required service component configuration in META-INF/switchyard.xml. The above route would produce the following configuration:
<component name="JavaDSLBuilder">
<implementation.camel xmlns="urn:switchyard-component-camel:config:1.0">
<java class="org.switchyard.quickstarts.camel.service.JavaDSLBuilder"/>
</implementation.camel>
<service name="JavaDSL">
<interface.java interface="org.switchyard.quickstarts.camel.service.JavaDSL"/>
</service>
</component>
The "from" endpoint in a Camel service must always equal the service name. This allows SwitchYard to establish service bindings outside the route definition itself.
XML Routes
Configuring a Camel service using XML is done using the <implementation.camel> configuration directly as follows:
<sca:component name="CamelComponent">
<implementation.camel xmlns="urn:switchyard-component-camel:config:1.0">
<route xmlns="http://camel.apache.org/schema/spring" id="Camel Test Route">
<log message="ItemId [${body}]"/>
<to uri="switchyard://WarehouseService?operationName=hasItem"/>
<log message="Title Name [${body}]"/>
</route>
</implementation.camel>
<sca:service name="OrderService">
<sca:interface.java interface="org.switchyard.component.camel.deploy.support.OrderService"/>
</sca:service>
<sca:reference name="WarehouseService">
<sca:interface.java interface="org.switchyard.component.camel.deploy.support.WarehouseService"/>
</sca:reference>
</sca:component>
You'll notice in the above configuration that the route in the <implementation.camel> does not specify a from endpoint on the route definition. For Camel XML routes, Switchyard automatically adds this for the service. The above would be invokable by using the following code (snippet from a SwitchYard test):
String title = newInvoker("OrderService").operation("getTitleForItem").sendInOut("10").getContent(String.class);
Running the above code snippet would generate the following in you console log:
10:57:45,915 INFO [impl.DefaultCamelContext] Apache Camel 2.6.0 (CamelContext: camel-1) started in 0.838 seconds
10:57:46,284 INFO [impl.DefaultCamelContext] Route: Camel Test Route started and consuming from: Endpoint[switchyard://OrderService]
10:57:46,307 INFO [impl.DefaultCamelContext] Apache Camel 2.6.0 (CamelContext: camel-1) is starting
10:57:46,307 INFO [impl.DefaultCamelContext] Total 1 routes, of which 1 is started.
10:57:46,307 INFO [impl.DefaultCamelContext] Apache Camel 2.6.0 (CamelContext: camel-1) started in 0.000 seconds
10:57:46,428 INFO [Camel Test Route] ItemId [10]
10:57:46,434 INFO [Camel Test Route] Title Name [Fletch]
SwitchYard Endpoints
The Camel component contains not only wraps Camel, it defines a Camel component itself which maps to switchyard:// endpoint URIs. As seen in the above examples, the switchyard:// endpoint scheme can be used to route between Camel routes and SwitchYard services. Endpoint configuration is very straightforward:
switchyard://[service-name]?operationName=[operation-name]
-
service-name : name of the SwitchYard service
-
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.
CDI Integration
SwitchYard integrates the CDI Bean Registry with the SwitchYard Camel component. This means that, within SwitchYard Camel Route definitions, you can reference named (@Named) CDI Beans.
Consider an example of where you have the following CDI bean:
@Named
@ApplicationScoped
public class StringUtil {
public String trim(String string) {
return string.trim();
}
// Other utilities...
}
This bean can be used inside your SwitchYard Camel Routes as follows:
@Route(JavaDSL.class)
public class JavaDSLBuilder extends RouteBuilder {
public void configure() {
from("switchyard://JavaDSL")
.split(body(String.class).tokenize("\n"))
.filter(body(String.class).startsWith("sally:"))
.bean(StringUtil.class, "trim(String)");
}
}
See Camel's Bean Binding documentation for more details.