I/O Monitoring (UBC.io)
Introduction
UBC - Unified Backend Connector includes a component for I/O monitoring and processing, which provides a comprehensive tool and framework for interface monitoring to and from SAP systems through a single entry point.
Key features:
- Monitor, restart, and edit various messages without environment system involvement in a clearly organized cockpit
- Logging of changes and executions
- Automatic restart functionality
- Logical chaining of processes through queueing
- Structured message search and display
- Alerting with workflow integration
- Easy integration with pre-delivered templates
- No additional licenses required - integrated into the on-premise system
Monitoring and Error Handling
There are two main monitoring and error handling transactions that provide a holistic overview of all messages within the system.
UBC.io is organized by "interfaces," which are logical groupings of one or more technical interfaces (e.g., all MES interfaces related to a production order). Each interface can have attributes that are mapped from the message payload to an index table for structured search and overview in a result list.
I/O Detail Monitor /UBC/IO
This transaction is used for structured searches of selected payload attributes, detailed analysis, and all error handling tasks.
First, select one or more interfaces for messages and further restrict the selection screen (which is an intersection of all available indexed fields and optionally Multi-index fields).
You can select, for example:
- Messages for material 4711 that were sent today
- Messages in an error state
- Messages containing a specific message in their log, e.g., "material is locked"
- And more...
By pressing Execute (F8), the result list will be displayed. As with the selection screen, it shows the intersection of all available indexed fields.
Depending on the interface processing mode (asynchronous/synchronous), the following options are available:
-
Editing messages (asynchronous only) The message will be copied, the old message will be set to status
OBS
, and the new message will be processed according to the processing type -
Restarting messages in error state (asynchronous only)
tipIf the user who triggers the restart is different from the user who initially triggered the message, the following applies:
- The initial user processes the transaction (as the bgRFC unit remains)
- The admin data for the message shows the user who restarted the message as "last changed by"
- The log will show which user processed the transaction. This log message is only displayed if the users (restart vs. processing) are different
-
Acknowledgment of messages in error state (asynchronous only)
-
Copying messages for testing
(Actions are available for multi-selection)
The screen has four main areas:
- Result list (top left) with all indexed fields, actions, etc. Click on the message number to select a message and view details. Selecting a message displays the other parts of the screen.
- Application log (top right) Processing log of a message including all actions that occurred.
- Runs (bottom left) Shows all runs of a message. A "Restart" starts a new run.
- Message payload (bottom right) Grid display of all message contents with options to view and download as JSON
Message Status
The following is a list of all possible message statuses:
ERROR
- The message is in an error state and awaits action (restart, acknowledgment)ACK
- A message in statusERROR
was acknowledgedSUCC
- The message was successfully processed without errorsOBS
- The message was edited. The old message was saved in statusOBS
for research purposes. The new message points to the old messageCOPY
- The message was copied and is ready for processingQUEUE
- The message was saved and awaits processing, which will start as soon as system resources are available or, if a predecessor exists, after the predecessor was processed successfully/acknowledgedPEND
- The message is currently being processedREADY
- The message is ready for processing but needs confirmation by a user who must release it by selecting "Restart" in the monitor (only for processing type Manual processing)
Processing Options (Queue Type)
Both asynchronous and synchronous processing of messages is available.
Synchronous Processing
The message will be processed synchronously. It behaves like any other method call, and the caller doesn't need to consider anything special. Synchronous processing is usually chosen for logging purposes only. Restarting such a message doesn't make much sense and is not possible! If needed for troubleshooting/debugging, copy the message instead.
Asynchronous Processing
No Queue (Transactional)
Messages will be processed in arbitrary order. Choose one of the options below if the messages are not related to each other.
Automatic Processing
Processing of the message starts immediately as soon as resources are available in the system asynchronously.
Manual Processing
New messages are saved in status READY
. Processing of the messages must be triggered by going to the I/O monitoring transaction /UBC/IO
and restarting a message in status READY
. Processing of the message then starts immediately as soon as resources are available asynchronously.
Queue (All Asynchronous Processing)
Messages will be processed in a well-defined order. Choose one of the options below if the messages are related to each other within a queue. The sequence is important!
If the first message in a queue gets stuck due to an error, the queue becomes blocked. Following entries will not be processed until the error of the first message is resolved (by acknowledgment or restart).
The queue key can be freely defined (up to 40 characters total) by concatenating parts of the index table (which was mapped from the message payload) or literals (for further distinction).
For example, messages containing a material need to be posted in a defined order to prevent locking and errors. The following configuration constructs a key like MATERIAL_<<matnr>>
. Best practice: use literals first to distinguish the type of object to queue (in this example: MATERIAL
). The queue key is globally valid across your interfaces.
Every queue key must match a prefix configured in your target bgRFC destination. See the bgRFC configuration section below.
By Creation Timestamp
Entries within a queue are ordered by the creation timestamp (UTC Long) of the message. First in - First out!
By Message Payload Index
You need to additionally specify a field of your index table where the external index is located - mapped from the message payload. An external index is an integer number starting with 1 without gaps. The external index is determined by the sender system and sent within the message payload. This technique is needed, for example, when you have a strict processing order but middleware in place, and you cannot ensure that messages that need to be processed first are also sent first.
Your sender system needs to generate the external index starting with 1.
Let's construct an example:
5 messages will be sent in arbitrary order, all allocated to the same queue:
- Message with Index 1
- Message with Index 3
- Message with Index 2
- Message with Index 5
- Message with Index 4
Using external index ensures messages are processed in the correct order:
- Message with Index 1
- Message with Index 2
- Message with Index 3
- Message with Index 4
- Message with Index 5
Processing of the next message in a queue waits until it was written to the queue and then unlocks the processing.
Queue Monitor /UBC/IO_QUEUE
This transaction provides an overview of all messages currently organized by a queue. You can see the reasons why messages are waiting (predecessors) and view details. You can jump to the monitor by selecting messages and clicking "monitor".
Development
This section contains all information needed for developing a new interface, from customizing to development.
Customizing
Interfaces
Start with transaction /UBC/IO_C
to define new interfaces.
-
Interface name and description As mentioned, UBC.io is organized by interfaces where multiple technical interfaces referring to the same logical unit (e.g., MES interfaces to a production order) are grouped logically. Interface name is unique, description can be translated.
-
Index table An index table is intended to hold administrative data for a message such as "status," "creation date," etc. It's a customer-created table with a fixed signature (see templates) that enables adding custom fields in a dedicated include and mapping message payload data to an index table. In the generic monitoring transactions, you can search/filter on all fields in an index table. You can also define "Jumps" to transactions using custom logic in BADIs. If no index table is specified, a default index table is used.
-
Queue type (see Processing options)
-
bgRFC destination If the chosen queue type is asynchronous, you must define a valid bgRFC inbound destination where entries for an interface will be processed (see system setup)
-
Message Index If the chosen queue type is
Message payload index
, you must specify the name of the field in your index table where the external index is stored for queueing. -
Mapping class (optional) The given mapping class can override the standard behavior, which applies the customizing field mapping. The mapping class must implement the interface
/C09/IF_CIO_MAP_IDX_SINGLE
. For implementation examples, see default implementation/C09/CL_CIO_MAP_IDX_SINGLE
. If the field is empty, the default implementation applies the customizing. Overriding this behavior makes sense when there is complex calculation logic that cannot be defined by customizing. -
Function class (optional) I/O monitoring implementation, inheriting from
/C09/CL_CIO_LIST
to override some default behavior if needed. If not specified, the default implementation is used. Not needed in most cases. Prefer using BADIs if possible.
Assign Technical Interfaces to UBC.io Interface
The basic concept is that individual functions will be organized by logical I/O interfaces. When a function is triggered, the UBC.io interface is assigned by the runtime. Most of the time this is a 1:1 assignment of function to interface. Technically, a function is a customer-specific class Z_
/Y_
that implements the interface /UBC/IF_IO_OPERATION
and defines the logical message structure (holds all information needed for processing a specific message).
Field Mapping
Field mapping is used to map message payload to index table fields for searching/indexing/queueing/overview purposes.
-
Order Mapping order, just increment in customizing defining mapping sequence (most of the time not relevant).
-
Field path Mapping path to specific field in payload:
The F4 Help assists in choosing fields
- Deep navigation: structures/tables separated by -
- Use search help (F4) for navigating within your payload (if type is known statically)
- Supports
[]
for tables- Access specific index by specifying the index, e.g., [1]
- Access by specific fields in table (only supporting
AND
condition), e.g.,[fieldA=ABC and fieldB='']
- Supports substring functionality for elements, e.g.,
fieldA+1(1)
(Offset 1, Length 1 of content in fieldA)
-
Fieldname table Fieldname in index table, custom include.
-
Optional By default, all mappings that cannot be successfully executed (missing table entry, etc.) result in an error (writing to application log, message in status
ERROR
). Check this checkbox to simply leave the target empty.
Multi Steps (LUWs)
An inbound interface can have more than one LUW. For example, when dealing with multiple goods movements in one interface, you must commit each goods movement.
To be restartable, an interface should consist of only one LUW (commit or not).
To fulfill the above requirement, you can configure "multi steps" interfaces to support more than one LUW, controlled by a single interface (and a top-level operation defining the message payload). Please see implementation details: Multi Step Interfaces.
In this scenario, your top-level operation, entered in section Assign technical interfaces to UBC.io interface, is just for defining the message payload, which will be shared across the configured steps.
-
Step Number Key of the table + the defined execution order of the steps. The execution order is by the sequence of steps, either processing started where the execution last stopped due to an error OR with the first step
-
Class name, implementing the Step interface executing Step logic
-
Commit mode Since no Step logic should ever contain a
COMMIT WORK
orROLLBACK WORK
, specify the commit mode after each step. -
Continue on Error Ignore errors, complete step, and continue with execution.
-
Restart always If step 10 was completed and 20 fails, on restart step 10 will not be executed again. Except in the case that step 10 was marked as "restart always."
Multi-Index Tables
Sometimes there are more complex use cases where you would like to search for field values in a table. Imagine having a payload like:
{
"order_header": {
"incoterm": "abc",
"shipTo": 4711
},
"order_items": [
{
"material": "123",
"plant": "0001"
},
{
"material": "456",
"plant": "0002"
},
{
"material": "789",
"plant": "0003"
}
]
}
You may want to search for messages regarding material "456". Since order_items
is a table, it cannot be mapped to a flat single index table for searching.
This is where "Multi-Index tables" comes in.
-
Multi-Index table A Multi-Index table is intended to have an entry for every line in the specified table. It's a customer-created table with a fixed signature, see templates: copy table
/UBC/IO_TTPLMIDX
and replace the fieldsmatnr
andcharge
with your custom ones. In the generic monitoring transactions, you can search for all fields in the multi-index table out-of-the-box. Please note that this only applies to the selection screen, as this doesn't really make sense for the result list.warningSince the Multi-Index and Single Index tables are different ones, the results are technically combined with "logical AND". If one entry in the list of "multi-index entries" is matching, the message is considered a match.
-
Base path Specify a tabular component within your actual payload structure. The standard implementation currently only supports tables, not tables within tables. You are free to use expressions like
item[1]-schedules
, butitems-schedules
is not supported. The last component needs to be a table to be considered for the multi-index set. -
Mapping class (optional) The given mapping class can override the standard behavior, which applies the customizing for field mapping at the level below. The mapping class must implement the interface
/C09/IF_CIO_MAP_IDX_MULTI
. For implementation examples, see default implementation/C09/CL_CIO_MAP_IDX_MULTI
. If the field is empty, the default implementation applies the customizing. Overriding this behavior makes sense when there is complex calculation logic that cannot be defined by customizing.
Field mapping For details, please see section field mapping. The same applies here, with the following additions/restrictions:
- The base path (see above) will be respected, so you will have only elements available for the standard mapping contained in the specified table.
(in this example: only elements contained in
IT_ITEM
specified above, you are free to apply the well-known mapping syntax here) - All mappings are optional, not throwing any error
Coming back to our initial example, that means we have 4 index table entries in general:
- 1 for the message itself in the single index table
- 3 entries in the Multi-Index table
The generic I/O monitor respects the Multi-Index entries and adds the fields to the selection screen as well.
Acknowledge Function
On the Function level, an acknowledge function can also be assigned. The function will be called when a message is acknowledged. It is useful, for example, when we need to send additional information to a subsequent system. The implementation is similar to a step in a "Multi Step scenario", basically a class implementing the interface /UBC/IF_IO_OPERATION_ACK
. See template class /UBC/CL_IO_TEMPLATE_SINGLE_ACK
for example.
Queue Keys
Mapping from Index Table Fields and/or Literals to Queue keys. Please consider the following best practice to avoid queue name conflicts: as a queue prefix, always start with the type the queue key represents.
For example:
You can see that the queue starts with the literal MATERIAL_
and then adds the material number. A queue example would be MATERIAL_4711
.
By default, alpha conversion is applied to a field value. The queue key will be concatenated according to the given sequence. You are free to add as many fields and literals to your queue key as needed. Just consider the limit of 40 characters total.
Auto Restart
First, define an Auto Restart group in View Cluster Entry restart groups
. This defines the "maximum runs" and wait time between runs.
You must assign specific combinations of T100
Message-Id and -Number. As soon as the error of an interface contains a message configured in its Auto Restart group, it will be considered. If an error message is not configured within the restart group, it will not be considered.
The following applies for the Message Keys:
- For Message Number, make sure to specify the full key with leading zeros (
001
and not1
) - You are allowed to use patterns like
*
and+
for Message Class and Number - If you leave a field (Message Class or Number) empty, it acts like a
*
wildcard for that field
For example, you will define the T100
Message Combination for "Message is locked" and define that the restart can be tried again in 5 minutes for 3 attempts.
If the material is locked again, the message won't be auto-restarted again.
Finally, the Auto Restart Group needs to be assigned to an Interface Function assignment at level functions
in view cluster.
Auto restart only makes sense for asynchronous interfaces, as for synchronous the caller usually waits for the response to process it. Thus, the Auto restart feature only respects asynchronous messages.
Workflow Integration
The concept for Workflow Integration is the same as for Auto Restart Groups.
-
Create a workflow definition and implement the workflow, transaction
/C09/CONFLOW_C
. Please note that currently, only UBC.flow workflows are supported! See product documentation for detailed and generic infos. Since this is highly customer-specific, we cannot provide an out-of-the-box implementation. Please see below for an example as a quick start. -
Link the newly created workflow to the interface: Starting with Transaction
/UBC/IO_CFL_C
, create a Workflow Group. -
In the view cluster entry
mapping groups <> messages
, assignT100
Message-Id and -Number combination and a target Workflow-Definition-Id to be started. For every matching message in a message run, the target Workflow will be started.
Workflows will be triggered only if the message is not auto-restartable anymore, meaning the maximum retries were reached or auto restart was not configured.
Example use case:
Alerting an erroneous message by given message, e.g., "Material is locked."
At first glance, triggering workflows for alerting seems complicated. But most of the time, it is highly recommended not to just trigger emails. Instead, we can easily use dialog work items and model more complex workflows if needed. Using the workflow approach, we can stick to the same procedure and just change some customizing. Start simple (only with mail alerting) and refine the flow if needed.
:::
Example Implementation
In the following, we provide an example implementation of a workflow that just triggers an email. See above for linking the workflow definition to the T100
message.
-
Create the workflow definition in
/UBC/FLOW_C
-
Go to Approval steps and create all possible workflow steps.
tipX0, X1, and X2 are predefined ones and should always be created.
-
Go to User Status Definition and create user status for involved user groups. Best practice is to have at least Initiator and Background.
-
Go to User Status Assignment and assign users to your user groups. Depending on whether you would like to transport the entries, choose the right entry in the view cluster.
warningMake sure to use one OR the other. Entries in both are not supported.
-
Define the actual flow by switching to Approval status - control. Always start with X0 and end with X1 or X2. Here, the one and only background step does not have any action assigned and always results in OK. The workflow then ends directly after sending the mail.
-
Optionally define mail settings by switching to Control mail setting. You are free to configure mail hooks by reaching certain results of the step.
Here is an example of the resulting mail:
A few notes:
- The HTML template
/UBC/S17_MAIL_TEMPLATE
was used and is delivered with every UBC installation. You are free to use your own HTML mail template. Just upload a new one in transactionSMW0
; you may copy from the existing template. - The Subject and Text Text-IDs are maintained and translated in transaction
SO10
. Make use of variables.- Subject
ZUBC_DEMO_SUBJECT_113
- Text
ZUBC_DEMO_ERROR_113
- Subject
- The HTML template
-
Now create an implementation for your workflow by creating a BADI and filtering (!) to your definition.
-
Please find the example ABAP implementation below.
class zubc_cl_cfl_badi_113 definition
public
create public.
public section.
interfaces if_badi_interface.
interfaces /c09/cfl_if_badi_0101.
protected section.
methods get_io_attributes
importing
iv_instid type /c09/cfl_s01-instid
exporting
ev_msg_id type /c09/cio_msgguid
ev_ifname type /c09/cio_ifname.
methods get_io_message
importing
iv_instid type /c09/cfl_s01-instid
returning
value(ro_result) type ref to /c09/cl_cio_msg.
private section.
endclass.
class zubc_cl_cfl_badi_113 implementation.
method /c09/cfl_if_badi_0101~execute_default_method.
" jump to I/O when clicking on linked object
get_io_attributes( exporting iv_instid = /c09/cfl_cl_workflow_0101=>ms_instances-instance->ms_data-instid
importing ev_msg_id = data(lv_msg_id)
ev_ifname = data(lv_ifname) ).
call function '/C09/CIO_START'
exporting
p_skip_se16n = abap_true
irt_ifname = value /c09/if_cio=>trt_ifname( ( sign = 'I' option = 'EQ' low = lv_ifname ) )
irt_msgguid = value /c09/if_cio=>trt_msgguid( ( sign = 'I' option = 'EQ' low = lv_msg_id ) ).
endmethod.
method /c09/cfl_if_badi_0101~get_add_attachments.
" add link to I/O as Attachment to mail
get_io_attributes( exporting iv_instid = is_data-instid
importing ev_msg_id = data(lv_msg_id)
ev_ifname = data(lv_ifname) ).
try.
insert lines of /ubc/cl_tools=>get_instance( )->get_gui_transaction_shortcut(
iv_name_base = 'Shortcut'
iv_transaction = /ubc/if_constants=>mc_cio-transaction_single-tcode
it_parameter = value #(
( name = /ubc/if_constants=>mc_cio-transaction_single-parameters-message_id value = lv_msg_id )
( name = /ubc/if_constants=>mc_cio-transaction_single-parameters-interface_name value = lv_ifname ) ) )
into table ct_attachment.
catch /ubc/cx_core.
endtry.
endmethod.
method /c09/cfl_if_badi_0101~get_datasource_mail.
try.
data(lo_msg) = get_io_message( is_data-instid ).
if lo_msg is not bound.
return.
endif.
" for usage in SO10 text variables, e.g. &/C09/CIO_IDX_ADMIN_EXTERNAL-NAME&
/c09/cfl_cl_helper_0101=>add_datasource_mail( exporting is_datastruc = lo_msg->mr_admin->_external
changing ct_application_input = ct_application_input ).
data(lo_tools) = /ubc/cl_tools=>get_instance( ).
" set messages, link with SO10 main text
data(lt_message) = lo_tools->convert_messages_bal_2_bapiret( lo_msg->get_bal_messages( ) ).
insert value #(
tdname = 'LOG_MESSAGES'
tlines = lo_tools->convert_text_to_tlines_flat( lo_tools->build_html_table_for_bapiret2( lt_message ) ) )
into table ct_so10_text ##NO_TEXT.
" add webgui link, link with SO10 main text
data(lv_link) = lo_tools->get_gui_transaction_link(
iv_transaction = /ubc/if_constants=>mc_cio-transaction_single-tcode
it_parameter = value #(
( name = /ubc/if_constants=>mc_cio-transaction_single-parameters-message_id value = lo_msg->mr_key->msgguid )
( name = /ubc/if_constants=>mc_cio-transaction_single-parameters-interface_name value = lo_msg->mr_admin->name ) ) ).
insert value #( tdname = 'WEBGUI_LINK'
tlines = lo_tools->convert_text_to_tlines_flat( lv_link ) )
into table ct_so10_text ##NO_TEXT.
catch /ubc/cx_core.
endtry.
endmethod.
method /c09/cfl_if_badi_0101~get_description.
data(lo_message) = get_io_message( is_data-instid ).
if lo_message is not bound.
return.
endif.
replace first occurrence of '&MSG&' in cv_description with |{ lo_message->mr_admin->msgnumber alpha = out }|.
replace first occurrence of '&IF&' in cv_description with lo_message->mr_admin->name.
endmethod.
method /c09/cfl_if_badi_0101~get_object_info.
cv_return = 'I/O message'(001).
endmethod.
method get_io_attributes.
/c09/cl_cio_cfl=>get_instance( )->get_attributes_for_instid( exporting iv_instid = iv_instid
importing ev_msg_id = ev_msg_id
ev_ifname = ev_ifname ).
endmethod.
method get_io_message.
get_io_attributes( exporting iv_instid = iv_instid
importing ev_msg_id = data(lv_msg_id)
ev_ifname = data(lv_ifname) ).
check lv_msg_id is not initial.
ro_result = /c09/cl_cio_msg=>get_instance( iv_msgguid = lv_msg_id
iv_ifname = lv_ifname ).
endmethod.
endclass.
Implementation
Please ensure the following:
- Implement your solution without technical errors (“no shortdumps”).
- Return meaningful errors from your interfaces (
IO_OPERATION->MESSAGES
) and avoid statements that interrupt message processing unexpectedly, such asMESSAGE TYPE 'E'
.
Failure to follow these guidelines will break the persistence rules and may result in inconsistencies such as:
- Missing runs
- Status shown as "Pending" instead of "Error"
While these issues may not be critical from a transactional perspective, they are undesirable from an error-handling perspective and may lead to user confusion.
Every Top-Level "Operation" Class must implement the interface /UBC/IF_IO_OPERATION
. Every public and non-read-only attribute of the class will be visible and accessible by UBC.io, meaning it is available for mapping, monitoring, queueing, etc. In most cases, it is recommended to pass values via the CONSTRUCTOR
(an OO best practice). The object itself is serialized during UBC processing, ensuring that all values are restored on restart and passed to subsequent steps.
Messages generated during processing must be appended to IO_OPERATION->MESSAGES
. These messages determine the Message Status after processing and populate the application log.
Single Operation Interfaces
For interfaces that do not require multiple steps, it is often sufficient for the Top-Level "Operation" Class to execute the interface logic directly. To achieve this, simply implement the interface /UBC/IF_IO_SINGLE_OPERATION
in your class. Define your attributes according to the message input and implement the method /UBC/IF_IO_OPERATION_STEP~EXECUTE
to perform the business logic. Refer to the template class /UBC/CL_IO_TEMPLATE_SINGLE
for an example.
class /ubc/cl_io_template_single definition
public
create public.
public section.
interfaces /ubc/if_io_single_operation.
methods constructor
importing
matnr type matnr
werks type werks_d.
"every public attribute is visible for I/O
data matnr type matnr.
data werks type werks_d.
protected section.
private section.
endclass.
class /ubc/cl_io_template_single implementation.
method constructor.
me->matnr = matnr.
me->werks = werks.
endmethod.
method /ubc/if_io_operation_step~execute.
"#TODO: actual implementation goes here
"if matnr = '4711'.
"endif.
"insert value #( msgid = 'V1' msgno = '899' msgty = 'S' msgv1 = 'processing OK' ) into table io_operation->messages.
endmethod.
endclass.
Multi-Step Interfaces
-
The Top Level "Operation" Class simply needs to implement the interface
/UBC/IF_IO_MULTI_OPERATION
and to define the message payload. See template class/UBC/CL_IO_TEMPLATE_MULTI_OP
for example.class /ubc/cl_io_template_multi_op definition
public
create public.
public section.
interfaces /ubc/if_io_multi_operation.
methods constructor
importing
matnr type matnr
werks type werks_d.
"every public attribute is visible for I/O
data matnr type matnr.
data werks type werks_d.
protected section.
private section.
endclass.
class /ubc/cl_io_template_multi_op implementation.
method constructor.
me->matnr = matnr.
me->werks = werks.
endmethod.
endclass. -
The "Step Class" needs to implement the interface
/UBC/IF_IO_OPERATION_STEP
and also the method/UBC/IF_IO_OPERATION_STEP~EXECUTE
to execute the business logic. For data access, the importing parameterIO_OPERATION
needs to be casted to the actual type. See template class/UBC/CL_IO_TEMPLATE_MULTI_STEP
for example.class /ubc/cl_io_template_multi_step definition
public
create public.
public section.
interfaces /ubc/if_io_operation_step.
protected section.
private section.
endclass.
class /ubc/cl_io_template_multi_step implementation.
method /ubc/if_io_operation_step~execute.
"#TODO: actual implementation goes here
"data from operation
"if cast /ubc/cl_io_template_multi_op( io_operation )->matnr = '4711'.
"endif.
"insert value #( msgid = 'V1' msgno = '899' msgty = 'S' msgv1 = 'processing step OK' ) into table io_operation->messages.
endmethod.
endclass.
Triggering Interfaces ("Operations" only)
- The Customizing was done for your top-level "Operation" class
- The class needs to be constructed and passed to the
/UBC/CL_IO_PROCESSOR=>INSTANCE->HANDLE()
method. The framework itself respects both cases: multi-steps and single operation, and takes care of the rest: execution, persistence, restartability, etc.Normally, a COMMIT is executed afterwards to trigger asynchronous processing and completion. This can be prevented by setting method parameter
IV_COMMIT = ABAP_FALSE
.
See template /UBC/CL_IO_TEMPLATE_CALL_DEMO
for example or:
/ubc/cl_io_processor=>instance->handle( new /ubc/cl_io_template_single( matnr = '4711' werks = '0001' ) ).
Again, make sure to have no explicit commits within your processing, as this will be controlled by the framework and would destroy restartability. If it is technically needed (for e.g., posting multiple goods movements), consider using the Multi-Step Approach.
Templates
To speed up development, there are ABAP templates for the use of single operations and multi-step operations.
Please have a look at the package /UBC/IO_TEMPLATE
.
Business Add-Ins (BADIs)
There is one enhancement spot called /C09/ES_CIO
, containing:
Interface Determination with /C09/BADI_CIO_FUNC
Basically, an assignment of Top Level "Operation" Class to an Interface has to be unique. If this is not possible (used in multiple scenarios), this BADI has to be implemented.
The target interface will be determined by the message payload in method /C09/IF_BADI_CIO_FUNC->DETERMINE_INTERFACE()
.
Add Dynamic Selection Fields with /C09/BADI_CIO_DATA
The BADI implementation can add specific logic to an Interface by implementing the interface /C09/IF_BADI_CIO_DATA
.
System Setup
Technical setup is part of UBC system setup, so please execute the setup task list first with transaction /UBC/SETUP_BASIC
.
bgRFC Configuration
To set up bgRFC processing, follow these steps:
- Create supervisor destination - optional, not needed if bgRFC is already set up for your system
The next steps depend on whether you want to use multiple bgRFC destinations for your interfaces or just use "one destination" for all of your UBC.io interfaces. Here you will find the steps needed to create a bgRFC destination + scheduler.
-
Create inbound destination The convention is that your name starts in your namespace (Z/Y). Here is an example of how to create the destination ZUBCIO_INBOUND:
A few notes:
- The server group (see transaction
RZ12
) should not be empty. Consider using at least standardparallel_generators
. By not specifying a server group, the bgRFC uses all qualified servers in an SAP System according to automatic resource-allocation rules. However, by defining server groups, you can control which servers can be used for parallel processing. An RFC group specifies the set of allowed servers as well as a mechanism to avoid overloading, e.g., "use only 75% of max. allowed dialog processes." - Prefixes
A new prefix is needed for every queue in your UBC.io customizing.
So for example, if your queue starts with the literalswarning
Without queue prefix, no queued processing!
MATERIAL_
, then you have to enter this prefix so that bgRFC queueing works correctly.
- The server group (see transaction
-
Create inbound scheduler Best practice: create the scheduler settings for your newly created destination.
You can experiment with the maximum possible parallelization by changing "Open Connections"
Auto Restart Job
If you decide to configure Auto Restart, a job needs to be scheduled to trigger Auto Restart after configured deadlines.
To do so, schedule a job for Report /C09/CIO_AUTORESTART
with a period of 1 Minute
. The auto restart of a single message does not get triggered as long as the minimum wait time has not been reached.
Authorization
The authorization object /UBC/IO_IF
is used for restricting the usage of UBC.io interface monitors (Main Monitor /UBC/IO
and Queue Monitor /UBC/IO_QUEUE
). Since UBC.io is organized by interfaces, the authorization object is also designed for restricting activities of specific interfaces.
The following authorization fields are provided:
-
/UBC/IO_NM
: interface name to restrict for, as chosen in UBC.io customizing (see/UBC/IO_C
) -
ACTVT
: allowed activity/activitiesPossible values are:
- 03 (Display) Restricts the display of messages. If no display activity is maintained for a specific interface, the message will not be shown in the I/O monitors.
- 91 (Reactivate)
Restricts the availability of operation
Restart
in I/O monitors. - 04 (Print, edit messages)
Restricts the availability of operation
Edit
in I/O monitors. - 90 (Copy)
Restricts the availability of operation
Copy
in I/O monitors. - 31 (Confirm)
Restricts the availability of operation
Acknowledge
in I/O monitors. - 02 (Change)
This activity acts as a collective one that includes all the changing operations from above:
- Restart
- Edit
- Copy
- Acknowledge
tipWe recommend using the dedicated activities mentioned above.
Data Archiving
UBC.io comes with a dedicated Archiving Object /C09/CIO
, used to archive all data that was persisted to monitor and process the messages.
As with most SAP standard applications, archive runs are scheduled within transaction SARA
.
The write step offers multiple options to select the messages. Please note that only messages will be archived that are in a completed state. Only own persistence:
- Index table entries
- Workflows in a completed step started by workflow integration, see Workflow Integration
will be archived.
The write step does not trigger data archiving of a connected business object or IDOC.
If needed, data archiving can also be included in customer archiving routines, calling methods of /C09/IF_CIO_ARC_MSG_SERVICE
.