Working with Camel and SCR
SCR stands for Service Component Runtime and is an implementation of OSGi Declarative Services specification. SCR enables any plain old Java object to expose and use OSGi services with no boilerplate code.
OSGi framework knows your object by looking at SCR descriptor files in its bundle which are typically generated from Java annotations by a plugin such as
Running Camel in an SCR bundle is a great alternative for Spring DM and Blueprint based solutions having significantly fewer lines of code between you and the OSGi framework. Using SCR your bundle can remain completely in Java world; there is no need to edit XML or properties files. This offers you full control over everything and means your IDE of choice knows exactly what is going on in your project.
Camel SCR support
Available as of Camel 2.15.0
Camel-scr bundle is not included in Apache Camel versions prior 2.15.0, but the artifact itself can be used with any Camel version since 2.12.0.
And finally provide the default configuration with:
That's all. And if you used
Below is an example of a complete Service Component class, generated by
Below is an example of a RouteBuilder class generated by
Let's take a look at
The values of these fields are set with values from properties by matching their names.
If you need to add some beans to CamelContext's registry for your routes, you can do it like this.
It is a good idea to check that required parameters are set and they have meaningful values before allowing the routes to start.
Note that pretty much everything in the route is configured with properties. This essentially makes your RouteBuilder a template. SCR allows you to create more instances of your routes just by providing alternative configurations. More on this in section Using Camel SCR bundle as a template.
AbstractCamelRunner's lifecycle in SCR
In (non-OSGi) unit tests you should use
The easiest way to create an Camel SCR bundle project is to use
You can generate a project with the following steps:
and the bundle is ready to be deployed.
Unit testing Camel routes
Service Component is a POJO and has no special requirements for (non-OSGi) unit testing. There are however some techniques that are specific to Camel SCR or just make testing easier.
Below is an example unit test, generated by
Now, let's take a look at the interesting bits one by one.
This allows you to override parts of the configuration by prefixing properties with "unit.". For example,
Prefixes can be used to handle the differences between the runtime environments where your routes might run. Moving the unchanged bundle through development, testing and production environments is a typical use case.
Here we configure the Service Component in test with the same properties that would be used in OSGi environment.
Components that are not available in test can be mocked like this to allow the route to start.
Camel's AdviceWith feature allows routes to be modified for test.
Here we start the Service Component and along with it the routes.
Here we send a message to a route in test.
Running the bundle in Apache Karaf
Once the bundle has been built with
Overriding the default configuration
By default, Service Component's configuration PID equals the fully qualified name of its class. You can change the example bundle's properties with Karaf's
Or you can change the configuration by editing property files in Karaf's
Using Camel SCR bundle as a template
Let's say you have a Camel SCR bundle that implements an integration pattern that you use frequently, say, from → to, with success/failure logging and redelivery which also happens to be the pattern our example route implements. You probably don't want to create a separate bundle for every instance. No worries, SCR has you covered.
Create a configuration PID for your Service Component, but add a tail with a dash and SCR will use that configuration to create a new instance of your component.
This will start a new CamelContext with your overridden properties. How convenient.
When designing a Service Component to be a template you typically don't want it to start without a "tailed" configuration i.e. with the default configuration.
To prevent your Service Component from starting with the default configuration add