3

I try to make c++ proxies form multiple WSDLs, but generated proxy class has wrong endpoint. Result endpoint for each method in proxy class is a joined value like:

soap_endpoint = "http://endpoint1 http://endpoint2 etc".

After running:

wsdl2h.exe -o out\wsdl.h -t typemap.dat service1.wsdl service2.wsdl

result wsdl.h has lines:

//gsoap booking service name:   ricercaRichiestaSoap11 
//gsoap booking service type:   ricercaRichiesta 
//gsoap booking service port:   http://e-servizicoll.apps.dtt:80/PrenotaPatente-ws/services/ricercaRichiestaEsame/ 
//gsoap booking service port:   http://e-servizicoll.apps.dtt:80/PrenotaPatente-ws/services/stampaFoglioRosa/ 
//gsoap booking service namespace:  http://www.dtt.it/xsd/PrenotaPatenteWS 
//gsoap booking service transport:  http://schemas.xmlsoap.org/soap/http 

After this command:

soapcpp2.exe -C -L -dout -j -x -I gsoap\import out\wsdl.h

it generates ricercaRichiestaSoap11Proxy class with two methods but they has joined endpoint:

soap_endpoint = "http://e-servizicoll.apps.dtt:80/PrenotaPatente-ws/services/ricercaRichiestaEsame/ http://e-servizicoll.apps.dtt:80/PrenotaPatente-ws/services/stampaFoglioRosa/";

How to solve this issue? Maybe I have to use different workflow to generate proxies or manually edit generated wsdl.h? Thanks.


I use gSoap 2.8.17 on win7 x64.

service1.wsdl:

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
    xmlns:sch="http://www.dtt.it/xsd/PrenotaPatenteWS"
    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
    xmlns:tns="http://www.dtt.it/xsd/PrenotaPatenteWS"
    targetNamespace="http://www.dtt.it/xsd/PrenotaPatenteWS">

  <wsdl:types> .... </wsdl:types>

  <wsdl:message name="ricercaRichiestaEsameResponse">
    <wsdl:part element="tns:ricercaRichiestaEsameResponse" name="ricercaRichiestaEsameResponse" />
  </wsdl:message>

  <wsdl:message name="ricercaRichiestaEsameRequest">
    <wsdl:part element="tns:ricercaRichiestaEsameRequest" name="ricercaRichiestaEsameRequest" />
  </wsdl:message>

  <wsdl:portType name="ricercaRichiesta">
    <wsdl:operation name="ricercaRichiestaEsame">
      <wsdl:input message="tns:ricercaRichiestaEsameRequest" name="ricercaRichiestaEsameRequest" />
      <wsdl:output message="tns:ricercaRichiestaEsameResponse" name="ricercaRichiestaEsameResponse" />
    </wsdl:operation>
  </wsdl:portType>

  <wsdl:binding name="ricercaRichiestaSoap11" type="tns:ricercaRichiesta">
    <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
    <wsdl:operation name="ricercaRichiestaEsame">
      <soap:operation soapAction="" />
      <wsdl:input name="ricercaRichiestaEsameRequest">
        <soap:body use="literal" />
      </wsdl:input>
      <wsdl:output name="ricercaRichiestaEsameResponse">
        <soap:body use="literal" />
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>

  <wsdl:service name="ricercaRichiestaService">
    <wsdl:port binding="tns:ricercaRichiestaSoap11" name="ricercaRichiestaSoap11">
      <soap:address location="http://e-servizicoll.apps.dtt:80/PrenotaPatente-ws/services/ricercaRichiestaEsame/" />
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>

service2.wsdl:

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
    xmlns:sch="http://www.dtt.it/xsd/PrenotaPatenteWS"
    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
    xmlns:tns="http://www.dtt.it/xsd/PrenotaPatenteWS"
    targetNamespace="http://www.dtt.it/xsd/PrenotaPatenteWS">

  <wsdl:types> .... </wsdl:types>

  <wsdl:message name="stampaFoglioRosaResponse">
    <wsdl:part element="tns:stampaFoglioRosaResponse" name="stampaFoglioRosaResponse" />
  </wsdl:message>

  <wsdl:message name="stampaFoglioRosaRequest">
    <wsdl:part element="tns:stampaFoglioRosaRequest" name="stampaFoglioRosaRequest" />
  </wsdl:message>

  <wsdl:portType name="stampaFoglioRosa">
    <wsdl:operation name="stampaFoglioRosa">
      <wsdl:input message="tns:stampaFoglioRosaRequest" name="stampaFoglioRosaRequest" />
      <wsdl:output message="tns:stampaFoglioRosaResponse" name="stampaFoglioRosaResponse" />
    </wsdl:operation>
  </wsdl:portType>

  <wsdl:binding name="stampaFoglioRosaSoap11" type="tns:stampaFoglioRosa">
    <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
    <wsdl:operation name="stampaFoglioRosa">
      <soap:operation soapAction="" />
      <wsdl:input name="stampaFoglioRosaRequest">
        <soap:body use="literal" />
      </wsdl:input>
      <wsdl:output name="stampaFoglioRosaResponse">
        <soap:body use="literal" />
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>

  <wsdl:service name="stampaFoglioRosaService">
    <wsdl:port binding="tns:stampaFoglioRosaSoap11" name="stampaFoglioRosaSoap11">
      <soap:address location="http://e-servizicoll.apps.dtt:80/PrenotaPatente-ws/services/stampaFoglioRosa/" />
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>
skozlovf
  • 241
  • 1
  • 3
  • 13
  • 1
    Why not run wsdl2h on all WSDLs together? Then use soapcpp2 option -j on the one .h file you get to generate the proxy and service classes for each WSDL service. Always works like a charm. – Dr. Alex RE Jul 05 '17 at 15:19
  • @Dr.AlexRE An example of that, if added to the documentation, would be helpful – villapx Dec 03 '18 at 14:22

2 Answers2

4

To create C++ proxies from multiple WSDLs to connect to different endpoint, you could do this:

  • Generate a header file for each WSDL

    wsdl2h.exe -o out\Service1.h -t typemap.dat service1.wsdl

    wsdl2h.exe -o out\Service2.h -t typemap.dat service2.wsdl

  • Generate a proxy class for each header

    soapcpp2.exe -C -L -dout -j -x -I gsoap\import out\Service1.h

    soapcpp2.exe -C -L -dout -j -x -I gsoap\import out\Service2.h

  • Now you will have

    Service1BindingProxy.h

    Service1BindingProxy.cpp

    Service2BindingProxy.h

    Service2BindingProxy.cpp

  • Generate a common soap definition for all wsdl files

    wsdl2h.exe -o out\CommonService.h -t typemap.dat *.wsdl

  • Generate common soap code and namespace map

    soapcpp2.exe -C -L -dout -j -x -I gsoap\import out\CommonService.h

  • And you have

    soapH.h

    soapStub.h

    soapC.cpp

  • Keep only one .nsmap file.

  • Compile the generated soap code, proxy classes and your implementation.

HAL
  • 3,888
  • 3
  • 19
  • 28
0

"it generates ricercaRichiestaSoap11Proxy class with two methods but they has joined endpoint."

This happens because the WSDLs use the same targetNamespace, which is rare and not recommended because it may result in clashes, like in this case. Never use the same targetNamespace for different WSDL-declared services. In this case you get the two endpoints (ports) because they are defined for the same targetNamespace mapped to the booking namespace prefix:

//gsoap booking service port:   http://e-servizicoll.apps.dtt:80/PrenotaPatente-ws/services/ricercaRichiestaEsame/ 
//gsoap booking service port:   http://e-servizicoll.apps.dtt:80/PrenotaPatente-ws/services/stampaFoglioRosa/ 

You can always specify an endpoint URL with the proxy invocation itself, such as proxy.stampaFoglioRosa("http://e-servizicoll.apps.dtt:80/PrenotaPatente-ws/services/stampaFoglioRosa/", NULL, ...params...), which will let the proxy connect to the specified endpoint URL.

Alternatively, you can run wsdl2h on the WSDLs separately as @HAL explained. But you may also want to use C++ namespaces with this approach using wsdl2h option -qNAME.

Dr. Alex RE
  • 1,772
  • 1
  • 15
  • 23