9 Replies Latest reply: Apr 24, 2012 2:05 AM by Stylianos Koussouris RSS

How to config JBoss ESB service to expose as Web Services which contains multiple operations?

Julian YANG Newbie

Hi, everyone.

When specify the inXsd, outXsd and faultXsd attributes of the actions element, JBoss ESB will generate a web service according to the schemas, but there is only onw operation in the generated web service. How to config or what to do if I want to generate multiple operations in the web service?

 

Thanks in advance.

  • 2. Re: How to config JBoss ESB service to expose as Web Services which contains multiple operations?
    Hans Wolffenbuttel Expert

    Hi Julian,

     

    The ESB works exactly as you describe. The sollution to exposure of multi webservice operations is probably to use a proxy in JBossESB which does just that. This means you need to build your own webservice to be proxied by JBossESB.

    Another way to solve your problem is to explain more about which problem you want to solve with JBossESB. Because there is always more than one way to solve anything.

     

    Regards,

     

    Hans

  • 3. Re: How to config JBoss ESB service to expose as Web Services which contains multiple operations?
    Julian YANG Newbie

    thanks, Hans

    A few days ago, after reading a book named "JBoss ESB Beginner's Guide", I know there is a way to solve my problem, but the book does not describe anything about it.

    Do you have any examples? You need not to explain much about it, just a piece of example is enough.

  • 4. Re: How to config JBoss ESB service to expose as Web Services which contains multiple operations?
    mlog Newbie

    Hi, Julian.

    You can’t configure ESB service to expose web service with more than one operation. Check it in the source code of org.jboss.internal.soa.esb.webservice.ESBContractGenerator class. But you could add any operations into generated wsdl manually instead. In this case, your client calls web service with the modified wsdl. So in your service which exposed as web service you have to route incoming request to appropriate service with ContentBasedRouter.

  • 5. Re: How to config JBoss ESB service to expose as Web Services which contains multiple operations?
    Stylianos Koussouris Newbie

    Yes, I noticed that too although the book has an example (chapter 8) clearly with 2 operations but only one is added to the resulting contract and WSDL

     

     

    <xs:schema version="1.0" targetNamespace="http://chapter8.samples.esb.soa.jboss.org/" xmlns:tns="http://chapter8.samples.esb.soa.jboss.org/" xmlns:xs="http://www.w3.org/2001/XMLSchema">
      <xs:element name="getAuthors" type="tns:getAuthors"/>
      <xs:element name="getBooks" type="tns:getBooks"/>
      <xs:complexType name="getBooks">
        <xs:sequence/>
      </xs:complexType>
      <xs:complexType name="getAuthors">
        <xs:sequence/>
      </xs:complexType>
    </xs:schema>
    

     

     

    The configuration of the service to be accessible via fat WS

     

    <actions inXsd="BookServiceRequest.xsd" mep="RequestResponse" outXsd="BookServiceResponse.xsd">
    

     

     

    results only in one operations being exposed. Why would it be in the book (seems strange since the authors would know this wouldn't work) if only one operation ever makes it to the WSDL/contract.

     

    Also, I am unclear how you would change the WSDL to include the rest of the rest of the operations. Isn't this automatically created when the .esb gets deployed? I found 2 WSDLs created when I deployed the sample and not sure if both have to be modified

     

    wsdl.png

     

  • 6. Re: How to config JBoss ESB service to expose as Web Services which contains multiple operations?
    Stylianos Koussouris Newbie

    I have read the following thread which explains the exact behavior of EBWS

     

    https://community.jboss.org/thread/148046

     

    however the book example was somewhat confusing the issue of having only 1 operation in the resulting WSDL.

     

    mlog, have you got a working example of what you suggested here https://community.jboss.org/message/724638#724638

  • 7. Re: How to config JBoss ESB service to expose as Web Services which contains multiple operations?
    Magesh Bojan Master

    Hi Stelios (hope I am right),

     

    As mlog said, EBWS will expose only one operation at a time, based on the schema. The first available element from the request.xsd will be used as the request part for that operation and the first available element in the response.xsd will be used for the response. The JBoss ESB Beginner's Guide had a very different intention to have both elements embedded into one schema file for the reader to test themselves. You can alter what is being exposed by ordering the element definitions accordingly.

     

    As Kevin mentions in the follwoing JIRA, EBWS was created to provide simple contract only possibly for validation purposes.

     

    Please log a feature request or update this JIRA with your comments.

     

    https://issues.jboss.org/browse/JBESB-3353

  • 8. Re: How to config JBoss ESB service to expose as Web Services which contains multiple operations?
    mlog Newbie

    Hi, Stylianos Koussouris.

    Suppose that you have two ESB services and want to expose them as two methods of one web service. These are simple services’ contracts and jboss-esb.xml:

     

    jboss-esb.xml

    <?xml version = "1.0" encoding = "UTF-8"?>
    <jbossesb
         xmlns="http://anonsvn.labs.jboss.com/labs/jbossesb/trunk/product/etc/schemas/xml/jbossesb-1.3.0.xsd"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://anonsvn.labs.jboss.com/labs/jbossesb/trunk/product/etc/schemas/xml/jbossesb-1.3.0.xsd http://anonsvn.jboss.org/repos/labs/labs/jbossesb/trunk/product/etc/schemas/xml/jbossesb-1.3.0.xsd"
         parameterReloadSecs="5"
    >
         <services>
              <service
                   category="foobar"
                   name="foo-service"
                   description=""
                   invmScope="GLOBAL"
              >
                   <actions
                        mep="RequestResponse"
                        inXsd="foo-request.xsd"
                        outXsd="foo-response.xsd"
                        webservice="false"
                   >
                        <action name="answer" class="org.jboss.soa.esb.actions.SystemPrintln">
                             <property name="message" value="anwser from foo method" />
                        </action>       
                   </actions>
              </service>  
    
              <service
                   category="foobar"
                   name="bar-service"
                   description=""
                   invmScope="GLOBAL"
              >
                   <actions
                        mep="RequestResponse"
                        inXsd="bar-request.xsd"
                        outXsd="bar-response.xsd"
                        webservice="false"
                   >
                        <action name="answer" class="org.jboss.soa.esb.actions.SystemPrintln">
                             <property name="message" value="anwser from bar method" />
                        </action>       
                   </actions>
              </service>  
    
              <service
                   category="foobar"
                   name="foo-bar-ws"
                   description=""
                   invmScope="GLOBAL"
              >
                   <actions
                        mep="OneWay"
                        inXsd="bar-request.xsd"
                        outXsd="bar-response.xsd"
                        webservice="true"
                   >
                        <action name="route" class="org.jboss.soa.esb.actions.MessageFilter">
                             <property name="cbrAlias" value="XPath"/>
                             <property name="destinations">
                                  <route-to
                                       service-category="foobar"
                                       service-name="foo-service"
                                       expression="//*[local-name()='foo-method-request']"
                                  />
                                  <route-to
                                       service-category="foobar"
                                       service-name="bar-service"
                                       expression="//*[local-name()='bar-method-request']"
                                  />
                             </property>
                        </action>                
                   </actions>
              </service>  
         </services>
    </jbossesb>
    

     

    foo-request.xsd

    <?xml version="1.0" encoding="UTF-8"?>
    <schema
         xmlns="http://www.w3.org/2001/XMLSchema"
         targetNamespace="http://foobar.service"
         xmlns:tns="http://foobar.service"
         elementFormDefault="qualified"
    >
         <element name="foo-method-request">
              <complexType>
                   <sequence>
                        <element name="foo-question" type="string"/>
                   </sequence>
              </complexType>
         </element>
    </schema>
    

     

    bar-request.xsd

    <?xml version="1.0" encoding="UTF-8"?>
    <schema
         xmlns="http://www.w3.org/2001/XMLSchema"
         targetNamespace="http://foobar.service"
         xmlns:tns="http://foobar.service"
         elementFormDefault="qualified"
    >
         <element name="bar-method-request">
              <complexType>
                   <sequence>
                        <element name="bar-question" type="string"/>
                   </sequence>
              </complexType>
         </element>
    </schema>
    

     

    foo-response.xsd

    <?xml version="1.0" encoding="UTF-8"?>
    <schema
         xmlns="http://www.w3.org/2001/XMLSchema"
         targetNamespace="http://foobar.service"
         xmlns:tns="http://foobar.service"
         elementFormDefault="qualified"
    >
         <element name="foo-method-response">
              <complexType>
                   <sequence>
                        <element name="foo-answer" type="string"/>
                   </sequence>
              </complexType>
         </element>
    </schema>
    

     

    bar-response.xsd

    <?xml version="1.0" encoding="UTF-8"?>
    <schema
         xmlns="http://www.w3.org/2001/XMLSchema"
         targetNamespace="http://foobar.service"
         xmlns:tns="http://foobar.service"
         elementFormDefault="qualified"
    >
         <element name="bar-method-response">
              <complexType>
                   <sequence>
                        <element name="bar-answer" type="string"/>
                   </sequence>
              </complexType>
         </element>
    </schema>
    

     

    While publishing the project wsdl was generated. It defines only one method:

     

    <wsdl:definitions targetNamespace="http://soa.jboss.org/foobar" xmlns:esbns1="http://foobar.service" xmlns:esbns2="http://foobar.service" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://soa.jboss.org/foobar" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
     <wsdl:types>
      <xs:schema targetNamespace="http://foobar.service" version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
       <xs:include schemaLocation="http://localhost:8080/ServiceAsWS/ebws/foobar/foo-bar-ws?wsdl&resource=bar-request.xsd"/>
      </xs:schema>
      <xs:schema targetNamespace="http://foobar.service" version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
       <xs:include schemaLocation="http://localhost:8080/ServiceAsWS/ebws/foobar/foo-bar-ws?wsdl&resource=bar-response.xsd"/>
      </xs:schema>
     </wsdl:types>
     <wsdl:message name="foo-bar-wsReq">
      <wsdl:part element="esbns1:bar-method-request" name="in"/>
     </wsdl:message>
     <wsdl:message name="foo-bar-wsRes">
      <wsdl:part element="esbns1:bar-method-response" name="out"/>
     </wsdl:message>
     <wsdl:portType name="foo-bar-wsPortType">
      <wsdl:operation name="foo-bar-wsOp">
       <wsdl:input message="tns:foo-bar-wsReq" name="foo-bar-wsReq"/>
       <wsdl:output message="tns:foo-bar-wsRes" name="foo-bar-wsRes"/>
      </wsdl:operation>
     </wsdl:portType>
     <wsdl:binding name="foo-bar-wsBinding" type="tns:foo-bar-wsPortType">
      <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
      <wsdl:operation name="foo-bar-wsOp">
       <soap:operation soapAction="http://soa.jboss.org/foobar/foo-bar-wsOpResp"/>
       <wsdl:input name="foo-bar-wsReq">
        <soap:body use="literal"/>
       </wsdl:input>
       <wsdl:output name="foo-bar-wsRes">
        <soap:body use="literal"/>
       </wsdl:output>
      </wsdl:operation>
     </wsdl:binding>
     <wsdl:service name="foo-bar-wsService">
      <wsdl:port binding="tns:foo-bar-wsBinding" name="foo-bar-wsPortType">
       <soap:address location="http://localhost:8080/ServiceAsWS/ebws/foobar/foo-bar-ws"/>
      </wsdl:port>
     </wsdl:service>
    </wsdl:definitions>
    

     

    Copy and modify generated wsdl according to your services' contracts as shown below (changes were marked with bold):

    <wsdl:definitions
        xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
        xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
        targetNamespace="http://foobar.service"
        xmlns:tns="http://foobar.service"
    >
     <wsdl:types>
    
    <schema
        xmlns="http://www.w3.org/2001/XMLSchema"
        targetNamespace="http://foobar.service"
        xmlns:tns="http://foobar.service"
        elementFormDefault="qualified"
    >
    
        <element name="foo-method-request">
            <complexType>
                <sequence>
                    <element name="foo-question" type="string"/>
                </sequence>
            </complexType>
        </element>
        <element name="foo-method-response">
            <complexType>
                <sequence>
                    <element name="foo-answer" type="string"/>
                </sequence>
            </complexType>
        </element>
        <element name="bar-method-request">
            <complexType>
                <sequence>
                    <element name="bar-question" type="string"/>
                </sequence>
            </complexType>
        </element>
        <element name="bar-method-response">
            <complexType>
                <sequence>
                    <element name="bar-answer" type="string"/>
                </sequence>
            </complexType>
        </element>
    
    </schema>
     </wsdl:types>
    
     <wsdl:message name="foo-request">
      <wsdl:part element="tns:foo-method-request" name="in"/>
     </wsdl:message>
    
     <wsdl:message name="foo-response">
      <wsdl:part element="tns:foo-method-response" name="out"/>
     </wsdl:message>
    
     <wsdl:message name="bar-request">
      <wsdl:part element="tns:bar-method-request" name="in"/>
     </wsdl:message>
    
     <wsdl:message name="bar-response">
      <wsdl:part element="tns:bar-method-response" name="out"/>
     </wsdl:message>
    
     <wsdl:portType name="foo-bar-wsPortType">
      <wsdl:operation name="foo-method">
       <wsdl:input message="tns:foo-request" name="foo-Req"/>
       <wsdl:output message="tns:foo-response" name="foo-Res"/>
      </wsdl:operation>
      <wsdl:operation name="bar-method">
       <wsdl:input message="tns:bar-request" name="bar-Req"/>
       <wsdl:output message="tns:bar-response" name="bar-Res"/>
      </wsdl:operation>
     </wsdl:portType>
    
     <wsdl:binding name="foo-bar-wsBinding" type="tns:foo-bar-wsPortType">
      <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
      <wsdl:operation name="foo-method">
       <wsdl:input name="foo-Req">
        <soap:body use="literal"/>
       </wsdl:input>
       <wsdl:output name="foo-Res">
        <soap:body use="literal"/>
       </wsdl:output>
      </wsdl:operation>
       <wsdl:operation name="bar-method">
       <wsdl:input name="bar-Req">
        <soap:body use="literal"/>
       </wsdl:input>
       <wsdl:output name="bar-Res">
        <soap:body use="literal"/>
       </wsdl:output>
      </wsdl:operation>
     </wsdl:binding>
    
     <wsdl:service name="foo-bar-wsService">
      <wsdl:port binding="tns:foo-bar-wsBinding" name="foo-bar-wsPortType">
       <soap:address location="http://localhost:8080/ServiceAsWS/ebws/foobar/foo-bar-ws"/>
      </wsdl:port>
     </wsdl:service>
    </wsdl:definitions>
    

     

    Call web service with modified wsdl. I have this output in console:

     

    INFO  [STDOUT] anwser from foo method: 
    INFO  [STDOUT] [<foob:foo-method-request xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:foob="http://foobar.service">
             <foob:foo-question>foo</foob:foo-question>
          </foob:foo-method-request>].
    INFO  [STDOUT] anwser from bar method: 
    INFO  [STDOUT] [<foob:bar-method-request xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:foob="http://foobar.service">
             <foob:bar-question>bar</foob:bar-question>
          </foob:bar-method-request>].
    
  • 9. Re: How to config JBoss ESB service to expose as Web Services which contains multiple operations?
    Stylianos Koussouris Newbie

    Hi Magesh (yeap its me),

     

    I have added my comment on the JIRA mentioned.

     

    Thanks