Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
Andre_Fischer
Product and Topic Expert
Product and Topic Expert
42,336

Updates



  • 12.05.2017

    • added code to lock the data before comparing the time stamp of the last change date with the time stamp read from the etag in the update method.



  • 16.05.2017

    • fixed MPC_EXT code that creates the function import

    • added code to lock the data before comparing the time stamp of the last change date with the time stamp read from the etag in the function import




Introduction


SAP Gateway offers an out of the box support for etags if a property of an entity type is marked as an etag. When using the generic framework support the following happens when using eTags.

Before an update is performed the Gateway framework on the hub performs a READ request and compares the Etag send by the client with the Etag retrieved from the backend. The Etag handling offered by the framework does not require any coding but it requires that the GET_ENTITY method has to be implemented. The generic SAP Gateway framework support is offered for read, update and delete requests.

Instead of using the generic framework support it is possible to perform a code based implementation in the SAP Business Suite backend system.

This has some advantages since it allows the developer to lock the data while checking the etag before the update is performed. When using the out of the box framework support this is not possible and you cannot be 100% sure that another user has updated the data in the short timeframe between the read request of the framework and your update request.

The second advantage is that a code based implementation also offers etag support for function imports.

The handling of etags in the backend is available as of SAP Gateway 2.0 SP09 and SAP NetWeaver 740 SP08. You have to implement some methods where you have to add code to tell the framework that the data provider class has implemented ETag handling.

Prerequisites


This blog is based on an OData service that has been desrbied in my following blog:

https://blogs.sap.com/2016/06/02/odata-service-development-with-sap-gateway-using-cds-via-referenced...

What are etags?


Etags are usually timestamps that are updated when an entity is updated. For more complex scenarios however timestamps might not be the best choice and a hashtag is the better approach. How to implement a hash tag based etag has been described in the following blog https://blogs.sap.com/2016/03/18/maintain-data-concurrency-in-odata/ by thiru.siva

 

How to annotate a property as an etag?


When doing code based development you can select the property that should be used as an etag on entity type level.



If you have used the referenced data source approach you have to perform these changes in the DEFINE method of the model provider extension class.

In the define method of the OData service that we used in the following blog

we will have to add to lines to set the property 'LastChangedDateTime' as an etag for the entity type   'Zsepm_C_Salesorder_TplType'.

 
  method define.

data lo_entity_type type ref to /iwbep/if_mgw_odata_entity_typ.
data lo_property type ref to /iwbep/if_mgw_odata_property.

super->define( ).

lo_entity_type = model->get_entity_type( iv_entity_name = 'Zsepm_C_Salesorder_TplType' ).
lo_property = lo_entity_type->get_property( iv_property_name = 'SalesOrder_Text' ).
lo_property->set_updatable( abap_true ).

lo_property = lo_entity_type->get_property( iv_property_name = 'LastChangedDateTime' ).
lo_property->set_as_etag( ).

endmethod.

 

Testing the out of the box ETag framework support


After you have implemented these changes you will get the following error message when trying to perform an update with the http status code 428 Value "Precondition Required".
<message xml:lang="en">The Data Service Request is required to be conditional. Try using the "If-Match" header.</message>

This check is done by the SAP Gateway framework on the hub.

We have to add an if-match HTTP header with a value like this:

W/"datetimeoffset'2017-05-05T09%3A15%3A05.6050000Z'"

In the Gateway Client you can easily add this header as shown in the following screen shot.



If we now perform the update request again we will receive an empty http response with the http returncode 204 which indicates that the update was successful.



If you try to perform the update without changing the value of the etag you will receive the error message Precondition Failed with an http return code 428.


Code based implementation of ETag support for updates


/IWBEP/IF_MGW_APPL_SRV_RUNTIME~GET_IS_CONDITIONAL_IMPLEMENTED


We first have to implement the method /IWBEP/IF_MGW_APPL_SRV_RUNTIME~GET_IS_CONDITIONAL_IMPLEMENTED by adding the following code
  method /IWBEP/IF_MGW_APPL_SRV_RUNTIME~GET_IS_CONDITIONAL_IMPLEMENTED.
* conditional handling set for Employee update and patch operations
IF iv_entity_set_name EQ 'Zsepm_C_Salesorder_Tpl' AND
( iv_operation_type = /iwbep/if_mgw_appl_types=>gcs_operation_type-update_entity OR
iv_operation_type = /iwbep/if_mgw_appl_types=>gcs_operation_type-patch_entity ).
rv_conditional_active = abap_true.
ELSE.
rv_conditional_active = abap_false.
ENDIF.
endmethod.

Please note that the name of the enity set of our service that we have created using referenced data source and Service Builder is called 'Zsepm_C_Salesorder_Tpl'. For other entity sets the framework would handle the Etag support.

Since the SAP Gatway Hub framework does now not perform the etag handling we have to add the follwing code into our update method because otherwise all updated request would be performed without checking the content of the etag.

Add Etag check to the update method


We now have to code to the update method that first checks whether the sales order has not changed by comparing the value of the last changed date with the value provided by the update request in the if-match header.

For this we use the get_conditional_info method of the  io_tech_request_context object. This method returns if_match as well as if_non_match headers in a deep structure that we have to evaluate.

In addition we are locking the sales order that we want to update before performing the update.

The lock is released if not updated is performed if the check of the etag fails.

If you add a break-point into the code you can see that a lock is aquired in transaction SM12.


Source code ZSEPM_C_SALESORD_UPDATE_ENTITY


    method ZSEPM_C_SALESORD_UPDATE_ENTITY.

data: lt_keys type /iwbep/t_mgw_tech_pairs,
ls_key type /iwbep/s_mgw_tech_pair,
ls_so_id type bapi_epm_so_id,
ls_headerdata_update type bapi_epm_so_header,
ls_headerdatax type bapi_epm_so_headerx,
ls_headerdata_key type zcl_ze2e100_xx_2_mpc=>ts_zsepm_c_salesorder_tpltype,
ls_headerdata_payload type zcl_ze2e100_xx_2_mpc=>ts_zsepm_c_salesorder_tpltype,
lt_return type table of bapiret2,
ls_return type bapiret2,
err_msg type string,
ls_message type scx_t100key.

* data definitions for etag handling
data ls_conditions type /iwbep/if_mgw_appl_types=>ty_s_conditions.
data ls_etag type /iwbep/if_mgw_appl_types=>ty_s_etag.
data lv_matched type abap_bool.
data lv_etag_value type c length 22 .
data ls_entity type sepm_isoe.

* Lock argument for table SNWD_LOCK

data: begin of ls_snwd_lock,
* node_key(000032) type c,
node_key type snwd_lock-NODE_KEY,
bo_name type snwd_lock-bo_name,
bo_node_name type snwd_lock-bo_node_name,
client type snwd_lock-client,
end of ls_snwd_lock.

data ls_so type snwd_so.


* " Initialization of lock argument:
call 'C_ENQ_WILDCARD' id 'HEX0' field ls_snwd_lock.

* " assign lock parameters to lock fields
ls_snwd_lock-bo_name = 'IF_EPM_SO'.
ls_snwd_lock-bo_node_name = 'IF_EPM_SO_HEADER'.
ls_snwd_lock-client = sy-mandt.


call method io_tech_request_context->get_converted_keys
importing
es_key_values = ls_headerdata_key.


" determine value of node_key.
select single * from snwd_so
where SO_ID = @ls_headerdata_key-salesorder
into @ls_so.

" add check whether product exist or not
if sy-subrc <> 0.
" implement suitable error handling here
ls_message-msgid = 'SY'.
ls_message-msgno = '002'.
concatenate 'Update for ' ls_headerdata_key-salesorder ' failed' into ls_message-attr1.

raise exception type /iwbep/cx_mgw_busi_exception
exporting
textid = ls_message.
else.
ls_snwd_lock-node_key = ls_so-node_key.
endif.

* lock the sales order entity by enqueue lock
call function 'ENQUEUE_EPM_LOCK'
exporting
mode_snwd_lock = 'E'
node_key = ls_snwd_lock-node_key
bo_name = ls_snwd_lock-bo_name
bo_node_name = ls_snwd_lock-bo_node_name
client = ls_snwd_lock-client
* X_NODE_KEY = ' '
* X_BO_NAME = ' '
* X_BO_NODE_NAME = ' '
_scope = '2'
_wait = ' '
_collect = ' '
exceptions
foreign_lock = 1
system_failure = 2
others = 3.

if sy-subrc <> 0.
" implement suitable error handling here
ls_message-msgid = 'SY'.
ls_message-msgno = '002'.
concatenate 'Could not aquire lock entry for ' ls_headerdata_key-salesorder into ls_message-attr1.

raise exception type /iwbep/cx_mgw_busi_exception
exporting
textid = ls_message.
endif.

* read the value of the timestamp from the database
select single * from sepm_isoe into ls_entity where salesorder = ls_headerdata_key-salesorder.
move ls_entity-lastchangeddatetime to lv_etag_value.

* read the etag value provided in the update request
io_tech_request_context->get_conditional_info(
importing
es_conditions = ls_conditions
).

*check if both values match
read table ls_conditions-if_match transporting no fields
with key any_value = abap_true.

if sy-subrc ne 0.
loop at ls_conditions-if_match into ls_etag.
read table ls_etag-tag_values transporting no fields
with key name = 'LASTCHANGEDDATETIME' value = lv_etag_value.
if sy-subrc eq 0.
lv_matched = abap_true.
exit.
endif.
endloop.
else.
lv_matched = abap_false.
endif.


if lv_matched eq abap_false.
* release the lock that we have aquired beforehand
call function 'DEQUEUE_EPM_LOCK'
exporting
mode_snwd_lock = 'E'
node_key = ls_snwd_lock-node_key
bo_name = ls_snwd_lock-bo_name
bo_node_name = ls_snwd_lock-bo_node_name
client = ls_snwd_lock-client
_scope = '2'
" _synchron = space
_collect = 'X'
exceptions
others = 3.

if sy-subrc <> 0.
" implement suitable error handling here
endif.

raise exception type /iwbep/cx_mgw_busi_exception
exporting
http_status_code = /iwbep/cx_mgw_busi_exception=>gcs_http_status_codes-precondition_failed
textid = /iwbep/cx_mgw_busi_exception=>precondition_failed.
endif.


* perform the update

io_data_provider->read_entry_data( importing es_data = ls_headerdata_payload ).

ls_so_id-so_id = ls_headerdata_key-salesorder.

" Salesorder header data (non-key) fields that can be updated
" via the BAPI are marked with an 'X'

ls_headerdatax-so_id = ls_headerdata_key-salesorder.
ls_headerdatax-note = 'X'.

" move content of the fields that should be
" updated from payload to the corresponding
" field of the BAPI

move ls_headerdata_key-salesorder to ls_headerdata_update-so_id.
move ls_headerdata_payload-t_salesorder to ls_headerdata_update-note.

call function 'BAPI_EPM_SO_CHANGE'
exporting
so_id = ls_so_id " EPM: SO Id
soheaderdata = ls_headerdata_update " EPM: so header data of BOR object
soheaderdatax = ls_headerdatax
tables
return = lt_return. " Return Parameter

if lt_return is not initial.

loop at lt_return into ls_return.
err_msg = ls_return-message .
endloop.

ls_message-msgid = 'SY'.
ls_message-msgno = '002'.
ls_message-attr1 = err_msg.

raise exception type /iwbep/cx_mgw_busi_exception
exporting
textid = ls_message.

endif.


endmethod.

 

Code based implementation of ETag support for function imports


Adding a function import


Since the service we are using has been generated using the referenced data source approach we cannot create a function import usingt the service builder. Reason is that the dialogue to create function imports does not find the entity types and entity sets of the CDS view.

We thus have to create a function import 'ConfirmOrder' by adding code to our DEFINE method of the modle provider extension class.
******************************************************************
* ACTION - ConfirmOrder
******************************************************************
data lo_action type ref to /iwbep/if_mgw_odata_action.
data lo_parameter type ref to /iwbep/if_mgw_odata_parameter.

lo_action = model->create_action( 'ConfirmOrder' ).
*Set return entity type
lo_action->set_return_entity_type( 'Zsepm_C_Salesorder_TplType' ).
*Set HTTP method GET, PUT or POST
lo_action->set_http_method( 'PUT' ). "#EC NOTEXT
* change 16.5.
*Set the action for entity type (not the entity set)
lo_action->set_action_for( 'Zsepm_C_Salesorder_TplType' ).
* Set return type multiplicity
lo_action->set_return_multiplicity( '0' ).

******************************************************************
* Parameters
******************************************************************

lo_parameter = lo_action->create_input_parameter( iv_parameter_name = 'SalesOrder' iv_abap_fieldname = 'SALESORDER' ).
lo_parameter->/iwbep/if_mgw_odata_property~set_type_edm_string( ).
lo_parameter->set_maxlength( iv_max_length = 10 ).
lo_parameter->BIND_DATA_ELEMENT(
exporting
IV_ELEMENT_NAME = 'SNWD_SO_ID'
IV_BIND_CONVERSIONS = ABAP_TRUE
).

Activate etag support through the backend


If you want to add Etag support for function modules you have to implement the following method /IWBEP/IF_MGW_APPL_SRV_RUNTIME~GET_IS_CONDI_IMPLE_FOR_ACTION. In this case the code will inform the framework that conditional handling is done by the service implementation in the backend for a function import 'ConfirmOrder'.
method /IWBEP/IF_MGW_APPL_SRV_RUNTIME~GET_IS_CONDI_IMPLE_FOR_ACTION.

if iv_action_name = 'ConfirmOrder'.
rv_conditional_active = abap_true.
else.
rv_conditional_active = abap_false.
endif.

endmethod.

 

Implement function import and add etag support


By implementating the method /iwbep/if_mgw_appl_srv_runtime~execute_action we can add business logic to the function import.

Like in the update method code has beend added that locks the sales order before checking the etag. Only after having checked that the sales order. hasn't been changed by another user  the status is updated.

 
    method /IWBEP/IF_MGW_APPL_SRV_RUNTIME~EXECUTE_ACTION.

data: ls_parameter type /iwbep/s_mgw_name_value_pair.
data: lv_soid type snwd_so_id.
data: ls_so_id type bapi_epm_so_id.
data: lt_return type standard table of bapiret2, ls_return type bapiret2.
data: ls_headerdata type bapi_epm_so_header.
data: ls_message type scx_t100key.
data: ls_entity type sepm_isoe.
types: begin of lty_import_parameter,
salesorder type snwd_so_id,
end of lty_import_parameter.
data: ls_parameter_values type lty_import_parameter,
lv_function_import_name type /iwbep/mgw_tech_name.
data: ls_conditions type /iwbep/if_mgw_appl_types=>ty_s_conditions.
data: ls_etag type /iwbep/if_mgw_appl_types=>ty_s_etag.
data: lv_matched type abap_bool.
data : lv_etag_value type c length 22 .


* Lock argument for table SNWD_LOCK

data: begin of ls_snwd_lock,
* node_key(000032) type c,
node_key type snwd_lock-NODE_KEY,
bo_name type snwd_lock-bo_name,
bo_node_name type snwd_lock-bo_node_name,
client type snwd_lock-client,
end of ls_snwd_lock.

data ls_so type snwd_so.


lv_function_import_name = io_tech_request_context->get_function_import_name( ).

io_tech_request_context->get_converted_parameters(
importing
es_parameter_values = ls_parameter_values ).

case lv_function_import_name.

when 'ConfirmOrder'.

* " Initialization of lock argument:
call 'C_ENQ_WILDCARD' id 'HEX0' field ls_snwd_lock.

* " assign lock parameters to lock fields
ls_snwd_lock-bo_name = 'IF_EPM_SO'.
ls_snwd_lock-bo_node_name = 'IF_EPM_SO_HEADER'.
ls_snwd_lock-client = sy-mandt.

" determine value of node_key.
select single * from snwd_so
where SO_ID = @ls_parameter_values-SalesOrder
into @ls_so.

" add check whether product exist or not
if sy-subrc <> 0.
" implement suitable error handling here
ls_message-msgid = 'SY'.
ls_message-msgno = '002'.
concatenate 'Update for ' ls_parameter_values-SalesOrder ' failed' into ls_message-attr1.

raise exception type /iwbep/cx_mgw_busi_exception
exporting
textid = ls_message.
else.
ls_snwd_lock-node_key = ls_so-node_key.
endif.

* lock the sales order entity by enqueue lock
call function 'ENQUEUE_EPM_LOCK'
exporting
mode_snwd_lock = 'E'
node_key = ls_snwd_lock-node_key
bo_name = ls_snwd_lock-bo_name
bo_node_name = ls_snwd_lock-bo_node_name
client = ls_snwd_lock-client
* X_NODE_KEY = ' '
* X_BO_NAME = ' '
* X_BO_NODE_NAME = ' '
_scope = '2'
_wait = ' '
_collect = ' '
exceptions
foreign_lock = 1
system_failure = 2
others = 3.

if sy-subrc <> 0.
" implement suitable error handling here
ls_message-msgid = 'SY'.
ls_message-msgno = '002'.
concatenate 'Could not aquire lock entry for ' ls_parameter_values-SalesOrder into ls_message-attr1.

raise exception type /iwbep/cx_mgw_busi_exception
exporting
textid = ls_message.
endif.




ls_so_id-so_id = ls_parameter_values-SalesOrder.

* add check for matching etags here
select single * from sepm_isoe into ls_entity where salesorder = ls_so_id-so_id.
move ls_entity-lastchangeddatetime to lv_etag_value.
io_tech_request_context->get_conditional_info(
importing
es_conditions = ls_conditions
).
* check if both values match
read table ls_conditions-if_match transporting no fields
with key any_value = abap_true.
if sy-subrc ne 0.
loop at ls_conditions-if_match into ls_etag.
read table ls_etag-tag_values transporting no fields
with key name = 'LASTCHANGEDDATETIME' value = lv_etag_value.
if sy-subrc eq 0.
lv_matched = abap_true.
exit.
endif.
endloop.
else.
lv_matched = abap_false.
endif.


if lv_matched eq abap_false.

* release the lock that we have aquired beforehand
call function 'DEQUEUE_EPM_LOCK'
exporting
mode_snwd_lock = 'E'
node_key = ls_snwd_lock-node_key
bo_name = ls_snwd_lock-bo_name
bo_node_name = ls_snwd_lock-bo_node_name
client = ls_snwd_lock-client
_scope = '2'
" _synchron = space
_collect = 'X'
exceptions
others = 3.

if sy-subrc <> 0.
" implement suitable error handling here
endif.

raise exception type /iwbep/cx_mgw_busi_exception
exporting
http_status_code = /iwbep/cx_mgw_busi_exception=>gcs_http_status_codes-precondition_failed
textid = /iwbep/cx_mgw_busi_exception=>precondition_failed.
endif.


* perform change of so if etag check was successful


call function 'BAPI_EPM_SO_CONFIRM'
exporting
so_id = ls_so_id
* persist_to_db = abap_true
tables
return = lt_return.


if not lt_return[] is initial.
me->/iwbep/if_sb_dpc_comm_services~rfc_save_log(
exporting
* iv_entity_type = iv_entity_name
it_return = lt_return
it_key_tab = it_parameter ).

else.



select single * from sepm_isoe into ls_entity where salesorder = ls_so_id-so_id.

if ls_entity is initial.
ls_message-msgid = 'SY'.
ls_message-msgno = '002'.
ls_message-attr1 = 'sales order not found'.

raise exception type /iwbep/cx_mgw_busi_exception
exporting
textid = ls_message.
endif.

copy_data_to_ref( exporting
is_data = ls_entity changing
cr_data = er_data
).

endif.
endcase.
endmethod.

 

As a result we are now able to perform a confirmation of a sales order with optimistic locking by executing the following URI.

 
/sap/opu/odata/SAP/ZE2E100_XX_2_SRV/ConfirmOrder?SalesOrderID='0500000017'

 
17 Comments
raeijpe
Contributor
0 Kudos
Nice blog Andre.
Pavan_Golesar
Active Participant
0 Kudos
Nice & Neat!

Function import is as well covered here, This is all what I was looking for setting and get-going with eTag functionality.

 

Thank you Andre again!

--Pavan G
Former Member
0 Kudos

Hello Andre,

We are facing a similar situation in one of our clients.

Does etag work for create_deep_entity??(we are using create_deep_entity to confirm work order/operation and do goods movement using a deep structure)

I have implemented method /IWBEP/IF_MGW_APPL_SRV_RUNTIME~GET_IS_CONDITIONAL_IMPLEMENTED and set rv_conditional_active abap_true for operation type CD and XS .

Thanks

Parul

 

Andre_Fischer
Product and Topic Expert
Product and Topic Expert
0 Kudos
 

Hi Parul,

etags are only used for update scenarios. I you create a ressource that does not exist you don't have to perform a check for the last change date of that ressource.

Best Regards,

Andre

 

 

Hi Andre,

I have a question in regards to your reply to Parul.

 

I wanted to enhance an existing custom OData app.  I was thinking of adding e-tag logic.

However,  they implemented CREATE_DEEP_ENTITY for both “Create” and “Update” functions.

They branch to each operation by inspecting the presence of the key field.  If null, then “Create”, else “Update”. The service doesn’t respond to “PUT” commands, only “POST” commands.

 

Is it possible to implement the e-tag solution in this scenario?

 

Thank you,

Kimberly

Andre_Fischer
Product and Topic Expert
Product and Topic Expert
0 Kudos

 

Hi Kimberly,

what you are doing here is not part of the official OData V2 spec. But since the app is not following the standard you could enhance it by using your custom etag handling.

The following code will search for a http header ‘myetag’.

The variable myetag in the end contains the value that is sent in this header. In this example I used ‘hugo’.

This is not an official etag handling but it might do what you are looking for.

Kudos also go to jonathan.bourne who posted this code three years ago in another thread.

Regards,

Andre

 

 

DATA: lo_facade TYPE REF TO /iwbep/if_mgw_dp_int_facade,
lt_request_headers TYPE tihttpnvp,
ls_request_headers LIKE LINE OF lt_request_headers,
myetag type string.

* Read the HTTP Request headers.
lo_facade ?= /iwbep/if_mgw_conv_srv_runtime~get_dp_facade( ).
lt_request_headers = lo_facade->get_request_header( ).

READ TABLE lt_request_headers with key name = 'myetag' INTO data(lv_request_header).

if sy-subrc = 0 . "do something
myetag = lv_request_header-value.
endif.

 

0 Kudos
Thank you for your feedback.  I will give this a try and post my results.

And thank you for the insight to the SAP standard usage.

Best Regards,

Kimberly

 
Pavan_Golesar
Active Participant
0 Kudos
Thanks Andre,

I'll Try and post the experience.

 

--PG
Former Member
0 Kudos
Hi Andre,

Thanks for this blog!

I have a question regarding eTags implementation.

You have used timestamp for etags value and we have input the if-match value as W/"datetimeoffset''<value of the timestamp> " 

If I want to use a field with edm.String type as eTag property, how do I pass the same in if-match?

I tried with if-match = W/"string'<some value for example A0001>'" but I get the error for invalid "if-match" format.

Please let me know how can we proceed with this error.

Best Regards,

Shahir Mirza
Andre_Fischer
Product and Topic Expert
Product and Topic Expert
0 Kudos
Hi Mirza,

I just tried it with a demo service based on DDIC import of table SNWD_BPA and I selected the phone number as the etag.

When providing the etag in the following format it worked.

This was also the format returned by the service

if-match              W/"'0622734333567'"

Best Regards,

Andre

 
Phani_Kumar
Participant
0 Kudos

Hi andre.fischer

Excellent BLog… You have been educating lots of guys like me… Thank you very much for that…!!!!

Just a small question , if we use E-Tag on an Entity , do we need to use this method

GET_IS_CONDITIONAL_IMPLEMENTED

OR will the framework automatically determine based on the E-Tag ID that was sent from UI?

 

Example : If I keep a HASH Based Field in my Entity and am using this field as  E-Tag for my Entity , before doing any of CRUD Operations , Based on the data , i am determining the HASH for the corresponding data and updating the tables .Later , If I have to update my entry , then I am fetching existing E-Tag from the system and I am passing some other data for update(which will also determine a HASH for this corresponding Data) and I believe, framework will automatically check the E-Tags existing in the system and  E-Tag calculated for the new Data and 

 

Update the data or Throw error message right?

Andre_Fischer
Product and Topic Expert
Product and Topic Expert
If you are using the framework support for etags before Performing an update the Framework will call the GET_ENTITY method and will compare the value of the property that is flagged as an ETag with the value sent by the update request.

If the comparison shows that the two values differ an error will be raised. If they do not differ the update method will be called.

Since you said that the hash value is already present and does not have to be calculated during runtime I would expect that it should work.

You only have to make sure to save a new hash value when updating your Entity.

Regards
Andre

 
Phani_Kumar
Participant
0 Kudos
Than you very much andre.fischer

I too understand it that way but has little fear that i might be wrong in understanding. You cleared my doubts ...
0 Kudos
hi andre.fischer

i have followed your post to create e-tag but i am facing few issues at this step-

retrieved the Etag value from Get request

etag" : "W/\"datetimeoffset'2020-10-22T23%3A50%3A04.5351960Z'

 


passed the  etag with changed date as below

W/\"datetimeoffset'2020-11-22T24%3A50%3A04.5351960Z'\"


but still i am getting the 428 error

could not figure out the issue

please help.
Andre_Fischer
Product and Topic Expert
Product and Topic Expert
If you have followed my implementation you should be able to debug your code and see what is sent by your client because it is your implementation that raises the error.

I see that I have used no backslash but the following format

W/”datetimeoffset’2017-05-05T09%3A15%3A05.6050000Z'”

 
0 Kudos

Thank You andre.fischer for your response.

there was small issue in my If-Match and fixed this.

issue resolved.

thank You

0 Kudos
I am getting error:


Error if-match


When performing any updates on our RAP app. The Preview on the Service Binding works, but not the App. Any suggestions on how to remove or implement etags or solve the issue?

 

Best, Ernesto Solana