11 Replies Latest reply on Feb 5, 2010 9:17 AM by ee7arh

    failover prevents context from being created if unable to connect

    ee7arh

      Hi,

       

      FuseBroker 5.0.3.4

      FuseMediationRouter 1.6.1.2

       

       

      We are starting our application from Spring using the org.apache.camel.spring.Main.main() method passing in an XML configuration file.

       

      Within that config file we define a JmsComponent bean which connects to an activeMQ instance on another machine:

       

       

       

      We also define many other beans for the local application besides this one.

       

      We notice that if the "failover" uri is unable to connect to the "myExternalHost" activeMQ instance when the application is started, the ApplicationContext is not created and remains null.

       

      We know this because:

       

      Main.getInstance().getApplicationContext() returns null

       

      If we remove the "failover" uri and the tcp connection to "myExternalHost" is allowed to fail, then the context is created and the above code returns an ApplicationContext object.

       

      This is causing us major problems because the connection to "myExternalHost" is one of many beans we create at startup. All the other beans declared on the local application are created successfully and so the application begins processing so it appears that everything is working correctly. However when we try to get the ApplicationContext, it returns null and so in fact the application is not fully initialised, thus in an inconsistent state.

       

      As another note, if "myExternalHost" was available at application restart, we get our context without problem. If it then goes down after this point, the ApplicationContext is still valid (not null). So this proves that it is not necessary for the bean to have connected to get an ApplicationContext instance and so it should be the same at startup.

       

      Help appreciated.

       

      Thanks

      Andrew

        • 1. Re: failover prevents context from being created if unable to connect
          ee7arh

          Hi,

           

          Could somebody pls check this....... I originally posted it in the MediationRouter forums but got told to post it here instead.

           

          Thanks

          Andrew

          • 2. Re: failover prevents context from being created if unable to connect
            davsclaus

            Why do you need to use?

            Main.getInstance().getApplicationContext() 
            

             

            • 3. Re: failover prevents context from being created if unable to connect
              davsclaus

              Camel spring main app is a development tool for quickly trying out camel.

               

              It has newer been targeted as production usage. Most people use some sort of server for that.

               

              There may bee a problem in the startup logic.

               

              Can you create a small camel application that demonstrates this. Eg try removing as much of your application and it still fails. Then we can use that to track down the issue and add it as an unit test as well.

              • 4. Re: failover prevents context from being created if unable to connect
                ee7arh

                Hi,

                 

                Thanks for the answer. I am using this statement because I need to send something to a Camel endpoint (a queue in fact) from within my code.

                 

                This is how our application works:

                 

                (1) Our application server is based only on Camel and ActiveMQ. We start our application by directly invoking the Spring Main.main(springConfigFile) passing in our camel-server.xml file. Within the XML file, we declare a local broker and so activeMQ is started. We also declare a JmsComponent bean which references another broker which may or may not be up at this time.

                 

                (2) At this point after Camel has initialized, we expect that if we execute the code Main.getInstance().getApplicationContext() within the same JVM as Camel, it should return a context but it fails to do so if failover is used and does not connect to the remote broker.

                 

                (3) We start a totally separate home-made TCP server application. This application is a client to the Camel/ActiveMQ Server. It sends messages to our ActiveMQ instance in (1) using the request/reply pattern. This means that a queue is defined to handle incoming requests and a temporary queue is used to send back the reply.

                 

                (4) When the client in (3) sends a request to the application in (1), a bean is called to handle the incoming request on the server side (1). This bean does some business logic processing and then before it returns something back to the client (3), it wants to put a message on a local queue programmatically for some asynchronous processing. This is why we need to call Main.getInstance().getApplicationContext() because although we are within the same JVM as the running Camel Instance, at this point of the thread of execution we have no reference to Camel and therefore cannot send anything to a queue. The entire code we want execute is:

                 

                ProducerTemplate camelTemplate;

                         

                camelContext = Main.getInstance().getApplicationContext();

                 

                // Create a producer template

                camelTemplate = (ProducerTemplate) camelContext.getBean("camelTemplate");

                 

                // Send to queue

                camelTemplate.sendBody("activemq:queue:myQueue", myMessage);

                 

                 

                We are not using an application server of any type, just Camel and ActiveMQ. We were not aware that starting Camel like this was just for development purposes so please feel free to suggest a better way of launching our application if we are missing something fundamental.

                 

                Thanks a lot

                Andrew

                • 5. Re: failover prevents context from being created if unable to connect
                  davsclaus

                  Not having the source in front of me at the moment. Gotta go soon, so no time to start the IDE editor.

                   

                  I assume you can get hold of CamelContext without the spring application context.

                   

                  And use getRegistry().lookup to lookup your bean

                   

                  And you can also use the method: createNewProducerTemplate on CamelContext to get a template instead of doing lookup.

                  • 6. Re: failover prevents context from being created if unable to connect
                    davsclaus

                    Ad 2)

                    You can disable the autoStartup of the JMS consumer

                     

                    And then Camel should be able to startup and you should get your application context.

                     

                    Then you can manually start the JMS consumer afterwards

                    • 7. Re: failover prevents context from being created if unable to connect
                      davsclaus

                      Hi

                       

                      I have created a ticket to improve the camel-jms to support continue starting Camel in case of connection issues for JMS consumers

                       

                      MR-248

                      • 8. Re: failover prevents context from being created if unable to connect
                        davsclaus

                        Hi use the option maxReconnectAttempts on the brokerURL to limit the number of retries.

                         

                        For example maxReconnectAttempts=5

                        • 9. Re: failover prevents context from being created if unable to connect
                          ee7arh

                          Hi,

                           

                          Many thanks for suggestions and opening issue. Will probably take the option of manually starting the consumer afterwards since we need to keep retrying the connection as it is major part of application.

                           

                          BRegards

                          Andrew

                          • 10. Re: failover prevents context from being created if unable to connect
                            davsclaus

                            Cool Rob Davies have implemented this in AMQ now

                             

                            See the ticket:

                            https://issues.apache.org/activemq/browse/AMQ-2385

                            • 11. Re: failover prevents context from being created if unable to connect
                              ee7arh

                              Thanks!!!! ))