How to keep data object in camel context - apache-camel

I have create a camel context; this camel context is having 4 routes. These all routes are related to complete a same feed processing operations. Now I have got a requirement to share a database object within the routes.
This object is supposed to be initialized at the time for context creation and should be available for all routes to validate data from.
So far; I have create a org.apache.camel.StartupListener and registered with the context. This listener will add some properties to the context. But my requirement does not ends with the only string values. I have to put a object in the context.
What should I do to add this object in the Camel Context?

You can always create a normal bean to keep reference to your shared object and get the bean like this in all routes:
MyBean myBean=exchange.getContext().getRegistry().lookup("MyBean",MyBean.class);
Or directly add your shared object as a bean (if possible)

Related

toD() - Dynamic URI formation in camel 2.23 scheduled via Quartz

I'm newbie to Apache camel and wanted to Implement the toD() which is to dynamically frame the URI and add request params values from Beans..
Code snippet below -
from("quartz2://timer?cron=0+0/1+++*+?")
.noAutoStartup().routeId(ROUTE_ID).log("Route Started")
.toD(http://localhost:3420/contextpath?from=${bean:bean.from} "+ "&size=${bean:bean.size}")
.process(processor)
Seems like, on every hit via Quartz the same URL is being triggered and hence I see duplicate values saved to DB.
Please suggest why Dynamic uri is not working as expected.
Am calling the processor, computing and setting the Bean values which i get from Response of Endpoint. But when the next time Quartz hits the url, the bean values are not updated and takes the default value
. Bean definition is usual getter setter, and registration is I have used Simple registry
SimpleRegistry simpleRegistry = new SimpleRegistry ();
// create CamelContext
context = new DefaultCamelContext (simpleRegistry);
simpleRegistry.put("bean", bean);
Thanks in Advance
In order to use dynamic URI on a camel-route you must include your variable inside a Simple expression.
Since Camel 2.16.0 release endpoint implementation toD() supports the Simple expression language so you can define a dynamic-URI as message-endpoint:
from("quartz2://timer?cron=0+0/1+++*+?")
.noAutoStartup()
.routeId(ROUTE_ID)
.log("Route Started")
.toD( "http://localhost:3420/contextpath?from=${bean:bean.from}&size=${bean:bean.size}" );
So the expressions ${bean:bean.from} and ${bean:bean.size} should get directly interpolated by using Bean language inside your URI-string. This bean-component bean: tells Camel to get the bean registered with your specified name bean and call the specified methods from and size.
Apache Camel: Rest DSL, section Using Dynamic to() has also a note:
Note: we need to use .endRest() to tell Camel where the route ends, so we can go back to the Rest DSL and continue defining REST services.
Otherwise you could implement that dynamic endpoint using simple inside your regular to(). See Apache Camel: How to use a dynamic URI in to().

Instance variable thread safe in managed bean in jsf 1.2

We are using JSF 1.2 and WAS 6.1 in our application.
I am from servlet background and understand instance variable of a servlet class are not thread safe because instance variable are shared among all requests AND each request creates a new thread and gets served using doGet or doPost or any other handler.
How is above scenario handled in JSF 1.2?
We are using ChangeAddress managed bean with the following entry in faces-config.xml. Does Faces Servlet create new instances of ChangeAddressBean for each request?
<managed-bean>
<managed-bean-name>ChangeAddress</managed-bean-name>
<managed-bean-class>com.ChangeAddressBean</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
If the answer to point 2 is yes then how are final static variable used for all requests? Do final static variables remain common for all requests? Value of
anAddressFinder is populated in a static block but value may differ for different type of users based on some condition. Does that mean value of anAddressFinder once populated for first request/user will remain same for all subsequent requests/users?
public class ChangeAddressBean{
int flatNumber;
final static AddressFinder anAddressFinder;
.
.
.
}
Yes. 2. The value of "anAddressFinder" is bound the the class definition, not a particular class instance. You're assumption is correct. This is not the approach you should use. Based on the name alone, "AddressFinder" sounds very much like it should be a singleton service. Let Spring manage and inject this dependency in your ManagedBean. Fetch the needed data in an init() post-construct method or similar. In general, avoid static members in this context. They make testing more difficult, and it your case are not thread-safe.

WIth Angular's ui-router, is it possible to get a list of all registered states?

Im architecting a fairly large angular application using ui-router. Im trying to add whitelisted states, which in this case means states that dont require authentication before you can see them. Id like to be able to specify entire states and their substates as whitelisted - that is, if I have states such as:
index.home
index.library
index.messages
index.messages.inbox
index.messages.outbox
index.messages.outbox.starred
Id like to be able to set 'index.messages.*', and not block any state that starts with 'index.messages'. I managed to do this by adding a listener for '$stateChangeStart' and doing some fancy string parsing on 'toState.name', but I suspect this would be easier to do if I had a full list of available states. Is there any way to get that? A cursory poke through the source showed me a $stateProvider.states object, but there doenst seem to be any way to access it.
I would say, that you are searching for method $state.get(), check it here:
API Reference $state
get(stateOrName, context)
Returns the state configuration object for any specific state or all states.
Parameters
stateOrName (optional) stringobject
(absolute or relative) If provided, will only get the config for the requested state. If not provided, returns an array of ALL state configs.
context (optional) stringobject
When stateOrName is a relative state reference, the state will be retrieved relative to context.
As stated in doc: "...If not provided, returns an array of ALL state configs..."

How to capture original endpoint URI within an expression (Recipient List EIP)

I'm attempting to use the Recipient List EIP to dynamically generate the consumer endpoint URI during runtime based on configuration entries in a database (http://camel.apache.org/how-to-use-a-dynamic-uri-in-to.html). I've got a number of routes that I want to handle this way so I'd like to build something that can handle multiple routes generically.
Therefore, my idea is to keep an in memory map of these URI values keyed on some type of identifying information (original endpoint URI seems like a logical choice) which would be updated if/when the database is updated to keep the routes in sync, and prevent having to go to the database for every exchange. Using the RouteBuilder, I am setting up the route with the recipient list and Bean expression.
from(endpointUri).recipientList(bean(MyBean.class, "getUri"));
I know that I can capture various objects such as the exchange, body, headers (as long as I know the name), etc using the Bean binding for the getUri method. Is it possible to somehow get the original endpoint URI value so that I can use it as a key to fetch the correct consumer endpoint?
The Exchange interface has getFromEndpoint() method which returns an Endpoint. The Endpoint interface has getEndpointUri() method which returns a String. Perhaps that's what you need? If that's not sufficient, you could set header value(s) at some point and then subsequently retrieve them later in your route.

Custom IdempotentConsumer/Processor in Apache Camel

I want to perform custom logic in an IdempotentConsumer. I've extended the class and implemented the logic. How can I add this to my route?
Do I have to make my own Definition class? Do I add it as a Processor? How do I get the parameters passed to the constructor?
Well, custom consumer/producer could be little overkill. I think for some kind of custom logic is enough to do it trough processor or custom bean.
1.Bean
Look at bean binding you can use simple language to pass arguments to your method. It will looks like this:
.bean(OrderService.class, "doSomething(${body}, true)")
.to("bean:orderService?method=doSomething(null, true)")
2.Processor
You have to realize your classes should be stateless because of concurrent matter of camel framework. Your constructor should be empty and your variables final otherwise whole bunch of magic could happen. Everything you want to pass to your logic component/processor should be passed via Exchange object. You can store your variables in getin() or getOut() messages as headers or body or Exchange properties and pass it to next endpoint. The exchange will change dynamically as it flows trough you camel routes. It should be your one and only one mutable object.

Resources