jasypt property placeholder not working - mule

I have this properties file:
secret.key = ENC(foobar)
region = ABC
Then in the config.xml:
<spring:beans>
<encryption:encryptor-config id="eConf" password-sys-property-name="MULE_ENCRYPTION_PASSWORD" algorithm="PBEWithMD5AndDES" password="" />
<encryption:string-encryptor id="stringEnc" config-bean="eConf" />
<encryption:encryptable-property-placeholder encryptor="stringEnc" location="${env}.properties" />
</spring:beans>
But the property placeholders don't work, for example:
<sqs:config secretKey="${secret.key}" region="${region}"></sqs-config>
Does anyone know why?

Encrypted password needs to be write within ENC() function and should be encrypted.
Let's consider in properties file where password value is Login#123... Now the encrypted value in properties file will be :-
password=ENC(B0u7D8wLwq/ugin31KNpP78gBcLP7VIN)
Step1 :- We can generate Key using following commands in Command prompt of \jasypt-1.9.2\bin directory :- encrypt input="Login#123" password=sqlpassword algorithm=PBEWithMD5AndDES
Step2 :- In runtime Environment we need to give (Right click->Run As->Run Configuration->Environment) :- Variable :- MULE_ENCRYPTION_PASSWORD and Value:-sqlpassword
In your Mule config, you need configure it as following :-
<spring:beans>
<spring:bean id="environmentVariablesConfiguration" class="org.jasypt.encryption.pbe.config.EnvironmentStringPBEConfig">
<spring:property name="algorithm" value="PBEWithMD5AndDES"/>
<spring:property name="passwordEnvName" value="MULE_ENCRYPTION_PASSWORD"/>
</spring:bean>
<!-- The will be the encryptor used for decrypting configuration values. -->
<spring:bean id="configurationEncryptor" class="org.jasypt.encryption.pbe.StandardPBEStringEncryptor">
<spring:property name="config" ref="environmentVariablesConfiguration"/>
</spring:bean>
<!-- The EncryptablePropertyPlaceholderConfigurer will read the -->
<!-- .properties files and make their values accessible as ${var} -->
<!-- Our "configurationEncryptor" bean (which implements -->
<!-- org.jasypt.encryption.StringEncryptor) is set as a constructor arg. -->
<spring:bean id="propertyConfigurer" class="org.jasypt.spring.properties.EncryptablePropertyPlaceholderConfigurer">
<spring:constructor-arg ref="configurationEncryptor"/>
<spring:property name="locations">
<spring:list>
<spring:value>conf/yourPropertyFile.properties</spring:value>
</spring:list>
</spring:property>
</spring:bean>
Then you can use encrypted values like :- ${password}
Reference :- http://blogs.mulesoft.org/encrypting-passwords-in-mule/
and http://pragmaticintegrator.wordpress.com/2014/03/09/using-encrypted-passwords-with-mule-esb/
and https://code.google.com/p/soi-toolkit/issues/detail?id=183
and http://soi-toolkit.googlecode.com/svn-history/r2022/wiki/UG_PropertyFile.wiki

I had similar issue, i did configure everything as explained in Activemq web site . In my case issue was PropertyPlaceholderConfigurer bean was loaded for to load other properties before the EncryptablePropertyPlaceholderConfigurer bean. So remove PropertyPlaceholderConfigurer bean's if any just add EncryptablePropertyPlaceholderConfigurer bean even for other non-encrypted properties as explained in Activemq then it works fine.

Related

Infinispan local cache error: Unable to invoke method public void org.infinispan.globalstate.impl.GlobalConfigurationManagerImpl.start()

I have upgraded a Spring boot service to Infinispan 9.4.16.Final from 5.2.20.Final. The service has two XML files. I used the conversion script to convert them. Both have local-cache entries and no other types of caches. One was left with empty transport element by the conversion tool.
When we deploy and run these services, we often see this warning at startup:
org.infinispan.manager.EmbeddedCacheManagerStartupException: org.infinispan.commons.CacheException: Unable to invoke method public void org.infinispan.globalstate.impl.GlobalConfigurationManagerImpl.start() on object of type GlobalConfigurationManagerImpl
The above is the first warning/error we see. There is no stack trace. Why would it be calling GlobalConfigurationManagerImpl when we're only using local cache?
A few lines later in the log, then I see many The cache has been stopped and invocations are not allowed! errors. The last error we see is as follows. The service fails to start up successfully.
Caused by: org.infinispan.commons.CacheException: Initial state transfer timed out for cache org.infinispan.CONFIG on <server_name>
Why are these errors/warnings happening on startup? Is there a problem in the config files? I've searched online and have not found a solution.
~~More Info~~~
Here is one of the two XML config files:
<infinispan
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation = "urn:infinispan:config:9.4 http://www.infinispan.org/schemas/infinispan-config-9.4.xsd"
xmlns = "urn:infinispan:config:9.4">
<threads/>
<cache-container name = "TestCenterServiceCache">
<!-- The conversion tool added this empty "transport" element. It was not present in our old config file -->
<transport/>
<jmx domain = "org.infinispan.TestCenterServiceCache"/>
<local-cache name = "authorizedLocations">
<expiration lifespan = "3600000"/>
</local-cache>
<!--caching for 24 hours: 3,600,000 milliseconds/hr x 24 hours -->
<local-cache name = "proximitySearchConfiguration">
<expiration lifespan = "86400000"/>
</local-cache>
</cache-container>
</infinispan>
The above is instantiated via applicationContext.xml. The first warning (GlobalConfigurationManagerImpl.start()) is referencing these beans.
<bean id="infinispanCacheManager"
class="org.infinispan.spring.embedded.support.InfinispanEmbeddedCacheManagerFactoryBean"
p:configurationFileLocation="classpath:testCenterServices-cache-config.xml" />
<bean id="cacheManager"
class="org.infinispan.spring.embedded.provider.SpringEmbeddedCacheManager">
<constructor-arg ref="infinispanCacheManager" />
</bean>
Here is the second XML config file:
<?xml version="1.0" ?>
<infinispan
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation = "urn:infinispan:config:9.4 http://www.infinispan.org/schemas/infinispan-config-9.4.xsd"
xmlns = "urn:infinispan:config:9.4">
<threads />
<cache-container name="AtlasServicesCacheManager">
<local-cache name="allLocaleCache" />
<local-cache name="localeCacheByID" />
<local-cache name="countryByCode" />
<local-cache name="allActiveCountries" />
<local-cache name="allCountries" />
<local-cache name="allStatesForCountryCode" />
<local-cache name="allActiveStatesForCountryCode" />
<local-cache name="stateForCountryCodeStateCode" />
</cache-container>
</infinispan>
The above is instantiated via java code.
#Bean(name="atlasServicesCacheManager")
public CacheManager makeCacheManager() throws IOException {
return new SpringEmbeddedCacheManager(new DefaultCacheManager("atlas-cache-config.xml"));
}
I don't know if it's meaningful, but only after the upgrade, we log messages that include "JGroups", such as Unable to use any JGroups configuration mechanisms provided in properties {}. Using default JGroups configuration!.
The service instances are running on Windows Server 2012 R2 Standard (Windows 8).
To fix this, remove the empty <transport /> element for local caches.
Adding that empty element seems to be a defect in the config-converter. With the empty transport element in place, it seems that Infinispan is partially configured for cluster synchronization. For details on the underlying issue, see bug report: https://issues.redhat.com/browse/ISPN-11854.

More than one object of type class org.codehaus.jackson.map.ObjectMapper

I have a bean configuration for handling dates in object-to-json transformer like below
<spring:beans>
<spring:bean id="jacksonObjectMapper" class="org.codehaus.jackson.map.ObjectMapper" />
<spring:bean
class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<spring:property name="targetObject" ref="jacksonObjectMapper" />
<spring:property name="targetMethod" value="configure" />
<spring:property name="arguments">
<spring:list>
<spring:value>WRITE_DATES_AS_TIMESTAMPS</spring:value>
<spring:value>false</spring:value>
</spring:list>
</spring:property>
</spring:bean>
</spring:beans>
I am getting the error
More than one object of type class org.codehaus.jackson.map.ObjectMapper registered but only one expected.
How can i fix this error?
Your 2nd bean definition does not have any Id or name defined. But it has a reference to the first bean ref="jacksonObjectMapper".
You may have an extra org.codehaus.jackson.map.ObjectMapper declared in you xml. Can you check it out?

Read properties from database and use it instead of mule-app.properties

I have been able to read the properties from a table in the database as it was described here Reading mule config from database
Now, I am not able to apply these properties to the flow configs and also access them as out bound properties in the Java Processor classes through the MuleEventContext's message.
Update: below is my flow XML code
<flow name="push-data">
<poll doc:name="Push Poll">
<fixed-frequency-scheduler frequency="${push.data.poll.frequency}" timeUnit="MINUTES" />
<set-property propertyName="tempFilePath" value="${temp.csv.file.path}" doc:name="Property"/>
<component class="com.reports.processors.PushDataProcessor" doc:name="PushDataProcessor"/>
<logger message="worked!!!" level="INFO" doc:name="Logger"/>
<exception-strategy ref="push-report-data_Catch_Exception_Strategy" doc:name="Reference Exception Strategy"/>
</flow>
I am trying to set the properties "push.data.poll.frequency" and "temp.csv.file.path". Earlier, these properties existed in the "mule-app.properties" file.
So, My question is, How do I set the properties loaded from the database to the flow. Please keep in mind that I have already loaded the properties from the database as described in the link above. I just want to be able to set these properties to the flow rather than taking them from the mule-app.properties.
EDIT: To add some more information,
I am using a class with #Configuration annotation. The class as described in the link above, loads the properties from the database. Below is the source code.
#Configuration(name="databasePropertiesProvider")
#Component
public class DatabasePropertiesProvider {
#Autowired(required=true)
private MyService myService;
#Bean
public Properties getProperties() throws Exception {
Properties properties = new Properties();
// get properties from the database
Map<String,String> propertiesMap = myService.getMuleAppPropertiesFromDB();
if(null != propertiesMap && !CollectionUtils.isEmpty(propertiesMap))
properties.putAll(propertiesMap);
return properties;
}
#Bean
public static PropertySourcesPlaceholderConfigurer placeHolderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}}
But this class runs after the app is initialized. Previously, I had configured the PropertySourcesPlaceholderConfigurer in the xml config with the factory-bean as the DatabasePropertiesProvider class. But since DatabasePropertiesProvider has a dependency on MyService class, and the dependency was not getting resolved due to MyService bean not initializing in the container before the property config, I had to make some changes to DatabasePropertiesProvider(the version above) so that this runs after the app initialization.
But now, the problem is that I am unable to access those properties that are loaded from the database.
UPDATE 2: I found a solution. Apparently I was trying to autowire the #Service MyService in the databasePropertiesProvider class. The autowiring was failing with null due to which I made some more modifications to the databasePropertiesProvider class so that It runs after the app is initialized.
Now when I look at it, I realized that I dont need to connect to the database through all the service and repository layers. I moved the query execution code from the repository class to the databasePropertiesProvider class and now the properties are loaded during initialization time and the flows can get the properties without making any changes.
Thanks for all your help guys. Made me do a lot of thinking.
Regards,
Zulfiqar
I found a solution. Apparently I was trying to autowire the #Service MyService in the databasePropertiesProvider class. The autowiring was failing with null due to which I made some more modifications to the databasePropertiesProvider class so that It runs after the app is initialized.
Now when I look at it, I realized that I dont need to connect to the database through all the service and repository layers. I moved the query execution code from the repository class to the databasePropertiesProvider class and now the properties are loaded during initialization time and the flows can get the properties without making any changes.
The whole code looks like this
XML Config:-
<bean class="net.intigral.reports.provider.properties.DatabasePropertiesProvider" id="databasePropertiesProvider">
<property name="entityManager" ref="entityManager" />
</bean>
<bean class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
<property name="properties">
<bean factory-bean="databasePropertiesProvider" factory-method="getProperties" />
</property>
</bean>
Java Code:-
public class DatabasePropertiesProvider {
EntityManager entityManager;
public Properties getProperties() throws Exception {
Properties properties = new Properties();
// get properties from the database
Map<String,String> propertiesMap = getMuleAppPropertiesFromDB();
if(null != propertiesMap && !CollectionUtilsIntg.isEmpty(propertiesMap))
properties.putAll(propertiesMap);
return properties;
}
public EntityManager getEntityManager() {
return entityManager;
}
public void setEntityManager(EntityManager entityManager) {
this.entityManager = entityManager;
}
#SuppressWarnings("unchecked")
private Map<String,String> getMuleAppPropertiesFromDB() {
Map<String,String> collect = null;
String query = "select key, value from MuleAppProps muleAppProps";
List<Object[]> results = entityManager.createQuery(query).getResultList();
if (CollectionUtilsIntg.isNotEmpty(results)) {
collect = results.stream().collect(Collectors.toMap(o -> (String)o[0], o -> (String)o[1]));
}
return collect;
}}
Now, I am able to load the properties the same way I used to load from mule-app.properties in the FLOWs.
Let your db contains following properties values with key/value pair as below :-
A simple example like below you can refer to read values from Database:-
<spring:beans>
<spring:bean id="dataSource" name="myCon" class="org.enhydra.jdbc.standard.StandardDataSource">
<spring:property name="url" value="jdbc:sqlserver://YourIpAddress\\SQLEXPRESS:1433;databaseName=YourDB;user=sa;password=yourDBPassword" />
<spring:property name="driverName" value="com.microsoft.sqlserver.jdbc.SQLServerDriver" />
</spring:bean>
<!-- Required to connect to datasource -->
<spring:bean name="PropertyPlaceholderConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<spring:property name="properties" ref="CommonsConfigurationFactoryBean" />
</spring:bean>
<spring:bean name="CommonsConfigurationFactoryBean"
class="org.springmodules.commons.configuration.CommonsConfigurationFactoryBean">
<spring:constructor-arg ref="DatabaseConfiguration" />
</spring:bean>
<spring:bean name="DatabaseConfiguration" class="org.apache.commons.configuration.DatabaseConfiguration">
<spring:constructor-arg type="javax.sql.DataSource" ref="dataSource" />
<spring:constructor-arg index="1" value="YourTableName" />
<spring:constructor-arg index="2" value="Key" />
<spring:constructor-arg index="3" value="Value" />
</spring:bean>
</spring:beans>
<db:generic-config name="Database_Configuration" dataSource-ref="dataSource" doc:name="Generic Database Configuration" />
<http:listener-config name="HTTP_Listener_Configuration" host="0.0.0.0" port="8081" doc:name="HTTP Listener Configuration" />
<flow name="firstflow" processingStrategy="synchronous">
<http:listener config-ref="HTTP_Listener_Configuration" path="/test" doc:name="HTTP" />
<set-payload value="File name ${file.name} File path ${file.path}" doc:name="Set Payload" />
</flow>
You need to add commons-configuration.jar, spring.jar and spring-modules-jakarta-commons.jar in your classpath
If you want to access properties values in Java class you can inject it using Spring property in init-method of Spring bean.
refer:- http://www.codeproject.com/Articles/28893/Loading-Application-Properties-from-a-Database

Camel file uri using property

I'm trying to use property file for routing from folder :
My property file has some property :
from.file = D:/Develop/resources
and I want to use it in camel context xml as file routing,
I tried:
<camel:route id="Main-Route">
<camel:from uri="file:${from.file}" />
<camel:to uri="seda:fooQueue" />
</camel:route>
But camel throws me exception :
Dynamic expressions with ${ } placeholders is not allowed. Use the fileName option to set the dynamic expression.
How can I do this ?
In Camel, you use {{property}} to inject properties in your routes.
Please read more here http://camel.apache.org/properties.html.
Your example would change to:
<camel:route id="Main-Route">
<camel:from uri="file:{{from.file}}" />
<camel:to uri="seda:fooQueue" />
</camel:route>
You also need to tell Camel where it can find your properties file. From the link above:
Spring XML offers two variations to configure. You can define a spring bean as a PropertiesComponent which resembles the way done in Java DSL. Or you can use the tag.
<bean id="properties" class="org.apache.camel.component.properties.PropertiesComponent">
<property name="location" value="classpath:com/mycompany/myprop.properties"/>
</bean>
Using the tag makes the configuration a bit more fresh such as:
<camelContext ...>
<propertyPlaceholder id="properties" location="com/mycompany/myprop.properties"/>
</camelContext>
In file component of apache camel,the starting directory should not contain dynamic expressions. If you want to provide dynamic starting directory also,you can set the whole path into CamelFileName header of file component from properties file with fileComponent defined as <to uri="file://">
the problem with this is that for reading place holder as :
${some-property} for some bean for example :
<bean id="bean" class="">
<property name="field Constructor" value="${some.property}" />
</bean>
I get error.
Solved it by defining also PropertyPlaceholderConfigurer:
<bean id="proprty" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<value>file:/D:/Proj/resources/myprop.properties
</value>
</bean>
<bean id="beanId" class="com.viewlinks.eim.properties.MyBean">
<property name="fieldConstructor" value="${some.property}" />
</bean>
<camel:camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
<propertyPlaceholder id="properties" location="file:/D:/Proj/resources/myprop.properties"/>
<camel:route id="Main-Route">
<camel:from uri="file:{{from.file}}" />
<camel:to uri="file:{{to.file}}" />
</camel:route>
</camel:camelContext>

Reading mule config from database

Is it possible to read mule configuration file path (file endpoints), smtp host /user/password (smtp endpoints) from database.We finally want to provide a User Interface , where the user can edit the properties through the screen.The normal properties file approach (key/Value) pairs was used earlier but needs to change to read these properties from the database.Any help on this will be greatly appreciated.
Yes, you can use a custom properties provider.
Its configuration would look like this:
<spring:bean class="org.mule.DatabasePropertiesProvider" id="DatabasePropertiesProvider"/>
<spring:bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<spring:property name="properties">
<spring:bean factory-bean="DatabasePropertiesProvider" factory-method="getProperties" />
</spring:property>
</spring:bean>
And the code for DatabasePropertiesProvider is as simple as this:
public class DatabasePropertiesProvider {
public Properties getProperties() throws Exception {
Properties properties = new Properties();
// get properties from the database
return properties;
}
}