0
votes

I have been successful in loading the mule app properties from the database at app init and setting them to the property placeholders of mule flows. The code for this is referenced here Read mule props from the DB

However, this works only during app startup. I want to be able to modify the properties in the database(which I can) and make it reflect on the mule flows at runtime without restarting the mule server.

To acheive this, I created a new flow with a Http Listener which invokes a java class that reads the properties from the database and tries to set it to bean factory using the PropertySourcesPlaceHolderConfigurer class. The sample code of the java class looks like this.

@Autowired
ConfigurableListableBeanFactory configurableListableBeanFactory;

@Autowired
MyService myService;

public MuleEventContext onCall(MuleEventContext eventContext){
Properties properties = new Properties();

    // get properties from the database
    Map<String,String> propertiesMap = getMuleAppPropertiesFromDB();
    if(null != propertiesMap && !CollectionUtilsIntg.isEmpty(propertiesMap))
        properties.putAll(propertiesMap);

PropertySourcesPlaceholderConfigurer cfg = new PropertySourcesPlaceholderConfigurer();
cfg.setProperties(properties);
cfg.postProcessBeanFactory(configurableListableBeanFactory);
}

This code ran succesfully but failed to set the properties to the mule app flows at runtime.

Does anyone have any idea how else this can be achieved?

Please help

1

1 Answers

1
votes

I believe PropertyPlaceholders life is ends as soon as application starts fully i.e. they are limited to application init and during beans creation only. If you want to be able to change properties at runtime, then you should not use property placeholders but use other properties mechanisms like creating a bean of org.springframework.beans.factory.config.PropertiesFactoryBean

<?xml version="1.0" encoding="UTF-8"?>
<mule  xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:doc="http://www.mulesoft.org/schema/mule/documentation" xmlns:http="http://www.mulesoft.org/schema/mule/http" xmlns:json="http://www.mulesoft.org/schema/mule/json" xmlns:spring="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mulesoft.org/schema/mule/json http://www.mulesoft.org/schema/mule/json/current/mule-json.xsd
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd">

    <http:listener-config doc:name="HTTP Listener Configuration" host="0.0.0.0" name="HTTP_Listener_Configuration" port="8081"/>
    <spring:beans>
        <spring:bean id="myProps" name="myProps" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
            <spring:property name="properties">
                <bean factory-bean="databasePropertiesProvider" factory-method="getProperties" />       
            </spring:property>
        </spring:bean>
    </spring:beans>
    <flow name="test">
        <http:listener config-ref="HTTP_Listener_Configuration" doc:name="Recieve HTTP request" path="/test"/>
        <logger message="#[app.registry.myProps['testPropertyName']]" />
    </flow>
</mule>

Instead of reading from file, you can use to load from db. Then in your mule config use these as #[app.registry.myPropes['mykey']]. Read about MEL context objects here.

In sample code above, I registered myPoros bean and loaded properties from database. app.registry is application registry context object available in mule, it gives you access to spring beans.