I'm using camel. This is (an extract of) my blueprint:
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
<cm:property-placeholder id="placeholder" persistent-id="com.adelco.articulos" />
<!-- Configures the Inbound and Outbound SAP Connections -->
<bean id="sap-configuration" class="org.fusesource.camel.component.sap.SapConnectionConfiguration">
.
.
</bean>
<!--A lot of things here, let's omit them-->
<!-- Route beans-->
<bean id="rutaSTEPEntrada" class="com.adelco.articulos.RutaSTEPEntrada"/>
<bean id="rutaSTEPSap" class="com.adelco.articulos.RutaSTEPSap"/>
<camelContext id="camel-articulos" xmlns="http://camel.apache.org/schema/blueprint">
<routeBuilder ref="rutaSTEPEntrada"/>
<routeBuilder ref="rutaSTEPSap"/>
</camelContext>
</blueprint>
I want "disable" the bean "sap-configuration" but without using XML comments. Something like this:
<bean id="sap-configuration" enabled=${ENABLED} class="org.fusesource.camel.component.sap.SapConnectionConfiguration">
.
.
</bean>
I can define the camel routes I want to activate using "autoStartup" and property placeholders "autoStartup=${ENABLED}" but I can't find how to do this with the bean.
This is not possible. Its how OSGi blueprint works. If you define a <bean> then its in use.
Related
I've referred to the JMS page of the Camel documentation and many related SO questions such as this one, but I'm unable to find a comprehensive list on the implementation.
I'm using Spring XML along with Camel and Weblogic for the server. I've made a test queue with the following names:
Server: TestJMSServer, Module: TestJMSModule, Queue: TestJMSQueue, CF: TestConnectionFactory.
According to the Camel documentation, my route should look something like this:
<camel:route id="test">
<camel:from uri="jms:TestJMSQueue" />
<camel:to uri="file:/Users/...." />
</camel:route>
This gives me an error saying "connectionFactory must be specified". So exactly what else do I need to add to my applicationContext.xml in order to listen to this queue?
You need to tell Camel's jms-component which JMS connection factory to use. Most likely you'll get that from jndi if you're using WebLogic.
In the example below i am looking up the connection factory using spring's jee:jndi-lookup (i believe that might even be a name you can use in WebLogic). The looked up factory is then made available as a spring bean with id myConnectionFactory.
This connection factory bean is then used for the connectionFactory property for camel's JmsComponent. Notice the id attribute: jms. This defines the camel endpoint uri scheme to be used in your routes.
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
<jee:jndi-lookup id="myConnectionFactory" jndi-name="jms/connectionFactory"/>
<route id="test" xmlns="http://camel.apache.org/schema/spring">
<from uri="jms:TestJMSQueue"/>
<to uri="file:/Users/...."/>
</route>
<bean id="jms" class="org.apache.camel.component.jms.JmsComponent">
<property name="connectionFactory" ref="myConnectionFactory"/>
<!-- more configuration required based on your requirements -->
</bean>
<!--
example uses invm amq broker:
<bean id="anothercnf" class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="vm://mybroker"/>
</bean>
-->
</beans>
Important Note: You will need to tune this further (setup transactions, setup concurrent consumers, possible configure a spring jms connection pool)
I'm using Camel blueprint on JBoss Developer studio, which is a new challenge for me.
I've googled and found stuff like this: http://camel.apache.org/activemq.html but what I'm trying to figure out is how you define your activeMQ connection if you're using the blueprint. Everything references and activeMQ bean, but nothing shows how to define it in the blueprint.
You should create an ActiveMQComponent outside the the camel context :
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
<bean id="activemq"
class="org.apache.activemq.camel.component.ActiveMQComponent">
<property name="brokerURL"
value="tcp://localhost:61616" />
</bean>
<camelContext xmlns="http://camel.apache.org/schema/blueprint">
...
</camelContext>
</blueprint>
Note that this is described as "spring XML configuration" in http://camel.apache.org/activemq.html. The blueprint XML schema is mostly the same as the one for Spring (you can list main differences at http://camel.apache.org/using-osgi-blueprint-with-camel.html), so in most case you can use what is described as "spring xml" in blueprint.
I have a service which refers to a single source.
<bean id="XYZService" class="com.services.impl.DataService1">
<constructor-arg ref="DataSource1" />
</bean>
<bean id="DataSource1" class="com.source.impl.DataSource1">
<constructor-arg ref="DBDataSource"/>
<constructor-arg value="xyz"/>
</bean>
<bean id="DataSource2" class="com.source.impl.DataSource2">
<constructor-arg ref="MsgDataSource"/>
<constructor-arg value="xyz"/>
</bean>
Now if i want to perform a conditional check and my service should be able listen to particular source based on a input variable something like below.
<bean id="XYZService" class="com.services.impl.DataService1">
<constructor-arg ref=" $VARIABLE == true ? DataSource1 : DataSource2" />
</bean>
I did tried SPEL however no luck. I am beginner in spring. Any help will be appreciated.
Thanks.
There are many solutions. Here are two: You can use profiles for this. Define two profiles, define the DataSource beans with the same name but different profiles. (docs)
Alternatively, you can use a single bean and a static factory method (docs).
<bean id="DataSource" class="com.source.impl.DataSourceFactory"
factory-method="createInstance"/>
Inside of DataSourceFactory.createInstance(), you can check the flag and then create the correct data source in plain Java.
The latter is a bit easier to understand, IMO. Using profiles allows you to keep everything in XML (but you should really consider switching to the Java Configuration). The drawback with profiles is that you must not forget to activate at least one of the bean won't be defined.
A third option is to use three XML files and then modify the list of XML files that should be parsed when you pass it to the ApplicationContext. But that only works if you have control over this part of the code.
Assuming you are using Spring 3.1 or later, Spring Profiles may be the best solution.
Using the example of Production and Dev/QA environments, common bean declarations go in a shared file
<beans>
<bean id="XYZService" class="com.services.impl.DataService1">
<constructor-arg ref="DataSource" />
</bean>
</beans>
A separate configuration contains production references
<beans profiles="prod">
<bean id="DataSource" class="com.source.impl.DataSource1">
<constructor-arg ref="DBDataSource"/>
<constructor-arg value="xyz"/>
</bean>
</beans>
Another contains dev references
<beans profile="dev">
<bean id="DataSource" class="com.source.impl.DataSource2">
<constructor-arg ref="MsgDataSource"/>
<constructor-arg value="xyz"/>
</bean>
</beans>
To activate the given profile add -Dspring.profiles.active=prod to your JVM arguments
You can find more info here
Another approach uses factory methods.
<bean id="DataSource" class="com.source.impl.DataSourceFactory" factory-method="getInstance">
<constructor-arg value="#{VARIABLE}" />
</bean>
The above fragment assumes that you want your factory method to explcitly invoke the constructor of each of your services. If you dead set on using Spring to create the instances you can pass each datasource implementation as constructor arguments and use the constructor method as a simple dispatcher.
You need something like this:
<constructor-arg
ref="#{systemProperties.variable == 'true' ? 'DataSource1' : 'DataSource2'}" />
where "variable" is set like -Dvariable=true.
I'm having a problem with RESTlet Framework configuration with Spring. I want to have one global filter for all requests and responses. I guess I can use Filter class and it's methods beforeHandle, afterHandle and setNext like this:
Filter.beforeHandle() -> Router -> Filter.afterHandle()
The problem is, that I'm using Spring configured RESTlet and I don't know if the regular Filter will work correctly with SpringRouter from org.restlet.ext.spring package. My current restlet configuration is as follows:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="root" class="org.restlet.ext.spring.SpringRouter">
<property name="attachments">
<map>
<entry key="/login">
<bean class="org.restlet.ext.spring.SpringFinder">
<lookup-method name="create"
bean="loginResource" />
</bean>
</entry>
</map>
</property>
</bean>
</beans>
I'm thinking about adding a bean with id root and class that extends class Filter, and pass to it as property next a bean with id router (which currently is called root). What do you think about this solution?
Mixing Restlet classes from the Spring extension with other one shouldn't be an issue. Spring* classes only provide additional configurability.
I am having xml. (Ehcache.xml)
I want to inject into it property from property file(on the classpath).
However since this xml is not a Spring managed bean I am not able to do so.
Any recommendations how to overcome this?
the xml:
...
properties="peerDiscovery=manual,rmiUrls=//**${other.node.hostname}**:41001/org.jasig.cas.ticket.ServiceTicket|//**${other.node.hostname}**:41001/org.jasig.cas.ticket.TicketGrantingTicket"
propertySeparator="," />
<cacheManagerPeerListenerFactory
class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"
properties="port=41001,socketTimeoutMillis=5000" />
</ehcache>
I want to inject ${other.node.hostname} from another properties file.
but I get this on runtime:
Caused by: java.net.URISyntaxException: Illegal character in authority at index 2: //${other.node.hostname}:41001/org.jasig.cas.ticket.TicketGrantingTicket
thanks,
ray.
in the ehcache.xml it won't work because it's not spring configuration. But if you define the equivalent configuration in spring instead of the ehcache file it should work:
<context:property-placeholder location="classpath:config.properties"/>
<bean id="myCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
<property name="cacheManager" ref="cacheManager"/>
<property name="maxElementsInMemory" value="${cache.maxMemoryElements}"/>
</bean>
the best is to use the ehcache.xml file the least possible and configure everything in spring, as most of the options in the file have a spring equivalent.