Possible to use nested properties with both spring and camel property placeholders?

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Possible to use nested properties with both spring and camel property placeholders?

jimi.hullegard
Hi,

I have a Camel project that uses Spring XML, with various settings in a separate settings.properties file. And these settings are used both in plain Spring XML (like arguments to java beans) and in Camel specific configuration (like endpoint URI).

Here is the part of my camel-context.xml that configures this:

                         <bean id="settingsFileLocation" class="java.lang.String">
                                                  <constructor-arg type="java.lang.String" value="file:./config/settings.properties" />
                         </bean>

                         <bean id="propertiesBean" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
                                                  <property name="ignoreResourceNotFound" value="false" />
                                                  <property name="localOverride" value="true" />
                                                  <property name="locations">
                                                                           <list>
                                                                                                    <value>#{settingsFileLocation}</value>
                                                                           </list>
                                                  </property>
                         </bean>

                         <!-- Camel expects this bean to have the id 'properties' -->
                         <bean id="properties" class="org.apache.camel.component.properties.PropertiesComponent">
                                                  <property name="ignoreMissingLocation" value="false" />
                                                  <property name="locations">
                                                                           <list>
                                                                                                    <value>#{settingsFileLocation}</value>
                                                                           </list>
                                                  </property>
                         </bean>

                         <!-- This bean is needed in order for property placeholder replacements to work in Spring bean properties -->
                         <!-- Also, we need to use a different placeholderPrefix to avoid collision with Camel Simple Language expression logic -->
                         <bean id="propertySourcesPlaceholderConfigurer" class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
                                                  <property name="properties" value="#{propertiesBean}" />
                                                  <property name="placeholderPrefix" value="@{" />
                                                  <property name="localOverride" value="true" />
                         </bean>


And my settings.properties looks like something like this:

mainDirectory=/opt/main
inputDirectory=/opt/main/input
tempDirectory=/opt/main/temp
outputDirectory=/opt/main/output
otherDirectory=/opt/main/other
etc...

Also, there are one main settings.properties file, and then one environment-specific file, that overrides some properties.

Now, since there are several properties for directories under the main directory, instead of having to specify "/opt/main" for each one, I would like to re-use the property mainDirectory somehow. Not only would it reduce the manual workload if I would decide to move this folder to a different path, it would mean that I would only have to define inputDirectory, tempDirectory etc in the main settings.properties, and only need to define the mainDirectory property in the environment specific settings.properties.

But... I can't figure out how to achieve this. If I use this syntax:

mainDirectory=/opt/main
inputDirectory={{mainDirectory}}/input


Then the {{mainDirectory}} isn't replaced when inputDirectory is used when setting up a spring bean

And if I use this syntax:

mainDirectory=/opt/main
inputDirectory=#{mainDirectory}/input

Then I get:

Caused by: org.springframework.expression.spel.SpelEvaluationException: EL1008E:(pos 0): Property or field 'mainDirectory' cannot be found on object of type 'org.springframework.beans.factory.config.BeanExpressionContext' - maybe not public?

Does it exist any solution to this problem? I use Camel 2.17.

Regards
/Jimi
Reply | Threaded
Open this post in threaded view
|

Re: Possible to use nested properties with both spring and camel property placeholders?

Willem.Jiang
Administrator
It looks like you are using the Spring and Camel Properties component together.
Camel support the {{}} syntax out of box , so you just need to find a way to let the spring bean too support :)  

--  
Willem Jiang


Blog: http://willemjiang.blogspot.com (English)  
http://jnn.iteye.com (Chinese)
Twitter: willemjiang  
Weibo: 姜宁willem



On November 3, 2016 at 9:20:25 PM, [hidden email] ([hidden email]) wrote:

> Hi,
>  
> I have a Camel project that uses Spring XML, with various settings in a separate settings.properties  
> file. And these settings are used both in plain Spring XML (like arguments to java beans)  
> and in Camel specific configuration (like endpoint URI).
>  
> Here is the part of my camel-context.xml that configures this:
>  
>  
> > />
>  
>  
>  
>  
>  
>  
>  
> #{settingsFileLocation}
>  
>  
>  
>  
>  
>  
>  
>  
>  
> #{settingsFileLocation}
>  
>  
>  
>  
>  
>  
>  
>  
>  
>  
>  
>  
>  
> And my settings.properties looks like something like this:
>  
> mainDirectory=/opt/main
> inputDirectory=/opt/main/input
> tempDirectory=/opt/main/temp
> outputDirectory=/opt/main/output
> otherDirectory=/opt/main/other
> etc...
>  
> Also, there are one main settings.properties file, and then one environment-specific  
> file, that overrides some properties.
>  
> Now, since there are several properties for directories under the main directory, instead  
> of having to specify "/opt/main" for each one, I would like to re-use the property mainDirectory  
> somehow. Not only would it reduce the manual workload if I would decide to move this folder  
> to a different path, it would mean that I would only have to define inputDirectory, tempDirectory  
> etc in the main settings.properties, and only need to define the mainDirectory property  
> in the environment specific settings.properties.
>  
> But... I can't figure out how to achieve this. If I use this syntax:
>  
> mainDirectory=/opt/main
> inputDirectory={{mainDirectory}}/input
>  
>  
> Then the {{mainDirectory}} isn't replaced when inputDirectory is used when setting  
> up a spring bean
>  
> And if I use this syntax:
>  
> mainDirectory=/opt/main
> inputDirectory=#{mainDirectory}/input
>  
> Then I get:
>  
> Caused by: org.springframework.expression.spel.SpelEvaluationException: EL1008E:(pos  
> 0): Property or field 'mainDirectory' cannot be found on object of type 'org.springframework.beans.factory.config.BeanExpressionContext'  
> - maybe not public?
>  
> Does it exist any solution to this problem? I use Camel 2.17.
>  
> Regards
> /Jimi
>