AutoGenerating routeId's in camel - apache-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.

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");

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.

Camel Restlet - Binding query parameters to message headers

Looking through Camel docs I couldn't find any way that allow me to bind the query parameters within the headers. For example :
Let's say I have an endpoint like that
http://localhost:8080/services/resource?filter=xxx
End I want to get that parameter from the header
exchange.getIn.().getHeaders().get('filter')
The query parameter 'filter' is not returned in the header. Anyone of you knows if this feature is coming by default in camel? I know I can build the binding by myself, but i am just looking for choose among camel-servlet (apparently that binding is implemented by default) and camel-restlet.
If you choose camel-restlet you can use the
restletBinding=#refName
to convert the query string parameters to headers.
The #refName is the bean ID of a RestletBinding object in the Camel Registry.

Intercepting Camel Endpoint Dynamically

I am trying to intercept an endpoint where the value of the URI matches some information in the exchange header.
Let say I have a field in the header called DatabaseName. I want to enforce that a specific route is only writing to the database specified in the header.
Can I do something like this?
interceptSendToEndpoint("mock:${in.header.DatabaseName}")
I tried that but it does not seem to work. What are my options?
I was also thinking of doing something like:
interceptSendToEndpoint("mock:*").when(...)?
But in this case, I am not sure if I can reference the URI of the intercepted node in the when expression.
Thanks
You can intercept using a wildcard and combine that with when to do what you want, see details at: http://camel.apache.org/intercept
The is a header on the Message with the key Exchange.INTERCEPTED_ENDPOINT (CamelInterceptedEndpoint) that has the endpoint uri that was intercepted. You can use that in the when to match the predicate. Something a like:
interceptSendToEndpoint("mock:*")
.when(simple("${header.CamelInterceptedEndpoint} == ${in.header.DatabaseName}"))
...
Use the recipientList instruction for this: http://camel.apache.org/how-do-i-use-dynamic-uri-in-to.html

webapp2 routes for external links

I want to manage external links in a central place in my app so that if they change I need only change them in one place.
Since I'm already using webapp2s routing, I figured I could use that, and use url_for just like every other link. So, tried the following:
Route('http://www.google.com', name='google', build_only=True)
but when I render the link, like this:
uri_for('google')
It encodes the http:// bit, like this:
http%3A//www.google.com
which means if you use it in a href tag, you end up with a relative link like this:
http://localhost:8080/some/path/http%3A//www.google.com
So, questions are:
Is webapp2s routing even designed for external links?
If yes, how to you add absolute URLs?
If no, is there a similar mechanism for doing so?
Would be nice to use webapp2s routing so I can seamlessly use url_for without having to write another 'same but different' method.
I managed to solve the issue by implementing my own uri_for method, and using that instead
def uri_for(_name, _request=None, *args, **kwargs):
uri = webapp2.uri_for(_name, _request, *args, **kwargs)
return urllib.unquote(uri)
Instead of _full (as voscausa mentioned above), you can put _netloc with the server name when calling uri_for. Putting _netloc forces _full to True.
See http://webapp-improved.appspot.com/api/webapp2.html#uri-routing

Resources