Dynamic reloading of CamelContext with SpringXML - apache-camel

Is it a good practice to load the entire Camel context from SpringXML (rather than dynamic re-loading of routes). Following code snippet seems to load the updated camel context from the file systems (based on a FileWatch service). Is that recommended?
// Detect file modification...
camelContext.stop();
camelContext.destroy();
((AbstractApplicationContext)applicationContext).close();
SpringCamelContext.setNoStart(true);
applicationContext = new ClassPathXmlApplicationContext(
new String[]{CAMEL_CONTEXT_FILE});
camelContext = (SpringCamelContext) applicationContext.getBean("foo-cc");
camelContext.start();

Seems to me like something that might be OK during development. This way it is possible to reload more than just routes, as Spring beans and configuration will be reloaded. Now, whether it is recommended or not would depend on what you're trying to accomplish and in what environment.

Related

Apache camel Endpoint schemes duplication

in apache camel, we have endpoints associated with scheme strings like "cxf", "ahc", "http" and the likes. What happens if there are two components built using the same scheme? I don't see a validation from camel framework which prevents the deployment of components with duplicate schemes. Should there be a validation in the first place or this is by design?
Regards
Gopal
I have a need to re-use available camel components from the community but change the endpoint scheme to make it unique. For example I want to use amqp component but in my blueprint route i would like to have unique scheme used "<camel from uri="mydomain-amqp">. This way I can re-use the amqp as a new component but also keep others using the amqp as is.
Camel prevents adding a component using a name/scheme that already exists. Adding your component under a different name would be something like this:
getContext().addComponent("mydomain-amqp", new AMQPComponent());

How to capture error at compile level in Apache Camel

I have route like
.bean(OrderService.class, "doSomething")
Now my question is if for any reason any developer misspell method name in route, we would not be able to identify at compile level or we may realize after going to production.
How to handle these scenario?
At a minimum I would recommend a test which ensures that your Camel components are registered with the Camel context, and if they're not, one would expect an exception to be thrown at application startup time.
In essence, you would want a Spring test suite (since Camel will leverage Spring's context for its own context) to ensure that your bean is wired in correctly here.
This cannot be a compile-time error or check since this is specific to how the application context is built, which is done dynamically at runtime.

How to do client-specific imports in a React frontend?

I'm working on a new project where I'm taking a full-stack application and decoupling the UI from the backend -- so basically our backend will be just a JSON API a new React-based frontend talks to.
The way our current full-stack architecture works is we have a base application in /core/app and then a client overrides folder for each client /clients/client{1,2,3}/app and then our file include logic checks the client folder first and then the core folder as a fallback.
Like php include_path precedence logic.
I feel pretty confident in how I'll setup the core app, but I'm not quite sure how I'll handle this override concept.
Ideally when I call:
import MyComponent from '../components/MyComponent
I know import statements can't be dynamic, but I'm looking for a solution to check in /clients/client1/components/MyComponent first and then /core/component/components/MyComponent second.
What is the recommended way to handle this sort of usecase? I thought about trying to be fancy with symlinks (ie: by default, each client gets a symlink to every single item in the core and then they'd override it as needed and replace the symlink).
That seems kind of hacky and I'm not sure how it'd work with hot-reloading so I'm hoping there's a more elegant approach.

Apache camel route deployment - Independently?

Suppose I have 10 different Camel routes in my application, is it possible to stop one particular route alone during an issue and make changes to it(in one of the java processors) and deploy it again without affecting other routes.
Also can I create and deploy a new route on the fly, while other routes are already functioning.
If these are not the default behaviour, what are the options available to achieve this?
Karaf (so do Apache ServiceMix / JBoss Fuse)has hot deployment (nowadays this might be supported in JBoss AS / WildFly as well ). Meaning, you can create your routes as independent blueprint xml files in the deploy folder (meaning just xmls). Likewise you can have xml files for every route, whenever you make changes to XML's, it will be redeployed automatically.
This approach has few drawbacks, it will be complex if you have to deal with JPA or if your route has to deal with custom processors / classes.
Check out the examples in Apache ServiceMix / JBoss Fuse project.
I would recommend this approach especially if you want to take a microcontainer approach - Something like light weight Apache Karaf + Camel Route XML files + Docker.
I have done this few years back, may be this feature is possible to achieve in any other containers as well, which I am not sure.
You can stop a route via org.apache.camel.CamelContext.stopRoute(id) & you can modify it by building a new route and adding it to the context. This would let you change the logic of a route at runtime.
This wouldn't automatically let you hot deploy a new Java processor. I think this aspect of your question isn't Camel specific - their seem to be a few options for this, including OSGi/Karaf mentioned by #gnanaguru.
Perhaps moving the logic that you think might change from a Java processor to somewhere more dynamic (like some JavaScript in an external file, or in the route itself) would be a simpler solution to your problem.

Transacted camel route with auto-startup set to false

I am in the process of developing a message router which has a bunch of routes that are started and stopped at runtime based some certain conditions.
By default all these routes are configured with auto-starup=false
Now I am trying to add transactional support to these routes and it seems that you cannot define a transacted route and control the its startup behavior at the same time. This is because RouteDefinition.transacted() returns a TransactedDefinition instance which does not have an autoStartup(boolean autoStartup) method.
I am sure I am not the only one to need this kind of functionality and just wondering what is the camel way of addressing such requirements.
Thank you in advance for your inputs
Maybe just set autoStartup first, eg
from("direct:start").autoStartup(false)
.transacted()
.to("mock:result");

Resources