10 Replies Latest reply on May 29, 2008 2:03 AM by Burr Sutter

    Publish ESB services to web services

    Jim ma Newbie

      Can we take the following steps to publish the ESB services to web sevices?

      1. generate the wsdl contract for the given jboss-esb.xml when do initialization for
      the esb service :

      <service category="ServiceESB" name="helloworld" description="Hello World">
       <actions mep="OneWay" input="serviceInput.xsd" output="serviceOutput.xsd" fault1="fault1.xsd">
       <action name="action1"
       class="org.jboss.soa.esb.actions.Action1"
       process="displayMessage"/>
       <action name="action2" class="org.jboss.soa.esb.actions.Action2" process="invokeCount"/>
       </actions>
       </service>

      For the first stage, the input/output and fault xsd need to be provided, the next stage , we can consider if we can generate these files by reflecting or analyzing the message.

      2. generate the web service implementation class used to publish web service.(to invoke the standard jaxws api
      Endpoint.publish(implementor) ). The generated web service implementation class for the above ESB service can be this :

      @WebServiceProvider(portName = "SoapPortInGeneratedWSDL", serviceName = "serviceNameInGeneratedWSDL",
       targetNamespace = "http://www.jboss.org/esb/service",
       wsdlLocation = "wsdl/helloworld.wsdl")
      @ServiceMode(value = Service.Mode.MESSAGE)
      public class HelloWorldService implements Provider<SOAPMessage> {
      
       public HelloWorldService() {
       //Complete
       }
      
       public SOAPMessage invoke(SOAPMessage request) {
       // Compose the SOAPMessage to ESB awared message
       Message message = MessageComposer.compose(request);
       //Get the action class name and process method from the esb service configuration
       message = Action1.displayMessage(message);
       message = Action2.invokeCount(message);
       SOAPMessage response = MessageComposer.decompose(message);
       return response;
       }
      }


      I think using JAX-WS dispatch and provider style to publish a web service is the simple way to do that .
      Because we do not need to generate the types class and can easily line up the actions classes.

      3. invoke the jboss-ws api to publish the web service with generated implementation class when the
      ESB service start up.

      I do not investigate the ESB code base deeply and have two questions for Step 2:

      a . Can each response message be easily transformed to a javax.xml.SOAPMessage when we have the output xsd file ?

      b. How can we compose the ActionProcessingException to soap message when we have fault xsd file? Take ActionProcessingException as a exception bean to marshal and unmarshall fault message?

      Any thoughts, comments and answer would be appreciated.

        • 1. Re: Publish ESB services to web services
          Kevin Conner Master

           

          "Jim Ma" wrote:

          I do not investigate the ESB code base deeply and have two questions for Step 2:

          a . Can each response message be easily transformed to a javax.xml.SOAPMessage when we have the output xsd file ?

          Unfortunately there is no easy way to do this with the current architecture so you have the freedom to do what you feel is best.

          The options could include transformations (smooks/xsd) on a part of the message, marshalling part of the message using JAXB etc. Generating the schema is also an option, perhaps by specifying the types rather than the xsd.

          The ESB 5 architecture will have the ability to automatically generate the schema from the service, so we need to consider these issue going forward.

          "Jim Ma" wrote:
          b. How can we compose the ActionProcessingException to soap message when we have fault xsd file? Take ActionProcessingException as a exception bean to marshal and unmarshall fault message?


          Again, there is no easy answer to this at the moment.

          What do you feel is the right approach for handling this?

          Kev

          • 2. Re: Publish ESB services to web services
            Jim Ma Apprentice

             

            Generating the schema is also an option, perhaps by specifying the types rather than the xsd.


            Agreed. So we can modify the configuration file as this :

            <service category="ServiceESB" name="helloworld" description="Hello World">
             <actions mep="OneWay" input="org.jboss.esb.Request" output="org.jboss.esb.Response" fault1="org.jboss.esb.Fault">
             <action name="action1"
             class="org.jboss.soa.esb.actions.Action1"
             process="displayMessage"/>
             <action name="action2" class="org.jboss.soa.esb.actions.Action2" process="invokeCount"/>
             </actions>
             </service>


            org.jboss.esb.Request , Response and Fault class can be a java bean and inherits from a mew class XMLMessageBase .
            XMLMessageBase is a sub class of xml MessageImpl . In XMLMessageBase, we can put the request part value in Esb message body . Also by invoking the method in XMLMessageBase, we can retrieve the response part value from esb message body .
            By reflecting the Request class, we can generate schema using apache XMLSchema even there is no annotation in it.
            Again, there is no easy answer to this at the moment.

            What do you feel is the right approach for handling this?


            So far ,what I have in mind is building the SOAPFault message using ActionProcessingException.






            • 3. Re: Publish ESB services to web services
              Mark Little Master

               

              "jim.ma" wrote:

              So far ,what I have in mind is building the SOAPFault message using ActionProcessingException.


              We already do that for ESB fault messages so I think it makes sense.

              • 4. Re: Publish ESB services to web services
                Kevin Conner Master

                 

                "jim.ma" wrote:
                org.jboss.esb.Request , Response and Fault class can be a java bean and inherits from a mew class XMLMessageBase .

                What is the reason for inheriting from a base class? Would it not be easier if these were POJOs?
                "jim.ma" wrote:
                In XMLMessageBase, we can put the request part value in Esb message body . Also by invoking the method in XMLMessageBase, we can retrieve the response part value from esb message body .

                I think it would be better to use a named location within the message body for both parts and allow the names to be configurable. This would then be consistent with the way we are handling similar tasks within the current codebase, for example the integration with jBPM/drools maps these named locations into/out of their variable scopes.

                "jim.ma" wrote:
                By reflecting the Request class, we can generate schema using apache XMLSchema even there is no annotation in it.

                This sounds like a good idea.

                Kev

                • 5. Re: Publish ESB services to web services
                  Jim Ma Apprentice

                   

                  What is the reason for inheriting from a base class? Would it not be easier if these were POJOs?


                  The mainly intention for it is we can make the Request/Response class as a subclass of esb Message.

                  If we create the Request object , we can directly use this object to invoke ESB message. After we exposed esb service as a web service , we can create this request object and use this class to marshal soap message like the jaxws client does.

                  think it would be better to use a named location within the message body for both parts and allow the names to be configurable. This would then be consistent with the way we are handling similar tasks within the current codebase, for example the integration with jBPM/drools maps these named locations into/out of their variable scopes.


                  That's I need to consider . I do not know if it can do this if we map the request object filed name to name location and the filed value to ESB part value. For example :
                  org.jboss.esb.Request extends XMLMessageBase {
                  public String foo;
                  public byte[] bar;
                  }

                  In XMLMessageBase class , we can ship the foo value and bar value into message body : getBody().add(field.getName(), filedValue);











                  • 6. Re: Publish ESB services to web services
                    Kevin Conner Master

                     

                    "jim.ma" wrote:
                    The mainly intention for it is we can make the Request/Response class as a subclass of esb Message.

                    But why is this a requirement? What is wrong with using POJOs and populating a created message?

                    "jim.ma" wrote:
                    That's I need to consider . I do not know if it can do this if we map the request object filed name to name location and the filed value to ESB part value. For example :
                    org.jboss.esb.Request extends XMLMessageBase {
                    public String foo;
                    public byte[] bar;
                    }


                    To fit in with the current code it would be better if it was handled as follows.
                    payloadProxy = new MessagePayloadProxy(config)

                    and then something like the following
                    Message message = MessageFactory.getInstance().getMessage();
                    payloadProxy.setPayload(message, <incoming request>);
                    ... evaluate pipeline ...
                    Object response = payloadProxy.getPayload(responseMessage);
                    


                    The payload proxy handles the details of previous message variants and also allows the message locations to be specified.

                    One thing that would be required would be a change in the way the pipeline works. At present the response/fault is handled asynchronously within the pipeline processing and we would need to refactor this code to allow for request/response processing.

                    • 7. Re: Publish ESB services to web services
                      Mark Little Master

                      Yes, +1 to Kev: I'd prefer to not override Message either.

                      • 8. Re: Publish ESB services to web services
                        Jim Ma Apprentice

                         

                        "Kevin.Conner@jboss.com" wrote:
                        "jim.ma" wrote:
                        The mainly intention for it is we can make the Request/Response class as a subclass of esb Message.

                        But why is this a requirement? What is wrong with using POJOs and populating a created message?


                        When we want to put the below class in request message body , which message body should I use ? RawBody, MapBody or ObjectBody?
                        org.jboss.esb.Request {
                         public String foo;
                         public byte[] bar;
                        }


                        what will be added to message body ?
                        body.add(requestObj)
                        or
                        body.add("foo", "foovalue");
                        body.add("bar", "barvalue");

                        If later is right, use the subclass can simplify adding the filed value in message body.(move the add(key, value) code to parent class and subclass can put all field value sby calling this.setMessageBodys()).

                        "Kevin.Conner@jboss.com" wrote:

                        To fit in with the current code it would be better if it was handled as follows.
                        payloadProxy = new MessagePayloadProxy(config)

                        and then something like the following
                        Message message = MessageFactory.getInstance().getMessage();
                        payloadProxy.setPayload(message, <incoming request>);
                        ... evaluate pipeline ...
                        Object response = payloadProxy.getPayload(responseMessage);
                        



                        Does payloadProxy get payLoad from the default location ? If there are multiple objects in message body , does it also work?



                        • 10. Re: Publish ESB services to web services
                          Burr Sutter Master

                          A thought on where in the ESB Message should the SOAP stuff go...

                          I think the raw XML as a string should go into message.getBody().add(soap_message); This is the "default location" which might be interesting to the action chain/pipeline.

                          The marshaled request & response should be at
                          message.getBody().add(SOAP_REQUEST,request); and
                          message.getBody().add(SOAP_RESPONSE,response); respectively
                          where SOAP_REQUEST is specified in the jboss-esb.properties file

                          It is very likely that the user will take the POJOs and map them into jBPM or Drools using the techniques shown in quickstart bpm_orchestration4

                          By "marshaled", I mean the POJO (not XML) of the request & response objects.