Camel route should be annotated with component or configuration - apache-camel

I have camel route which basically used to move files from source to destination as below
public class SimpleRouteBuilder extends RouteBuilder {
#Override
public void configure() throws Exception {
from("file:C:/inputFolder?noop=true").to("file:C:/outputFolder");
}
}
Question is which annotation(#component or #Configuration) should be used to load this route

If you are using Spring or Spring Boot etc then it should be #Component which ensures the class is enlisted into the spring bean registry, which Camel then scans for RouteBuilder classes and automatic adds to the CamelContext.
Mind that Spring Boot has some classpaths it only scans (I think its the package of the main class and sub packages), so if you put it inside other packages outside that, you may need to configure spring boot to scan for other packages.

Related

Configure http4 certificate in application.yml

I'm trying to move my http4 certificate configuration away from RouteBuilder class and to application.yml file. My code is exactly like the Java example on this page under the "Setting up SSL for HTTP Client - Programmatic Configuration of the Component": (https://camel.apache.org/http4.html#HTTP4-UsingtheJSSEConfigurationUtility). However, on the website there is no yml example, only the Java solution that I currently have and Spring DSL solution. Does anybody know how to translate the Java code to yml?
#Configuration
public class configureHttps4Certificate extends RouteBuilder {
#Override
public void configure() throws Exception {
KeyStoreParameters ksp = new KeyStoreParameters();
ksp.setResource("pathToResource");
ksp.setPassword("password");
TrustManagersParameters tmp = new TrustManagersParameters();
tmp.setKeyStore(ksp);
SSLContextParameters scp = new SSLContextParameters();
scp.setTrustManagers(tmp);
HttpComponent httpComponent = getContext().getComponent("https4", HttpComponent.class);
httpComponent.setSslContextParameters(scp);
}
}
If you use SpringBoot you can easily create Java configuration classes that automatically import values from property or YAML files just by using one annotation.
#ConfigurationProperties("app.config")
public class MyConfiguration
Check out this section of the SpringBoot documentation that describes this mechanism.

File Poller implementation in Spring Boot-Camel Application

I am new to Apache Camel Framework. I have to develop an application in Spring Boot and Camel which polls given directory repeatedly(even after the directory undergo any modifications, the poller should go on polling for another scheduled interval and so on.
I found something like below code in camel.
public class FilePoller extends RouteBuilder {
#Override
public void configure() {
from("file:H:\\InputFolder?delay=1000&noop=true")
.process(new Processor() {
public void process(Exchange msg) {
File file = msg.getIn().getBody(File.class);
//LOG.info("Processing file: " + file);
System.out.println("Polling file:"+file);
}
});
}
}
The above code only waits for 1 second and then execute the subsequent code without polling the directory.
Can anybody help me in developing a Spring Boot-Camel application that polls a directory or a file repeatedly every given interval of time. Thanks in advance
Refer this camel file component documentation.
https://github.com/apache/camel/blob/master/camel-core/src/main/docs/file-component.adoc
To integrate with Spring boot you need to use SB version < 2.0

How to use same CamelContext in multiple jar on the same war

I'm using the camel 2.16.2 and I need to use the one CamelContext across multiple jars as I need to have all the Camel Routers in to one CamelContext. So my war will have all those jars as maven artifacts.
Please let me know how do I handle above scenario?
Edit
Just to elaborate more on above question.
In my war myApp.war, I have initialized the CamelContext. There are three jars myApp1.jar, myApp2.jar and myApp3.jar. Each jar has it own routers defined separately.
How do I start the routers in each jar ?
Can I use the same CamelContext injected to each routers?
If I cannot handle through jars, is it possible to implement with multiple war (myApp1.war, myApp2.war and myApp3.war) and each war having different camelContext and communicate to those routers from the main war (myApp.war) ?
As other guys said, you can't use the same CamelContext across different Jars. Could you explain a little what you want to do?
IMHO what you want to do is use routes defined in different Jars. So for that you can define a Camel Context and add all the routes from different Jars. Of course your Camel-Context-JAR has to have access to all those jars.
<camel:camelContext id="camel5">
<camel:package>org.apache.camel.spring.example</camel:package>
</camel:camelContext>
Or class by class
<camelContext id="camel5" xmlns="http://camel.apache.org/schema/spring">
<routeBuilder ref="myBuilder" />
</camelContext>
<bean id="myBuilder" class="org.apache.camel.spring.example.test1.MyRouteBuilder"/>
Or if you are using CDI you can follow this great article https://dzone.com/articles/using-camel-routes-in-java-ee-components
Reference: http://camel.apache.org/spring.html
After doing some research found a way to implement this. Infact we can use the same CamelContext across different jars as all jars are in the same war (Web Container).
We can implement easily with Apache Camel 2.16.2 with camel CDI. If you're using wildfly to deploy your war then you may need to add the camel patch. Download the the wildfly 9.0.2 pach
Steps are Given Below.
In your war create a servlet or restService and Inject the camelContext.
#Inject
#ContextName("cdi-context")
private CamelContext camelctx;
Create a router in the jar with below annotation.
#Startup
#ApplicationScoped
public class MyJRouteBuilder extends RouteBuilder {
In Configure method add
#Override
public void configure() throws Exception {
from("direct:startTwo").routeId("MyJRouteBuilder")
.bean(new SomeBeanThree());
}
Create a BootStrap Class in your jar and add the Router
#Singleton
#Startup
public class BootStrap {
private CamelContext camelctx;
#PostConstruct
public void init() throws Exception {
camelctx.addRoutes(new MyJRouteBuilder());
}
Add your jar as a artifact in the war pom.xml. Once you deploy the war you can see MyJRouteBuilder is Registred in the cdi-context CamelContext. So now you can access your Router anywhere you want.
Hope this would useful anyone who has the same issue what I had.

Spring MVC AngularJS No mapping found

I've been following the tutorial for integrating Spring Security with AngularJS, but it uses Spring Boot. I can get the tutorial examples working, but I need my app to run as a regular MVC application under Tomcat.
The problem is getting the application to route to the index.html page for the initial view. The only mappings I have in the controllers are the REST calls I want to receive from Angular, but I can't seem to get the application to go to the index page. Spring Boot does this automatically, but I'm going to run this as a web app under Tomcat. Trying to go there directly causes a 'No mapping found' error.
I'm using Java configuration and have the antMatchers, etc as described in the tutorial.
Here are a few entries in my config classes to make this happen.
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/index.html", "/home.html", "/login.html", "/").permitAll()
.antMatchers("/css/**").permitAll()
.antMatchers("/js/**").permitAll()
.antMatchers(HttpMethod.POST, "/user").permitAll().anyRequest()
.authenticated().and()
.csrf()
.csrfTokenRepository(csrfTokenRepository()).and()
.addFilterAfter(csrfHeaderFilter(), CsrfFilter.class);
if ("true".equals(System.getProperty("httpsOnly"))) {
LOGGER.info("launching the application in HTTPS-only mode");
http.requiresChannel().anyRequest().requiresSecure();
}
}
#Configuration
#EnableWebMvc
#ComponentScan("com.mygroupnotifier.controller")
public class ServletContextConfig extends WebMvcConfigurerAdapter {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/css/**").addResourceLocations("/resources/static/css/");
registry.addResourceHandler("/js/**").addResourceLocations("/resources/static/js/");
registry.addResourceHandler("/*.html").addResourceLocations("/resources/static/");
}
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("forward:/index.html");
}
}
As usual the most difficult part of this is getting the leading and ending / on the classes and the html files.

Weld CDI on Google App Engine: Injection in servlet not happening

This is my first time working with GAE and I'm trying to get CDI working. Long story short: The #Inject field in my servlet is not getting injected (it's always null).
I'm working in Eclipse and debug the application on the local test server included in the GAE SDK (which is started by Eclipse as well). When I access the servlet on localhost, I get a null-pointer exception for someService. I've also output the value of someService to verify it is really null, which it is.
Edit: When I added a #Named("skldjfx") qualifier to the injection point, Weld complained the dependency is unsatisfied (in the validation phase), so that's a good sign. However, the field is still always null.
Servlet:
public class BlogServlet extends HttpServlet {
#Inject private SomeService someService;
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws IOException {
resp.setContentType("text/plain");
resp.getWriter().println("Hello. " + someService.getSomeValue());
// \
// always null
}
}
SomeService class:
#ApplicationScoped
public class SomeService {
private String someValue = "some value";
public String getSomeValue() {
return someValue;
}
}
I've configured Weld's Listener in web.xml:
<listener>
<listener-class>org.jboss.weld.environment.servlet.Listener</listener-class>
</listener>
The listener is properly loaded because it logs its initialization message: org.jboss.weld.environment.servlet.Listener contextInitialized.
I've included (an empty) beans.xml in both war/WEB-INF and war/META-INF. I also tried it without META-INF. Maybe beans.xml isn't processed? Other contents in the WEB-INF folder (such as web.xml) are processed properly.
How can I verify if beans.xml is processed and/or fix SomeService not getting injected?
It looks like it's not possible to use CDI with GAE, because GAE's Jetty fork ignores jetty-web.xml, which is needed to specify the BeanManager. See this link and this link. Really strange GAE is not supporting the use of CDI.
Note that these links are really old, but so far I haven't found any evidence to the contrary.
Anyway, my next step will be to use Google's own dependency injection framework Guice. Using it with GAE is described here. I'd prefer CDI though.

Resources