Enterprise Resource Planning Blogs by SAP
Get insights and updates about cloud ERP and RISE with SAP, SAP S/4HANA and SAP S/4HANA Cloud, and more enterprise management capabilities with SAP blog posts.
cancel
Showing results for 
Search instead for 
Did you mean: 
mario-dc
Employee
Employee

Introduction


With the introduction of ABAP Cloud we now have a new, modern ABAP development model to build cloud-ready business apps, services, and extensions. If you are not yet familiar with this innovation, I highly recommend having a look at this introduction and this architectural overview.

A common requirement when developing business applications is the ability to execute certain logic asynchronously. This may be due to a number of reasons. Maybe a large amount of data must be processed, which takes a long time, and the business process shall continue while that takes place. Maybe there is the need for a recurring mass activity that shall run in the background. In any case, asynchronous processing is crucial.

In this blog post I want to lay out the different possibilities that are available with ABAP Cloud. Currently we have three different approaches:

  1. Background Processing Framework (bgPF)

  2. Application Jobs

  3. Eventing


Each option has its own merits and advantages, and it will be up to you to identify which one is the most appropriate for your use case.

A short reminder on the availability of ABAP Cloud: it is enforced on SAP BTP ABAP Environment and SAP S/4HANA Cloud, public edition (Developer Extensibility is available in the 3-system landscape starting with release 2208) and it is available on SAP S/4HANA Cloud, private edition & on-premise (starting with release 2022).

Background Processing Framework


The newest of the features presented in this blog is the background processing framework (bgPF). This provides a simple and straight-forward way to execute custom logic asynchronously, without any configuration overhead. Developers can even decide whether to enforce transactional control for the asynchronously executed logic.

The first step is to create a class that implements either the if_bgmc_op_single (enforcing transactional consistency) or if_bgmc_op_single_tx_uncontr (unontrolled – no enforcement of transactional consistency) interface. The execute method of either interface should contain the logic that shall be executed asynchronously:
CLASS zmdc_bgpf_impl DEFINITION
PUBLIC
FINAL
CREATE PUBLIC .

PUBLIC SECTION.
INTERFACES if_bgmc_op_single_tx_uncontr.
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.



CLASS zmdc_bgpf_impl IMPLEMENTATION.

METHOD if_bgmc_op_single_tx_uncontr~execute.
"Custom code
ENDMETHOD.

ENDCLASS.



The second step is to simply call the logic in question at the desired point in your business process. This is achieved using the previously created custom class and the standard class cl_bgmc_process_factory:
    DATA(new) = NEW zmdc_bgpf_impl(  ).

DATA background_process TYPE REF TO if_bgmc_process_single_op.

TRY.
background_process = cl_bgmc_process_factory=>get_default( )->create( ).
* background_process->set_operation( new ).
background_process->set_operation_tx_uncontrolled( new ).
background_process->save_for_execution( ).
COMMIT WORK. "not needed in RAP since the framework will do that for you

CATCH cx_bgmc INTO DATA(exception).
"handle exception
ENDTRY.

Depending on the context, you may have to trigger the execution with a COMMIT WORK statement. This is not required if the process is triggered from within the RAP runtime, as the framework will trigger the commit.

This feature was initially released with release 2308 for SAP BTP, ABAP environment and SAP S/4HANA Cloud, public edition and with release 2023 for SAP S/4HANA Cloud, private edition and on-premise. Keep in mind that further improvements are planned and will be delivered with future releases.

Application Jobs


Another option for decoupling parts of your code are custom application jobs. Alongside the standard jobs delivered by SAP, you can create your own jobs containing custom code. These can then be scheduled through different means:

  1. Manually by a business user in the corresponding Fiori app (Application Jobs).

  2. Programatically, directly from your custom ABAP code.


An application job is defined by a job catalog entry, a job template and a handler class containing the custom code to be executed. The handler class implements interfaces if_apj_dt_exec_object (for design-time) and if_apj_rt_exec_object (for runtime). Most importantly, the if_apj_rt_exec_object~execute method contains the logic that shall be executed asynchronously:
CLASS zcl_mdc_apj DEFINITION
PUBLIC
FINAL
CREATE PUBLIC .

PUBLIC SECTION.

INTERFACES if_apj_dt_exec_object .
INTERFACES if_apj_rt_exec_object .

PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.



CLASS zcl_mdc_apj IMPLEMENTATION.

METHOD if_apj_rt_exec_object~execute.
" Custom logic
ENDMETHOD.

We then need to make sure that this application job is scheduled. In cases where the business application shall take care of this automatically, it makes sense to make use of the released class cl_apj_rt_api. The code should look something like:
  METHOD schedule.

DATA lv_job_text TYPE cl_apj_rt_api=>ty_job_text VALUE 'Trigger Custom Job'.
DATA lv_template_name TYPE cl_apj_rt_api=>ty_template_name VALUE 'ZMDC_APJ_DEMO_TEMP'.
DATA ls_start_info TYPE cl_apj_rt_api=>ty_start_info.
DATA ls_scheduling_info TYPE cl_apj_rt_api=>ty_scheduling_info.
DATA ls_end_info TYPE cl_apj_rt_api=>ty_end_info.
DATA lv_jobname TYPE cl_apj_rt_api=>ty_jobname.
DATA lv_jobcount TYPE cl_apj_rt_api=>ty_jobcount.

********** Set scheduling options *******************
ls_start_info-start_immediately = 'X'.
ls_scheduling_info-periodic_granularity = ''.
ls_scheduling_info-periodic_value = 1.
ls_scheduling_info-test_mode = abap_false.
ls_scheduling_info-timezone = 'CET'.
ls_end_info-type = 'NUM'.
ls_end_info-max_iterations = 3.
*****************************************************

TRY.
cl_apj_rt_api=>schedule_job(
EXPORTING
iv_job_template_name = lv_template_name
iv_job_text = lv_job_text
is_start_info = ls_start_info
is_scheduling_info = ls_scheduling_info
is_end_info = ls_end_info
IMPORTING
ev_jobname = lv_jobname
ev_jobcount = lv_jobcount
).
CATCH cx_apj_rt INTO DATA(exc).
DATA(lv_txt) = exc->get_longtext( ).
DATA(ls_ret) = exc->get_bapiret2( ).
ENDTRY.
ENDMETHOD.

Finally, we can just call the schedule method as required to trigger some asynchronous processing. You can find a nice tutorial from my colleague Andre Fischer here.

Eventing


As of release 2208, RAP supports the usage of custom RAP events. Such events are easily defined in any custom behavior definition and can then be raised during the save sequence. By executing the relevant business logic everytime the event is raised we can achieve the desired asynchrony.

Events can be consumed locally with minimal configuration effort. They can also be consumed remotely, which requires integration with the eventing infrastructure provided by SAP Event Mesh on SAP BTP (see for example the integration documentation for SAP S/4HANA Cloud, public edition). You will require entitlements for the corresponding BTP services and will need to perform the  corresponding connectivity setup (check out this tutorial for a great guide for SAP BTP ABAP Environment).

Event definition


Define an event by declaring it in your behavior definition as shown below. You will also need to define an additional save method:
managed implementation in class ZCL_MDC_BIP unique;
strict ( 2 );
with draft;

define behavior for Z_I_MDC_EVT alias CustomBO
persistent table zmdc_evt_db
draft table ZMDC_EVT_DB_D
with additional save
authorization master( global )
lock master total etag id
{
create;
update;
delete;

event customEvent parameter ZMDC_Event_Parameter;

This custom event should now be raised in the implementation of the additional save method:
CLASS lsc_z_i_mdc_evt DEFINITION INHERITING FROM cl_abap_behavior_saver.
PROTECTED SECTION.
METHODS save_modified REDEFINITION.
ENDCLASS.

CLASS lsc_z_i_mdc_evt IMPLEMENTATION.

METHOD save_modified.
RAISE ENTITY EVENT z_i_mdc_evt~customEvent
FROM VALUE #( ( Name = 'TestName' Quantity = 10 ) ).
ENDMETHOD.

ENDCLASS.

PUBLISH FOR LOCAL CONSUMPTION

If you are going to consume the event in the same system, then the implementation is already done!

PUBLISH FOR REMOTE CONSUMPTION

If you want to expose the event to the SAP BTP Event Mesh service, you will additionally need to create an event binding in ADT and expose the event to the eventing infrastructure. This will allow consumption of the event from external systems.

For more information, see Business Events.

Event publishing


LOCAL CONSUMPTION

If you are consuming an event locally, in the same system, then you only require a local event handler class. This class inherits from cl_abap_behavior_event_handler and can contain handler methods for different events:
CLASS lcl_abap_behv_event_handler DEFINITION INHERITING FROM cl_abap_behavior_event_handler.

PRIVATE SECTION.

METHODS consume_custom_event FOR ENTITY EVENT event_parameters FOR CustomBO~customEvent.

ENDCLASS.

CLASS lcl_abap_behv_event_handler IMPLEMENTATION.

METHOD consume_custom_event.
" Custom logic
ENDMETHOD.

ENDCLASS.

REMOTE CONSUMPTION

If you are consuming an event from SAP Event Mesh, you instead need to create an event consumption model:


Event Consumption Model


Along with the event consumption model itself, several additional objects are automatically created. The generated handler class (zcl_newevent in the screenshot) contains the event handler methods:
CLASS zcl_newevent DEFINITION
PUBLIC
INHERITING FROM zcl_newevent_base
FINAL
CREATE PUBLIC .

PUBLIC SECTION.
METHODS zif_newevent_handler~handle_zmdctest_create_v1 REDEFINITION.
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.


CLASS zcl_newevent IMPLEMENTATION.
METHOD zif_newevent_handler~handle_zmdctest_create_v1.
"Custom logic
ENDMETHOD.
ENDCLASS.

With that, you can execute some of your business logic asynchronously, either in the original system or in remote systems. For more information, see Business Event Consumption

Summary


You now have 3 different ways of executing code asynchronously when developing with ABAP Cloud. You should analyze your use case and determine which of these options is the best for you.

Feel free to share any interesting use cases that you have encountered and, of course, do not hesitate to post any questions that you may have. We are always happy to help all ABAP developers out there to make the journey into the cloud!
10 Comments
matt
Active Contributor
Please can you edit your blog and use the {;} button for your code instead of screenshots. That way we can easily cut and paste.
afordham
Participant

But the pain of typing it in is what makes you remember it 😉

mario-dc
Employee
Employee
Hi Matthew, thanks a lot for the suggestion. I have replaced the screenshots with actual code.
matt
Active Contributor
0 Kudos
Super. now I can like it! 🙂
pepl
Active Participant
It would be great if SAP also delivers something like JS Promise natively. I have reviewed CL_ABAP_PARALLEL - indeed it does a lot of good stuff to prevent system overload, but parallel execution is not same as async/await logic just because that in fact it still stays synchronous.

I have developed the concept in this project https://github.com/abapify/promise which breaks this paradigm.

You can start some threads, keep working on another things in your code and then come later for results. However it is not possible to use it in the cloud because no RFC functions is allowed ( even if it's allowed internally ).

If SAP would reconsider such limitation and would allow devs to use aRFC ( or similar functionality ) in the cloud abap - that would be a different story.

Unfortunately non of methods mentioned above still cover a case like this without persisting data

  1. start doing this

  2. start doing that

  3. if this is finished..

  4. if that is finished..

  5. if this failed..

  6. if that failed..

  7. if both finished..

  8. if at least one failed..

  9. if first is finished..


And my promises PoC is capable to cover those cases, but not in cloud yet..
Jochen
Explorer
0 Kudos

We are using "Parallel-processing as a special variant of asynchonous RFC" (Link), especially for "mass-invoicing" (Point-of-Sales processing), or mass-data processing in general. It's an rather old framework, but very effective.

An OO-framework (instead of RFC function-calls) would be nice - any plans to do that?

Just found that Blog: Restricted ABAP for SAP BTP ABAP Environment - cl_abap_parallel  -  nice!

thx

afordham
Participant
0 Kudos
It already exists using class CL_ABAP_PARALLEL, if you have access to that.
narios
Explorer
0 Kudos
Dear Mario,

We are using S4 On premise. Still, we would like to have our custom code as cloud-ready as possible. We tried to make use of background processing framework (bgPF) classes to run a process in background (instead of the traditional FM in background task). But, the interface & classes are not available in the on premise S4 version.

Do you know if there are any plans for the release of this functionality in the next S4 Onprem versions?

Thanks

Natalia
AlexanderRother
Advisor
Advisor
Hi Natalia,

yes absolutely. The new bgPF is available with SAP S/4HANA 2023. The full scope will be available in release 2025. Please check the official roadmap for details.

Best regards,
Alexander
SergioFerrariIt
Participant
0 Kudos
bgPF is very promising!

2025 is very far away and I would have hoped to have everything with an FPS by the end of 2024 but there are already lot of features.

Thanks a lot