In this post, you will learn about Concurrency handling in OData Services using etags and different ways to implement etags in SAP.

Note: This post assumes that you already know how to create OData Project in SEGW. In case you do not have this knowledge, I suggest going through earlier posts from OData Series.

ETags can also be managed using a field like a timestamp. This concept is covered in the post, Building OData Services [16] : Concurrency handling using ETag with timestamp field.

Implementing ETAG with an Entity Hash

1. Create a table with a hash field.

The hash field need not be put in the table but can be simply generated in the READ / GetEntity method. For simplicity and visualization

2. Create Project & Entity based on the table

3. Set up the ETag field for the Entity

4. Generate the project.

5. Create a new method to get a hash value for the entity. This can be created in the DPC_EXT class or in a separate utility class

Code reference

METHOD calculate_hash.

  DATA : lv_str TYPE xstring.
  EXPORT id = pi_data TO DATA BUFFER lv_str.

  CALL FUNCTION 'CALCULATE_HASH_FOR_RAW'
    EXPORTING
*     ALG            = 'SHA1'
      data           = lv_str
    IMPORTING
      hash           = pe_hash_160
    EXCEPTIONS
      unknown_alg    = 1
      param_error    = 2
      internal_error = 3
      OTHERS         = 4.
  IF sy-subrc <> 0.
    CLEAR pe_hash_160.
  ENDIF.

ENDMETHOD.

6. Implement Read and Update operations i.e. methods CUSTOMERSET_GET_ENTITY and CUSTOMERSET_UPDATE_ENTITY

The hash needs to be calculated in the READ operation.

METHOD customerset_get_entity.

  DATA customer TYPE zcl_jp_etag_hash_mpc=>ts_customer.
  TRY.
      io_tech_request_context->get_converted_keys(
        IMPORTING es_key_values = customer ).

      SELECT SINGLE FROM zjp_customer1
        FIELDS *
        WHERE customerid = @customer-customerid
        INTO CORRESPONDING FIELDS OF @er_entity.
      IF sy-subrc EQ 0.
        er_entity-etag = me->calculate_hash( er_entity ).
      ENDIF.
    CATCH cx_sy_itab_line_not_found.
  ENDTRY.

ENDMETHOD.

In case you have the hash field in the table you can update the hash as well.

METHOD customerset_update_entity.

  io_data_provider->read_entry_data( IMPORTING es_data = er_entity ).

  DATA lv_short_time_stamp TYPE timestamp.
  GET TIME STAMP FIELD lv_short_time_stamp.

  er_entity-changetime = lv_short_time_stamp.
  er_entity-etag       = me->calculate_hash( er_entity ).

  MODIFY zjp_customer1 FROM er_entity.
  IF sy-subrc NE 0.
    CLEAR er_entity.
  ENDIF.

ENDMETHOD.

Implementing ETAG with a Partial-Entity Hash

In this method, the only change is in the method that generates the hash. Pass a structure that has only the required fields from the entity type that are required for hash calculation. The same fields should be used in READ / UPDATE etc.

Testing ETag with Hash

Use Gateway Client (/IWFND/GW_CLIENT) to test the service.

Test GET/READ operation

Request URI /sap/opu/odata/SAP/ZJP_ETAG_HASH_SRV/CustomerSet('01')?$format=json

Use the ETag and payload from the response to create and execute a PUT request.

Request URI : /sap/opu/odata/SAP/ZJP_ETAG_HASH_SRV/CustomerSet('01')
Payload:
{
  "Customerid" : "01",
  "Customername" : "Iron Man 1",
  "Changetime" : "\/Date(1666707359000)\/",
  "Etag" : "A2F1E2DAD4BE6AAAC7BD2C738187E787AAC87D10"
}

Add a new header with Name If-Match and Value as the ETag from the response.

Request

Response

The same request when executed again gives an error as the hash no longer matches.

Visit OData Development in SAP to explore all articles on OData.


If you like the content, please subscribe…

Join 4,010 other subscribers

Discovering ABAP YouTube Channel