I am learning Camel and trying to integrate it with Spring Boot applications. From what I've read there appear to be two main ways to configure the Camel routes (and other related entities): 1) via Java DSL, or 2) via XML DSL. We don't think the Java DSL approach will work for us, as it doesn't seem that it would allow dynamic route definitions. Maybe I'm wrong? If dynamic routing can somehow be done using Java DSL and whatever, I'd like to know about it.
So, I'm focusing on configuring the routes in XML, where we should have a little more flexibility. The idea is that a given application (or service) could be handed a constructed XML route configuration at deploy-time that would specify the details of that service's routing.
The first question I have is how can we indicate to Camel (or Spring Boot and Camel) what/where the configuration file(s) are? Does it expect specific file naming and/or project location, or is it more flexible? Can it be broken into separate files?
By the way, we configure our Spring Boot applications via a combination of Java-based bean configuration and an application.yml file. We don't use XML for Spring Boot configuration.
I've poked around in a number of places on the Camel site (https://camel.apache.org/) but haven't found much information on this subject. The emphasis definitely favors the Java DSL approach.
There is a spring boot example with XML DSL at
https://github.com/apache/camel-spring-boot/tree/master/examples/camel-example-spring-boot-xml
You can use property placeholders in your Camel routes that can be configured via spring boot configuration (eg application.properties etc).
From Camel pov, then XML or Java can be equally dynamic. You can remove/add routes at runtime. But mind that its not always a good thing to do dynamic changes in production, without knowing if the changes works.
Related
I'd like to write a framework on top of spring boot that does a bunch of things, like exposing specific endpoints and doing specific logic.
But I'd like to build it as a framework in the sense that someone else can take it, implement a number of specific interfaces and it will then run as a spring boot web application.
I haven't found how to do this specifically.
I've looked into this article about writing a custom starter, but it looks like the dependency is the wrong way round. I want the custom code "plugged into" the framework rather than calling the classes of the starter directly, if that makes sense.
It seems you're looking for the EnableAutoConfiguration plugin. This is the core of any spring boot libraries that wants to deal with spring boot custom beans without user help. EnableAutoConfiguration classes need to be placed in spring.factories file.
spring.factories file can have multiple classes each class needs to be provided using org.springframework.boot.autoconfigure.EnableAutoConfiguration=A,B,C
Using these boot classes you can create many beans that could be the backbone of your framework. Also if you want to provide custom properties as boot does, you need to add those properties file spring-configuration-metadata.json file.
For your reference, you can see this repo Rqueue
Background
I have built a console java application using kotlin and gradle.
The gradle file creates a fat jar which I can run from the command line using
java -jar <project>.jar
The jar contains the application.properties file from which properties are read.
Problem
I would like to specify on the command line that the application.properties file should be read from some external path.
When using spring boot, I have used
java -jar -Dspring.config.location=somepath/application.properties <project>.jar
and this works.
But it does not seem to be working in the non-spring boot application
Question
Is it possible to specify external configuration on the command line for non spring boot applications?
Spring boot has a whole chapter in the documentation which deals with various ways of configuration.
Obviously if you don't have spring boot you should implement something similar to it by yourself.
First thing you should decide - at which level you need the configuration to be integrated into your application:
Do you only want to read the key/values from command line or maybe rely on environment variables or system properties?
In general, what is the source of your configuration: Yaml? Properties file? maybe consul or etc.d?
Do you want to create a java object that reflects the configurations that you've read (like classes annotated with #ConfigurationProperties in spring boot do?
Do you want to support only one source of configuration or you want the various sources of configurations to be supported?
If you ware using Spring, do you want configuration properties to be automatically injected into beans?
If you're planning to use properties/yaml (like application.properties in spring boot) - where do you want to place them? Non spring boot application won't read them "auto-magically", you'll have to implement this logic.
Are you planning to deal with profiles (non-spring-boot application still supports flavors of loading different beans depending on specified profile).
Spring boot has answered all these questions and more.
Here are some options that you might want to give a try to if you're running outside the spring boot context but still have spring application:
Since spring 3.1, I guess, there is a#PropertySource annotation that you can use to make spring load properties from the file in the classpath or some "place" in the filesystem. This article summarizes the usage of this method as well as compares what spring boot has up on its sleeves as opposed to regular spring application. This is also a nice tutorial that covers regular spring features.
Something out of spring eco-system but still can be useful: apache common configuration project. There are some workarounds to integrate it with spring application, see here
Considering all the answers here I concluded that though it is possible to enable external configuration in applications that are not spring boot, it does require some effort.
Therefore I decided to use Spring Boot in the container.
Is it possible to add route in Spring Integration during execution? I'm doing project in Spring Boot and I need to use Spring Integration to make routes able to create during runtime. I can't find proper example or documentation that describes is it possible and how to to that.
What is route in your mind? Are you really referring to the router component? Why then dynamic routers doesn’t work for you: https://docs.spring.io/spring-integration/docs/5.2.2.RELEASE/reference/html/message-routing.html#dynamic-routers?
So, you can populate router mappings at runtime using an AbstractMappingMessageRouter.
Since some version, we don’t require initial mapping any more.
If you speak about something what we call flows, then you need to take a look into Java DSL and it dynamic flows registration: https://docs.spring.io/spring-integration/docs/5.2.2.RELEASE/reference/html/dsl.html#java-dsl-runtime-flows
I have a WSDL-file, which describes properties of a SOAP-requests (XSD-parts and also service-parts). Using Maven, I was able to generate model classes.
Now I want to use given classes to provide some SOAP-services.
Most of tutorials using Spring Boot, but I don't want. They also use a given wsdl-file and xsd-file, which I don't have.
All I want, is to have a easy to code SOAP endpoint, which uses Spring integration, where I can use stuff link #Inject. Do you have an idea?
I know we can use Java DSL and Spring DSL for working with routes in camel context.
Can anybody tell me which one is more efficient? And What is the advantage of one over the other?
I personally prefer the java dsl as the IDE completion helps very nicely with the DSL. The Java DSL also nicely follows when you do refactorings.
I often combine using a spring context and the Java DSL.
You can use the java dsl for the actual Camel development and use spring or blueprint for your route setup or bean configuration, or bridging Camel to spring or Karaf.
Personally, with help of some Configuration Management Platform (like disconf, https://github.com/knightliao/disconf), and some rules which defined in advance, I can change camel routes (add or remove) dynamically, without changing java code, or the xml.
It will be a little more complex using spring xml to do this. But using dsl, I just need to put configs in different if/else, which switched by configs.