injecting properties in camel route from wildfly modules - apache-camel

I am using SwithcYard 2.0.0.Beta1. Application server is WildFly 8.1. I want to load properties from modules.
As example I have a module /wildfly/modules/system/layers/base/org/study/configuration/test
my module.xml
<?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.3" name="org.study.configuration" slot="test">
<resources>
<resource-root path="."/>
</resources>
</module>
This is properties file:
user=foo
password=bar
provider=CryptoProvider
directory=domain;login:pwd#host/dir?password=pwd&preMove=backup&move=processed&moveFailed=error&charset=UTF-8
This is how I include that module in wildfly profile:
<subsystem xmlns="urn:jboss:domain:ee:2.0">
<global-modules>
<module name="org.study.configuration" slot="test"/>
</global-modules>
And now I want to load that properties in my camel route:
.to("smb://{{directory}}")
or
in bean
KeyStore ks = KeyStore.getInstance("PKCS12", {{provider}});
Is it possible? how to do this?

It is possible, but as long as your properties are in the file you have to load it first.
What you define in the module - it is just a class path for your application.
If you use Java DSL:
Properties myProps = new Properties();
Stream is = this.getClass().getClassLoader().getResourceAsStream("MyAppProp.properties");
myProps.load(is);
System.getProperties().putAll(myProps);
If you use Spring DSL just define regular Spring properties.
a. with Spring bean namespace
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>MyAppProp.properties</value>
</property>
</bean>
b. with Spring context namespace
<context:property-placeholder location="MyAppProp.properties"/>
Then you can use them inside Camel route as you said:
.to("smb://{{directory}}")
PS. you have an ability to define properties directly in the module.xml as well
<module xmlns="urn:jboss:module:1.3" name="org.study.configuration" slot="test">
<properties>
<property name="directory" value="myTestDirectory"/>
</properties>
...

Related

Spring bean from one bundle is not accessible in camel route in another bundle

I have one jar file (connection.jar) which is an OSGI bundle with folder structure src/main/resources/META-INF/spring/mq-connect.xml
following connectivity code is placed in the mq-connect.xml
<beans ...... >
....
....
....
....
<!-- AMQ jms component -->
<bean id="amqtx" class="org.apache.activemq.camel.component.ActiveMQComponent">
<property name="connectionFactory" ref="amqPooledConnectFactory" />
...
...
...
<property name="maxConcurrentConsumers" value="${concurrent.consumers}" />
</bean>
</beans>
I have another osgi bundle (connection_impl.jar) which contains camel routes. I want to use "amqtx" bean as the component in the camel endpoint.
Following is the code which I put in the camel-context.xml to access the "amqtx"
<beans ...... >
<import resource="classpath*:mq-connect.xml"/>
...
...
...
...
<camelContext trace="true" streamCache="true" autoStartup="true" xmlns="http://camel.apache.org/schema/spring">
<route customId="true" id="TEST_AMQ">
<description>Test connectivity from another file</description>
<from uri="amqtx:INBOUND.QUEUE" />
<transacted ref="AMQ_PROPAGATION_REQUIRED" />
<to uri="OUTBOUND.QUEUE" />
<log message="Route completed successfully" />
</route>
</camelContext>
</beans>
I am using jboss-a-mq-6.2.1 and deploying to Karaf container. OSGi bundle connection.jar deploys successfully but connection_impl fails to deploy.
It gives following error in the A-MQ logs
Stack Trace:
org.apache.camel.RuntimeCamelException: org.apache.camel.FailedToCreateRouteException: Failed to create route TEST_AMQ:
Route(TEST_AMQ)[[From[amqtx:INBOUND.QUEUE]] -> ... because of Failed to resolve endpoint: amqtx://INBOUND.QUEUE due to: No component found with scheme: amqtx
I tried the part in various ways but still amqtx is not accessible in another bundle.
Please suggest any missing import,export/wrong configuration so that amqtx component in connection.jar is accessible in connection_impl.jar
Not sure if you can make this work at all but it is definitely not recommended to import a spring xml in another bundle.
Better export the bean as a service in the first bundle and refer it as a service in the second. This will also decouple your bundle in a better way.
I am in agreement with Christian. When you are using OSGI bundles are typically isolated unless you explicitly set exports for a library another bundle uses or you are exposing an OSGI Service. If you would like to setup an OSGI service my recommendation is doing it the Spring Framework way since its relatively clean. You can expose your Component via an interface. I'll show an example below.
Typically I like to have 3 bundles managing this. I usually have a bundle that contains just the interface that I will be exposing between separate bundles. A Bundle that is the implementation of the interface and a bundle that leverages the interface's injected implementation to accomplish a task.
//Interface bundle will expose an Interface and any Pojos associated. Ex:
public interface AlternateFacilityApi {
public String getAlternateFacility(String facilityName);
}
//Implementation bundle will register an OSGI service based off of the implementation bean from your interface (yes the previous bundle is a dependency OSGI wires in)
public Class MyAlternateFacilityImpl implements AlternateFacilityApi {
public String getAlternateFacility(String facilityName) {
return "Bob's house";
}
//camel context
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:osgi="http://www.springframework.org/schema/osgi"
xmlns:ctx="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd
http://www.springframework.org/schema/osgi
http://www.springframework.org/schema/osgi/spring-osgi.xsd">
<osgi:service id="AlternateFacilityService" ref="alternateFacilityService" interface="com.world.api.AlternateFacilityApi" />
<bean id="alternateFacilityService" class="com.world.service.MyAlternateFacilityImpl"
/>
</beans>
//Ok and finally the Process looking to leverage the OSGI Service
public Class AlternateFacilityLookup {
private AlternateFacilityApi apiLookupBean;
public String getMyAlternateFacility(String facilityName) {
return apiLookupBean.getAlternateFacility(facilityName);
}
//excluded setters and getters
}
//camel context
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:osgi="http://www.springframework.org/schema/osgi"
xmlns:ctx="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd
http://www.springframework.org/schema/osgi
http://www.springframework.org/schema/osgi/spring-osgi.xsd">
<osgi:reference id="AlternateFacilityLookupService" interface="com.world.api.AlternateFacilityApi" />
<bean id="MyAlternateFacilityBean" class="com.awesome.AlternateFacilityLookup">
<property name="apiLookupBean" ref="AlternateFacilityLookupService" />
</bean>

Spring MVC 4.2.4 / Controller with RequestMapping("/**") and static resources

I have an angular application which uses ui-router, and is served by a SpringMvc (4.2.4) java app. I decided to map any requests to a single Controller/method which loads the single JSP page of my project.
But, When I try to add static resources mappings, to load js and css files, those static resources are ignored... Every requests, inside the [mayapp]/resources/* path leads to my single jsp page.
Here is my config :
web.xml
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/servlet.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
servlet.xml
<context:component-scan base-package="com.adveasys.omrh.front.web" />
<mvc:annotation-driven></mvc:annotation-driven>
<mvc:resources mapping="/resources/**" location="/resources/">
<mvc:resource-chain resource-cache="false" auto-registration="false">
<mvc:resolvers>
<bean class="org.springframework.web.servlet.resource.GzipResourceResolver"/>
<bean class="org.springframework.web.servlet.resource.PathResourceResolver"/>
</mvc:resolvers>
</mvc:resource-chain>
</mvc:resources>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/" />
<property name="suffix" value=".jsp" />
</bean>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/" />
<property name="suffix" value=".jsp" />
</bean>
MainController.java
#RequestMapping("/**")
public ModelAndView mainPage(HttpServletRequest request) throws JsonProcessingException {
Before having this problem, I used the default servlet in web.xml for every /resources/*, But I am generating a .gz version of my scripts/css with maven
and I want this kind of configuration to be able to user the GzipResourceResolver.
Things I already tried, and did not work
declare 2 distincts DispatcherServlets in web.xml, one for JSP only, the other one only for resources. (I splitted the mvc configuration into 2 different files for each servlets)
#RequestMapping("/") in the controller, the user must enter the website at the root address, not acceptable.
I tried to set an order on and as a property for InternalResourceViewResolver
Thanks in advance.
Alright,
after digging in debug mode. HandlerMappings where in this order :
RequestMappingHandlerMapping (the #Controller one, inner property "order" = 0)
SimpleUrlHandlerMapping (the resources one, inner property "order" = 0)
BeanNameUrlHandlerMapping (don't know what it is ... ^^)
When calling a /resource/* file the RequestMappingHandlerMapping was the first to respond as a valid candidate.
after adding such an order in Spring configuration :
<mvc:resources mapping="/resources/**" location="/resources/" order = "-1">
It worked.

playframework 2.X JPA to MSSQL Unable to build Hibernate SessionFactory

I want to using JPA connect to MSSQL,using sample computer-database-jpa can access h2 sql ,but when i change to mssql ,it's put a error message "PersistenceException: [PersistenceUnit: defaultPersistenceUnit] Unable to build Hibernate SessionFactory" who can help me thanks!
my application.conf
# Database configuration
# ~~~~~
# You can declare as many datasources as you want.
# By convention, the default datasource is named `default`
db.default.driver=net.sourceforge.jtds.jdbc.Driver
db.default.url="jdbc:jtds:sqlserver://127.0.0.1:1433;DatabaseName=TCGW;SelectMethod=cursor:sendStringAsUnicode=true"
db.default.user=qqqq
db.default.password=qqqq
#db.default.driver=org.h2.Driver
#db.default.url="jdbc:h2:mem:play"
db.default.jndiName=DefaultDS
applyEvolutions.default=true
hibernate.use_sql_comments=true
my persistence.xml
<persistence-unit name="defaultPersistenceUnit" >
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<non-jta-data-source>DefaultDS</non-jta-data-source>
<properties>
<!--
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
-->
<property name="hibernate.dialect" value="org.hibernate.dialect.SQLServerDialect"/>
</properties>
</persistence-unit>

JPA2: can an EntityManager not created via EJB injection still use JTA transactions

I have the following:
An JAR module, containing a DAO class like so:
public class WhateverDao {
#PersistenceContext(name="pu")
EntityManager entityManager;
public Whatever saveOrUpdate(Whatever entity) {
//entityManager.joinTransaction();
return entityManager.merge(entity);
}
The jar also contains a persistence.xml like so:
<persistence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0" xmlns="http://java.sun.com/xml/ns/persistence">
<persistence-unit name="pu" transaction-type="JTA">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<jta-data-source>jdbc/jee6Test_mysql_datasource</jta-data-source>
<!-- Entities classes declared here -->
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
<property name="hibernate.hbm2ddl.auto" value="update" />
<property name="hibernate.transaction.factory_class" value="org.hibernate.transaction.JTATransactionFactory"/>
</properties>
</persistence-unit>
</persistence>
and an empty beans.xml file.
This jar is used inside a web application (a WAR file), where the DAO is injected into a stateless EJB like so:
#Stateless
#LocalBean
public class WhateverEJBImpl {
#Inject
private WhateverDao whateverDao;
public void saveWhatever(Whatever whatever) throws IOException {
whateverDao.saveOrUpdate(whatever);
}
My issue basicaly is that I can't manage to make this code actually persist something in the database. As far as I understand:
my EntityManager should be "Container Managed" (due to how I configured it in the persistence.xml, and the fact that I obtain it via #PersistenceContext annotation, finally also because the jar is part of a WAR file which is deployed in JBOSS EAP 6.2 - also tried with WebLogic 12c).
The fact that I'm calling it through a stateless EJB means that, by default, there's already a transaction available, so there's no need for me to manage it manually
However, using the above described example simply doesn't persist any data to the db (when calling the EJB saveWhatever method).
What I've also tried tried:
calling entityManager.joinTransaction() before calling entityManager.merge(...) (commented line in the DAO code snippet). This gives the error:
javax.ejb.EJBException: javax.persistence.TransactionRequiredException: No active JTA transaction on joinTransaction call
manually calling entityManager.getTransaction().begin() and commit() (before and after entityManager.merge(...). This gives the error:
javax.ejb.EJBException: java.lang.IllegalStateException: A JTA EntityManager cannot use getTransaction()
So, my question is, please: How do I:
make it so I can have a separate DAO class, in a separate JAR, that uses EntityManager without programmatically (manually) dealing with transactions
Integrate this DAO-classes-containing jar into a WebApplication that uses EJB so that I can take advantage of JTA and have it auto-manage my transactions (more to the point, I'd like to have the Stateless EJB promised behavior, where JTA takes care of creating a transaction for each of the EJB's method calls)
OK, well, for anyone else experiencing this: if you think everything's correctly setup with your EJBs and JTA, but still JTA transactions don't work, (fail silently, etc), here's how I solved it:
I changed from this persistence unit:
<!-- bad persistence.xml, JTA transactions don't work -->
<persistence-unit name="pu" transaction-type="JTA">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<jta-data-source>jdbc/jee6Test_mysql_datasource</jta-data-source>
<!-- <class> tags go here -->
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
<property name="hibernate.hbm2ddl.auto" value="update" />
<property name="hibernate.transaction.factory_class" value="org.hibernate.transaction.JTATransactionFactory"/>
</properties>
</persistence-unit>
To this one:
<!-- good persistence.xml, JTA transactions work -->
<persistence-unit name="pu" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider> <!-- note change here ->
<jta-data-source>jdbc/jee6Test_mysql_datasource</jta-data-source>
<!-- <class> tags go here -->
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
<property name="hibernate.hbm2ddl.auto" value="update" />
<!-- and removal of <property> here -->
</properties>
</persistence-unit>

Jboss RestEasy web service connection pooling

Getting error
NoSuchMethodError: org.apache.http.impl.conn.DefaultClientConnectionOperator.(Lorg/apache/http/conn/scheme/SchemeRegistry;Lorg/apache/http/conn/DnsResolver;)
Using httpclient-4.2-alpha1.jar
Configuration :
<!-- Rest easy connection pooling -->
<bean id="poolingClientConnectionManager" class="com.auction.acp.rest.impl.ConnectionManager" >
</bean>
<bean id="httpClient" class="org.apache.http.impl.client.DefaultHttpClient" >
<constructor-arg name="conman" ref="poolingClientConnectionManager"> </constructor-arg>
</bean>
When I explore jar this constructor is already there.
First thing which is coming in my mind is some other library [I'm using JBoss] is in use.
Tried with exclusions in jboss-deployment-structure.xml but no luck.
<exclusions>
<module name="org.apache.httpcomponents" />
<module name="org.apache.http.impl.conn" />
</exclusions>
If the constructor exists in the JAR you're "exploring" but JBoss can't find it, it means JBoss is not using the JAR you want it to. I suggest using Logback for logging, as it'll add the name of the JAR to the stacktrace in your logs so you know which JAR JBoss is using.

Resources