In this beginner blog post we are going to see how we can use #ISOLATED (Isolated Processing) in ABAP Restful Application Programming Model.
Previous Blog Posts
ABAP RAP – Instance Authorization
ABAP RAP – Global Authorization
ABAP RAP – #CHANGE_SET
Thanks you Ramjee Korada for your help and guidance.
Use Case:
Isolated processing can be used when there is requirement to operate on multiple records with single Action example in list report Application. using #ISOLATED user can enable multi-inline editing on the list control.
Our use case is to update all valid records and leave Invalid (validation failed) records.
As this #ISOLATED is added to List report using UI Annotation @UI.LineItem the action is then processed for all selected records (instances).
Use case is to process valid records leaving Invalid records (per custom validations), in this kind of scenario we can use #ISOLATED for invocation grouping annotation.
With the use of #ISOLATED every record is executed in independent sessions and Valid records can be committed to database leaving Invalid records.
#ISOLATED can be used with
@UI.lineItem
@UI.identification, by adding parameter invocationGrouping to UI annotation
This UI annotation is not specific to ABAP Restful Application Model, but it can be used with any Fiori Application.
#CHANGE_SET VS #ISOLATED
#CHANGE_SET | #ISOLATED |
1- Multiple records can be processed at once | 1- Multiple records can be processed at once |
2- All records must be valid | 2- Only valid records are processed leaving Invalid records unprocessed |
3- Single Session created for processing the records | 3- Multiple Session are created, one per record to be processed |
4- All records are processed in one go | 4- Individual record processed one by one |
Example Implementation:
For demo we are going to create RAP based Fiori Application using Managed scenario and V2 Service type.
In this example we are using V2 Service type because we are not going to Implement Draft capability in our application. As a limitation of RAP architecture if Draft Implementation is not done then application will not display Create and Edit buttons.
Step 1
Created DB Table
@EndUserText.label : 'Student Table'
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #RESTRICTED
define table zrap_stud_5001 {
key client : abap.clnt not null;
key id : sysuuid_x16 not null;
firstname : abap.char(100);
lastname : abap.char(100);
age : abap.numc(4);
course : abap.char(50);
courseduration : abap.numc(4);
status : abap_boolean;
gender : abap.char(1);
dob : abap.dats;
lastchangedat : timestampl;
locallastchangedat : timestampl;
}
Step 2
Created Interface CDS View Entity for reading data from DB table created in previous step
@AbapCatalog.viewEnhancementCategory: [#NONE]
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Interface View Entity for Student'
@Metadata.ignorePropagatedAnnotations: true
@ObjectModel.usageType:{
serviceQuality: #X,
sizeCategory: #S,
dataClass: #MIXED
}
define root view entity ZRAP_I_STUDENT_5001
as select from zrap_stud_5001
{
key id as Id,
firstname as Firstname,
lastname as Lastname,
age as Age,
course as Course,
courseduration as Courseduration,
status as Status,
gender as Gender,
dob as Dob,
lastchangedat as Lastchangedat,
locallastchangedat as Locallastchangedat
}
Created Projection CDS View for Interface view and add annotations.
@EndUserText.label: 'projection View for Student'
@AccessControl.authorizationCheck: #NOT_REQUIRED
@Metadata.ignorePropagatedAnnotations: true
@Metadata.allowExtensions: true
@ObjectModel.usageType:{
serviceQuality: #X,
sizeCategory: #S,
dataClass: #MIXED
}
define root view entity ZRAP_C_STUDENT_5001
as projection on ZRAP_I_STUDENT_5001 as Student
{
@EndUserText.label: 'Student ID'
key Id,
@EndUserText.label: 'First Name'
Firstname,
@EndUserText.label: 'Last Name'
Lastname,
@EndUserText.label: 'Age'
Age,
@EndUserText.label: 'Course Name'
Course,
@EndUserText.label: 'Course Duration'
Courseduration,
@EndUserText.label: 'Status'
Status,
@EndUserText.label: 'Gender'
Gender,
@EndUserText.label: 'DOB'
Dob,
Lastchangedat,
Locallastchangedat
}
Create Metadata Extension for Consumption View. This will help creating UI for Fiori Application
@Metadata.layer: #PARTNER
annotate view ZRAP_C_STUDENT_5001 with
{
@UI.facet: [{ id: 'Student', purpose: #STANDARD,
type: #IDENTIFICATION_REFERENCE,
label: 'Student', position: 10
}]
@UI: {
lineItem: [{ position: 10,
label: 'Update Status',
type: #FOR_ACTION,
dataAction: 'statusUpdate',
invocationGrouping: #ISOLATED
}],
identification: [{ position: 10, label: 'Student ID' }]
}
Id;
@UI: {
lineItem: [{ position: 20, label: 'First Name' }],
identification: [{ position: 20, label: 'First Name' }]
}
Firstname;
@UI: {
lineItem: [{ position: 30, label: 'Last Name' }],
identification: [{ position: 30, label: 'Last Name' }]
}
Lastname;
@UI: {
lineItem: [{ position: 40, label: 'Age' }],
identification: [{ position: 40, label: 'Age' }]
}
Age;
@UI: {
lineItem: [{ position: 50, label: 'Course' }],
identification: [{ position: 50, label: 'Course' }]
}
Course;
@UI: {
lineItem: [{ position: 60, label: 'Course Duration' }],
identification: [{ position: 60, label: 'Course Duration' }],
selectionField: [{ position: 10 }]
}
Courseduration;
@UI: {
lineItem: [{ position: 70, label: 'Status' }],
identification: [{ position: 70, label: 'Status' }]
}
Status;
@UI: {
lineItem: [{ position: 80, label: 'Gender' }],
identification: [{ position: 80, label: 'Gender' }]
}
Gender;
@UI: {
lineItem: [{ position: 90, label: 'DOB' }],
identification: [{ position: 90, label: 'DOB' }]
}
Dob;
}
In above Metadata extension for Projection View we have added parameters to @UI.lineItem annotation to enable Batch processing. Refer below screen shot.
Action Method is added with name statusUpdate.
Step 3
Create behavior Definition for Interface View, also create Class and Implementation as well.
managed implementation in class zbp_rap_i_student_5001 unique;
strict ( 1 );
define behavior for ZRAP_I_STUDENT_5001 alias Student
persistent table ZRAP_STUD_5001
lock master
authorization master ( global )
//etag master <field_name>
{
create;
update;
delete;
action statusUpdate;
field ( numbering : managed, readonly ) Id;
mapping for ZRAP_I_STUDENT_5001 {
//Id = id;
Firstname = firstname;
Lastname = lastname;
Age = age;
Course = course;
Courseduration = courseduration;
Status = status;
Gender = gender;
Dob = dob;
Lastchangedat = lastchangedat;
Locallastchangedat = locallastchangedat;
}
}
In behavior Definition for Interface View we have added action statusUpdate shown in below screen shot.
Create Behavior Definition for Projection View
projection;
strict ( 1 );
define behavior for ZRAP_C_STUDENT_5001 alias Student
{
use create;
use update;
use delete;
use action statusUpdate;
}
Step 4
Create Service Definition for Projection / Consumption View.
Once Service Definition is created
@EndUserText.label: 'Service Defination for Student'
define service ZRAP_EXPOSE_STUDENT_5001 {
expose ZRAP_C_STUDENT_5001;
}
Step 5
Create Service Binding. Activate the Service Bindings and then Publish. Once Published successfully Binding looks like below screen shot.
Step 6
Testing Application:
Select Entity Set name and click on Preview button to run Application. Once Executed Application looks like below Screen shot.
New action button with caption Update Status is added.
As next Step we are going to create List and Object Page Fiori Application using created V2 Service in Business Application Studio.
Once Application is create and run below is output. We got Action Button available correctly but we are still seeing Single select option in List.
Note:
If V2 service is used List report will always show single select option (Radio Buttons)
If V4 service is used List report will always show multi select option (Checkbox)
Now to convert List report from single select to multi select we need to make changes in manifest.json file
Refer below changes in manifest.json file. Once the tableSettings multiSelect property is set to true, List report will show Multi Select option (Checkbox)
Refresh application again and see the Radio Buttons are now replaced with Checkbox on each line.
Once Checkbox are selected Update Status action button gets activated. Now our goal is to update Status field with Yes once Action button is pressed. All selected records should be updated at once.
Step 7
Updating statusUpdate method with core update logic. We have Implemented statusUpdate method.
We have a validation condition which will validate Student Age < 25. If Age is < 25 then record is Invalid and should not be updated with Status = Yes.
if there are any Invalid records in processing system should show Error message for all Invalid Records and also should Update the remaining all Valid records (Age > 25).
Since we have activated the #ISOLATED with @UI.LineItem parameter invocationGrouping
we will be getting all selected record’s keys.
METHOD statusUpdate.
READ ENTITIES OF zrap_i_student_5001 IN LOCAL MODE
ENTITY Student
ALL FIELDS WITH CORRESPONDING #( keys )
RESULT DATA(students)
FAILED failed.
SORT students BY Status DESCENDING.
LOOP AT students ASSIGNING FIELD-SYMBOL(<lfs_students>).
IF <lfs_students>-Age < 25.
APPEND VALUE #( %tky = <lfs_students>-%tky ) TO failed-student.
APPEND VALUE #( %tky = <lfs_students>-%tky
%msg = new_message_with_text(
severity = if_abap_behv_message=>severity-error
text = <lfs_students>-Firstname && ' has Age less then 25, status not updated '
) ) TO reported-student.
ELSE.
<lfs_students>-Status = abap_true.
ENDIF.
ENDLOOP.
IF failed-student IS INITIAL.
SORT students BY Status DESCENDING.
MODIFY ENTITIES OF zrap_i_student_5001 IN LOCAL MODE
ENTITY Student
UPDATE FIELDS ( Status ) WITH CORRESPONDING #( students )
.
ENDIF.
ENDMETHOD.
Once Implementation is completed Activate the changes and Run Fiori Application again and select multiple records from List and execute Update Status Action.
Two records in below Screen shot (Green Box) should get updated because Age > 25.
Select all records and click on Update Status Action button
Valid records are updated, leaving Invalid records and showing Error Message.
Note:
With the use of #ISOLATED every record is executed in independent sessions and Valid data can be committed to database.
Action method will be executed for each record and complete the update in database unlike #CHANGE_SET where all or none record will be updated.