9 Replies Latest reply on Jul 27, 2009 9:27 AM by oisin

    deploy pure .xml as a route

    vector_jdev.work

      Hello!

      I would like to ask about is it a good idea to deploy routes as a pure xml file in deploy dir.

      For the first glance it looks like a great idea - we are having some bundles and need to have route between then.

       

      Actually when trying this code

       

        <osgi:camelContext xmlns="http://activemq.apache.org/camel/schema/spring">

          <package>com.mysql.jdbc</package>

          <endpoint id="ee" uri="jdbc:testdb"/>

           

          <route>

            <from uri="timer://myTimer?fixedRate=true&amp;period=2000"/>

            <setBody>

                <constant>select * from incoming_table where process_status=0</constant>

            </setBody>

            <to uri="jdbc:testdb" />

            <to uri="log:ExampleRouter"/>

          </route>

        </osgi:camelContext>

                                                                                      <bean id="testdb" class="org.springframework.jdbc.datasource.DriverManagerDataSource">

              <property name="driverClassName" value="com.mysql.jdbc.Driver"/>

              <property name="url" value="jdbc:mysql://localhost:3306/mydb"/>

              <property name="username" value="root"/>

              <property name="password" value="root"/>

      </bean>

       

      It is said java.sql.SQLException: No suitable driver

      When I take a look at headers of created bundle there wasn't any import statement for com.mysql.jdbc.

      It means that it can not load driver. Are there any ways to point imported packaged in xml file?

       

      I attached the camel-router-sample.xml, just create your local mysql db and deploy .xml to /deploy dir

      Edited by: vector on Jul 22, 2009 2:01 PM

        • 1. Re: deploy pure .xml as a route
          janstey

          ServiceMix will actually add in the proper import statements to the generated bundle based on what classes you reference. You still need to ensure that the bundles you reference are loaded. I think for JDBC support, you'll need at least the following

           

          osgi/install mvn:org.springframework/spring-jdbc/2.5.6
          osgi/install mvn:org.springframework/spring-tx/2.5.6
          

           

          Cheers,

          Jon

          • 2. Re: deploy pure .xml as a route
            oisin

             

            I would like to ask about is it a good idea to deploy routes as a pure xml file in deploy dir.

             

             

            If you have a route that can work self-supported with no other requirements that are not already present as a bundle in the target runtime, then doing this is a fine idea.

             

            There's a short video of this at http://repo.fusesource.com/videos/fid/osgideploy.mov that illustrates a similar situation for a route that uses JMS.

             

            So if you can make sure that your target container has all the bundles it needs to support the route already in place, then there's no issue about just putting the XML file into the deploy dir. It would be cool if we could work this out automatically

            • 3. Re: deploy pure .xml as a route
              vector_jdev.work
              janstey wrote:

              ServiceMix will actually add in the proper import statements to the generated bundle based on what classes you reference. You still need to ensure that the bundles you reference are loaded. I think for JDBC support, you'll need at least the following

               

              > osgi/install mvn:org.springframework/spring-jdbc/2.5.6
              > osgi/install mvn:org.springframework/spring-tx/2.5.6
              > 

               

              Cheers,

              Jon

               

              Hello!

              I have the following on my Fuse:

               

              smx@root:osgi> list | grep Spring

                 ID   State         Spring     Level  Name

              Spring Context (2.5.6)

              Spring Core (2.5.6)

              Spring Beans (2.5.6)

              Spring AOP (2.5.6)

              Apache ServiceMix Kernel :: Spring Deployer (1.1.0.fuse)

              Spring Transaction (2.5.6)

              Apache ServiceMix NMR Spring (1.1.0.fuse)

              Spring JMS (2.5.6)

              Spring Context Support (2.5.6)

              Spring JDBC (2.5.6)

               

              It means I have Spring Jdbc with Spring Transaction support. It is still not woking.

              Well, I only have Import-Package = org.springframework.jdbc.datasource in my auto-generated manifest. Actually I am not using MySQL driver directly, but need to import that because spring components use it to access to DB. How can I do that?

              • 4. Re: deploy pure .xml as a route
                janstey

                Ah, got it. You can customize your bundle manifest as follows.

                 

                <beans xmlns="http://www.springframework.org/schema/beans" ... >
                
                  <manifest>
                    Import-Package = org.springframework.jdbc.datasource,com.mysql.jdbc
                  </manifest>
                
                  <osgi:camelContext xmlns="http://activemq.apache.org/camel/schema/spring">
                ...
                

                 

                Cheers,

                Jon

                • 5. Re: deploy pure .xml as a route
                  vector_jdev.work

                  One more thing I just want ask/discuss.

                  Imagine that we have an OSGI based system with a hundred bundles or so.

                  As a sample we have a component that notifies some people by sending them messages via specific protocol. It exposed as OSGI service with method sendMessages(List<String> messages);

                  Then if we need to load messages from different sources like DB, RSS, XML, so on...

                   

                  The information coming from different datasources in a different format ( List of strings, list of objects, comma separated single stringOfMessages, or list of maps like that returned from sql:endpoint ).

                   

                  If we need to use that OSGI sendmessage service that allows List messages as input, then is there any way to write transformation rules in pure xml?

                  Other idea is having a special osgi bundle Transformer with a set of methods to transform all possible inputs to all possible outputs used in the system. Can you coment both of these, or advice some best practice for that?

                   

                  -


                  Let me just add one more extra question to that scenario. Imaging that we're not only get messages to send from a different sources, but also needs to have people destination from other source, then we need to pass both messages&destination so that sender can send messages to destination. How can we place that in single camel xml?

                   

                  Thanks.

                   

                  Edited by: vector on Jul 24, 2009 2:05 PM

                  • 6. Re: deploy pure .xml as a route
                    oisin

                    I'm not sure I'm parsing your message properly. I'll just go through the details for clarification, rather than making assumptions.

                     

                     

                    Imagine that we have an OSGI based system with a hundred bundles or so.

                    As a sample we have a component that notifies some people by sending them messages via specific protocol. It exposed as OSGI service with method sendMessages(List<String> messages);

                     

                     

                    The sample you have in mind is a bundle, which contains a Camel route, which registers its starting point as an OSGi service with a single API method that takes a list of strings.

                     

                    When the method is called, the route does something to send the message to a consumer somewhere else (where? in the container? outside the container?).

                     

                     

                    Then if we need to load messages from different sources like DB, RSS, XML, so on...

                     

                    The information coming from different datasources in a different format ( List of strings, list of objects, comma separated single stringOfMessages, or list of maps like that returned from sql:endpoint ).

                     

                     

                    The sample was sending messages, and now this mentions loading messages. Is this another route? Or the same route doing something else?

                     

                     

                    If we need to use that OSGI sendmessage service that allows List<String> messages as input, then is there any way to write transformation rules in pure xml?

                     

                     

                    Yes, there are ways to write transformation rules in pure XML. But that's a general answer to a general question - where are these transformation rules going to be? Are they added to the sample route after the service endpoint?

                     

                     

                    Other idea is having a special osgi bundle Transformer with a set of methods to transform all possible inputs to all possible outputs used in the system. Can you coment both of these, or advice some best practice for that?

                     

                     

                    At this point here I am starting to think that you need an NMR-like entity. It would make things much, much clearer if you could maybe draw a sketch of the communications in this system. The use-case sounds like some kind of super-router that consumes N protocols and then produces M protocols

                    • 7. Re: deploy pure .xml as a route
                      vector_jdev.work

                      Hello Oisin! I am sorry for general description. Let me just be more specific then.

                       

                      1. We are trying fuse in production, and want  most of the routes will be deployed as xml. The most of bundles should be deployed as bundles without any coupling between bundle+route in one jar. That is because we have highly reusable components and don't want couple them with routes.

                       

                      2. Let's just be more specific about my question. We have a bundle that can send sms messages via specific binary protocol. It has method send(String phone, List(values from map). Can this be done in pure xml or we need to couple camel route to some module then?

                       

                      Thanks.

                      • 8. Re: deploy pure .xml as a route
                        davsclaus

                        Ad 2)

                        You need to add a transformation step after the SQL so you can transform the message into the format needed by the phone bean.

                         

                        This transformation can be added to the route in XML but the actual code that moves the data from the SQL maps to the other List is done in regular Java code.

                         

                        You can use a Processor to do this work. Or in fact you can use a regular POJO where you define the mapping

                         

                        List body) {

                           ... // do the mapping here

                        }

                         

                        See more here:

                        http://camel.apache.org/message-translator.html

                        • 9. Re: deploy pure .xml as a route
                          oisin

                           

                          We are trying fuse in production, and want most of the routes will be deployed as xml. The most of bundles should be deployed as bundles without any coupling between bundle+route in one jar. That is because we have highly reusable components and don't want couple them with routes.

                           

                           

                          That's a reasonable approach - you could provide the reusable components as OSGi services and then the routes could use those services (using the bean: URL, since the bean discovery now works with the OSGi service registry in 1.6.2 branch and 2.0M3). That's a good use of the internal SOA style of OSGi.

                           

                           

                          The problem that camel:sql endpoint return List<Map<String, Object>> where each map is ColumnName>Value and I need to transform that to List<String>(values from map). Can this be done in pure xml or we need to couple camel route to some module then?

                           

                           

                          I agree with @davsclaus - the best way to do this is to use the message translator pattern and have a bean to do the translation. This gives you the control you need to do fast, correct translation.

                           

                          In terms of packaging it, I think the message translator could be included as part of the route bundle, which does contravene your pure XML requirement, but the message translator function will be small and probably non-reusable. However, the OSGi bean resolution could help you here - you could reference your translator bean something like (trivial example, without all the bits you will really need):

                           

                          <from uri="sql:select * from table where id=#">
                          <to uri="bean:org.example.MyTranslator?translate">
                          <to uri="bean:org.example.MySMSSender?send">
                          

                           

                          and you could have a standard OSGi bundle where you register the OSGi Service org.example.MyTranslator, which is the singleton bean that does the translation. Your route will be pure XML then, and it should wire up correctly when it's deployed.

                           

                          Again - disclaimer - I haven't actually done this, but the theory is sound!