Skip to Content
Technical Articles

How to use the RAP Generator in SAP S/4HANA on premise?

In this blog I would like to provide a short click-trough so that you know how to generate a RAP BO using the RAP Generator in an SAP S/4HANA on premise system.

When using the RAP Generator in an on premise system you have to do a few things differently than in an SAP BTP ABAP environment system.

The RAP Generator by default generates code using the language version ABAP for Cloud Development*.

Since the language version of objects depends on the language version settings of the package in which the objects are being created you have to create a package that uses the language version “ABAP for Cloud Development”.

The boundary conditions for using the ABAP language version “ABAP for Cloud Development” have been discussed in detail by my colleague Thomas Schneider in his blog post Restricted ABAP and SAP S/4HANA On-Premise | SAP Blogs.

Make sure your system runs at least on top of SAP S/4HANA 2020 FSP1

The RAP Generator requires features and functions of the XCO libraries that have been delivered with on premise systems only as of SAP S/4HANA 2020 FSP1.

It uses in addition the generation of OData V4 services which are alos only supported as of SAP S/4HANA 2020 FSP1.

Use the branch On-premise-2020

The source code of the generator that has been adapted for the use in on premise systems has been published in the branch on-premise-2020 and can be installed using ABAPGIT.

SAP-samples/cloud-abap-rap at On-Premise-2020 (github.com)

Create a package with language version ABAP for Cloud Development

You have to start with creating a new package that has language version ABAP for Cloud Development.

* In principle it would also be possible to generate code in the language version Standard.¬†But this would require to change the code of the RAP Generator class. But I did not want to make it to easy to leave the path of future proof cloud compatible development ūüėČ.

 

Run the RAP Generator

Lets have a look at the following simple example.

Create a table in the package

@EndUserText.label : ' Inventory data group 0001'
@AbapCatalog.enhancementCategory : #NOT_EXTENSIBLE
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #L
@AbapCatalog.dataMaintenance : #ALLOWED
define table zrap_inven_af00 {
  key client            : mandt not null;
  key uuid              : sysuuid_x16 not null;
  inventory_id          : abap.numc(6);
  product_id            : abap.char(10);
  @Semantics.quantity.unitOfMeasure : 'zrap_inven_af00.quantity_unit'
  quantity              : abap.quan(13,3);
  quantity_unit         : abap.unit(3);
  @Semantics.amount.currencyCode : 'zrap_inven_af00.currency_code'
  price                 : abap.curr(16,2);
  currency_code         : abap.cuky;
  remark                : abap.char(256);
  not_available         : abap_boolean;
  created_by            : syuname;
  created_at            : timestampl;
  last_changed_by       : syuname;
  last_changed_at       : timestampl;
  local_last_changed_at : timestampl;

}

and a class to generate your RAP BO.

Please note that the RAP Generator now takes a second (optional) input parameter xco_lib which  when using the on premise version of the RAP Generator in an on premise system has to be of type /dmo/cl_rap_xco_on_prem_lib.

The complete code of the command line class that calls the generator looks like follows:

CLASS zcl_test_rap_gen_002  DEFINITION
 PUBLIC
  INHERITING FROM cl_xco_cp_adt_simple_classrun
  FINAL
  CREATE PUBLIC .

  PUBLIC SECTION.

  PROTECTED SECTION.
    METHODS main REDEFINITION.
  PRIVATE SECTION.

    DATA package_name  TYPE sxco_package VALUE  'Z_DEMO_01'.
    DATA unique_number TYPE string VALUE 'AF00'.
    METHODS get_json_string RETURNING VALUE(json_string) TYPE string.

ENDCLASS.


CLASS zcl_test_rap_gen_002  IMPLEMENTATION.

  METHOD main.

    DATA(xco_api) = NEW /dmo/cl_rap_xco_on_prem_lib( ).
    DATA(json_string) = get_json_string(  ).  

    "create RAP BO
    DATA(rap_generator) = NEW /dmo/cl_rap_generator(
      json_string =  json_string
      io_xco_lib  =  xco_api
    ).

    DATA(todos) = rap_generator->generate_bo(  ).
    DATA(rap_bo_name) = rap_generator->root_node->rap_root_node_objects-behavior_definition_i.
    out->write( |RAP BO { rap_bo_name }  generated successfully| ).
    out->write( |Todo's:| ).
    LOOP AT todos INTO DATA(todo).
      out->write( todo ).
    ENDLOOP.


  ENDMETHOD.


  METHOD get_json_string.

    json_string ='{' && |\r\n|  &&
                 '  "implementationType": "managed_uuid",' && |\r\n|  &&
                 '  "namespace": "Z",' && |\r\n|  &&
                 |  "suffix": "_{ unique_number }",| && |\r\n|  &&
                 '  "prefix": "RAP_",' && |\r\n|  &&
                 |  "package": "{ package_name }",| && |\r\n|  &&
                 '  "draftenabled": true, ' && |\r\n|  &&
                 '  "datasourcetype": "table",' && |\r\n|  &&
                 '  "bindingtype": "odata_v2_ui",' && |\r\n|  &&
                 '  "hierarchy": {' && |\r\n|  &&
                 '    "entityName": "Inventory",' && |\r\n|  &&
                 |    "drafttable": "zrap_invend{ unique_number }",| && |\r\n|  &&
                 |    "dataSource": "zrap_inven_{ unique_number }",| && |\r\n|  &&
                 '    "objectId": "inventory_id"    ' && |\r\n|  &&
                 '    }' && |\r\n|  &&
                 '}'.

  ENDMETHOD.


ENDCLASS.

and press F9.

You should get the following response in the console:

RAP BO ZUI_RAP_Inventory_AF00_O2 generated successfully
Todo's:
Messages from XCO framework
Type: BDEF Object name: ZI_RAP_INVENTORY_AF00 Message: Class "ZBP_I_RAP_INVENTORY_AF00" does not exist. 
Type: BDEF Object name: ZI_RAP_INVENTORY_AF00 Message: If "with draft" is used, flag a "total etag" field.

 

Steps after generation

As indicated by the messages you see above you have to perform some manual steps.

  1. Behavior definitionIn the behavior definition you have to change the the statement lock master and and add total etag LastChangedAt to it.
  2. Generate the behavior implementation classSince the RAP Generator cannot generate the behavior implementation class you have to perform this manual step yourself. You can however used code completion (Press Ctrl+1) to do this.
  3. Now you have to add the statement “use draft;” to the behavior projection
  4. Create and activate the Service BindingSince the RAP Generator cannot generate the Service Binding in SAP S/4 HANA 2020 you have to perform this step manually.Just right click on the Service Definition and select the option to generate the Service Binding from the context menu.

Result

As you can see, the RAP Generator has generated a RAP Business Object as it does it in SAP BTP ABAP Environment.

 

 

9 Comments
You must be Logged on to comment or reply to a post.
  • Hi Andre,

    Thank you for sharing.

    An error occurred on line 166 of /DMO/CL_RAP_GENERATOR due to the lack of the method TRAVERSE.

    The environment is S / 4 2020 (SAP_BASIS 755 SP000).

    • Hi Suzuki,

      sorry, but you are right. You have to have at least FSP1 of SAP S/4HANA 2020 installed.

      This is because the traverse method has not yet been delivered with SAP S/4HANA 2020 FSP00.

      Kind regards,

      Andre

  • Hello,

    I'm really excited to try what you've ported.

    I created  package $ZRAP_GENERATOR and set the language version to ABAP for Cloud Development. I've tried to install it via ABAP Git - but when I want to import the repository I'm getting the following error.

    "Namespace /DMO/ does not exist. Create it in transaction SE03". How can I import Code in this namespace?
    Thanks in advance
    Martin
    • So I tried reading the sap and abapGit documentation...always a good place to start.

      Between the two documentations I was able to create the namespace /DMO/ but it still wasn't modifable.

      To make the namespace modifiable, I used SE03, set system change option. Again more documentation.

      Next problem - importing name space development, can't be done from a $package - so I need to replace $ZRAP_GENERATOR with ZRAP_GENERATOR. Done.

      Unfortunately I still can't import the code. I'm getting errors like these. Can anyone give me a hint?

      Object CLAS /DMO/CL_RAP_GENERATOR cannot be assigned to package ZRAP_GENERATOR Import of object /DMO/CL_RAP_GENERATOR failed

      Just a final thought - would it be possible to refactor these classes from /DMO/ to Z classes? That would make installation much simpler. I have in mind there might be some open source tools that can help here - although I can't name the project right now. I see that ABAP Git distributes its internal Z-Classes and interfaces as local classes/interfaces via abapMerge. Perhaps that could be a solution? Internally use /DMO/ classes and distribute as local classes?

      • Hi,

        I guess you should first create a package with /DMO/ namespace (e.g. /DMO/RAP_GENERATOR) and assign the class to it.

        • Hi,

           

          creating a package /DMO/RAP_GENERATOR did allow ABAPGit to import the project.

          I used the language version standard for this package.

          However there seem to be some restrictions on the usage of these classes outside of /DMO/.

          I get error messages like: Use of Class /DMO/CL_RAP_XCO_ON_PREM_LIB is not permitted.

          My current work around is the create the generator class zcl_test_rap_gen_002 in the /DMO/ package as /dmo/zcl_test_rap_gen_002 (okay - the z isn't really required anymore). Great so...the program activates!

          However the /dmo/cl_rap_gererator has syntax errors. In ABAP Git I changed the branch from master (head) to On-Premise-2020, and the syntax errors went away!

          Finally I'm able to generate RAP objects. Awesome.

          I was hoping to generate the RAP objects from the SAP Fiori Elements course - but there seem to be too many missing features in onPrem / and the class /dmo/cl_fe_travel_generator is much more complicated (many associations to other cds views, etc) than the sample here.

          I managed to complete the manual steps 1-3 - but when I try to create the service binding from the service definition it gives the me the errror "Usage fo ZRAP_INVENTORY_AF00 not permitted". This error message when away when I change the package back to a ABAP standard package