Application Development Blog Posts
Learn and share on deeper, cross technology development topics such as integration and connectivity, automation, cloud extensibility, developing at scale, and security.
cancel
Showing results for 
Search instead for 
Did you mean: 
Former Member

A time ago I was asked to create a Webservice consumption directly from ABAP without any soa.

We listen too much about SAP PI as an integrator and every SAP connection is done thru it (that's the best way to do it, I think) but it is not the only way. Since ERP 4.7  it is possible to consume/provide services directly from ABAP.

When our scenario is SAP -> WebService the first thing we need is a working webservice.

Test service:

Here I'll create a Service Consumer for consumption of a test webservice from http://www.webservicex.net/length.asmx?WSDL it's service that converts lenght units.

First, let's take a better look to the WSDL:

In this file there are 3 operations:

  • lengthUnitSoap
  • lengthUnitHttpGet
  • lengthUnitHttpPost

For this post the only relevant port service is lengthUnitSoap that implements Soap standards. The two others are for HTTP consumption directly (not our focus here).

Before we can simply import our file to SAP, taking a better look into it we see that some messages have more than one part tag:

This kind of message is incompatible with SAP, so if there are any messages with more than exactly one part tag the system will return you an error before import your file. Even if the message is not used in the service that you are implementing.

In thes scenario what can we do?

Simple: we can edit the file to match our needs.

Save the original WSDL file to your computer (as .xml or .wsdl) then edit it.

The editted WSDL file shoud seem like this:

<?xml version="1.0" encoding="utf-8"?>
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:tns="http://www.webserviceX.NET/" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" targetNamespace="http://www.webserviceX.NET/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
  <wsdl:types>
    <s:schema elementFormDefault="qualified" targetNamespace="http://www.webserviceX.NET/">
      <s:element name="ChangeLengthUnit">
        <s:complexType>
          <s:sequence>
            <s:element minOccurs="1" maxOccurs="1" name="LengthValue" type="s:double" />
            <s:element minOccurs="1" maxOccurs="1" name="fromLengthUnit" type="tns:Lengths" />
            <s:element minOccurs="1" maxOccurs="1" name="toLengthUnit" type="tns:Lengths" />
          </s:sequence>
        </s:complexType>
      </s:element>
      <s:simpleType name="Lengths">
        <s:restriction base="s:string">
          <s:enumeration value="Angstroms" />
          <s:enumeration value="Nanometers" />
          <s:enumeration value="Microinch" />
          <s:enumeration value="Microns" />
          <s:enumeration value="Mils" />
          <s:enumeration value="Millimeters" />
          <s:enumeration value="Centimeters" />
          <s:enumeration value="Inches" />
          <s:enumeration value="Links" />
          <s:enumeration value="Spans" />
          <s:enumeration value="Feet" />
          <s:enumeration value="Cubits" />
          <s:enumeration value="Varas" />
          <s:enumeration value="Yards" />
          <s:enumeration value="Meters" />
          <s:enumeration value="Fathoms" />
          <s:enumeration value="Rods" />
          <s:enumeration value="Chains" />
          <s:enumeration value="Furlongs" />
          <s:enumeration value="Cablelengths" />
          <s:enumeration value="Kilometers" />
          <s:enumeration value="Miles" />
          <s:enumeration value="Nauticalmile" />
          <s:enumeration value="League" />
          <s:enumeration value="Nauticalleague" />
        </s:restriction>
      </s:simpleType>
      <s:element name="ChangeLengthUnitResponse">
        <s:complexType>
          <s:sequence>
            <s:element minOccurs="1" maxOccurs="1" name="ChangeLengthUnitResult" type="s:double" />
          </s:sequence>
        </s:complexType>
      </s:element>
      <s:element name="double" type="s:double" />
    </s:schema>
  </wsdl:types>
  <wsdl:message name="ChangeLengthUnitSoapIn">
    <wsdl:part name="parameters" element="tns:ChangeLengthUnit" />
  </wsdl:message>
  <wsdl:message name="ChangeLengthUnitSoapOut">
    <wsdl:part name="parameters" element="tns:ChangeLengthUnitResponse" />
  </wsdl:message>
  <wsdl:portType name="lengthUnitSoap">
    <wsdl:operation name="ChangeLengthUnit">
      <wsdl:input message="tns:ChangeLengthUnitSoapIn" />
      <wsdl:output message="tns:ChangeLengthUnitSoapOut" />
    </wsdl:operation>
  </wsdl:portType>
  <wsdl:binding name="lengthUnitSoap" type="tns:lengthUnitSoap">
    <soap:binding transport="http://schemas.xmlsoap.org/soap/http" />
    <wsdl:operation name="ChangeLengthUnit">
      <soap:operation soapAction="http://www.webserviceX.NET/ChangeLengthUnit" style="document" />
      <wsdl:input>
        <soap:body use="literal" />
      </wsdl:input>
      <wsdl:output>
        <soap:body use="literal" />
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:binding name="lengthUnitSoap12" type="tns:lengthUnitSoap">
    <soap12:binding transport="http://schemas.xmlsoap.org/soap/http" />
    <wsdl:operation name="ChangeLengthUnit">
      <soap12:operation soapAction="http://www.webserviceX.NET/ChangeLengthUnit" style="document" />
      <wsdl:input>
        <soap12:body use="literal" />
      </wsdl:input>
      <wsdl:output>
        <soap12:body use="literal" />
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:service name="lengthUnit">
    <wsdl:port name="lengthUnitSoap" binding="tns:lengthUnitSoap">
      <soap:address location="http://www.webservicex.net/length.asmx" />
    </wsdl:port>
    <wsdl:port name="lengthUnitSoap12" binding="tns:lengthUnitSoap12">
      <soap12:address location="http://www.webservicex.net/length.asmx" />
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>

Creating an ABAP Proxy:

After deleting the messages without only one part and the respectively port-types we can import the WSDL file into SAP.

To do so in transaction SE80 select package from the dropdown create or use an existent package to your services and right click it select Create->Enterprise Service:

A Wizzard will start.

Select Service Consumer an click continue:

Select Local File and click Continue:

Select the editted WSDL file and click continue:

Select Package, Prefix and Request to your Service consumer and click Continue:

IMPORTANT: The prefix must be started with Z or Y otherwise the SAP will ask for object Keys.

Click Complete:

Our service consumer is now created, but it is still not activated:

Click the Activate Button .

Sucssess!

We're now half way done.

We have our proxy but it still does not works. That's because we have not configured the endpoint of service.

To do so I'll go to transaction SOAMANAGER. (LPCONFIG in older versions) where we'll configure the endpoit of our service.

Configuration:

Go to transaction SOAMANAGER if everything goes right you'll be redirected to a web browser in the following page (if you were redirected to a login page, just fill your SAP user/password):

Click in Application and Scenario Communicaton and Single Service Administration:

Search for your created proxy (just remember it is a Consumer Proxy):

Tip: you can find both  External and Internal name in tab External View from your proxy:

Back to our Webservice Administration:

Select your service, click Apply Selection Button and go to Configurations tab:

Click Create Logical Port Button Fill the port name, Description, Configuration Type and WSDL Base:

(the File with WSDL Document is your modifyed WSDL document that you saved in your computer in the beginning of this post)

Click Apply Settings and Save:

Testing:

Back in our SAP ERP system we can test the service just by clicking in test tool (F8).

Select your Logical Port (just created) and click on execute button:

Fill some valid Values:

Click on Execute Button  and check the response:

Calling From ABAP Program:

Here is a test program for calling this Proxy:

*& Report  ZTEST_PROXY
REPORT  ZTEST_PROXY.
* Data Declarations
DATA: cl_proxy TYPE REF TO ZCO_LENGTH_UNIT_SOAP, " Proxy Class
       data_in  TYPE ZCHANGE_LENGTH_UNIT_SOAP_IN, " Proxy Input
       data_out TYPE ZCHANGE_LENGTH_UNIT_SOAP_OUT, " Proxy Output
       fault    TYPE REF TO cx_root. " Generic Fault
* Instantiate the proxy class providing the Logical port name
CREATE OBJECT cl_proxy EXPORTING LOGICAL_PORT_NAME = 'DEFAULT_PORT'.
* Set Fixed Values
data_in-LENGTH_VALUE = '32'.
data_in-FROM_LENGTH_UNIT = 'Inches'.
data_in-TO_LENGTH_UNIT  = 'Millimeters'.
TRY .
   cl_proxy->CHANGE_LENGTH_UNIT( EXPORTING INPUT = data_in
                                 IMPORTING OUTPUT = data_out ).
CATCH cx_root INTO fault.
* Here is the place for error handling
   BREAK-POINT.
ENDTRY.
*  Here the structure data_out is filled case none Exceptions occurs
BREAK-POINT.
5 Comments