In mule I have many applications running on the same container that access a jdbc connector with the same connection string/user/password set.
Of course any app has configured the same global connector in its xml configuration file, so there is code duplication.
Is there a way to define only once per container the connection and access it from any app?
I would try this: have one app create the datasource and store it in JNDI and have the other apps pick it up from JNDI.
Since there is no strong guarantee of app start ordering, it's possible that one app that needs the JNDI datasource would start too soon. You would need to configure Spring to be able to perform the JNDI lookup again in case of failure and configure a threaded retry policy on the Mule JDBC connector.
Also you will need to install the datasource and database JARs in lib/user so all apps could use them.
Just create a spring bean for your JDBC connector in xml some where in your system and have all your applications load it in your apps:
<spring:import resource="JDBC-beans.xml" />
and the xml:
<?xml version="1.0" encoding="UTF-8"?>
<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-3.0.xsd ">
<!-- Initialization for data source -->
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/TEST"/>
<property name="username" value="root"/>
<property name="password" value="password"/>
</bean>
</beans>
I have solved this kind of problem using a Domain project, where I inserted all database configurations that have been used by other projects.
Related
I have a requirement that to configure the database connector using my custom-defined Datasource(Spring based). When configuring my data-source to DB Connector with my custom bean, I am getting an error that cannot set javax.sql.Datasource to org.mule.extension.db.internal.domain.data source.DataSourceConnetionSettings.dataSourceRef. When I didn't configure my DB connector and referred to the data source using java invoke, able to get the Datasource object. How can I pass this Datasource this my database connector in runtime?
Referred to the below but didn't help.
https://help.mulesoft.com/s/article/Spring-based-datasources
Can someone help me with the last point in the below knowledgebase?
https://help.mulesoft.com/s/article/How-to-configure-connector-with-dynamic-parameters
<db:config name="Database_Config">
<db:data-source-connection dataSourceRef="myDbConnetor" />
</db:config>
My beans.xml as like below:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/jdbc
http://www.springframework.org/schema/jdbc/spring-jdbc-4.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.1.xsd">
<context:annotation-config />
<context:component-scan base-package="com.test.datasource.*" />
<bean id="myDbConnetor" class="com.test.datasource.MyCustomDataSource"/>
</beans>
Is it possible to reference my own properties inside the <broker> configuration portion of the activemq.xml file?
I'm setting my property values by altering the ACTIVEMQ_OPTS in the "env" script, e.g. adding something like:
ACTIVEMQ_OPTS="${ACTIVEMQ_OPTS} -Dmy.property=MyValue"
And I have the following at the start of my activemq.xml file:
<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 http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd">
<!-- Allows us to use system properties as variables in this configuration file -->
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<value>file:${activemq.conf}/credentials.properties</value>
</property>
</bean>
Configuring <beans> in the activemq.xml file works fine with my own properties in the "value", e.g. this works fine:
<bean id="myBean" class="MyClass">
<property name="someProperty" value="${my.property}"/>
</bean>
and ${my.property} is resolved perfectly ... but I just can't figure out how to get my properties to resolve when inside the <broker> element or one of it's children (like the persistenceAdapter).
For example, in the following case ...
<persistenceAdapter>
<replicatedLevelDB directory="${activemq.data}/leveldb" zkAddress="${my.zk.address}" zkPath="/activemq" bind="tcp://0.0.0.0:0" weight="${my.weight}"/>
</persistenceAdapter>
... the ${activemq.data} property is resolved ... but I can't seem to figure out how to get any of my own properties to resolve within the <broker> element of the activemq.xml configuration file ... I just keep getting an error that '${my.weight}' isn't a valid number (which is kind of insulting, if you think about it ;-)
I am stuck with the same problem
Got it to work but not sure if that is the right way.
You have to add it to the startup scripts.
If you are using active.bat
"%_JAVACMD%" %ACTIVEMQ_SUNJMX_START% %ACTIVEMQ_DEBUG_OPTS% %ACTIVEMQ_OPTS% %ACTIVEMQ_SSL_OPTS%
-Dactivemq.classpath="%ACTIVEMQ_CLASSPATH%"
-Dactivemq.home="%ACTIVEMQ_HOME%"
-Dactivemq.base="%ACTIVEMQ_BASE%"
-Dactivemq.conf="%ACTIVEMQ_CONF%"
-Dactivemq.data="%ACTIVEMQ_DATA%"
-Djava.io.tmpdir="%ACTIVEMQ_TMP%"
-D**remote.host.ip=1.2.3.4**
-jar "%ACTIVEMQ_HOME%/bin/activemq.jar" %*
If you are using wrapper, add it to wrapper.conf
wrapper.java.additional.**13**=-Dremote.host.ip="1.2.3.4"
Make sure to increment bolded number.
Yes, you can use property placeholders to load a properties file or use environment variables. It looks like you are using Spring, so you'd need to use the Spring-specific property placeholder mechanism.
Property file:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="properties">
...
Environment variables:
<context:property-placeholder />
Also see:
Spring property placeholders
In Fabric8, the preferred way to obtain an ActiveMQ connection is via the mq-fabric profile, which provides an ActitveMQConnection object via Declarative Services. An example of this is given on GitHub, which works just fine.
However, I've yet to find a way for Declarative Services and Blueprint Services to collaborate in Fabric8 (or any OSGI-environment, really), thus, my OSGI application must either use DS or blueprint. Mixing both doesn't seem to be an option.
If you want to use blueprint (which I do), you must first create a broker through the web UI, then go back to the console and type cluster-list, finding the port that Fabric8 assigned to the broker and then configure a connection in blueprint like so:
<bean id="activemqConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="tcp://mydomain:33056" />
<property name="userName" value="admin" />
<property name="password" value="admin" />
</bean>
While this does work, it's not exactly deployment-friendly, as it involves a few manual steps that I'd like to avoid if possible. The main issue is that I don't know what that port is going to be. I've combed through the config files and couldn't find it anywhere.
Is there a cleaner, more automated way to obtain an ActiveMQ connection in Fabric8 via blueprint, or must we use Declarative Services?
Stumbled across a solution to this issue in the fabric-camel-demo, which illustrates how to instantiate an ActiveMQConnectionFactory bean in Fabric8 via Blueprint.
<!-- use the fabric protocol in the brokerURL to connect to the ActiveMQ broker registered as default name -->
<!-- notice we could have used amq as the component name in Camel, and avoid any configuration at all,
as the amq component is provided out of the box when running in fabric -->
<bean id="jmsConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="discovery:(fabric:default)"/>
<property name="userName" value="admin"/>
<property name="password" value="admin"/>
</bean>
Hope this helps!
How can I create JDBCResources, -Pools and Security Realms in a Glassfish 3.1 Server from within my Application, if they are not already created? I am writing an application that relies on this resources, however I don't want to configure the server manually every time the application is deployed on a different server.
Doing this with a shell script feels like a workaround.
Glassfish provides a REST interface. You can create a new security (authentication) realm in a certain configuration (say, server-config in a DAS on localhost, admin port 4848) with a POST to:
http://localhost:4848/management/domain/configs/config/server-config/security-service/auth-realm
Do a GET to that resource to see the parameters.
You can use the same interface to create connection pools.
Ok, I found a solution for half of the Question.
I created a file called glassfish-resources.xml in my WEB-INF folder and added the following content to it:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE resources PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Resource Definitions//EN" "http://glassfish.org/dtds/glassfish-resources_1_5.dtd">
<resources>
<jdbc-connection-pool
name="java:app/jdbc/BeerUserPool"
res-type="javax.sql.DataSource"
datasource-classname="org.postgresql.ds.PGSimpleDataSource"
pool-resize-quantity="2"
max-pool-size="32"
steady-pool-size="0"
statement-timeout-in-seconds="30">
<property name="User" value="USERNAME"></property>
<property name="Password" value="PASSWORD"></property>
<property name="PortNumber" value="12345678"></property>
<property name="dataBaseName" value="DATABASE_NAME"></property>
<property name="ServerName" value="yourDBUrl.com"></property>
<property name="Ssl" value="false"></property>
<property name="ProtocolVersion" value="0"></property>
</jdbc-connection-pool>
<jdbc-resource
pool-name="java:app/jdbc/BeerUserPool"
jndi-name="java:app/jdbc/BeerUser"></jdbc-resource>
<
</resources>
Addingt the java:app/ to the names is important, without it it won't work correctly. This connection pool is also only application scoped and gets destroyed after the application is undebloyed (except you add an additional argument).
This pool can now be accessed with JPA with the following persistence.xml.
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence">
<persistence-unit name="jsf-jpa-war" transaction-type="JTA">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>java:app/jdbc/BeerUser</jta-data-source>
<properties>
<property name="eclipselink.logging.level" value="FINE"/>
</properties>
</persistence-unit>
</persistence>
However I found no soultion how I can define the security realms in the same way.
Hello has anyone ever used Camel with IBM's MQ. We are looking at possibly using the two products together but have no example of the two products working together.
I have extensive use of IBM MQ's with camel. There is no issue using both together. I will paste a sample configuration from one of my spring context files leveraging a camel Jms Endpoint, A spring connection factory, and an IBM MQ definition.
Camel Route
from("someplace")
.to("cpaibmmq:queue:myQueueName");
Spring Context
<bean name="cpaibmmq" class="org.apache.camel.component.jms.JmsComponent" destroy-method="doStop">
<property name="transacted" value="${jms.transacted}" />
<property name="concurrentConsumers" value="${cpa.concurrentConsumers}" />
<property name="maxConcurrentConsumers" value="${cpa.concurrentConsumers}" />
<property name="acceptMessagesWhileStopping" value="${jms.acceptMessagesWhileStopping}" />
<property name="acknowledgementModeName" value="${jms.acknowledgementModeName}" />
<property name="cacheLevelName" value="${jms.cacheLevelName}" />
<property name="connectionFactory" ref="ibmFac1" />
<property name="exceptionListener" ref="ibmFac1" />
</bean>
<bean id="ibmFac1" class="org.springframework.jms.connection.SingleConnectionFactory" destroy-method="destroy">
<constructor-arg>
<bean class="com.ibm.mq.jms.MQQueueConnectionFactory">
<property name="transportType" value="1" />
<property name="channel" value="${cpa.wmq.channel}" />
<property name="hostName" value="${cpa.wmq.hostname}" />
<property name="port" value="${cpa.wmq.port}" />
<property name="queueManager" value="${cpa.wmq.mqmanager}" />
</bean>
</constructor-arg>
</bean>
The best I have been able to get is documented below, illustrated as a Spring XML application context that itself hosts the CAMEL context and routes. This sample works with the IBM native MQ JCA-compliant resource adapter v7.5, CAMEL 2.16, Spring core 4.2. I have deployed it in Glassfish, Weblogic, and JBoss EAP7 servers.
The complexity is bound to handling the flow of MQ reports whose philosophy conflicts with that of a plain JMS reply-to message. For a detailed explanation, please refer to Implementing native websphere MQ with CoD over Camel JMS component
This example based on the CAMEL XML DSL is self-contained and easy to test.
We start with Spring & CAMEL declarations:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:camel="http://camel.apache.org/schema/spring"
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://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd">
The CAMEL context follows with 2 routes: MQ to JMS and JMS to MQ, here chained to form a bridge to ease testing.
<camel:camelContext id="mqBridgeCtxt">
<camel:route id="mq2jms" autoStartup="true">
Weird: on Weblogic, the only way to get (e.g.) 3 listeners is to enforce 3 connections (with 3 Camel:from statements in sequence) with max 1 session each, otherwise an MQ error ensues: MQJCA1018: Only one session per connection is allowed. On JBoss, you can simply adjust concurrentConsumers=...
<camel:from uri="wmq:queue:TEST.Q1?concurrentConsumers=1&disableReplyTo=true&
acknowledgementModeName=SESSION_TRANSACTED"/>
The disable disableReplyTo option above ensures that CAMEL will not produce a reply before we can test the MQ message type to be 1=Request(-reply) or 8=datagram (one way!). That test and reply construction is not illustrated here.
Then we enforce the EIP to InOnly on the next posting to plain JMS to be consistent with the Inbound MQ mode.
<camel:setExchangePattern pattern="InOnly"/>
<!-- camel:process ref="reference to your MQ message processing bean fits here" / -->
<camel:to uri="ref:innerQueue" />
</camel:route>
This ends the MQ-to-jms route; next comes the jms-to-MQ route still in the same CAMEL context:
<camel:route id="jms2mq" autoStartup="true">
<camel:from uri="ref:innerQueue" />
<!-- remove inner message headers and properties to test without inbound side effects! -->
<camel:removeHeaders pattern="*"/>
<camel:removeProperties pattern="*" />
<!-- camel:process ref="reference to your MQ message preparation bean fits here" / -->
Now comes the request flag for the MQ CoD report to be returned by remote destination. We also enforce the MQ message to be of Datagram type (value 8).
<camel:setHeader headerName="JMS_IBM_Report_COD"><camel:simple resultType="java.lang.Integer">2048</camel:simple></camel:setHeader>
<camel:setHeader headerName="JMS_IBM_Report_Pass_Correl_ID"><camel:simple resultType="java.lang.Integer">64</camel:simple></camel:setHeader>
<camel:setHeader headerName="JMS_IBM_MsgType"><camel:simple resultType="java.lang.Integer">8</camel:simple></camel:setHeader>
The ReplyTo queue can be specified either via the ReplyTo uri option, else as a header as below.
Next we do use CamelJmsDestinationName header to enforce suppressing of the JMS MQ message header MQRFH2 (using targetClient MQ URL option value 1). In other words, we want to send a plain vanilla MQ binary message (i.e. Only the MQMD message descriptor followed by the payload).
<camel:setHeader headerName="JMSReplyTo"><camel:constant>TEST.REPLYTOQ</camel:constant></camel:setHeader>
<camel:setHeader headerName="CamelJmsDestinationName"> <camel:constant>queue://MYQMGR/TEST.Q2?targetClient=1</camel:constant></camel:setHeader>
More MQMD fields may be controlled through reserved JMS properties as illustrated below. See restrictions in IBM doc.
<camel:setHeader headerName="JMS_IBM_Format"><camel:constant>MQSTR </camel:constant></camel:setHeader>
<camel:setHeader headerName="JMSCorrelationID"><camel:constant>_PLACEHOLDER_24_CHARS_ID_</camel:constant></camel:setHeader>
The destination queue in the URI is overwritten by the CamelJmsDestinationName above, hence the queue name in the URI becomes a placeholder.
The URI option preserveMessageQos is the one that - as observed - allows sending a message with the ReplyTo data being set (to get the MQ CoD Report), yet prevent CAMEL to instantiate a Reply message listener by enforcing the InOnly MEP.
<camel:to uri="wmq:queue:PLACEHOLDER.Q.NAME?concurrentConsumers=1&
exchangePattern=InOnly&preserveMessageQos=true&
includeSentJMSMessageID=true" />
</camel:route>
</camel:camelContext>
We have not finished, we have still to declare our queue factories for both a native JMS provider and Websphere MQ (via the native IBM WMQ JCA Resource Adapter), to be adjusted to your context.
We use here JNDI lookups on administrative objects.
<camel:endpoint id="innerQueue" uri="jmsloc:queue:transitQueue">
</camel:endpoint>
<jee:jndi-lookup id="mqQCFBean" jndi-name="jms/MYQMGR_QCF"/>
<jee:jndi-lookup id="jmsraQCFBean" jndi-name="jms/jmsra_QCF"/>
<bean id="jmsloc" class="org.apache.camel.component.jms.JmsComponent">
<property name="connectionFactory" ref="jmsraQCFBean" />
</bean>
<bean id="wmq" class="org.apache.camel.component.jms.JmsComponent">
<property name="connectionFactory" ref="mqQCFBean" />
</bean>
</beans>
An alternative to fetching the factories (and JCA adapters) from JNDI is to declare the JMS client as Spring beans. In Weblogic and Glassfish, you'll be better inspired by deploying the native IBM JCA resource adapter and creating JNDI resources then referenced in the Spring Context as above, in JBoss a direct MQ client bean declaration suits best as below)
<bean id="mqCFBean" class="com.ibm.mq.jms.MQXAConnectionFactory">
<property name="hostName" value="${mqHost}"/>
<property name="port" value="${mqPort}"/>
<property name="queueManager" value="${mqQueueManager}"/>
<property name="channel" value="${mqChannel}"/>
<property name="transportType" value="1"/> <!-- This parameter is fixed and compulsory to work with pure MQI java libraries -->
<property name="appName" value="${connectionName}"/>
</bean>
<bean id="wmq" class="org.apache.camel.component.jms.JmsComponent">
<property name="connectionFactory" ref="mqCFBean"/>
<property name="transacted" value="true"/>
<property name="acknowledgementModeName" value="AUTO_ACKNOWLEDGE"/>
</bean>
Comments and improvements welcome.
A quick google revealed following,
http://lowry-techie.blogspot.de/2010/11/camel-integration-with-websphere-mq.html
HTH