Part I. Developer Guide
This part contains information for developers.
Auto-configured Camel primitives Copy linkLink copied to clipboard!
Camel CDI provides beans for common Camel primitives that can be injected in any CDI beans, for example:
@Inject
@Uri("direct:inbound")
ProducerTemplate producerTemplate;
@Inject
MockEndpoint outbound; // URI defaults to the member name, i.e. mock:outbound
@Inject
@Uri("direct:inbound")
Endpoint endpoint;
@Inject
TypeConverter converter;
Camel context configuration Copy linkLink copied to clipboard!
If you just want to change the name of the default CamelContext bean, you can used the @ContextName qualifier provided by Camel CDI, for example:
@ContextName("camel-context")
class MyRouteBean extends RouteBuilder {
@Override
public void configure() {
from("jms:invoices").to("file:/invoices");
}
}
Else, if more customisation is needed, any CamelContext class can be used to declare a custom Camel context bean. Then, the @PostConstruct and @PreDestroy lifecycle callbacks can be done to do the customisation, for example:
@ApplicationScoped
class CustomCamelContext extends DefaultCamelContext {
@PostConstruct
void customize() {
// Set the Camel context name
setName("custom");
// Disable JMX
disableJMX();
}
@PreDestroy
void cleanUp() {
// ...
}
}
Producer and disposer methods can also be used as well to customize the Camel context bean, for example:
class CamelContextFactory {
@Produces
@ApplicationScoped
CamelContext customize() {
DefaultCamelContext context = new DefaultCamelContext();
context.setName("custom");
return context;
}
void cleanUp(@Disposes CamelContext context) {
// ...
}
}
Similarly, producer fields can be used, for example:
@Produces
@ApplicationScoped
CamelContext context = new CustomCamelContext();
class CustomCamelContext extends DefaultCamelContext {
CustomCamelContext() {
setName("custom");
}
}
This pattern can be used for example to avoid having the Camel context routes started automatically when the container initialises by calling the setAutoStartup method, for example:
@ApplicationScoped
class ManualStartupCamelContext extends DefaultCamelContext {
@PostConstruct
void manual() {
setAutoStartup(false);
}
}
Multiple Camel contexts Copy linkLink copied to clipboard!
Any number of CamelContext beans can actually be declared in the application as documented above. In that case, the CDI qualifiers declared on these CamelContext beans are used to bind the Camel routes and other Camel primitives to the corresponding Camel contexts. From example, if the following beans get declared:
@ApplicationScoped
@ContextName("foo")
class FooCamelContext extends DefaultCamelContext {
}
@ApplicationScoped
@BarContextQualifier
class BarCamelContext extends DefaultCamelContext {
}
@ContextName("foo")
class RouteAdddedToFooCamelContext extends RouteBuilder {
@Override
public void configure() {
// ...
}
}
@BarContextQualifier
class RouteAdddedToBarCamelContext extends RouteBuilder {
@Override
public void configure() {
// ...
}
}
@ContextName("baz")
class RouteAdddedToBazCamelContext extends RouteBuilder {
@Override
public void configure() {
// ...
}
}
@MyOtherQualifier
class RouteNotAddedToAnyCamelContext extends RouteBuilder {
@Override
public void configure() {
// ...
}
}
The RoutesBuilder beans qualified with @ContextName are automatically added to the corresponding CamelContext beans by Camel CDI. If no such CamelContext bean exists, it gets automatically created, as for the RouteAddedToBazCamelContext bean. Note this only happens for the @ContextName qualifier provided by Camel CDI. Hence the RouteNotAddedToAnyCamelContext bean qualified with the user-defined @MyOtherQualifier qualifier does not get added to any Camel contexts. That may be useful, for example, for Camel routes that may be required to be added later during the application execution.
Since Camel version 2.17.0, Camel CDI is capable of managing any kind of CamelContext beans. In previous versions, it is only capable of managing beans of type CdiCamelContext so it is required to extend it.
The CDI qualifiers declared on the CamelContext beans are also used to bind the corresponding Camel primitives, for example:
@Inject
@ContextName("foo")
@Uri("direct:inbound")
ProducerTemplate producerTemplate;
@Inject
@BarContextQualifier
MockEndpoint outbound; // URI defaults to the member name, i.e. mock:outbound
@Inject
@ContextName("baz")
@Uri("direct:inbound")
Endpoint endpoint;
Configuration properties Copy linkLink copied to clipboard!
To configure the sourcing of the configuration properties used by Camel to resolve properties placeholders, you can declare a PropertiesComponent bean qualified with @Named("properties"), for example:
@Produces
@ApplicationScoped
@Named("properties")
PropertiesComponent propertiesComponent() {
Properties properties = new Properties();
properties.put("property", "value");
PropertiesComponent component = new PropertiesComponent();
component.setInitialProperties(properties);
component.setLocation("classpath:placeholder.properties");
return component;
}
If you want to use DeltaSpike configuration mechanism you can declare the following PropertiesComponent bean:
@Produces
@ApplicationScoped
@Named("properties")
PropertiesComponent properties(PropertiesParser parser) {
PropertiesComponent component = new PropertiesComponent();
component.setPropertiesParser(parser);
return component;
}
// PropertiesParser bean that uses DeltaSpike to resolve properties
static class DeltaSpikeParser extends DefaultPropertiesParser {
@Override
public String parseProperty(String key, String value, Properties properties) {
return ConfigResolver.getPropertyValue(key);
}
}
You can see the camel-example-cdi-properties example for a working example of a Camel CDI application using DeltaSpike configuration mechanism.
Auto-configured type converters Copy linkLink copied to clipboard!
CDI beans annotated with the @Converter annotation are automatically registered into the deployed Camel contexts, for example:
@Converter
public class MyTypeConverter {
@Converter
public Output convert(Input input) {
//...
}
}
Note that CDI injection is supported within the type converters.
Lazy Injection / Programmatic Lookup Copy linkLink copied to clipboard!
Available as of Camel 2.17
While the CDI programmatic model favors a type-safe resolution mechanism that occurs at application initialization time, it is possible to perform dynamic / lazy injection later during the application execution using the programmatic lookup mechanism.
Camel CDI provides for convenience the annotation literals corresponding to the CDI qualifiers that you can use for standard injection of Camel primitives. These annotation literals can be used in conjunction with thejavax.enterprise.inject.Instance interface which is the CDI entry point to perform lazy injection / programmatic lookup.
For example, you can use the provided annotation literal for the @Uriqualifier to lazily lookup for Camel primitives, for example for ProducerTemplatebeans:
@Any
@Inject
Instance<ProducerTemplate> producers;
ProducerTemplate inbound = producers
.select(Uri.Literal.of("direct:inbound"))
.get();
Or for Endpoint beans, for example:
@Any
@Inject
Instance<Endpoint> endpoints;
MockEndpoint outbound = endpoints
.select(MockEndpoint.class, Uri.Literal.of("mock:outbound"))
.get();
Similarly, you can use the provided annotation literal for the@ContextName qualifier to lazily lookup for CamelContext beans, for example:
@Any
@Inject
Instance<CamelContext> contexts;
CamelContext context = contexts
.select(ContextName.Literal.of("foo"))
.get();
You can also refined the selection based on the Camel context type, for example:
@Any
@Inject
Instance<CamelContext> contexts;
// Refine the selection by type
Instance<DefaultCamelContext> context = contexts.select(DefaultCamelContext.class);
// Check if such a bean exists then retrieve a reference
if (!context.isUnsatisfied())
context.get();
Or even iterate over a selection of Camel contexts, for example:
@Any
@Inject
Instance<CamelContext> contexts;
for (CamelContext context : contexts)
context.setUseBreadcrumb(true);
Injecting a Camel context from Spring XML Copy linkLink copied to clipboard!
While CDI favors a type safe dependency injection mechanism, it may be useful to reuse existing Camel XML configurations by injecting them into a Camel CDI application. In other use cases, it might be handy to rely on the Camel XML DSL to configure its Camel context(s).
To inject by CDI a camelContext defined in Spring XML, you need to use the Java @Resource annotation, instead of the @Inject @ContextName annotations in the Camel CDI extension. For example,
...
public class RouteCaller {
...
@Resource(name = "java:jboss/camel/context/simple-context")
private CamelContext context;
...
The string java:jboss/camel/context/simple-context is the name of the deployed context registered in the JNDI registry. simple-context is the xml:id of the camelContext element in the Spring XML file.
Using the @Inject @ContextName annotations can result in the creation of a new camelContext instead of injecting the named context, which later causes endpoint lookups to fail.