Camel Module Overview
Apache Camel is an Open Source framework that provides robust support for integrating systems.
In Apache Camel, data travelling between systems is represented by a Message,
which consists of a body
, headers
, messageId
, and timestamp
. Messages participate in a Message Exchange, which is used to represent the request-response pattern.
As a Message travels from system to system, the format of the Message body can vary (i.e. File
, JSON
, XML
, etc.)
and Apache Camel provides Type Converters to convert from one data format to another. All data formats available in the Camel Module are listed in the Apache Camel Data Formats section and the Smile Data Formats section.
While a Message is used to represent the data itself, a Route is used to define a series of processing steps a Message should take as it travels from a source to a destination. In Smile, users can define routes using YAML DSL or XML DSL
Processors are another important concept in Apache Camel. Processors can be used to perform logic at any point along a Route. They could be used to translate a message, add headers, perform validation logic, or call a service. Processors are extremely versatile and can be used to perform virtually any logic that can be represented by Java code.
Sometimes it is useful to package related Processors and services together. In Apache Camel, this is called a Component. Components provide access to systems and services that are categorized under a URI scheme. These systems and services can be leveraged as a Message travels along a Route.
For example, the Kafka Component can be used to define the beginning of a Route by consuming Messages from a Kafka topic. It can also be used to produce a Message to a Kafka topic at any point along a Route. All components available in the Camel Module are listed in the Apache Camel Components section and the Smile Component section.
Smile supports all Apache Camel Data Formats.
Smile supports the following custom Data Formats:
IBaseResource
Smile supports all Core Components.
Smile supports the following Non-Core Components:
Note: Jetty component is currently not provided due to version conflicts with the application jetty library version. Netty-http
is provided as a replacement, however, make sure to familiarize with netty stream Note
The Smile Component is a custom Component with the URI scheme below:
smile:[moduleId]/[processorName]
Which can be broken down into:
smile:
- URI scheme[moduleId]
- ID of a Smile module[processorName]
- Name of a Smile module processor followed by optional parametersSee Camel Processors for a list of Smile Processors.
See Camel Converters for a list of Converters provided by Smile for automatic conversion between processors.
Health checks can be defined for a Camel module, by configuring a bean named healthChecks
that returns a map of names to health checks. Any health-checks added here will be automatically run with the frequency determined by module.clustermgr.config.stats.heartbeat_persist_frequency_ms
(default once every 15 seconds). Server health-checks are available on the Admin Json endpoint, e.g. http://localhost:9000/runtime-status/node-statuses/health-checks
. Smile CDR uses the Dropwizard Metrics library to manage health checks. The values of the healthChecks
map need to extend com.codahale.metrics.health.HealthCheck
.
Note: Don't confuse the HealthCheck class with apache
's homonymous class.
You may need to add a dependency as the following to your project to make com.codahale.metrics.health.HealthCheck
class visible:
<dependency>
<groupId>io.dropwizard.metrics</groupId>
<artifactId>metrics-healthchecks</artifactId>
<version>${dropwizard_metrics_version}</version>
</dependency>
The context depicted next shows a Spring Context Config class that creates a custom processor and a health check.
This is a Spring Framework AnnotationConfigApplicationContext
class. It is characterized by having the @Configuration
annotation on the class itself, as well as having one or more non-static factory methods annotated with @Bean
, which create instances of your custom Processors or beans that can be used in your YAML DSL or XML DSL Routes.
The following example shows a Spring Context Config class that registers a custom Processor:
@Configuration
public class TestCustomAppCtx {
@Bean
public TestCustomProcessor testCustomProcessor() {
return new TestCustomProcessor();
}
/**
* This bean is a named list of HealthChecks that will be registered with the server.
*/
@Bean(name = "healthChecks")
public Map<String, HealthCheck> healthChecks() {
Map<String, HealthCheck> retVal = new HashMap<>();
// Name the health check and class whatever makes sense in your environment. For example:
// retVal.put("Lab system X", new LabSystemXHealthCheck());
// retVal.put("Payment system Y", new PaymentSystemYHealthCheck());
retVal.put("Remote System", new RemoteSystemHealthCheck());
return retVal;
}
}
public class TestCustomProcessor implements Processor {
private static final Logger log = LoggerFactory.getLogger(TestCustomProcessor.class);
@Override
public void process(Exchange exchange) throws Exception {
// get incoming Message
Message message = exchange.getIn();
// log incoming Message body
log.info("Message body: {}", message.getBody(String.class));
// log incoming Message headers
log.info("Message headers: {}", message.getHeaders());
// Modify Message body
message.setBody("Hello World!");
// Add Message header
message.setHeader("some-header-name", "some-header-value");
// log new Message body
log.info("Message body: {}", message.getBody(String.class));
// log new Message headers
log.info("Message headers: {}", message.getHeaders());
}
}
HapiContext
and FhirContext
beans, you can @Autowire
them from the Smile Application Context. This will help to avoid conflicts during application start up.
The Spring Context Config class and all the classes used to create custom Processors, custom health checks and beans must be packaged into a Java JAR file.
If you are using Apache Maven as your build system, this just means you should use a normal project with a packaging of jar
.
Once you have created a JAR with all your custom classes, it should be placed in the customerlib/
directory of the Smile CDR installation, and Smile CDR should be restarted. You can then follow the steps below to create a new Camel module:
.yaml
or .xml
file to the Camel Routes (File) field.com.example.camel.TestCustomAppCtx
.A sample Camel project is available at the following links:
Description - Uses the Timer Component to create a Message every second with an empty body. This Message is then passed to the TestCustomProcessor
which calls the process(Exchange)
method. This method simply logs the incoming Message body
and headers
,
modifies them, and then logs them again.
<route>
<from uri="timer:test"/>
<to uri="bean:testCustomProcessor"/>
</route>
here is the same route in YAML DSL:
- from:
uri: "timer:test"
steps:
- to:
uri: "bean:testCustomProcessor"