1 2 Previous Next 26 Replies Latest reply on Dec 4, 2013 11:32 AM by patrickawilson

    External JMS Reference - How?

    patrickawilson

      I am very new to Switchyard and having a tough time trying to figure out how to configure and code for an external JMS reference.  My project is, at the moment, a simple one.  XML data as defined by a WSDL comes into the composite.  A JAXB transformation takes place and the resulting Java object is routed to a bean.  A byte array is then extracted from that Java object.  This part is working.

       

      Next I want to but the byte array onto an external JMS queue.  I am very familiar with JMS.  If it was just Java I would create a connection, session,and queue client reference and put the message onto the queue.But how to do that in Switchyard?

       

      In the Switchyard design palette I have created a reference on the bean. 

      I have promoted the reference.

      I have added a JMS binding to it.

       

      So here I am in the CDI Bean with a java object that I want to put on an external queue.  How does one go about doing that?

      I know that the @Reference gets used somehow but I have not yet managed to figure out how to tie it all together,

       

      Thanks,.

        • 1. Re: External JMS Reference - How?
          rcernich

          Hey Patrick,

           

          You might want to look at one of the jca-outbound-* quickstarts.  The do not use JMS for their reference bindings, but they do show how you would go about wiring up your application.

           

          Specifically, @Reference is used to inject the reference into your bean.  When you invoke a method on this, it will proxy the call to the composite reference.  For example, if your reference interface defines a void send(byte[]) method, you would simply call _reference.send(bytes) in your bean.  All the JMS details are contained within the composite reference, and the bean doesn't care, or need to know.  If at a later time, you wish to change how the external service is invoked (e.g. if it changes from JMS to REST), all you need to do is change the binding on the reference; the bean remains unchanged.

           

          Hope that helps,

          Rob

          • 2. Re: External JMS Reference - How?
            kcbabo

            Rob's answer is 100% correct, but one point of clarification.  When he says that "they do not use JMS for reference bindings", he means the JMS gateway binding.  There are two options for sending and receiving JMS messages with SwitchYard:

             

            - JCA : can be used with any JCA resource adapter, but comes with built-in support for sending and receiving JMS messages through the HornetQ resource adapter in EAP.  You can configure this to use ActiveMQ as well.

            - JMS : uses the camel-jms component to send and receive JMS messages using JMS APIs.

             

            So the jca-outbound-* quickstarts can be used to send JMS messages through reference bindings, they just don't use the JMS gateway to do it. 

            • 3. Re: External JMS Reference - How?
              patrickawilson

              Appreciate the replies.  Going to try to take it further and ask more questions as they come up.  Did a Google on HornetQ vs ActiveMQ and got some interesting information.  There seem to be strong points for each, with HornetQ being lighter and probably faster while ActiveMQ is a bit more feature rich.  HornetQ seems to be what is shipped by default so I will stick with that for now.

               

              If examples are centered around JCA I will try that route for now.  Don't know the first thing about JCA but one can certainly learn.  I would definitely like to go to a JMS Camel implementation eventually.  If there are any examples that use Camel to send messages out of the composite they would be appreciated.

               

              A little about myself: I worked for Sonic Software some years back and did development on their JMS and ESB products - mostly the former.  What is interesting is that I know these products from the inside as a developer but not from the outside as a user.  That was also seven years ago and things change.  In the interim I have been in IBM land (Websphere J2EE) so I have really lost touch with how the rest of the world lives.  Very happy to return to the more dynamic environment that is open, standards based software.

               

              At any rate, given past experience I know from an architectural point of view where I want to go.  What I am trying to come up to speed on is the "how".  In general I hate configuration because I always feel like I am fighting a black box.  Hoping that Switchyard changes that view .

              • 4. Re: External JMS Reference - How?
                rcernich

                Hey Patrick,

                 

                I recommended the JCA examples to show you how to go about wiring up a reference to an external service.  If you want to use a JMS instead, simply add a JMS binding to your reference instead of a JCA binding.

                 

                Hope that helps,

                Rob

                • 5. Re: External JMS Reference - How?
                  patrickawilson

                  Thanks again.  I am looking at them now and my Java developer brain is having a bit of a tough time wrapping around how they work.

                   

                  In OrderServiceBean we inject references to ShippingReference and FillingStockReference:

                      @Inject @Reference("ShippingReference")

                      private OrderService _shipping;

                      @Inject @Reference("FillingStockReference")

                      private OrderService _fillingStock;


                  Then we have the implementation of the OrderService interface in OrderServiceBean

                      @Override

                      public void process(String order) {

                          if (_stock.contains(order)) {

                              _shipping.process(order);

                          } else {

                              _fillingStock.process(order);

                          }

                      }


                  At this point my brain is going in circles.  OrderServiceBean implements OrderService and references _shipping and _fillingStock ... which also implement OrderService?


                  So the fact that OrderServiceBean implements OrderService and the references also implement OrderService is coincidental?  OrderServiceBean could implement FooInterface, transform FooInterface into the form of OrderService, and then use the references to output the transformed data ... true?




                  • 6. Re: External JMS Reference - How?
                    rcernich

                    Hey Patrick,

                     

                    You could say it's coincidental, or you could say that's how the application was designed.  In any case, the concepts being conveyed are:

                    • There are three business services defined in this application: OrderService, ShippingReference and FillingStockReference
                    • Each of those services expose a Java interface named org.switchyard.quickstarts.jca.outbound.OrderService
                    • Each of the services implements the interface specific to itself:
                      • OrderService (the service) processes order requests and is provided (implemented) by the application
                      • ShippingReference processes shipping requests for orders (i.e. ship this order) and is an external service used (referenced) by the application
                      • FillingStockReference processes orders for items on back order (i.e. stock the warehouse for this order) and is an external service used by the application

                     

                    So, while each service implements the same interface (which, conceptually, is immaterial), they each fulfil a different business service (process orders, ship orders, stock the warehouse).  If you want a pure Java example, you could think of EventListener, Observer, etc.  These may be implemented by many classes, but each class provides its own implementation specific to its own needs and requirements.  ShippingReference does process orders, as does FillingStockReference.  Given the Java analogy, it probably doesn't help that the references are not implemented within the application, so you can't "see" what they do, to know they are different; you have to infer based on the names.

                     

                    Hope that helps,

                    Rob

                    • 7. Re: External JMS Reference - How?
                      patrickawilson

                      Right - three different implementations of the same interface.  Just wanted to make sure that I understood what i was reading.

                       

                      My end goal is to deliver the message to an external Websphere MQ queue.  I assume this should not be a problem since all I should need is a properly configured JMS client.

                       

                      Continuing down the rabbit hole ...

                      JCA needs HornetQ

                      HornetQ needs the standalone-full server config

                      The standalone-full server config needs a JDK and not a JRE

                      The JBoss EA6.1 server is packaged with a JRE not a JDK

                       

                      ...

                      • 8. Re: External JMS Reference - How?
                        patrickawilson

                        Still struggling to put it all together.  Looking for an understanding of what needs to be done to get this up and running.  I was under the impression that installing JBoss and then installing Switchyard over it was sufficient.  However, HornetQ does not appear to be installed.  Attempts to install it were not successful (the install script was not there).

                         

                        For my task my only immediate need is the ability to create and access a ConnectionFactory and maybe create a queue definition.  The actual end point is a Websphere MQ instance running on a different box.  Later on we will want to make more use of either HornetQ or ActiveMQ, but right now it is all just a pass through,

                         

                        So ... more questions:

                        1. Does HornetQ or ActiveMQ have to be installed separately?  The docs that I read indicated that the ConnectionFactory had to be defined via their XML files (which are not present in my install), 

                         

                        2.  Where can one find up to date instructions for the installation and configuration of HornetQ and ActiveMQ?

                         

                        3. Do I even need HornetQ or ActiveMQ at this stage?  I am trying to connect to an external JMS provider.

                         

                        I know that these are very newbie questions.  Been living in IBM J2EE land for too long and trying to play catch up.  Appreciate the help.

                        • 9. Re: Re: External JMS Reference - How?
                          kcbabo

                          EAP comes bundled with HornetQ, but the subsystem is not loaded in the default configuration profile (standalone.xml).  If you run with the standalone-full.xml configuration, then HornetQ will be available.

                           

                          > cd jboss-eap-6.1
                          > bin/standalone.sh -c standalone-full.xml
                          
                          • 10. Re: Re: External JMS Reference - How?
                            kcbabo

                            Sorry, just processed the second part of your post where you mentioned that you are connecting to an external WS MQ broker.  So to answer your question #3 - you don't need HornetQ or ActiveMQ in order to do that.

                            • 11. Re: Re: External JMS Reference - How?
                              patrickawilson

                              Thanks - wasn't sure if a JMS implementation was required to create a JMS client.

                               

                              So how does one connect to an external reference in Switchyard?  Presumably a connection is still required, therefore a connection factory.  i have the host, port, and queue name.  just trying to figure out how to plug that into Switchyard.

                              • 12. Re: External JMS Reference - How?
                                igarashitm

                                Hi Patrick,

                                 

                                Did you already deploy WebsphereMQ ResourceAdapter on JBoss which has SwitchYard installed? References to the ConnectionFactory and JMS Queue object is provided by ResourceAdapter. SwitchYard JCA gateway then acquire those from ResourceAdapter instance.

                                 

                                I just googled and found a few thread related to this topic in the AS7 forum:

                                Re: Websphere MQ integration with MDB on AS7/EAP6 reloaded

                                Re: Configure MQ Resource Adapter for MDB - JBoss 7.1

                                 

                                You may need to define "connection-definition" to make JMS ConnectionFactory available, and "admin-object" for JMS queue admin object. I haven't tried with WebsphereMQ yet, but it should be almost same as we're doing today for ActiveMQ:

                                SwitchYard JCA component and ActiveMQ Resource Adapter

                                 

                                hth

                                Tomo

                                • 13. Re: External JMS Reference - How?
                                  patrickawilson

                                  I am not having much luck getting to an external JMS provider so I thought that I would try routing to a local HornetQ install first.  Getting a "No bean could be found in the registry" error.  Looked at HornetQ docs and noted that hornetq-jboss-beans.xml was called out as a configuration item.  However, I don't see this config file referenced in switchyard examples.  It would seem necessary since this seems to be the link between HornetQ and a container managed environment. 

                                   

                                  Caught exception of type org.apache.camel.ResolveEndpointFailedException with message: Failed to resolve endpoint: jms://queue:ConsertGSQueue?connectionFactory=ConsertGSConnectionFactory due to: No bean could be found in the registry for: ConsertGSConnectionFactory of type: javax.jms.ConnectionFactory

                                    Caused by exception of type org.apache.camel.NoSuchBeanException, message: No bean could be found in the registry for: ConsertGSConnectionFactory of type: javax.jms.ConnectionFactory: org.apache.camel.ResolveEndpointFailedException: Failed to resolve endpoint: jms://queue:ConsertGSQueue?connectionFactory=ConsertGSConnectionFactory due to: No bean could be found in the registry for: ConsertGSConnectionFactory of type: javax.jms.ConnectionFactory

                                      at org.apache.camel.impl.DefaultCamelContext.getEndpoint(DefaultCamelContext.java:469) [camel-core-2.10.0.jar:2.10.0]

                                   

                                   

                                  Caused by: org.apache.camel.NoSuchBeanException: No bean could be found in the registry for: ConsertGSConnectionFactory of type: javax.jms.ConnectionFactory

                                      at org.apache.camel.util.CamelContextHelper.mandatoryLookup(CamelContextHelper.java:130) [camel-core-2.10.0.jar:2.10.0]

                                      at org.apache.camel.util.EndpointHelper.resolveReferenceParameter(EndpointHelper.java:326) [camel-core-2.10.0.jar:2.10.0]

                                      at org.apache.camel.util.EndpointHelper.resolveReferenceParameter(EndpointHelper.java:308) [camel-core-2.10.0.jar:2.10.0]

                                      at org.apache.camel.impl.DefaultComponent.resolveAndRemoveReferenceParameter(DefaultComponent.java:304) [camel-core-2.10.0.jar:2.10.0]

                                      at org.apache.camel.impl.DefaultComponent.resolveAndRemoveReferenceParameter(DefaultComponent.java:283) [camel-core-2.10.0.jar:2.10.0]

                                      at org.apache.camel.component.jms.JmsComponent.createEndpoint(JmsComponent.java:475) [camel-jms-2.10.0.jar:2.10.0]

                                      at org.apache.camel.impl.DefaultComponent.createEndpoint(DefaultComponent.java:91) [camel-core-2.10.0.jar:2.10.0]

                                      at org.apache.camel.impl.DefaultCamelContext.getEndpoint(DefaultCamelContext.java:451) [camel-core-2.10.0.jar:2.10.0]

                                  • 14. Re: External JMS Reference - How?
                                    igarashitm

                                    Once you start EAP6 with standalone-full.xml config, JMS ConnectionFactory for the HornetQ is bound to "java:/ConnectionFactory" by default. You can just specify this for the connectionFactory parameter of Camel JMS binding or you may want to add "ConsertGSConnectionFactory" JNDI name into jms-connection-factories section defined in standalone-full.xml.

                                    1 2 Previous Next