How to dynamically setting CamelContext ID in Spring DSL? - apache-camel

How to set camelContext id dynamically in the spring DSL? Consider my scenario like this,
Bundle A : having camelContext where I set id attribute say simple-ctx. This bundle has some other utilities beans which is used in some other bundle.
Bundle B : importing A context file where I defined the camel context. in B I have defined B specific routes
Bundle C : importing A context file where I defined the camel context. in C I have defined C specific routes
Now, bundle B and C is depends on Bundle A. Now, if I do context-list command it lists simple-ctx. Which means Bundle B and C has same camelContext id.
I wanted to achieve that id should like simple-ctx-B and simple-ctx-C without defining the camelContext in B or C.
Appreciate your suggestion and feedback.

This is not possible. The id is a fixed value. However the JMX naming can be take in dynamic values such as counters, bundle ids, etc.
http://camel.apache.org/camel-jmx.html
It sounds as if you want A to have a naming where the prefix is the name of its parent?
Also instead of having camelContext in all the bundles. You can have routes in A instead so these routes are included in the same camelContext as from B or C: http://camel.apache.org/how-do-i-import-routes-from-other-xml-files.html

Related

How to set route node properties?

While monitoring an Apache Camel application with hawt.io, I noticed that the nodes of a camel route have some properties that I cannot influence with the Java DSL, but which are displayed in hawt.io. It would be pretty awesome if you could define them anyway.
I am particularly interested in the id and the description of a node in the route. My route currently looks something like this (screenshot below):
My route
rabbitmq://tso11
log4
process4
to3
process5
to4
The displayed names (log4, process4, process5, ...) are automatically generated "id" properties. There is also an always empty property "description".
It would be awesome if I could change this somehow for a much better readable route:
My route
rabbitmq://tso11
log incoming message
process for header extraction
to xslt processor additional-mappint.xslt
process for conversion to nms42 format
to nms42 endpoint
Maybe there is a way? Maybe only with XML based DSL?
Here is a screenshot:
In Java DSL, you can set the id of a node thanks to the method id(String id).
In the next example, the id of the endpoint mock:bar has been set to bar:
from("direct:start")
.to("mock:foo")
.to("mock:bar").id("bar")
.to("mock:result");

support for java.time.Instant serde via jackson JavaTimeModule

I'd like to support serde of POJO classes that include java.time.Instant member fields. As such, I was happy to find a Jackson module that is designed precisely for this use case:
https://github.com/FasterXML/jackson-modules-java8
Unfortunately I am unable to register the JavaTimeModule as follows because it fails to compile given I need to import a flink-shaded jackson2 jar that includes JavaTimeModule but am unable to find it (eg in maven-central):
private ObjectMapper mapper = new ObjectMapper()
.enable(MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS)
.registerModule(new JavaTimeModule());
Thoughts?
thx,
james
It's not entirely clear how you currently use jackson. But in general, there is no need to include flink-shaded-jackson in your user jar. In fact, it is heavily discouraged. The whole point of shading is that you can use your own version without class conflicts. So simply add jackson with the respective module to your gradle project and use it as is.
Now if you use any given format/connector of Flink that uses the flink-shaded-jackson, then you need to shade the time module in the same fashion, unfortunately. You can use the json schema module as a reference.

Camel 2.24.2 : PropertiesComponent override with environment variable

I am attempting use the PropertiesComponent and reading a property file that is in my classpath. I have built a standalone executable jar and I am using the camel Main class - no spring boot.
However, I would like to override one of those properties using environment variables, but it is not working. I am able to override it using the -D, but the documentation indicated that it is possible to override it using an environment variable.
Here is the sample code snippets
Main main = new Main();
main.addRouteBuilder(new HelloRoute());
main.bind("doWork", new DoWork());
PropertiesComponent pc = new PropertiesComponent();
pc.setLocation("classpath:app.properties");
main.bind("properties", pc);
main.run();
Here is the property file
account.route.id=account_route_get
account.route.get=account_route_get_description
startup_route=false
And here is my route where I am attempting to use it. I am attempting to override the startup_route and it does not work correctly.
rest("/account")
.get("/{name}")
.consumes("application/json")
.outType(Account.class)
.route()
.id("{{account.route.id}}")
.description("{{account.route.get}}")
.autoStartup("{{startup_route}}")
.to("log:{{account.route.get}}?level=INFO")
.to("bean:doWork?method=info(${header.name})")
.endRest()
I found this CAMEL-13502 but it is in a different Camel version, and I am wondering if this is also relevant for Camel 2.24.2
Thanks
I'm guessing you don't want to explicitly call out that you want the variable from the OS environment variables.
If you did want to do that, you could state
.autoStartup("${env:STARTUP_ROUTE}")
but if you are wanting a more dynamic solution, another option could be to create a
choice()
that first checks if the environment variable of that name exists, and if not, to default to the one in the properties file.
.when("${env:STARTUP_ROUTE} != null")
.autoStartup("${env:STARTUP_ROUTE}")
.otherwise()
.autoStartup("{{startup_route}}")
Finally, the Camel documentation of Property Component also states:
You can control these modes using the systemPropertiesMode and environmentVariableMode options on the properties component.
When I ran a sample in my project, I did have the ability to configure the systemPropertiesMode, but I didn't have an option for environmentVariableMode so unsure if that is a feature of a higher level Camel version than I'm using.

Specify an optional environment property in Apache Camel XML

I am using an environment variable in Apache Camel which is optional and in certain cases the value won't be there, but still I want my config to work, assuming the not found environment variable as blank.
camelContext id="inboud" xmlns="http://camel.apache.org/schema/spring">
<!-- and then let Camel use those #Component scanned route builders -->
<propertyPlaceholder id="properties"
location="properties/app${env}.properties" ignoreMissingLocation="true" />
<!-- Messages placed here will be raw data from force.com-->
<template id="frceProducerTemplate" />
Here the ${env} I want to make as optional and if it's not present then the location must be taken as properties/app.properties.
Any idea anyone?
There is no support for default values if an ENV variable is not there. You can read more about using property placeholders here: http://camel.apache.org/using-propertyplaceholder.html
However you can likely add 2 locations, one with the ENV and another without the ENV. And then turn on ignoreMissingLocation="true" then if the ENV is not there Camel will ignore it.

AutoGenerating routeId's in camel

In apache-camel, is there a way to auto generate routeId's overriding the existing ones with route numbers(generated in RouteDefinitionHelper)?
There is to the best of my knowledge no autoGeneration policy on routeNaming you can use, but you could do something similar to this:
private String myURI;
from("jms:queue:" + myURI).routeId("JmsComponent:" + myURI)
.to("....");
By using something like blueprint or spring to inject your variable to the java class you can change your URI and it will adjust the route name accordingly. You could also use the full URI in your private variable then parse the endpointURI yourself and format it for the routeId.
You can specify them directly for routes as well as processors in your routes.
from("direct:start").routeId("MyMainRoute")
.to("direct:out").id("MyOutputProcessor");
These ids will be visible in your jConsole so you can see statistics on your routes and processors as well.

Resources