Quantcast
Channel: ABAP Development
Viewing all articles
Browse latest Browse all 948

Consuming WebServices directly from ABAP

$
0
0

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:

1.png

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:

2.png

A Wizzard will start.

Select Service Consumer an click continue:

3.png

Select Local File and click Continue:

4.png

Select the editted WSDL file and click continue:

5.png

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

6.png

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

 

Click Complete:

7.png

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

8.png

Click the Activate Button 9.png.

 

Sucssess! 10.png

 

 

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):

11.png

Click in Application and Scenario Communicaton and Single Service Administration:

 

12.png

 

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

 

13.png

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

14.png

Back to our Webservice Administration:

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

15.png

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)

16.png

Click Apply Settings and Save:

17.png

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:

 

18.png

 

Fill some valid Values:

19.png

 

Click on Execute Button  and check the response:

20.png

 

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.

Viewing all articles
Browse latest Browse all 948

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>