4 Replies Latest reply on Feb 14, 2014 11:24 AM by jachym.culka

    Accessing Camel Component properties

    jachym.culka

      Hi, I am currently stuck with a following problem; some camel components support additional properties that can't be directly accessed in SY. For example quartz camel component has property properties and propertiesFile that I'd like to set but can't figure out how this can be done in Switchyard. Is there a way how to intercept component creation or supply modified one into SY/Camel runtime? (my naive approach was to have CDI producer of said component that was qualified by @Named with component id/name - "quartz" in this case, but that didn't work). Any help is greatly appreciated.

       

      Btw. I'm trying to make camel quartz component / quartz binding clustered and persistent but can't figure out how to supply my custom quartz.properties to the component, which leads to the previous question.

       

      Thanks

      JC

        • 1. Re: Accessing Camel Component properties
          kcbabo

          You can add endpoint parameters that are not defined in the component configuration schema via the <additionalUriParameters> element:

          components/camel/camel-quartz/src/test/resources/v1/switchyard-quartz-binding-beans.xml at master · jboss-switchyard/com…

           

          The quartz component will automatically pick up quartz.properties from the org/quartz directory in your deployment.  I'm pretty sure you can't pass a different path as an endpoint parameter, btw.

          • 2. Re: Accessing Camel Component properties
            jachym.culka

            Additional Uri parameters was the first thing I've tried, but I got following error:

             

            There are 1 parameters that couldn't be set on the endpoint. Check the uri if the parameters are spelt correctly and that they are properties of the endpoint. Unknown parameters=[{propertiesFile=/org/quartz/quartz.properties}]

             

            I think thats because Im trying to set Component property as a route parameter. In plain camel it would be something like this:


            <bean id="quartz" class="org.apache.camel.component.quartz.QuartzComponent">
              
            <property name="propertiesFile" value="com/test/app/myquartz.properties"/>
            </bean>

             

            Which in SY AFAIK cannot be simply done.

            As you said, quartz should automatically load property file form my jar, which is done on the following line.

            org/apache/camel/component/quartz/QuartzComponent.java:445

            -> InputStream is = StdSchedulerFactory.class.getClassLoader().getResourceAsStream("org/quartz/quartz.properties");

             

            problem seems to be that class loader thats used for loading that property file does not see the property file in my SY jar. (I double checked to see if its really in the jar on the correct path - somemodule-1.0.0-SNAPSHOT.jar/org/quartz/quartz.properties) The default prop file from modules/system/layers/soa/org/quartz-scheduler/quartz/main/quartz-1.8.5.jar/org/quartz/quartz.properties is always loaded.

             

            Class loader thats used for loading is following:

            ModuleClassLoader for Module "org.quartz-scheduler.quartz:main"

            • 3. Re: Accessing Camel Component properties
              kcbabo

              Yep, I see the same thing here.  The problem is that Camel is overriding the default load order in Quartz by passing a Properties object directly to StdSchedulerFactory.  If the properties file is not set on the component config, then Camel tries to load it using the Quartz class loader instead of the application's class loader:

              https://github.com/apache/camel/blob/camel-2.10.x/components/camel-quartz/src/main/java/org/apache/camel/component/quartz/QuartzComponent.java#L447

               

              Would you mind filing a bug for this so we can work around it from the outside in SwitchYard?  For now, it looks like we will need to look to see if the deployment has a quartz.properties in it, and if so we will need to set the Camel component configuration directly in our deployer.  As a separate task, we can add the ability to set this via a configuration parameter in switchyard.xml, but that will need to go in as an enhancement (requires a config schema change, etc.).

               

              thanks,

              keith

              1 of 1 people found this helpful
              • 4. Re: Re: Accessing Camel Component properties
                jachym.culka

                We have tried to do some workaround for this issue in our project that seemed to work at first but in fact it really did not. We have modified quartz module descriptor to load additional resources containing property file, which worked quite nicely at fist.

                 

                Custom quarz module, where in resources folder theres org/quartz/quartz.properties with custom quartz properties

                <module xmlns="urn:jboss:module:1.0" name="org.quartz-scheduler.quartz">
                
                  <resources>
                  <resource-root path="resources"/> <!-- ADDED --> 
                  <resource-root path="quartz-1.8.5.jar"/>
                  </resources>
                
                  <dependencies>
                  <module name="javax.api" /> <!-- ADDED required for resolving jndi ds in quartz.properties --> 
                  <module name="org.slf4j"/>
                  <module name="org.apache.commons.collections"/>
                  </dependencies>
                </module>
                
                
                
                

                Quartz config is picked up and scheduler is correctly started in clustered persistent mode. BUT problem was when we tried the failover by undeploying our module on one of server nodes and we got following exceptions:

                [Server:server-one] 13:49:50,019 INFO  [org.quartz.core.JobRunShell] (BeeiScheduler-camel-4_Worker-5) Job DEFAULT.quartz-endpoint5 threw a JobExecutionException: : org.quartz.JobExecutionException: No CamelContext could be found with name: camel-2

                [Server:server-one]     at org.apache.camel.component.quartz.CamelJob.execute(CamelJob.java:48) [camel-quartz-2.10.0.jar:2.10.0]

                [Server:server-one]     at org.quartz.core.JobRunShell.run(JobRunShell.java:216) [quartz-1.8.5.jar:]

                [Server:server-one]     at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:549) [quartz-1.8.5.jar:]

                When we dug deeper we found out that there's some information about camel context name stored in quartz job description in DB that contains dynamically assigned context name which may be different on different nodes of cluster or changed by redeploying sy module.

                 

                In the end we decided to take different route and implemented custom clustered scheduling in our modules. We now use clustered singleton in JB AS 7 with EE timer service that invokes url bindings on SY modules through loadbalancer.

                About filing that bug, I will do it asap.

                 

                JC