Unable to set up interceptor/brokerplugin in ActiveMQ - activemq

I have written a simple authentication/authorization plugin that I want to inject into ActiveMQ. I want it to be called onConnect and onSubscribe. I have followed these steps at the ActiveMQ website but a couple of things happen.
1) If I put in my bean declaration in the default activemq.xml file in //beans/broker/plugins I get a validation error saying that the node "bean" is not allowed there.
2) If I put the plugin declaration outside of the broker element it will inject the element, but it will not call installPlugin() nor the hooks, presumably because that is for the broker to do.
3) If I change the XML namespace declaration in the default activemq.xml (http://activemq.apache.org/schema/core) to that which is stated in the docs listed above (http://activemq.org/config/1.0) along with the proper URLs, I get the error that it cannot find the schema document.
The only thing I can come up with is that either there were changes in 5.6 that were not reflected in the documentation, I'm doing something very wrong, or I'm just crazy. Here is the relevant portion of the xml doc (minus several nodes not directly related to the problem).
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:amq="http://activemq.org/config/1.0"
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-2.0.xsd
http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd">
<broker xmlns="http://activemq.apache.org/schema/core" brokerName="localhost" dataDirectory="${activemq.data}">
<plugins>
<bean id="tokenLoginPlugin" class="auth.TokenLoginPlugin">
<property name="host" value="localhost" />
</bean>
</plugins>
</broker>
This generates the following exception.
The matching wildcard is strict, but no declaration can be found for element 'broker'.
If I use the xmlns declarations from the default activemq.xml file, I get the following.
Invalid content was found starting with element 'bean'
I can see that it's a validation error, but none of the docs seem to be pointing me in the right direction.

Figured it out, though I had tried it before and it hadn't worked. Perhaps I had messed up my namespaces the last time. I changed my plugin definition and added the Spring namespace to my bean declaration.
<plugins>
<bean id="tokenLoginPlugin" class="auth.TokenLoginPlugin" xmlns="http://www.springframework.org/schema/beans">
<property name="host" value="localhost" />
</bean>
</plugins>

My configuration is :
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:amq="http://activemq.apache.org/schema/core"
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-2.0.xsd
http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd">
<plugins>
<bean xmlns="http://www.springframework.org/schema/beans" id="probePlugin" class="com.ProbePlugin"/>
</plugins>
</beans>

Related

How to configure Database with custom Datasource in MUlesoft

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>

referencing properties in <broker> portion of the activemq.xml configuration

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

Mule - make Global Elements more global

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.

Apache Camel select then insert

I am very very new to Apache Camel and I am looking to create a simple application which reads 200 products from mysql db 1 and then inserts the products into mysql db 2. No changes required to the data, it is just a one for one bulk select and then bulk insert.
I have been looking at the camel-sql-example project which uses the sql component. I like the way it's structured so I've attempted to go with this example project as my base.
Would anyone be able to help me with the location of a good example for this or giving me a rough indication of what my camel route (spring arcehtype) should look like?
Is something like this correct?
<?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://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="sourceDataSource" class="org.apache.commons.dbcp.BasicDataSource">
...
</bean>
<bean id="targetDataSource" class="org.apache.commons.dbcp.BasicDataSource">
...
</bean>
<!-- configure the Camel SQL component to use the JDBC data source -->
<bean id="sourceSql" class="org.apache.camel.component.sql.SqlComponent">
<property name="dataSource" ref="sourceDataSource"/>
</bean>
<bean id="targetSql" class="org.apache.camel.component.sql.SqlComponent">
<property name="dataSource" ref="targetDataSource"/>
</bean>
<bean id="productBean" class="org.apache.camel.example.sql.ProductBean"/>
<camelContext xmlns="http://camel.apache.org/schema/spring">
<propertyPlaceholder location="classpath:sql.properties" id="placeholder"/>
<route id="processProduct-route">
<from uri="sourceSql:{{sql.selectProduct}}"/>
<to uri="targetSql:{{sql.insertProduct}}"/>
<log message="${body}"/>
</route>
</camelContext>
thanks
I tested this today and what I've specified above seems to work! Something that I did not expect though was that the route just loops and continues to run multiple times. I only need it to run once. I'm looking into how to achieve this.

Glassfish create JDBCResources, -Pools and Security Realms from application

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.