14 Replies Latest reply on Apr 23, 2014 10:14 AM by kcbabo

    Can't use Camel unit test framework with SwitchYard endpoints

    simplex-software

      Greetings, I'm using FSW 6 on Windows 7. I deployed a service having a Camel implementation and a Camel URI binding. In order to invoke the service I'm using a Camel unit test like the following:

       

      @Test public void testStartService() throws Exception

      {

        template.sendBody ("switchyard://HelloWorldComponentService", "Hello World !");

      }

       

      Running this unit test using "mvn test" raises the following:

       

      java.lang.ClassCastException: org.apache.camel.impl.DefaultCamelContext cannot be cast to org.switchyard.common.camel.SwitchYardCamelContext at fr.simplex_software.switchyard.TestHelloWorld2.testStartService(TestHelloWorld2.java:14) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:601) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27) at org.junit.rules.TestWatcher$1.evaluate(TestWatcher.java:55) at org.junit.rules.RunRules.evaluate(RunRules.java:20) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229) at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27) at org.junit.runners.ParentRunner.run(ParentRunner.java:309) at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:53) at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:123) at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:104) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:601) at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:164) at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:110) at org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:175) at org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcessWhenForked(SurefireStarter.java:107) at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:68)

       

      The Camel ProducerTemplate uses a CamelDefaultContext while producing message to SwitchYard endpoints obviously requires a SwitchYardCamelContext instance. And the SwitchYardCamelContext cannot be casted to a CamelDefaultContext instance. How then is one supposed to use the Camel unit test framework with SwitchYard ?

       

      Many thanks in advance.

       

      Nicolas DUMINIL

        • 1. Re: Can't use Camel unit test framework with SwitchYard endpoints
          kcbabo

          Can you provide some background on why you are using the Camel test framework vs. the SY test framework to test SwitchYard endpoints/services? 

          • 2. Re: Can't use Camel unit test framework with SwitchYard endpoints
            jorgemoralespou_2

            SwitchYard provides for some JUnit testing capabilities, which are documented here:

             

            If you use SwitchYard service you have to test it with SwitchYard capabilities (container). If you are using plain camel service, you can test it with Camel Junit capabilities. If you are testing SwitchYard service with Camel component, you should also use SwitchYard testing capabilities.

             

            Hope it helps.

            • 3. Re: Can't use Camel unit test framework with SwitchYard endpoints
              simplex-software

              Hello,

               

               

              Keith Babo wrote:

               

              Can you provide some background on why you are using the Camel test framework vs. the SY test framework to test SwitchYard endpoints/services?

              Yes, sure. The reason is obvious: SwitchYard has unit test support for HTTP, CDI, Smmoks, etc. but not for Camel. So, given a service having a Camel implementation and a Camel URI binding, I need to unit test it by producing a message to the endpoint using Camel producer template.

              • 4. Re: Can't use Camel unit test framework with SwitchYard endpoints
                simplex-software

                hello,

                 

                Jorge Morales wrote:

                 

                SwitchYard provides for some JUnit testing capabilities, which are documented here:

                 

                If you use SwitchYard service you have to test it with SwitchYard capabilities (container). If you are using plain camel service, you can test it with Camel Junit capabilities. If you are testing SwitchYard service with Camel component, you should also use SwitchYard testing capabilities.

                 

                Hope it helps.

                Many thanks for sending me links to the documentation. As you may assume, I've read the documentation before submitting cases. I would lime very much to test a service having a Camel implementation and a Camel URI binding using SwitchYard testing capabilities, as you're suggesting, it only happens that it appears that SwitchYard doesn't provide any Camel testing capabilities.

                1 of 1 people found this helpful
                • 5. Re: Can't use Camel unit test framework with SwitchYard endpoints
                  kcbabo

                  nicolas duminil wrote:

                  Yes, sure. The reason is obvious: SwitchYard has unit test support for HTTP, CDI, Smmoks, etc. but not for Camel. So, given a service having a Camel implementation and a Camel URI binding, I need to unit test it by producing a message to the endpoint using Camel producer template.

                   

                  You just listed the set of MixIns, which are independent from the core unit test facilities of SwitchYard.  The SwitchYard unit test framework allows you to inject an invoker to test a service directly regardless of the implementation - there's absolutely no need to use a producer template to invoke a switchyard:// endpoint directly.

                  • 6. Re: Can't use Camel unit test framework with SwitchYard endpoints
                    simplex-software

                    Keith Babo a écrit:

                     

                    nicolas duminil wrote:

                    Yes, sure. The reason is obvious: SwitchYard has unit test support for HTTP, CDI, Smmoks, etc. but not for Camel. So, given a service having a Camel implementation and a Camel URI binding, I need to unit test it by producing a message to the endpoint using Camel producer template.

                     

                    You just listed the set of MixIns, which are independent from the core unit test facilities of SwitchYard.  The SwitchYard unit test framework allows you to inject an invoker to test a service directly regardless of the implementation - there's absolutely no need to use a producer template to invoke a switchyard:// endpoint directly.

                    Okay, I'm glad to hear that. But my question was "how to do it" ? For example, considering I have the foolowing binding:

                     

                      <camel:binding.uri configURI="direct://input">
                        <sy:operationSelector operationName="helloWorld"/>
                      </camel:binding.uri>

                     

                    How can I unit test this Camel route, i.e; just producing a message to the "direct://input" endpoint such to trigger the route, without of course having a real client like in an integration test scenario ? If you have an answer to the question I'd be very gratefull to you but please don't send me links to the documentation or quickstarts as I read everything and didn't find solution to my problem.

                     

                    Kind regards,

                     

                    Nicolas DUMINIL

                    • 7. Re: Re: Can't use Camel unit test framework with SwitchYard endpoints
                      kcbabo
                      Okay, I'm glad to hear that. But my question was "how to do it" ? For example, considering I have the foolowing binding:

                       

                      Well, your original question included this an example of a test:

                      @Test public void testStartService() throws Exception
                      {
                        template.sendBody ("switchyard://HelloWorldComponentService", "Hello World !");
                      }
                      

                       

                      There's no need to use the Camel test framework to test a Camel route with a switchyard:// consumer endpoint.  You can use an Invoker in your unit test to accomplish the same thing:

                      @ServiceOperation("HelloWorldComponentService")
                      private Invoker helloWorldService;
                      
                      • 8. Re: Re: Can't use Camel unit test framework with SwitchYard endpoints
                        kcbabo

                        nicolas duminil wrote:

                        Okay, I'm glad to hear that. But my question was "how to do it" ? For example, considering I have the foolowing binding:

                         

                        <camel:binding.uri configURI="direct://input">
                           <sy:operationSelector operationName="helloWorld"/>
                        </camel:binding.uri>

                         

                        How can I unit test this Camel route, i.e; just producing a message to the "direct://input" endpoint such to trigger the route, without of course having a real client like in an integration test scenario ? If you have an answer to the question I'd be very gratefull to you but please don't send me links to the documentation or quickstarts as I read everything and didn't find solution to my problem.

                         

                         

                        There are two levels of testing from a SY perspective:

                         

                        1) If you are truly unit testing your services, then you don't need to worry about the binding to test a Camel routing implementation.  You can inject a test invoker directly into your unit test and invoke the service independent of the binding.  Many of the quickstarts demonstrate this and the documentation also covers it.

                        2) If you are creating an integration test, which tests both the binding and the implementation in a test, then you need to initiate the test using the binding type in use.

                         

                        My impression is that you are approaching this from the second perspective.  If you want to go that route, we can certainly provide help on how to do it, but I want to make sure you are aware that you can test your service implementations independent of the binding as well.

                         

                        If you are testing through the binding, then the test case needs to generate a message in the native format of the binding.  If you are testing a SOAP binding, for example, you would create a SOAP message and send it to the binding over HTTP.  Even in the case of using a Camel URI binding, you would create a message in whatever format the component expected based on the endpoint scheme (HTTP for http://, TCP for mina://, etc., etc.).  Using a direct:// endpoint in a camel binding is of limited practical use because a direct endpoint is only available to camel clients in the same application (same camel context specifically).  Since the purpose of bindings is to make services available to other applications, a direct binding doesn't do a whole lot.

                        1 of 1 people found this helpful
                        • 9. Re: Re: Can't use Camel unit test framework with SwitchYard endpoints
                          jorgemoralespou_2

                          nicolas duminil escribió:

                           

                          Many thanks for sending me links to the documentation. As you may assume, I've read the documentation before submitting cases. I would lime very much to test a service having a Camel implementation and a Camel URI binding using SwitchYard testing capabilities, as you're suggesting, it only happens that it appears that SwitchYard doesn't provide any Camel testing capabilities.

                           

                          Hi Nicolas,

                          probably from you example, I realized you didn't read the docs, as you were invoking a Switchyard service with a camel template, and that, as you have seen, doesn't work.

                          template.sendBody ("switchyard://HelloWorldComponentService", "Hello World !");
                          

                           

                          As Keith says, if you want to do JUnit, the probably you need to test the service, and not the binding, and this can be accomplished with SwitchYard testing capabilities, as said in the docs. If you want to test the binding, then probably it is an integration test, for which you probably should be using a full JEE container (with Switchyard capabilities) and be able to send the message in the native "binding" format.

                           

                          Maybe, you can send the composite definition to see if we can provide you with more help.

                           

                          Cheers,

                          • 10. Re: Re: Can't use Camel unit test framework with SwitchYard endpoints
                            kcbabo

                            Forgot to mention that it is possible to use ProducerTemplate to talk to Camel endpoints, but keep in mind the considerations I outlined in my prior post.  You would still use our unit test support, but you can get at the CamelContext from ServiceDomain like so:

                             

                            @RunWith(SwitchYardRunner.class)
                            @SwitchYardTestCaseConfig(
                                    config = SwitchYardTestCaseConfig.SWITCHYARD_XML, 
                                    mixins = { CDIMixIn.class })
                            public class ExampleTest {
                            
                                private SwitchYardTestKit testKit;
                            
                                @Test
                                public void testIntake() throws Exception {
                                    ServiceDomain domain = testKit.getServiceDomain();
                                    CamelContext ctx = (CamelContext)domain.getProperty("CamelContextProperty");
                                    ProducerTemplate producer = ctx.createProducerTemplate();
                                    producer.sendBody("direct://HelloService", "Message content");
                                }
                            }
                            

                             

                            This would allow you to test a service which has a direct: binding :

                             

                            <sca:service name="Hello/HelloService" promote="Hello/HelloService">
                               <sca:interface.java interface="org.jboss.example.ExampleService"/>
                               <camel_1:binding.uri name="camel1" configURI="direct://HelloService"/>
                            </sca:service>
                            
                            • 11. Re: Re: Can't use Camel unit test framework with SwitchYard endpoints
                              simplex-software

                              hanks for the update.

                               

                               

                              "Using a direct:// endpoint in a camel binding is of limited practical use because a direct endpoint is only available to camel clients in the same application (same camel context specifically).  Since the purpose of bindings is to make services available to other applications, a direct binding doesn't do a whole lot."

                               

                              This was an example. My point was not to discussed about the use of the direct:// endpoint. If you prefer, consider then a vm:// endpoint instead of a direct one. But I don't think it changes anything to the problem and the question is the same: how to produce a message to this endpoint such to trigger the route ?

                               

                              Kind regards,

                               

                              Nicolas DUMINIL

                              • 12. Re: Re: Can't use Camel unit test framework with SwitchYard endpoints
                                simplex-software

                                Thanks Keith, this is the answer to my question, many thanks.

                                • 13. Re: Re: Can't use Camel unit test framework with SwitchYard endpoints
                                  simplex-software

                                  @Jorge Morales:

                                   

                                  "from you example, I realized you didn't read the docs, as you were invoking a Switchyard service with a camel template, and that, as you have seen, doesn't work."

                                   

                                  As opposed to what you're saying, as shown by Keith's solution, using Camel producer template in SwitchYard works perfectly. Please refrain yourself to comment or reply to posts when you don't have any valuable solution to propose.

                                  • 14. Re: Re: Can't use Camel unit test framework with SwitchYard endpoints
                                    kcbabo

                                    I believe that Jorge was trying to help move the discussion forward here with suggestions, so his contribution was a positive influence in this thread.  To be fair, this aspect of the test kit is not well documented at all, so it's not a surprise that the solution took a bit of discussion.  I have filed a JIRA to correct this for 2.0:

                                    [SWITCHYARD-2052] Improve visibility of Camel in test kit - JBoss Issue Tracker

                                     

                                    This has actually been a good discussion as it helped me realize that we should make it easier to get to Camel from the test kit.  Come to think of it, ProducerTemplate could be useful for testing lots of other bindings types as the details encoding/transport will be taken care of by Camel.  For example, if I have a file:// endpoint for a service, I can use a ProducerTemplate with a file URI to test it out instead of using java.io directly and adding a bunch of cruft to my test case.