You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@camel.apache.org by salemi <sa...@avaya.com> on 2013/09/30 21:52:59 UTC

dynamicly change the url of the element after the camelcontext is started

Hi,

During the camel startup, our code will query a database and retrieve the
uri information for all the jms endpoints.

I was wondering how can I overwrite the uri of the <from> elements in
example below?

	    <route id="routeTypeName" autoStartup="false" >
			<from uri="{{type}}.{{name}}"/>
Ali



-----
Alireza Salemi
--
View this message in context: http://camel.465427.n5.nabble.com/dynamicly-change-the-url-of-the-from-element-after-the-camelcontext-is-started-tp5740599.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Re: dynamicly change the url of the element after the camelcontext is started

Posted by Babak Vahdat <ba...@swissonline.ch>.
Hi

No you don't really need to override the first method you've mentioned
below, as just overriding the second one is enough and does the job for you.
See the link to the test I've already provided you in this thread.

That said, in case you want to override the way how the system properties
should affect resolving the Spring placeholders (the default is
PropertyPlaceholderConfigurer.SYSTEM_PROPERTIES_MODE_FALLBACK) then IMHO you
should better do a proper wiring/configuration instead of coding the stuff
by yourself, that's just set the mode you want to have without any coding,
see the Javadoc for how to do it:

http://tinyurl.com/osd4lzc

http://tinyurl.com/q7pvfpn

I' ve extended the test to cover/show this as well, following the diff for
it:

https://github.com/apache/camel/commit/bcc65808bc7373832410ee53bb98db258add3259

Babak


salemi wrote
> Thank you Babak. It had to overwrite the following methods in order for
> Spring and Camel to work.
> 
> 
> public class MyBridgePropertyPlaceholderConfigurer extends
> BridgePropertyPlaceholderConfigurer{
> 
> 	@Override	
> 	protected String resolvePlaceholder(String placeholder, Properties props,
> int systemPropertiesMode){......}
> 	@Override
> 	public Properties resolveProperties(CamelContext context, boolean
> ignoreMissingLocation, String... uri){........}
> 
> }
> 
> Ali





--
View this message in context: http://camel.465427.n5.nabble.com/dynamicly-change-the-url-of-the-from-element-after-the-camelcontext-is-started-tp5740599p5741102.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Re: dynamicly change the url of the element after the camelcontext is started

Posted by salemi <sa...@avaya.com>.
Thank you Babak. It had to overwrite the following methods in order for
Spring and Camel to work.


public class MyBridgePropertyPlaceholderConfigurer extends
BridgePropertyPlaceholderConfigurer{

	@Override	
	protected String resolvePlaceholder(String placeholder, Properties props,
int systemPropertiesMode){......}
	@Override
	public Properties resolveProperties(CamelContext context, boolean
ignoreMissingLocation, String... uri){........}

}

Ali



-----
Alireza Salemi
--
View this message in context: http://camel.465427.n5.nabble.com/dynamicly-change-the-url-of-the-from-element-after-the-camelcontext-is-started-tp5740599p5741057.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Re: dynamicly change the url of the element after the camelcontext is started

Posted by Babak Vahdat <ba...@swissonline.ch>.
Hi,

I just modified the test so that it better fits into your given use-case,
e.g. now also the "from clause" contains a placeholder (as in your case):

Test:
https://github.com/apache/camel/blob/master/components/camel-spring/src/test/java/org/apache/camel/component/properties/CamelSpringPropertyPlaceholderConfigurer3Test.java

Spring setup:
https://github.com/apache/camel/blob/master/components/camel-spring/src/test/resources/org/apache/camel/component/properties/CamelSpringPropertyPlaceholderConfigurer3Test.xml

Babak


Babak Vahdat wrote
> Hi
> 
> Sorry for the confusion, given your concrete use-case I just added a test
> showing how you can achieve this "dynamic" behaviour:
> 
> http://git-wip-us.apache.org/repos/asf/camel/diff/17f9678a
> 
> Babak
> salemi wrote
>> Thanks Babak. 
>> 
>> When Spring comes up and it tries to resolve the properties for the
>> beans, it doesn't use the PropertiesResolver and it uses
>> PropertyPlaceholderConfigurer's method called processProperties which
>> uses a PlaceholderResolvingStringValueResolver and you can't overwrite it
>> !
>> 
>> The code always calls the method resolvePlaceholder in
>> PropertyPlaceholderConfigurer.





--
View this message in context: http://camel.465427.n5.nabble.com/dynamicly-change-the-url-of-the-from-element-after-the-camelcontext-is-started-tp5740599p5740793.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Re: dynamicly change the url of the element after the camelcontext is started

Posted by Babak Vahdat <ba...@swissonline.ch>.
Hi

Sorry for the confusion, given your concrete use-case I just added a test
showing how you can achieve this "dynamic" behaviour:

http://git-wip-us.apache.org/repos/asf/camel/diff/17f9678a

Babak


salemi wrote
> Thanks Babak. 
> 
> When Spring comes up and it tries to resolve the properties for the beans,
> it doesn't use the PropertiesResolver and it uses
> PropertyPlaceholderConfigurer's method called processProperties which uses
> a PlaceholderResolvingStringValueResolver and you can't overwrite it !
> 
> The code always calls the method resolvePlaceholder in
> PropertyPlaceholderConfigurer.





--
View this message in context: http://camel.465427.n5.nabble.com/dynamicly-change-the-url-of-the-from-element-after-the-camelcontext-is-started-tp5740599p5740786.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Re: dynamicly change the url of the element after the camelcontext is started

Posted by salemi <sa...@avaya.com>.
Thanks Babak. 

When Spring comes up and it tries to resolve the properties for the beans,
it doesn't use the PropertiesResolver and it uses
PropertyPlaceholderConfigurer's method called processProperties which uses a
PlaceholderResolvingStringValueResolver and you can't overwrite it !



-----
Alireza Salemi
--
View this message in context: http://camel.465427.n5.nabble.com/dynamicly-change-the-url-of-the-from-element-after-the-camelcontext-is-started-tp5740599p5740781.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Re: dynamicly change the url of the element after the camelcontext is started

Posted by Babak Vahdat <ba...@swissonline.ch>.
You can reach/do the same there as well see the setter method:

BridgePropertyPlaceholderConfigurer#setResolver

Through which you can inject your own PropertiesResolver implementation. So
to recapitulate, just implement you own PropertiesResolver by extending
DefaultPropertiesResolver. Then implement resolveProperties as:

public class MyPropertiesResolver extends DefaultPropertiesResolver {

    public Properties resolveProperties(CamelContext context, boolean
ignoreMissingLocation, String... uri) throws Exception {
        Properties answer = super.resolveProperties(context,
ignoreMissingLocation, uri);

        // now retrieve the remaining *dynamic* properties from the DB and
add them all to
        // the answer

        return answer;
    }

}

And then inject this PropertiesResolver to
BridgePropertyPlaceholderConfigurer using the setter method above.

Babak


salemi wrote
> Thank you Babak. Since we are using Camel 2.10 we are using the
> BridgePropertyPlaceholderConfigurer as followed below:
> 
>     
> <bean id="bridgePropertyPlaceholder"
> class="org.apache.camel.spring.spi.BridgePropertyPlaceholderConfigurer" >
>         
> <property name="location" value="classpath:settings.properties"/>
>     
> </bean>
> How does BridgePropertyPlaceholderConfigurer with the PropertiesComponent?
> 
> Thanks,
> Ali





--
View this message in context: http://camel.465427.n5.nabble.com/dynamicly-change-the-url-of-the-from-element-after-the-camelcontext-is-started-tp5740599p5740705.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Re: dynamicly change the url of the element after the camelcontext is started

Posted by salemi <sa...@avaya.com>.
Thank you Babak. Since we are using Camel 2.10 we are using the
BridgePropertyPlaceholderConfigurer as followed below:

    <bean id="bridgePropertyPlaceholder"
class="org.apache.camel.spring.spi.BridgePropertyPlaceholderConfigurer" >
        <property name="location" value="classpath:settings.properties"/>
    </bean>

How does BridgePropertyPlaceholderConfigurer with the PropertiesComponent?

Thanks,
Ali





-----
Alireza Salemi
--
View this message in context: http://camel.465427.n5.nabble.com/dynamicly-change-the-url-of-the-from-element-after-the-camelcontext-is-started-tp5740599p5740702.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Re: dynamicly change the url of the element after the camelcontext is started

Posted by Babak Vahdat <ba...@swissonline.ch>.
There's a also the following unit-test which should make the idea below clear
to you (check the custom MyCustomResolver implementation):

https://github.com/apache/camel/blob/master/camel-core/src/test/java/org/apache/camel/component/properties/PropertiesResolverTest.java

Babak


Babak Vahdat wrote
> You can make use of the other PropertiesComponent method to pass over an
> array of locations upfront:
> 
>    PropertiesComponent.setLocations(String[] locations)
> 
> So given your code example it would become:
> 
>    PropertiesComponent pc = new PropertiesComponent();
>    pc.setLocations(new String[] {"classpath:settings.properties",
> "classpath:com/mycompany/dynamic.properties"});
>    context.addComponent("properties", pc);
> 
> That said I think a better approach, instead of creating a new properties
> file on the fly and passing it over to PropertiesComponent as above, is to
> implement your own:
> 
>    org.apache.camel.component.properties.PropertiesResolver
> 
> That's this method signature:
> 
>    Properties resolveProperties(CamelContext context, boolean
> ignoreMissingLocation, String... uri) throws Exception;
> 
> For which you can extend a pre-existing implementation:
> 
>    org.apache.camel.component.properties.DefaultPropertiesResolver
> 
> And just override the resolveProperties() method of super in that you call
> super.resolveProperties() and then add the *dynamic* key/value pairs you
> read from the DB to the properties being returned.
> 
> And then the resulting code would somehow look like:
> 
>    PropertiesComponent pc = new PropertiesComponent();
>    pc.setPropertiesResolver(new MyPropertiesResolver())
>    pc.setLocation("classpath:settings.properties"); 
>    context.addComponent("properties", pc); 
> 
> And of course the same wiring in Java code above can be achieved using
> Spring IoC as well.
> 
> Babak
> salemi wrote
>> Hi Babak,
>> 
>> Thank you for your quick respond. We tried the approach to override a
>> property at the run time. It seem like if you set the uri attribute for
>> the 
>> <from>
>>  element then it become immutable!
>> 
>> In our example we have defined the following elements in the camel
>> context file
>> <bean id="bridgePropertyPlaceholder"
>> class="org.apache.camel.spring.spi.BridgePropertyPlaceholderConfigurer" >
>>         
>> <property name="location" value="classpath:settings.properties"/>
>> </bean>
>> 
>> <route id="routeTypeName" autoStartup="false" >
>>                         
>> <from uri="{{type}}.{{name}}.{{dynamic}}"/>
>> In the settings.properties we define:
>> type=type
>> name=name
>> 
>> When camel comes up we retrieve the value for dynamic from db. Are you
>> proposing to create a new file on the fly and add the name and value to
>> the file?
>> 
>> PropertiesComponent pc = new PropertiesComponent();
>> pc.setLocation("classpath:com/mycompany/dynamic.properties");
>> context.addComponent("properties", pc);
>> 
>> My developer tried to overwrite the existing values of a property using
>> using a JVM System Property and he told me he can't get it to work.





--
View this message in context: http://camel.465427.n5.nabble.com/dynamicly-change-the-url-of-the-from-element-after-the-camelcontext-is-started-tp5740599p5740620.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Re: dynamicly change the url of the element after the camelcontext is started

Posted by Babak Vahdat <ba...@swissonline.ch>.
You can make use of the other PropertiesComponent method to pass over an
array of locations upfront:

PropertiesComponent.setLocations(String[] locations)

So given your code example it would become:

   PropertiesComponent pc = new PropertiesComponent();
   pc.setLocations(new String[] {"classpath:settings.properties",
"classpath:com/mycompany/dynamic.properties"});
   context.addComponent("properties", pc);

That said I think a better approach, instead of creating a new properties
file on the fly and passing it over to PropertiesComponent as above, is to
implement your own:

   org.apache.camel.component.properties.PropertiesResolver

That's this method signature:

   Properties resolveProperties(CamelContext context, boolean
ignoreMissingLocation, String... uri) throws Exception;

For which would just extend the pre-existing implementation:

   org.apache.camel.component.properties.DefaultPropertiesResolver

And just override the resolveProperties method of super in that you call
super.resolveProperties() and then add the *dynamic* key/value pairs you
read from the DB to the properties being returned.

And then the resulting code would somehow look like:

   PropertiesComponent pc = new PropertiesComponent();
   pc.setPropertiesResolver(new MyPropertiesResolver())
   pc.setLocation("classpath:settings.properties"); 
   context.addComponent("properties", pc); 

And of course the same wiring in Java code above can be achieved using
Spring IoC as well.

Babak


salemi wrote
> Hi Babak,
> 
> Thank you for your quick respond. We tried the approach to override a
> property at the run time. It seem like if you set the uri attribute for
> the 
> <from>
>  element then it become immutable!
> 
> In our example we have defined the following elements in the camel context
> file
> <bean id="bridgePropertyPlaceholder"
> class="org.apache.camel.spring.spi.BridgePropertyPlaceholderConfigurer" >
>         
> <property name="location" value="classpath:settings.properties"/>
> </bean>
> 
> <route id="routeTypeName" autoStartup="false" >
>                         
> <from uri="{{type}}.{{name}}.{{dynamic}}"/>
> In the settings.properties we define:
> type=type
> name=name
> 
> When camel comes up we retrieve the value for dynamic from db. Are you
> proposing to create a new file on the fly and add the name and value to
> the file?
> 
> PropertiesComponent pc = new PropertiesComponent();
> pc.setLocation("classpath:com/mycompany/dynamic.properties");
> context.addComponent("properties", pc);
> 
> My developer tried to overwrite the existing values of a property using
> using a JVM System Property and he told me he can't get it to work.





--
View this message in context: http://camel.465427.n5.nabble.com/dynamicly-change-the-url-of-the-from-element-after-the-camelcontext-is-started-tp5740599p5740612.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Re: dynamicly change the url of the element after the camelcontext is started

Posted by salemi <sa...@avaya.com>.
Hi Babak,

Thank you for your quick respond. We tried the approach to override a
property at the run time. It seem like if you set the uri attribute for the
<from> element then it become immutable!

In our example we have defined the following elements in the camel context
file

<bean id="bridgePropertyPlaceholder"
class="org.apache.camel.spring.spi.BridgePropertyPlaceholderConfigurer" >
        <property name="location" value="classpath:settings.properties"/>
</bean>

<route id="routeTypeName" autoStartup="false" >
                        <from uri="{{type}}.{{name}}.{{dynamic}}"/>

In the settings.properties we define:
type=type
name=name

When camel comes up we retrieve the value for dynamic from db. Are you
proposing to create a new file on the fly and add the name and value to the
file?

PropertiesComponent pc = new PropertiesComponent();
pc.setLocation("classpath:com/mycompany/dynamic.properties");
context.addComponent("properties", pc);

My developer tried to overwrite the existing values of a property using
using a JVM System Property and he told me he can't get it to work.




-----
Alireza Salemi
--
View this message in context: http://camel.465427.n5.nabble.com/dynamicly-change-the-url-of-the-from-element-after-the-camelcontext-is-started-tp5740599p5740609.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Re: dynamicly change the url of the element after the camelcontext is started

Posted by Babak Vahdat <ba...@swissonline.ch>.
Hi Ali,

you could make use of the PropertiesComponent for this purpose:

http://camel.apache.org/properties.html#Properties-ConfiguringinJavaDSL

You can find lots of tests about using this component inside Spring DSL
here:

https://github.com/apache/camel/tree/master/components/camel-spring/src/test/java/org/apache/camel/component/properties

Babak


salemi wrote
> Hi,
> 
> During the camel startup, our code will query a database and retrieve the
> uri information for all the jms endpoints.
> 
> I was wondering how can I overwrite the uri of the 
> <from>
>  elements in example below?
> 
> 	    
> <route id="routeTypeName" autoStartup="false" >
> 			
> <from uri="{{type}}.{{name}}"/>
> Ali





--
View this message in context: http://camel.465427.n5.nabble.com/dynamicly-change-the-url-of-the-from-element-after-the-camelcontext-is-started-tp5740599p5740607.html
Sent from the Camel - Users mailing list archive at Nabble.com.