Wednesday, 10 July 2019

How to create an openApi Rest Service from an oData v4 Rest Service with SAP Netweaver ABAP

Motivation and Introduction:


Rest Services are very popular and widely used. But Rest is only a programming paradigm and or an architectural approach as such it doesn’t set up any contract how services are offered, and which format the payload will have finally.

To address this contract there are a lot of service descriptions available meanwhile. You can have a look on how many there are at wikipedia. The ones I came accross the last years very frequently are oData and openApi.

SAP Netweaver comes with great support of oData and as both service descriptions have the same paradigm (Rest) underneath the differences between oData and openApi are not that great as one maybe think about.

Although it’s possible to write Restful Services with ABAP with some framework classes of package SREST you won’t have the service infrastructure of SAP Netweaver Gateway at hand and nonfunctional requirements, like technical error logging and tracing capabilities become crucial with distributed applications.

The OASIS group is maintaining a toolset to generate an openApi description from oData service description document.

https://github.com/oasis-tcs/odata-openapi

Here I’d like to dive into that and see how to build a simple java client from such an openApi description which transparently accesses an oData service. That becomes especially interesting with oData v4, as the payload is ‘plain json’ there. So we’ve a good chance to see that working and leverage the SAP Netweaver Gateway features for openApi services built on the ABAP stack.

In order to do that we will:

1. Build and deploy a simple v4 oData service
2. Download and install the toolset to generate the openApi description
3. Generate the openApi description the oData services description
4. Download and build the swagger code generator
5. Generate and install the openapi client from the openApi description
6. Build and run a simple java program which uses the openapi client generated.

Prerequisites:


To follow the steps here the following software need to be available/installed:

◈ Nodejs
◈ Git SCM
◈ JDK (here 1.8)
◈ Apache Maven
◈ SAP Netweaver ABAP 750 SP4

Build and Deploy a simple v4 oData service


SAP ABAP Tutorials and Materials, SAP ABAP Certifications, SAP ABAP Guides, SAP ABAP Learning

Go to Transaction “SEGW” and click “New” button to create a new service

SAP ABAP Tutorials and Materials, SAP ABAP Certifications, SAP ABAP Guides, SAP ABAP Learning

Create the project with the settings shown at the screenshot. Especially choose Project type “OData 4.0 Service” and store as local object.

SAP ABAP Tutorials and Materials, SAP ABAP Certifications, SAP ABAP Guides, SAP ABAP Learning

Expand the node „Data Model“ double click on Entity Types, press the New button on the right pane, enter Entity Type Name „contractType“ and press enter.

SAP ABAP Tutorials and Materials, SAP ABAP Certifications, SAP ABAP Guides, SAP ABAP Learning

1. Expand the node „contractType“, double click on properties
2. Press the New button two times.
3. Set the first properties name to „contractId“, check the checkbox for „Key“, select type kind to „Core Type“ and choose data type „Edm.String“
4. Set the second properties name to „contractName“, select „type kind to „Core Type“ and choose data type „Edm.String“
5. Press „Save“

SAP ABAP Tutorials and Materials, SAP ABAP Certifications, SAP ABAP Guides, SAP ABAP Learning

Double click on entity sets, press the new button on the right pane, set entity set name to „contract“ and entity type name to „contractType“, press enter and save

SAP ABAP Tutorials and Materials, SAP ABAP Certifications, SAP ABAP Guides, SAP ABAP Learning

Press Generate

SAP ABAP Tutorials and Materials, SAP ABAP Certifications, SAP ABAP Guides, SAP ABAP Learning

Leave the class names as provided and save as local object in the next dialogs.

SAP ABAP Tutorials and Materials, SAP ABAP Certifications, SAP ABAP Guides, SAP ABAP Learning

1. Expand the runtime artifacts
2. Double click on „ZCL_ZTEST_SERVICE_V4_DPC_EXT“
3. And double click on „ZCL_ZTEST_SERVICE_V4_DPC_EXT“ on the right pane in order to open the class editor.

Add the following method to ZCL_ZTEST_SERVICE_V4_DPC_EXT

method GET_CONTRACT_SAMPLE_DATA.
    clear ET_CONTRACTS.

    APPEND INITIAL LINE TO ET_CONTRACTS ASSIGNING FIELD-SYMBOL(<fs_contract>).
    <fs_contract>-CONTRACTID = 1.
    <fs_contract>-CONTRACTNAME = 'Sample contract 1'.

    APPEND INITIAL LINE TO ET_CONTRACTS ASSIGNING <fs_contract>.
    <fs_contract>-CONTRACTID = 2.
    <fs_contract>-CONTRACTNAME = 'Other contract'.

    APPEND INITIAL LINE TO ET_CONTRACTS ASSIGNING <fs_contract>.
    <fs_contract>-CONTRACTID = 3.
    <fs_contract>-CONTRACTNAME = 'Test contract '.

    APPEND INITIAL LINE TO ET_CONTRACTS ASSIGNING <fs_contract>.
    <fs_contract>-CONTRACTID = 4.
    <fs_contract>-CONTRACTNAME = 'Special contract'.

    APPEND INITIAL LINE TO ET_CONTRACTS ASSIGNING <fs_contract>.
    <fs_contract>-CONTRACTID = 5.
    <fs_contract>-CONTRACTNAME = 'Final contract'.

  endmethod.

Redefine the method CONTRACT_READ_LIST as follows:

  method CONTRACT_READ_LIST.
**TRY.
*CALL METHOD SUPER->CONTRACT_READ_LIST
*  EXPORTING
*    IO_REQUEST  =
*    IO_RESPONSE =
*    .
** CATCH /IWBEP/CX_GATEWAY .
**ENDTRY.


      GET_CONTRACT_SAMPLE_DATA(
    importing
      ET_CONTRACTS = data(lt_contracts)
  ).
  IO_RESPONSE->SET_BUSI_DATA( IT_BUSI_DATA = lt_contracts ).
*    catch /IWBEP/CX_GATEWAY.    "

  data:
        ls_proc_info type /IWBEP/IF_V4_REQU_BASIC_CREATE=>TY_S_TODO_LIST.

  LS_PROC_INFO-PROCESS-BUSI_DATA = abap_true.

  IO_RESPONSE->SET_IS_DONE( IS_TODO_LIST = VALUE #(  ) ).
  endmethod.

Goto Transaction /IWBEP/V4_ADMIN

SAP ABAP Tutorials and Materials, SAP ABAP Certifications, SAP ABAP Guides, SAP ABAP Learning

Click on Register Group

SAP ABAP Tutorials and Materials, SAP ABAP Certifications, SAP ABAP Guides, SAP ABAP Learning

Create a service group with the following settings:

Service Group: ZTEST_SERVICE_V4

Description: Odata V4 Sample Services

Package: $TMP

SAP ABAP Tutorials and Materials, SAP ABAP Certifications, SAP ABAP Guides, SAP ABAP Learning

Click on register

SAP ABAP Tutorials and Materials, SAP ABAP Certifications, SAP ABAP Guides, SAP ABAP Learning

Register the service as shown in the screenshot

SAP ABAP Tutorials and Materials, SAP ABAP Certifications, SAP ABAP Guides, SAP ABAP Learning

Finally you should see the Service we’ve created assigned to the service group we’ve created.

Goto Transaction /IWFND/V4_ADMIN

SAP ABAP Tutorials and Materials, SAP ABAP Certifications, SAP ABAP Guides, SAP ABAP Learning

Click on “Publish Service Groups”

SAP ABAP Tutorials and Materials, SAP ABAP Certifications, SAP ABAP Guides, SAP ABAP Learning

Choose System alias „LOCAL“ and press button „Get Service Groups“

SAP ABAP Tutorials and Materials, SAP ABAP Certifications, SAP ABAP Guides, SAP ABAP Learning

Select the Service Group „ZTEST_SERVICE_V4“ (the group we’ve created) and press „Publish Service Groups“

SAP ABAP Tutorials and Materials, SAP ABAP Certifications, SAP ABAP Guides, SAP ABAP Learning

Leave the settings as they are at the „Publish Service Group“ dialog and click „Ok“. Then create a new transport request an save the settings.

SAP ABAP Tutorials and Materials, SAP ABAP Certifications, SAP ABAP Guides, SAP ABAP Learning

You should see a success message.

SAP ABAP Tutorials and Materials, SAP ABAP Certifications, SAP ABAP Guides, SAP ABAP Learning

Go back to /IWBEP/V4_ADMIN find the service group and select the service and press the button „Service Test“

SAP ABAP Tutorials and Materials, SAP ABAP Certifications, SAP ABAP Guides, SAP ABAP Learning

Choose local gateway system

SAP ABAP Tutorials and Materials, SAP ABAP Certifications, SAP ABAP Guides, SAP ABAP Learning

Now you see the Gateway Client with the metadata url. Press „Execute“ to retrieve the services metadata.

SAP ABAP Tutorials and Materials, SAP ABAP Certifications, SAP ABAP Guides, SAP ABAP Learning

Now we’ve the oData Service description document. Right click in the browser and save it as „odata_v4_service_description.xml“

SAP ABAP Tutorials and Materials, SAP ABAP Certifications, SAP ABAP Guides, SAP ABAP Learning

Additionally we can do some testing. Use the url „/sap/opu/odata4/sap/ztest_service_v4/default/sap/ztest_v4_service/0001/contract“ and Execute

SAP ABAP Tutorials and Materials, SAP ABAP Certifications, SAP ABAP Guides, SAP ABAP Learning

So we see the sample data we’ve provided at the mock data method.

For now, we’ve our oData v4 Test Service and the according service description document. So we can go on to translate the oData Service description to a openApi description.

Download and install the toolset to generate the openApi description


Here we will install the toolset from https://github.com/oasis-tcs/odata-openapi

Open a command window go to a directory of you choice to download/clone the toolset from github:

C:\user\project> git clone https://github.com/oasis-tcs/odata-openapi.git
Cloning into 'odata-openapi'...
remote: Enumerating objects: 206, done.
remote: Counting objects: 100% (206/206), done.
remote: Compressing objects: 100% (82/82), done.
remote: Total 4291 (delta 157), reused 164 (delta 120), pack-reused 4085
Receiving objects: 100% (4291/4291), 6.50 MiB | 28.68 MiB/s, done.
Resolving deltas: 100% (3613/3613), done.

As the toolset is cloned to you local repository change into the odata-openapi subfolder an use npm to install the tool locally:

C:\user\project>cd odata-openapi
C:\user\project\odata-openapi> npm install -g
C:\Users\Administrator\AppData\Roaming\npm\odata-openapi3 -> C:\Users\Administrator\AppData\Roaming\npm\node_modules\oda
ta-openapi\lib\cli.js
+ odata-openapi@0.0.0
added 4 packages from 2 contributors in 1.819s
PS C:\user\project\odata-openapi>

With that we have the toolset installed locally and we can continue and create the openApi specification from the oData Service description.

Generate the openApi description the oData services description


Now give the the oData v4 service description document to the tool odata-openapi3 in order to generate the openApi specification from.

C:\user\project\oDataServiceAsOpenApi> odata-openapi3 --host hostname:port .\odata_v4_service_description.xml

Hint: You can get the hostname from Transaction SICF when searching for service „odata4“ and test the service. You see the host and port at the browser then.

SAP ABAP Tutorials and Materials, SAP ABAP Certifications, SAP ABAP Guides, SAP ABAP Learning

The tool created a file „odata_v4_service_description.openapi3.json“

Open this file in an editor copy the content and go to https://editor.swagger.io/ and paste the files content into the editor pane:

SAP ABAP Tutorials and Materials, SAP ABAP Certifications, SAP ABAP Guides, SAP ABAP Learning

Now we see the v4 oData service described by an openApi description

In order to support at least basic authentication with the java client we will generate apply security settings manually at the openApi specification in the swagger editor. I converted to YAML for convenience.

add the following to the components section:

  securitySchemes:
    basicAuth:     # <-- arbitrary name for the security scheme
      type: http
      scheme: basic

SAP ABAP Tutorials and Materials, SAP ABAP Certifications, SAP ABAP Guides, SAP ABAP Learning

and the following security constraint at the end of file so it’s used for the whole service:

security:
  - basicAuth: [basicAuth]  # <-- use the same name here 

SAP ABAP Tutorials and Materials, SAP ABAP Certifications, SAP ABAP Guides, SAP ABAP Learning

After the security configuration it’s also necessary to care about the service-root path at the service description. So change the following default …/service-root:

SAP ABAP Tutorials and Materials, SAP ABAP Certifications, SAP ABAP Guides, SAP ABAP Learning

to the actual path of our oData service:

SAP ABAP Tutorials and Materials, SAP ABAP Certifications, SAP ABAP Guides, SAP ABAP Learning

Save the modified openApi specification in order to use it later to generate the java client.

Download and build the swagger code generator


To generate the java client from the openApi specification we will next download and build the swagger code generator tool. 

Go to a directory of your choice and clone the repository of the swagger code generator:

git clone https://github.com/swagger-api/swagger-codegen.git

Change into the subfolder swagger-codegen and checkout the version 3.0.9

cd swagger-codegen
git checkout tags/v3.0.9

When checkout is finished start building and packaging with maven

mvn clean package -DskipTests

Building swagger-codegen can take a while, at the you should see a message that the Build was successful. Now we’re ready to generate the java client using the code generator.

Generate and install the openapi client from the openApi description


Although that’s not the best practice we’ll use the generator from its project folder (swagger-codegen) and place the files and output folders there to keep things simple.

To create the java client we create a java-config.json file in the swagger-codegen project folder with the following content:

{
    "modelPackage" : "com.sample.test.model",
    "apiPackage"   : "com.sample.test.api",
    "invokerPackage" : "com.sample.test.client",
    "groupId" : "com.sample.test",
    "artifactId"  : "sample-openapi-client",
    "fullJavaUtil" : true,
    "dateLibrary" : "java8"

We also copy the modified openApi specification into that folder. Here I renamed the file to odata-v4-service-description.openapi.yaml

It’s also necessary to create the empty output folder where the java client is generated to:

mkdir java-sample-client

Then we can call the code generator using the following command:

java -jar .\modules\swagger-codegen-cli\target\swagger-codegen-cli.jar 
generate -i odata-v4-service-description.openapi.yaml 
-l java -c .\java-config.json -o java-sample-client

After that we can see the generated client at the subfolder java-sample-client

SAP ABAP Tutorials and Materials, SAP ABAP Certifications, SAP ABAP Guides, SAP ABAP Learning

To build and install the client to the repository go into this folder and use:

mvn clean install

After that you should see a success message:

SAP ABAP Tutorials and Materials, SAP ABAP Certifications, SAP ABAP Guides, SAP ABAP Learning

As we’ve now created the client and installed it we can now write a program which uses this client to access the oData Rest service running on our abap netweaver.

Build and run a simple java programm which uses the openapi client generated


To create the test program here eclipse with M2Eclipse is used to make usage of maven as simple as possible.

Start eclipse and create a new Project:

SAP ABAP Tutorials and Materials, SAP ABAP Certifications, SAP ABAP Guides, SAP ABAP Learning

SAP ABAP Tutorials and Materials, SAP ABAP Certifications, SAP ABAP Guides, SAP ABAP Learning

Choose Maven project to create a new Maven project.

SAP ABAP Tutorials and Materials, SAP ABAP Certifications, SAP ABAP Guides, SAP ABAP Learning

Check to create a simple project without archetype selection and press next.

SAP ABAP Tutorials and Materials, SAP ABAP Certifications, SAP ABAP Guides, SAP ABAP Learning

Choose your attributes for the artifact and press finish.

Find the pom.xml in the project and add the dependency to the client we generated:

<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.test</groupId>
<artifactId>openapi-test-client</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>OpenApi Test Client</name>
<description>OpenApi Test Client</description>

<dependencies>
<dependency>
<groupId>com.sample.test</groupId>
<artifactId>sample-openapi-client</artifactId>
<version>LATEST</version>

</dependency>
</dependencies>
</project>

Hint: The group id “com.sample.test” and the artifact-id “sample-openapi-client” are the ones we’ve set at the java-client.json configuration we used to generate the client

SAP ABAP Tutorials and Materials, SAP ABAP Certifications, SAP ABAP Guides, SAP ABAP Learning

Use Maven->Update Project to work with the latest repository status

Next create a class with Test program:

package test;

import com.sample.test.api.ContractApi;
import com.sample.test.client.ApiClient;
import com.sample.test.client.ApiException;
import com.sample.test.model.CollectionOfContractType;

public class SampleClient {

public static void main(String[] args) throws ApiException {

ContractApi api = new ContractApi();
ApiClient apiClient = new ApiClient();
apiClient.setUsername("YOURUSERNAME);
apiClient.setPassword("**********");
api.setApiClient(apiClient);
CollectionOfContractType list = 
api.contractGet();
System.out.println(list);
}

}

Replace username and password.

SAP ABAP Tutorials and Materials, SAP ABAP Certifications, SAP ABAP Guides, SAP ABAP Learning

Use maven to build the test program.

SAP ABAP Tutorials and Materials, SAP ABAP Certifications, SAP ABAP Guides, SAP ABAP Learning

Choose the goals “clean package” and run the build.

SAP ABAP Tutorials and Materials, SAP ABAP Certifications, SAP ABAP Guides, SAP ABAP Learning

After successful build run the sample client class as Java Application

SAP ABAP Tutorials and Materials, SAP ABAP Certifications, SAP ABAP Guides, SAP ABAP Learning

Now we can see the mock data we’ve provided in our oData Service retrieved from a java program. The access is transparently. The java client uses openApi standards only and doesn’t need to be aware of the oData implementation behind the scenes.

No comments:

Post a Comment