7 Replies Latest reply on Apr 22, 2012 6:59 PM by ffang

    camel-jdbc and osgi namingservice questions

    sekaijin

      Good morning.

       

      I use ServiceMix to deploy routes built dynamically.

       

      on my platform I have defined lot of datasources.

      they are not defined in the bundles containing my routes because they are shared by several bundles.

       

      For bundles containing a road I use blueprint.

      But my roads must be built dynamically, they can be written in xml.

      So I spend a routeBuilder and I use the DSL camel to build them.

           <blueprint xmlns="...">
                      <camelContext id="myContext" trace="false" xmlns="http://camel.apache.org/schema/blueprint">

                      <package>foo.my.package</package>

                      </camelContext>

                      </blueprint>

      My RouteBuilders then read the parameters and construct a road.

           public class MyRouteBuilder extends RouteBuilder
                 String inUrl;

                 String DataSourceName;

                

                 public RouteBuilder()
                 super();

                 inUrl = getParameter("input.url");

                 DataSourceName = getDataSourceNameFor("somme.info");

                 ...

                 }

                

                 public void configure() {

                 RouteDefinition r = from(inUrl);
                 if ("sommeValue".equals(sommeParameter) {}

                 r.bean(MyBean.class);

                 ...

                 r.to("jdbc:" + DataSourceName)

                 ...

       

       

       

       

       

      When a route needs a datasource, reading parameters gives the name of the datasource. So I can easily pass the url to the endpoint to define correctly the route.

       

      but there is one thing I do not quite understand.

      in the camel doc when using DSL to set an endpoint jdbc, it is written the datasource to be recorded in a JNDIregister.

      the example code simply gives

       

       

       

       

       

       

       

       

       

       

       

           JndiRegistry reg =super.createRegistry();
                           reg.bind("testdb", ds);

                           return  reg;

      but no information about a class you do that.

       

      In an OSGI, a NamingService which are already registered my datasources.

       

      Camel-jdbc he uses the NamingService of OSGI?

      I need to set a JNDI register?

      How to define it?

       

      I can not find clear information about this subject.

      Thank you for your help

       

      A+JYT

      PS: Sorry for my approximative english

       

      Edited by: sekaijin on Mar 8, 2012 9:49 AM

        • 1. Re: camel-jdbc and osgi namingservice questions
          ffang

          Hi,

           

          If you publish your DataSource as OSGi service then you can use OSGi style jndi name to refer it, configure the OSGi style jndi name looks like

           

           

          take a look at related discussion[1] & to get more details.

           

          http://fusesource.com/forums/thread.jspa?messageID=10587

          http://fusesource.com/forums/thread.jspa?messageID=10525

           

          Freeman

          • 2. Re: camel-jdbc and osgi namingservice questions
            sekaijin

            Thank you for that answer.

             

            But my problem is not how I reference an datasource JNDI in blueprint XML. this is simple.

             

            The name of the datasource is known only when the bundle starts.

             

            The sequence is as follows.

             

            startup OSGI bundle

            Blueprint reading

            Creation of routebuilder

            (in constructor)

            loading the bundle configuration (from a database)

            it is only then that I the name of the datasource: datasourcename

             

            construction of the road. (configure method of routebuilder)

            r.to ("jdbc:" + datasourcename)

             

            how to tell the camel datasourcename datasource is registered in JNDI of OSGI?

             

            I cannot reference the name of the datasource in bleuprint file, because it is  known only as the execution.

             

            So I can only intervene in my java code.

             

            The question remains

            what should I do for a camel route defined in Java DSL in a bundle to use a datasource exposed on OSGI as service?

             

            Thank

            A+JYT

            • 3. Re: camel-jdbc and osgi namingservice questions
              sekaijin

              Hello,

              I can not run camel-jdbc in java.

               

              I defines a route with camel-blueprint, via a road builder (not in XML)

              because I know the road to be built when bundle start.

               

              when starting the bundle, I read a database that contains definitions of endpoints. with there informations, I build the road. where in the database I have a record defining an endpoint jdbc datasource I create a datasource "myDataSourceName" and the uri "jdbc:myDataSourceName"

               

              in the documentation I've read, I had to do

              JndiRegistry reg = super.createRegistry();

              reg.bind("testdb", db);

              return reg;

               

              but I'm in the configure method or in constructor of route builder

              I can not call super.createRegistry(); the register already exists

              I tried context.getRegistry (); who gets a JndiRegistry but getRegistry() return a simple Registry.

              The bind method does not exist on Registry.

              I tried (JndiRegistry) context.getRegistry();

              but I get a CastException.

               

              public RouteBuilder()

              super();

              inUrl = getParameter("input.url");

              ... read configuration datas

              DataSourceName = "myDataSourceName";

               

              DataSource DS = DataSourceFactory.create(DataSourceName, ....); //using pooled datasource factory (c3p0)

               

              JndiRegistry reg = (JndiRegistry) getContext().getRegistry(); //CastException

              reg.bind("myDataSourceName", reg);//

              //Or

              Registry reg = getContext().getRegistry();

              reg.bind("myDataSourceName", reg);//

               

              dsUri = "jdbc:"   DataSourceName;

              }

               

              public void configure() {{color}

              RouteDefinition r = from(inUrl);

              if ("sommeValue".equals(sommeParameter) {}

              r.bean(MyBean.class);

              ...

              r.to("dsUri)

               

               

              I have a similar problem in JUnit

              CamelTestSupport created a camelContext and a Registry

              then create the RouteBuilder (calls constructor)

              and calls the configure() method

               

              I've created an object datasource but inpossible to put it in the registry.

               

              can you help me ?

              A JYT

              • 4. Re: camel-jdbc and osgi namingservice questions
                ffang

                Hi,

                 

                As I said before, IMO, In OSGi container you should publish your DataSource as OSGi service but not register on JndiRegistry, then you can use OSGi style jndi name to refer it in other bundles.

                 

                Freeman

                • 5. Re: camel-jdbc and osgi namingservice questions
                  sekaijin

                  Hi

                   

                  No this is not the same problem.

                   

                  bundle is when I start I do not know if the datasource exists

                  if it does not exist I create it and then I must save it in JNDI

                   

                  but  getContext().GetRegistry(); can not call the bind method.

                  for that you need to use.

                  new InitialContext();

                   

                  but if we make new InitialContext();

                  the datasource is not recorded in camel Registry when you're in a JUnit test.

                   

                  test set for a camel routebuilder

                  public class extends MyRouteBuilder RouteBuilder

                  public RouteBuilder () {

                  / / Create a datasource

                  datasource = ....;

                  / / Save it in camel registry

                  InitialContext = new InitialContext ();

                  InitialContext. bind (datasourcename, datasource);

                  }

                   

                  on junit camelTestSupport, the datasource is not present in the Camel registry

                  public void configure() {

                           Registry reg = getContext().getRegistry();

                           dataSource = (DataSource) reg.lookup(datasourcename);

                  }

                   

                  and with this code the datasource is not present in JNDI Registry

                  public void configure() {

                           InitialContext reg= new InitialContext();

                           dataSource = (DataSource) reg.lookup(datasourcename);

                  }

                   

                  and the following code does not work either

                  public void configure() {

                  from(...)

                  .to("jdbc:" + datasourcename);

                  }

                   

                   

                  I've debugged step by step:

                  In the constructor the datasource is in the registry.

                  After the constructor is no longer present.

                  A+JYT

                   

                  Edited by: sekaijin on Apr 2, 2012 4:00 PM

                  • 6. Re: camel-jdbc and osgi namingservice questions
                    sekaijin

                    Hi

                     

                    I've found a solution.

                     

                    the problem comme with CamelTestSupport.

                    When you call new InitialContext(); CamelTestSupport by default use

                    a CamelInitialContextFactory this initialContext returns a different jndiContext each call.

                     

                    the solution is to use a CamelInitialContextFactory that returns the same jndiContext each call.

                     

                    Add jndi.properties file into ressouce folder that content

                    java.naming.factory.initial = fr.foo.CamelInitialContextFactory

                    create the fr.foo.CamelInitialContextFactory class

                    public class CamelInitialContextFactory extends org.apache.camel.util.jndi.CamelInitialContextFactory {

                        private static Context jndiContext = null;

                     

                       @Override

                        public Context getInitialContext(Hashtable<?, ?> environment) throws NamingException {

                          if (null == jndiContext) {

                             jndiContext = super.getInitialContext(environment);

                          }

                          return jndiContext;

                        }

                    }

                     

                    to add anything into registry

                    final InitialContext reg = new InitialContext();

                    reg.bind("jdbc/myDatasource", dataSource);

                     

                    to read it with camel methods

                    Registry reg = getContext().getRegistry();

                    dataSource = (DataSource) reg.lookup("jdbc/myDatasource");

                     

                    and to read it with jni methods

                    InitialContext reg = new InitialContext();

                    dataSource = (DataSource) reg.lookup("jdbc/myDatasource");

                     

                    By

                    PS: sorry my approximative english

                    • 7. Re: camel-jdbc and osgi namingservice questions
                      ffang

                      Hi,

                       

                      Thanks for sharing your solution.

                       

                      Freeman