From 925b6812f70442ea1fc0793d52f54c05c037fdb1 Mon Sep 17 00:00:00 2001 From: Dhiraj Thakkar Date: Fri, 15 Sep 2023 11:25:38 -0700 Subject: [PATCH 1/2] Add example for SAP ABAP SDK dynamo db --- .doc_gen/metadata/dynamodb_metadata.yaml | 88 +++++ sap-abap/services/dyn/package.devc.xml | 10 + .../dyn/zcl_aws1_dyn_actions.clas.abap | 357 ++++++++++++++++++ ...zcl_aws1_dyn_actions.clas.testclasses.abap | 347 +++++++++++++++++ .../dyn/zcl_aws1_dyn_actions.clas.xml | 79 ++++ .../dyn/zcl_aws1_dyn_scenario.clas.abap | 219 +++++++++++ ...cl_aws1_dyn_scenario.clas.testclasses.abap | 57 +++ .../dyn/zcl_aws1_dyn_scenario.clas.xml | 25 ++ 8 files changed, 1182 insertions(+) create mode 100644 sap-abap/services/dyn/package.devc.xml create mode 100644 sap-abap/services/dyn/zcl_aws1_dyn_actions.clas.abap create mode 100644 sap-abap/services/dyn/zcl_aws1_dyn_actions.clas.testclasses.abap create mode 100644 sap-abap/services/dyn/zcl_aws1_dyn_actions.clas.xml create mode 100644 sap-abap/services/dyn/zcl_aws1_dyn_scenario.clas.abap create mode 100644 sap-abap/services/dyn/zcl_aws1_dyn_scenario.clas.testclasses.abap create mode 100644 sap-abap/services/dyn/zcl_aws1_dyn_scenario.clas.xml diff --git a/.doc_gen/metadata/dynamodb_metadata.yaml b/.doc_gen/metadata/dynamodb_metadata.yaml index 018b973d949..d4c853f483f 100644 --- a/.doc_gen/metadata/dynamodb_metadata.yaml +++ b/.doc_gen/metadata/dynamodb_metadata.yaml @@ -137,6 +137,14 @@ dynamodb_CreateTable: - description: snippet_tags: - dynamodb.JavaScript.table.createTable + SAP ABAP: + versions: + - sdk_version: 1 + github: sap-abap/services/dyn + excerpts: + - description: + snippet_tags: + - dyn.abapv1.create_table Swift: versions: - sdk_version: 1 @@ -289,6 +297,14 @@ dynamodb_DescribeTable: - description: snippet_tags: - dynamodb.JavaScript.table.describeTable + SAP ABAP: + versions: + - sdk_version: 1 + github: sap-abap/services/dyn + excerpts: + - description: + snippet_tags: + - dyn.abapv1.describe_table Python: versions: - sdk_version: 3 @@ -528,6 +544,14 @@ dynamodb_DeleteTable: - description: snippet_tags: - dynamodb.JavaScript.table.deleteTable + SAP ABAP: + versions: + - sdk_version: 1 + github: sap-abap/services/dyn + excerpts: + - description: + snippet_tags: + - dyn.abapv1.delete_table Swift: versions: - sdk_version: 1 @@ -656,6 +680,14 @@ dynamodb_PutItem: - description: Put an item in a table using the &DDB; document client. snippet_tags: - dynamodb.JavaScript.docClient.put + SAP ABAP: + versions: + - sdk_version: 1 + github: sap-abap/services/dyn + excerpts: + - description: + snippet_tags: + - dyn.abapv1.put_item Swift: versions: - sdk_version: 1 @@ -777,6 +809,14 @@ dynamodb_GetItem: - description: Get an item from a table using the &DDB; document client. snippet_tags: - dynamodb.JavaScript.docClient.get + SAP ABAP: + versions: + - sdk_version: 1 + github: sap-abap/services/dyn + excerpts: + - description: + snippet_tags: + - dyn.abapv1.get_item Swift: versions: - sdk_version: 1 @@ -896,6 +936,14 @@ dynamodb_UpdateItem: in &DDB;. For API details see UpdateCommand. snippet_tags: - dynamodb.JavaScript.docClient.updateV3 + SAP ABAP: + versions: + - sdk_version: 1 + github: sap-abap/services/dyn + excerpts: + - description: + snippet_tags: + - dyn.abapv1.update_item Swift: versions: - sdk_version: 1 @@ -1023,6 +1071,14 @@ dynamodb_DeleteItem: - description: Delete an item from a table using the &DDB; document client. snippet_tags: - dynamodb.JavaScript.docClient.delete + SAP ABAP: + versions: + - sdk_version: 1 + github: sap-abap/services/dyn + excerpts: + - description: + snippet_tags: + - dyn.abapv1.delete_item C++: versions: - sdk_version: 1 @@ -1160,6 +1216,14 @@ dynamodb_ListTables: - description: snippet_tags: - dynamodb.JavaScript.table.listTables + SAP ABAP: + versions: + - sdk_version: 1 + github: sap-abap/services/dyn + excerpts: + - description: + snippet_tags: + - dyn.abapv1.list_tables Swift: versions: - sdk_version: 1 @@ -1292,6 +1356,14 @@ dynamodb_Query: - description: snippet_tags: - dynamodb.JavaScript.docClient.query + SAP ABAP: + versions: + - sdk_version: 1 + github: sap-abap/services/dyn + excerpts: + - description: + snippet_tags: + - dyn.abapv1.query_table Swift: versions: - sdk_version: 1 @@ -1416,6 +1488,14 @@ dynamodb_Scan: - description: snippet_tags: - dynamodb.JavaScript.table.scan + SAP ABAP: + versions: + - sdk_version: 1 + github: sap-abap/services/dyn + excerpts: + - description: + snippet_tags: + - dyn.abapv1.scan_items Swift: versions: - sdk_version: 1 @@ -1868,6 +1948,14 @@ dynamodb_Scenario_GettingStartedMovies: - description: snippet_tags: - javascript.dynamodb_scenarios.dynamodb_basics + SAP ABAP: + versions: + - sdk_version: 1 + github: sap-abap/services/dyn + excerpts: + - description: + snippet_tags: + - dyn.abapv1.getting_started_with_tables C++: versions: - sdk_version: 1 diff --git a/sap-abap/services/dyn/package.devc.xml b/sap-abap/services/dyn/package.devc.xml new file mode 100644 index 00000000000..fa92507edf9 --- /dev/null +++ b/sap-abap/services/dyn/package.devc.xml @@ -0,0 +1,10 @@ + + + + + + Package for Amazon Dynamo DB + + + + diff --git a/sap-abap/services/dyn/zcl_aws1_dyn_actions.clas.abap b/sap-abap/services/dyn/zcl_aws1_dyn_actions.clas.abap new file mode 100644 index 00000000000..41e8a6f5e65 --- /dev/null +++ b/sap-abap/services/dyn/zcl_aws1_dyn_actions.clas.abap @@ -0,0 +1,357 @@ +" """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +" " Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights +" " Reserved. +" " SPDX-License-Identifier: MIT-0 +" """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +CLASS zcl_aws1_dyn_actions DEFINITION + PUBLIC + FINAL + CREATE PUBLIC . + + PUBLIC SECTION. + PROTECTED SECTION. + PRIVATE SECTION. + + METHODS create_table + IMPORTING + VALUE(iv_table_name) TYPE /aws1/dyntablename + RETURNING + VALUE(oo_result) TYPE REF TO /aws1/cl_dyncreatetableoutput . + METHODS describe_table + IMPORTING + VALUE(iv_table_name) TYPE /aws1/dyntablename + RETURNING + VALUE(oo_result) TYPE REF TO /aws1/cl_dyndescrtableoutput . + METHODS delete_table + IMPORTING + VALUE(iv_table_name) TYPE /aws1/dyntablename . + METHODS list_tables + RETURNING + VALUE(oo_result) TYPE REF TO /aws1/cl_dynlisttablesoutput . + METHODS put_item + IMPORTING + VALUE(iv_table_name) TYPE /aws1/dyntablename + VALUE(it_item) TYPE /aws1/cl_dynattributevalue=>tt_putiteminputattributemap . + METHODS get_item + IMPORTING + VALUE(iv_table_name) TYPE /aws1/dyntablename + !it_key TYPE /aws1/cl_dynattributevalue=>tt_key + RETURNING + VALUE(oo_item) TYPE REF TO /aws1/cl_dyngetitemoutput . + METHODS update_item + IMPORTING + VALUE(iv_table_name) TYPE /aws1/dyntablename + VALUE(it_item_key) TYPE /aws1/cl_dynattributevalue=>tt_key + VALUE(it_attribute_updates) TYPE /aws1/cl_dynattrvalueupdate=>tt_attributeupdates + RETURNING + VALUE(oo_output) TYPE REF TO /aws1/cl_dynupdateitemoutput . + METHODS delete_item + IMPORTING + VALUE(iv_table_name) TYPE /aws1/dyntablename + VALUE(it_key_input) TYPE /aws1/cl_dynattributevalue=>tt_key . + METHODS query_table + IMPORTING + VALUE(iv_table_name) TYPE /aws1/dyntablename + VALUE(iv_year) TYPE numeric + RETURNING + VALUE(oo_result) TYPE REF TO /aws1/cl_dynqueryoutput . + METHODS scan_items + IMPORTING + VALUE(iv_table_name) TYPE /aws1/dyntablename + !iv_rating TYPE numeric + RETURNING + VALUE(oo_scan_result) TYPE REF TO /aws1/cl_dynscanoutput . +ENDCLASS. + + + +CLASS ZCL_AWS1_DYN_ACTIONS IMPLEMENTATION. + + + METHOD create_table. + CONSTANTS cv_pfl TYPE /aws1/rt_profile_id VALUE 'ZCODE_DEMO'. + + DATA(lo_session) = /aws1/cl_rt_session_aws=>create( cv_pfl ). + DATA(lo_dyn) = /aws1/cl_dyn_factory=>create( lo_session ). + + " snippet-start:[dyn.abapv1.create_table] + TRY. + DATA(lt_keyschema) = VALUE /aws1/cl_dynkeyschemaelement=>tt_keyschema( + ( NEW /aws1/cl_dynkeyschemaelement( iv_attributename = 'year' + iv_keytype = 'HASH' ) ) + ( NEW /aws1/cl_dynkeyschemaelement( iv_attributename = 'title' + iv_keytype = 'RANGE' ) ) ). + DATA(lt_attributedefinitions) = VALUE /aws1/cl_dynattributedefn=>tt_attributedefinitions( + ( NEW /aws1/cl_dynattributedefn( iv_attributename = 'year' + iv_attributetype = 'N' ) ) + ( NEW /aws1/cl_dynattributedefn( iv_attributename = 'title' + iv_attributetype = 'S' ) ) ). + + " Adjust read/write capacities as desired. + DATA(lo_dynprovthroughput) = NEW /aws1/cl_dynprovthroughput( + iv_readcapacityunits = 5 + iv_writecapacityunits = 5 ). + oo_result = lo_dyn->createtable( + it_keyschema = lt_keyschema + iv_tablename = iv_table_name + it_attributedefinitions = lt_attributedefinitions + io_provisionedthroughput = lo_dynprovthroughput ). + " Table creation can take some time. Wait till table exists before returning. + lo_dyn->get_waiter( )->tableexists( + iv_max_wait_time = 200 + iv_tablename = iv_table_name ). + MESSAGE 'DynamoDB Table' && iv_table_name && 'created.' TYPE 'I'. + " This exception can happen if the table already exists + CATCH /aws1/cx_dynresourceinuseex INTO DATA(lo_resourceinuseex). + DATA(lv_error) = |"{ lo_resourceinuseex->av_err_code }" - { lo_resourceinuseex->av_err_msg }|. + MESSAGE lv_error TYPE 'E'. + ENDTRY. + " snippet-end:[dyn.abapv1.create_table] + ENDMETHOD. + + + METHOD delete_item. + CONSTANTS cv_pfl TYPE /aws1/rt_profile_id VALUE 'ZCODE_DEMO'. + + DATA(lo_session) = /aws1/cl_rt_session_aws=>create( cv_pfl ). + DATA(lo_dyn) = /aws1/cl_dyn_factory=>create( lo_session ). + + " snippet-start:[dyn.abapv1.delete_item] + TRY. + DATA(lo_resp) = lo_dyn->deleteitem( + iv_tablename = iv_table_name + it_key = it_key_input ). + MESSAGE 'Deleted one item.' TYPE 'I'. + CATCH /aws1/cx_dyncondalcheckfaile00. + MESSAGE 'A condition specified in the operation could not be evaluated.' TYPE 'E'. + CATCH /aws1/cx_dynresourcenotfoundex. + MESSAGE 'The table or index does not exist' TYPE 'E'. + CATCH /aws1/cx_dyntransactconflictex. + MESSAGE 'Another transaction is using the item' TYPE 'E'. + ENDTRY. + " snippet-end:[dyn.abapv1.delete_item] + + ENDMETHOD. + + + METHOD delete_table. + CONSTANTS cv_pfl TYPE /aws1/rt_profile_id VALUE 'ZCODE_DEMO'. + + DATA(lo_session) = /aws1/cl_rt_session_aws=>create( cv_pfl ). + DATA(lo_dyn) = /aws1/cl_dyn_factory=>create( lo_session ). + + " snippet-start:[dyn.abapv1.delete_table] + TRY. + lo_dyn->deletetable( iv_tablename = iv_table_name ). + " Wait till the table is actually deleted. + lo_dyn->get_waiter( )->tablenotexists( + iv_max_wait_time = 200 + iv_tablename = iv_table_name ). + MESSAGE 'Table ' && iv_table_name && ' deleted.' TYPE 'I'. + CATCH /aws1/cx_dynresourcenotfoundex. + MESSAGE 'The table ' && iv_table_name && ' does not exist' TYPE 'E'. + CATCH /aws1/cx_dynresourceinuseex. + MESSAGE 'The table cannot be deleted since it is in use' TYPE 'E'. + ENDTRY. + " snippet-end:[dyn.abapv1.delete_table] + ENDMETHOD. + + + METHOD describe_table. + CONSTANTS cv_pfl TYPE /aws1/rt_profile_id VALUE 'ZCODE_DEMO'. + + DATA(lo_session) = /aws1/cl_rt_session_aws=>create( cv_pfl ). + DATA(lo_dyn) = /aws1/cl_dyn_factory=>create( lo_session ). + + " snippet-start:[dyn.abapv1.describe_table] + TRY. + oo_result = lo_dyn->describetable( iv_tablename = iv_table_name ). + DATA(lv_tablename) = oo_result->get_table( )->ask_tablename( ). + DATA(lv_tablearn) = oo_result->get_table( )->ask_tablearn( ). + DATA(lv_tablestatus) = oo_result->get_table( )->ask_tablestatus( ). + DATA(lv_itemcount) = oo_result->get_table( )->ask_itemcount( ). + MESSAGE 'The table name is ' && lv_tablename + && '. The table ARN is ' && lv_tablearn + && '. The tablestatus is ' && lv_tablestatus + && '. Item count is ' && lv_itemcount TYPE 'I'. + CATCH /aws1/cx_dynresourcenotfoundex. + MESSAGE 'The table ' && lv_tablename && ' does not exist' TYPE 'E'. + ENDTRY. + " snippet-end:[dyn.abapv1.describe_table] + + ENDMETHOD. + + + METHOD get_item. + CONSTANTS cv_pfl TYPE /aws1/rt_profile_id VALUE 'ZCODE_DEMO'. + + DATA(lo_session) = /aws1/cl_rt_session_aws=>create( cv_pfl ). + DATA(lo_dyn) = /aws1/cl_dyn_factory=>create( lo_session ). + + " snippet-start:[dyn.abapv1.get_item] + TRY. + oo_item = lo_dyn->getitem( + iv_tablename = iv_table_name + it_key = it_key ). + DATA(lt_attr) = oo_item->get_item( ). + DATA(lo_title) = lt_attr[ key = 'title' ]-value. + DATA(lo_year) = lt_attr[ key = 'year' ]-value. + DATA(lo_rating) = lt_attr[ key = 'rating' ]-value. + MESSAGE 'Movie name is: ' && lo_title->get_s( ) + && 'Movie year is: ' && lo_year->get_n( ) + && 'Moving rating is: ' && lo_rating->get_n( ) TYPE 'I'. + CATCH /aws1/cx_dynresourcenotfoundex. + MESSAGE 'The table or index does not exist' TYPE 'E'. + ENDTRY. + " snippet-end:[dyn.abapv1.get_item] + + ENDMETHOD. + + + METHOD list_tables. + CONSTANTS cv_pfl TYPE /aws1/rt_profile_id VALUE 'ZCODE_DEMO'. + + DATA(lo_session) = /aws1/cl_rt_session_aws=>create( cv_pfl ). + DATA(lo_dyn) = /aws1/cl_dyn_factory=>create( lo_session ). + + " snippet-start:[dyn.abapv1.list_tables] + TRY. + oo_result = lo_dyn->listtables( ). + " You can loop over the oo_result to get table properties like this + LOOP AT oo_result->get_tablenames( ) INTO DATA(lo_table_name). + DATA(lv_tablename) = lo_table_name->get_value( ). + ENDLOOP. + DATA(lv_tablecount) = lines( oo_result->get_tablenames( ) ). + MESSAGE 'Found ' && lv_tablecount && ' tables' TYPE 'I'. + CATCH /aws1/cx_rt_service_generic INTO DATA(lo_exception). + DATA(lv_error) = |"{ lo_exception->av_err_code }" - { lo_exception->av_err_msg }|. + MESSAGE lv_error TYPE 'E'. + ENDTRY. + " snippet-end:[dyn.abapv1.list_tables] + + ENDMETHOD. + + + METHOD put_item. + CONSTANTS cv_pfl TYPE /aws1/rt_profile_id VALUE 'ZCODE_DEMO'. + + DATA(lo_session) = /aws1/cl_rt_session_aws=>create( cv_pfl ). + DATA(lo_dyn) = /aws1/cl_dyn_factory=>create( lo_session ). + + " snippet-start:[dyn.abapv1.put_item] + TRY. + DATA(lo_resp) = lo_dyn->putitem( + iv_tablename = iv_table_name + it_item = it_item ). + MESSAGE '1 row inserted into DynamoDB Table' && iv_table_name TYPE 'I'. + CATCH /aws1/cx_dyncondalcheckfaile00. + MESSAGE 'A condition specified in the operation could not be evaluated.' TYPE 'E'. + CATCH /aws1/cx_dynresourcenotfoundex. + MESSAGE 'The table or index does not exist' TYPE 'E'. + CATCH /aws1/cx_dyntransactconflictex. + MESSAGE 'Another transaction is using the item' TYPE 'E'. + ENDTRY. + " snippet-end:[dyn.abapv1.put_item] + + ENDMETHOD. + + + METHOD query_table. + CONSTANTS cv_pfl TYPE /aws1/rt_profile_id VALUE 'ZCODE_DEMO'. + + DATA(lo_session) = /aws1/cl_rt_session_aws=>create( cv_pfl ). + DATA(lo_dyn) = /aws1/cl_dyn_factory=>create( lo_session ). + + " snippet-start:[dyn.abapv1.query_table] + + TRY. + " Query movies for a given year . + DATA(lt_attributelist) = VALUE /aws1/cl_dynattributevalue=>tt_attributevaluelist( + ( NEW /aws1/cl_dynattributevalue( iv_n = |{ iv_year }| ) ) ). + DATA(lt_key_conditions) = VALUE /aws1/cl_dyncondition=>tt_keyconditions( + ( VALUE /aws1/cl_dyncondition=>ts_keyconditions_maprow( + key = 'year' + value = NEW /aws1/cl_dyncondition( + it_attributevaluelist = lt_attributelist + iv_comparisonoperator = |EQ| + ) ) ) ). + oo_result = lo_dyn->query( + iv_tablename = iv_table_name + it_keyconditions = lt_key_conditions ). + DATA(lt_items) = oo_result->get_items( ). + "You can loop over the results to get item attributes + LOOP AT lt_items INTO DATA(lt_item). + DATA(lo_title) = lt_item[ key = 'title' ]-value. + DATA(lo_year) = lt_item[ key = 'year' ]-value. + ENDLOOP. + DATA(lv_count) = oo_result->get_count( ). + MESSAGE 'Item count is: ' && lv_count TYPE 'I'. + CATCH /aws1/cx_dynresourcenotfoundex. + MESSAGE 'The table or index does not exist' TYPE 'E'. + ENDTRY. + " snippet-end:[dyn.abapv1.query_table] + + ENDMETHOD. + + + METHOD scan_items. + CONSTANTS cv_pfl TYPE /aws1/rt_profile_id VALUE 'ZCODE_DEMO'. + + DATA(lo_session) = /aws1/cl_rt_session_aws=>create( cv_pfl ). + DATA(lo_dyn) = /aws1/cl_dyn_factory=>create( lo_session ). + + " snippet-start:[dyn.abapv1.scan_items] + TRY. + " Scan movies for rating greater than or equal to the rating specified + DATA(lt_attributelist) = VALUE /aws1/cl_dynattributevalue=>tt_attributevaluelist( + ( NEW /aws1/cl_dynattributevalue( iv_n = |{ iv_rating }| ) ) ). + DATA(lt_filter_conditions) = VALUE /aws1/cl_dyncondition=>tt_filterconditionmap( + ( VALUE /aws1/cl_dyncondition=>ts_filterconditionmap_maprow( + key = 'rating' + value = NEW /aws1/cl_dyncondition( + it_attributevaluelist = lt_attributelist + iv_comparisonoperator = |GE| + ) ) ) ). + oo_scan_result = lo_dyn->scan( iv_tablename = iv_table_name + it_scanfilter = lt_filter_conditions ). + DATA(lt_items) = oo_scan_result->get_items( ). + LOOP AT lt_items INTO DATA(lo_item). + " You can loop over to get individual attributes. + DATA(lo_title) = lo_item[ key = 'title' ]-value. + DATA(lo_year) = lo_item[ key = 'year' ]-value. + ENDLOOP. + DATA(lv_count) = oo_scan_result->get_count( ). + MESSAGE 'Found ' && lv_count && ' items' TYPE 'I'. + CATCH /aws1/cx_dynresourcenotfoundex. + MESSAGE 'The table or index does not exist' TYPE 'E'. + ENDTRY. + " snippet-end:[dyn.abapv1.scan_items] + + ENDMETHOD. + + + METHOD update_item. + CONSTANTS cv_pfl TYPE /aws1/rt_profile_id VALUE 'ZCODE_DEMO'. + + DATA(lo_session) = /aws1/cl_rt_session_aws=>create( cv_pfl ). + DATA(lo_dyn) = /aws1/cl_dyn_factory=>create( lo_session ). + + " snippet-start:[dyn.abapv1.update_item] + TRY. + oo_output = lo_dyn->updateitem( + iv_tablename = iv_table_name + it_key = it_item_key + it_attributeupdates = it_attribute_updates ). + MESSAGE '1 item updated in DynamoDB Table' && iv_table_name TYPE 'I'. + CATCH /aws1/cx_dyncondalcheckfaile00. + MESSAGE 'A condition specified in the operation could not be evaluated.' TYPE 'E'. + CATCH /aws1/cx_dynresourcenotfoundex. + MESSAGE 'The table or index does not exist' TYPE 'E'. + CATCH /aws1/cx_dyntransactconflictex. + MESSAGE 'Another transaction is using the item' TYPE 'E'. + ENDTRY. + " snippet-end:[dyn.abapv1.update_item] + + ENDMETHOD. +ENDCLASS. diff --git a/sap-abap/services/dyn/zcl_aws1_dyn_actions.clas.testclasses.abap b/sap-abap/services/dyn/zcl_aws1_dyn_actions.clas.testclasses.abap new file mode 100644 index 00000000000..b8e86ba0b1e --- /dev/null +++ b/sap-abap/services/dyn/zcl_aws1_dyn_actions.clas.testclasses.abap @@ -0,0 +1,347 @@ +" """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +" " Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights +" " Reserved. +" " SPDX-License-Identifier: MIT-0 +" """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +CLASS ltc_zcl_aws1_dyn_actions DEFINITION DEFERRED. +CLASS zcl_aws1_dyn_actions DEFINITION LOCAL FRIENDS ltc_zcl_aws1_dyn_actions. + +CLASS ltc_zcl_aws1_dyn_actions DEFINITION FOR TESTING + DURATION LONG + RISK LEVEL HARMLESS. + + PROTECTED SECTION. + METHODS: create_table FOR TESTING RAISING /aws1/cx_rt_generic, + describe_table FOR TESTING RAISING /aws1/cx_rt_generic, + list_tables FOR TESTING RAISING /aws1/cx_rt_generic, + put_item FOR TESTING RAISING /aws1/cx_rt_generic, + get_item FOR TESTING RAISING /aws1/cx_rt_generic, + query_table FOR TESTING RAISING /aws1/cx_rt_generic, + scan_items FOR TESTING RAISING /aws1/cx_rt_generic, + update_item FOR TESTING RAISING /aws1/cx_rt_generic, + delete_item FOR TESTING RAISING /aws1/cx_rt_generic, + delete_table FOR TESTING RAISING /aws1/cx_rt_generic. + + PRIVATE SECTION. + CONSTANTS cv_pfl TYPE /aws1/rt_profile_id VALUE 'ZCODE_DEMO'. + + DATA ao_dyn TYPE REF TO /aws1/if_dyn. + DATA ao_session TYPE REF TO /aws1/cl_rt_session_base. + DATA ao_dyn_actions TYPE REF TO zcl_aws1_dyn_actions. + DATA av_table_name TYPE /aws1/dyntablename. + + METHODS setup RAISING /aws1/cx_rt_generic. + METHODS teardown RAISING /aws1/cx_rt_generic. + + METHODS put_item_local + IMPORTING iv_title TYPE string + iv_year TYPE numeric + iv_rating TYPE numeric + RAISING /aws1/cx_rt_generic. + METHODS delete_table_local RAISING /aws1/cx_rt_generic. + METHODS create_table_local RAISING /aws1/cx_rt_generic. + METHODS assert_table_exists RAISING /aws1/cx_rt_generic. + METHODS assert_table_notexists RAISING /aws1/cx_rt_generic. + METHODS query_table_local + IMPORTING iv_year TYPE numeric + RETURNING VALUE(ot_items) TYPE /aws1/cl_dynattributevalue=>tt_itemlist + RAISING /aws1/cx_rt_generic. + +ENDCLASS. + +CLASS ltc_zcl_aws1_dyn_actions IMPLEMENTATION. + + METHOD setup. + ao_session = /aws1/cl_rt_session_aws=>create( iv_profile_id = cv_pfl ). + ao_dyn = /aws1/cl_dyn_factory=>create( ao_session ). + ao_dyn_actions = NEW zcl_aws1_dyn_actions( ). + av_table_name = |code-example-create-table|. + ENDMETHOD. + + METHOD teardown. + delete_table_local( ). + ENDMETHOD. + + METHOD create_table. + DATA(lo_table) = ao_dyn_actions->create_table( av_table_name ). + assert_table_exists( ). + MESSAGE 'create_table successful' TYPE 'I'. + ENDMETHOD. + + METHOD describe_table. + create_table_local( ). + DATA(lo_table_description) = ao_dyn_actions->describe_table( + av_table_name ). + DATA(lv_returned_tablename) = lo_table_description->get_table( )->ask_tablename( ). + cl_abap_unit_assert=>assert_equals( + exp = av_table_name + act = lv_returned_tablename + msg = |Expected the table name to be { av_table_name } but found { lv_returned_tablename }| ). + MESSAGE 'describe_table successful' TYPE 'I'. + ENDMETHOD. + + METHOD list_tables. + create_table_local( ). + DATA(lo_tables) = ao_dyn_actions->list_tables( ). + + LOOP AT lo_tables->get_tablenames( ) INTO DATA(lo_table_name). + IF lo_table_name->get_value( ) = av_table_name. + DATA(lv_found) = abap_true. + ENDIF. + ENDLOOP. + cl_abap_unit_assert=>assert_true( + act = lv_found + msg = |List table is successful| ). + MESSAGE 'list_tables successful' TYPE 'I'. + ENDMETHOD. + + METHOD put_item. + create_table_local( ). + DATA(lt_item) = VALUE /aws1/cl_dynattributevalue=>tt_putiteminputattributemap( + ( VALUE /aws1/cl_dynattributevalue=>ts_putiteminputattrmap_maprow( + key = 'title' value = NEW /aws1/cl_dynattributevalue( iv_s = 'Jaws' ) ) ) + ( VALUE /aws1/cl_dynattributevalue=>ts_putiteminputattrmap_maprow( + key = 'year' value = NEW /aws1/cl_dynattributevalue( iv_n = '1975' ) ) ) + ( VALUE /aws1/cl_dynattributevalue=>ts_putiteminputattrmap_maprow( + key = 'rating' value = NEW /aws1/cl_dynattributevalue( iv_n = '7.8' ) ) ) ). + ao_dyn_actions->put_item( iv_table_name = av_table_name + it_item = lt_item ). + DATA(lt_items) = query_table_local( '1975' ). + READ TABLE lt_items INTO DATA(lt_attributes) INDEX 1. + DATA(lo_rating) = lt_attributes[ key = 'rating' ]-value. + DATA(lv_rating) = lo_rating->ask_n( ). + cl_abap_unit_assert=>assert_equals( exp = |7.8| + act = lv_rating + msg = |Expected rating 7.5, found { lv_rating } | ). + MESSAGE 'put_item successful' TYPE 'I'. + ENDMETHOD. + + METHOD get_item. + create_table_local( ). + put_item_local( iv_title = 'Jaws' + iv_year = 1975 + iv_rating = '7.5' ). + DATA(lo_item) = ao_dyn_actions->get_item( iv_table_name = av_table_name + it_key = VALUE /aws1/cl_dynattributevalue=>tt_key( + ( VALUE /aws1/cl_dynattributevalue=>ts_key_maprow( + key = 'title' value = NEW /aws1/cl_dynattributevalue( iv_s = 'Jaws' ) ) ) + ( VALUE /aws1/cl_dynattributevalue=>ts_key_maprow( + key = 'year' value = NEW /aws1/cl_dynattributevalue( iv_n = '1975' ) ) ) + ) ). + DATA(lt_attributes) = lo_item->get_item( ). + DATA(lo_rating) = lt_attributes[ key = 'rating' ]-value. + DATA(lv_rating) = lo_rating->ask_n( ). + cl_abap_unit_assert=>assert_equals( exp = |7.5| + act = lv_rating + msg = |Expected rating 7.5, found { lv_rating } | ). + MESSAGE 'get_item successful' TYPE 'I'. + ENDMETHOD. + + METHOD query_table. + create_table_local( ). + put_item_local( iv_title = 'Jaws' + iv_year = 1975 + iv_rating = '7.5' ). + put_item_local( iv_title = 'Star Wars' + iv_year = 1979 + iv_rating = '8.1' ). + put_item_local( iv_title = 'Barbie' + iv_year = 2023 + iv_rating = '7.9' ). + DATA(lo_query_result) = ao_dyn_actions->query_table( iv_table_name = av_table_name + iv_year = 1975 ). + READ TABLE lo_query_result->get_items( ) INTO DATA(lt_item) INDEX 1. + DATA(lo_title) = lt_item[ key = 'title' ]-value. + DATA(lv_title) = lo_title->ask_s( ). + cl_abap_unit_assert=>assert_equals( exp = |Jaws| + act = lv_title + msg = |Expected title Jaws, found { lv_title }| ). + MESSAGE 'query_table successful' TYPE 'I'. + ENDMETHOD. + + METHOD scan_items. + create_table_local( ). + put_item_local( iv_title = 'Jaws' + iv_year = 1975 + iv_rating = '7.5' ). + put_item_local( iv_title = 'Star Wars' + iv_year = 1979 + iv_rating = '8.1' ). + put_item_local( iv_title = 'Barbie' + iv_year = 2023 + iv_rating = '7.8' ). + " Scan table for rating higher than 7.8 + DATA(lo_scan_result) = ao_dyn_actions->scan_items( iv_table_name = av_table_name + iv_rating = '7.8' ). + DATA(lv_count) = lo_scan_result->get_count( ). + cl_abap_unit_assert=>assert_equals( exp = |2| + act = lv_count + msg = |Expected count 3, found { |lv_count| }| ). + MESSAGE 'scan_item successful' TYPE 'I'. + ENDMETHOD. + + METHOD update_item. + create_table_local( ). + put_item_local( iv_title = 'Jaws' + iv_year = 1975 + iv_rating = '7.5' ). + put_item_local( iv_title = 'Star Wars' + iv_year = 1979 + iv_rating = '8.1' ). + DATA(lt_attributeupdates) = VALUE /aws1/cl_dynattrvalueupdate=>tt_attributeupdates( + ( VALUE /aws1/cl_dynattrvalueupdate=>ts_attributeupdates_maprow( + key = 'rating' value = NEW /aws1/cl_dynattrvalueupdate( + io_value = NEW /aws1/cl_dynattributevalue( iv_n = '7.6' ) + iv_action = |PUT| ) ) ) ). + DATA(lt_key) = VALUE /aws1/cl_dynattributevalue=>tt_key( + ( VALUE /aws1/cl_dynattributevalue=>ts_key_maprow( + key = 'title' value = NEW /aws1/cl_dynattributevalue( iv_s = 'Jaws' ) ) ) + ( VALUE /aws1/cl_dynattributevalue=>ts_key_maprow( + key = 'year' value = NEW /aws1/cl_dynattributevalue( iv_n = '1975' ) ) ) ). + DATA(lo_resp) = ao_dyn_actions->update_item( + iv_table_name = av_table_name + it_item_key = lt_key + it_attribute_updates = lt_attributeupdates ). + " Use query item to verify that the update was successful. + DATA(lt_attributelist) = VALUE /aws1/cl_dynattributevalue=>tt_attributevaluelist( + ( NEW /aws1/cl_dynattributevalue( iv_n = '1975' ) ) ). + DATA(lt_key_conditions) = VALUE /aws1/cl_dyncondition=>tt_keyconditions( + ( VALUE /aws1/cl_dyncondition=>ts_keyconditions_maprow( + key = 'year' + value = NEW /aws1/cl_dyncondition( + it_attributevaluelist = lt_attributelist + iv_comparisonoperator = |EQ| + ) ) ) ). + DATA(lt_items) = query_table_local( 1975 ). + READ TABLE lt_items INTO DATA(lt_item) INDEX 1. + DATA(lo_rating) = lt_item[ key = 'rating' ]-value. + DATA(lv_rating) = lo_rating->ask_n( ). + cl_abap_unit_assert=>assert_equals( exp = |7.6| + act = lv_rating + msg = |Expected ratig 7.6, found { lv_rating }| ). + MESSAGE 'update_item successful' TYPE 'I'. + ENDMETHOD. + + METHOD delete_item. + create_table_local( ). + put_item_local( iv_title = 'Jaws' + iv_year = 1975 + iv_rating = '7.5' ). + put_item_local( iv_title = 'Star Wars' + iv_year = 1975 + iv_rating = '8.1' ). + DATA(lt_key) = VALUE /aws1/cl_dynattributevalue=>tt_key( + ( VALUE /aws1/cl_dynattributevalue=>ts_key_maprow( + key = 'title' value = NEW /aws1/cl_dynattributevalue( iv_s = 'Jaws' ) ) ) + ( VALUE /aws1/cl_dynattributevalue=>ts_key_maprow( + key = 'year' value = NEW /aws1/cl_dynattributevalue( iv_n = '1975' ) ) ) ). + ao_dyn_actions->delete_item( iv_table_name = av_table_name + it_key_input = lt_key ). + DATA(lt_items) = query_table_local( '1975' ). + DATA(lv_count) = lines( lt_items ). + cl_abap_unit_assert=>assert_equals( exp = |1| + act = lv_count + msg = |Expected count 1, found { |lv_count| }| ). + MESSAGE 'delete_item successful' TYPE 'I'. + ENDMETHOD. + + METHOD delete_table. + create_table_local( ). + ao_dyn_actions->delete_table( av_table_name ). + assert_table_notexists( ). + MESSAGE 'delete_table successful' TYPE 'I'. + ENDMETHOD. + + METHOD assert_table_exists. + DATA(lv_status) = ao_dyn->describetable( iv_tablename = av_table_name )->get_table( )->get_tablestatus( ). + lv_status = ao_dyn->describetable( iv_tablename = av_table_name )->get_table( )->get_tablestatus( ). + cl_abap_unit_assert=>assert_equals( + exp = lv_status + act = 'ACTIVE' + msg = |Expected the table to be in 'ACTIVE' status but received { lv_status }| ). + ENDMETHOD. + + METHOD assert_table_notexists. + TRY. + DATA(lv_status) = ao_dyn->describetable( iv_tablename = av_table_name )->get_table( )->get_tablestatus( ). + /aws1/cl_rt_assert_abap=>assert_missed_exception( iv_exception = |/AWS1/CX_RT_SERVICE_GENERIC| ). + CATCH /aws1/cx_rt_service_generic. + "ignore. expected since the table does not exist + ENDTRY. + ENDMETHOD. + + METHOD delete_table_local. + TRY. + DATA(lo_resp) = ao_dyn->deletetable( av_table_name ). + ao_dyn->get_waiter( )->tablenotexists( + iv_max_wait_time = 200 + iv_tablename = av_table_name ). + CATCH /aws1/cx_dynresourcenotfoundex. + ENDTRY. + ENDMETHOD. + + METHOD put_item_local. + DATA(lt_item) = VALUE /aws1/cl_dynattributevalue=>tt_putiteminputattributemap( + ( VALUE /aws1/cl_dynattributevalue=>ts_putiteminputattrmap_maprow( + key = 'title' value = NEW /aws1/cl_dynattributevalue( iv_s = iv_title ) ) ) + ( VALUE /aws1/cl_dynattributevalue=>ts_putiteminputattrmap_maprow( + key = 'year' value = NEW /aws1/cl_dynattributevalue( iv_n = |{ iv_year }| ) ) ) + ( VALUE /aws1/cl_dynattributevalue=>ts_putiteminputattrmap_maprow( + key = 'rating' value = NEW /aws1/cl_dynattributevalue( iv_n = |{ iv_rating }| ) ) ) ). + ao_dyn->putitem( iv_tablename = av_table_name + it_item = lt_item ). + ENDMETHOD. + + METHOD create_table_local. + TRY. + DATA(lt_keyschema) = VALUE /aws1/cl_dynkeyschemaelement=>tt_keyschema( + ( NEW /aws1/cl_dynkeyschemaelement( iv_attributename = 'year' + iv_keytype = 'HASH' ) ) + ( NEW /aws1/cl_dynkeyschemaelement( iv_attributename = 'title' + iv_keytype = 'RANGE' ) ) ). + DATA(lt_attributedefinitions) = VALUE /aws1/cl_dynattributedefn=>tt_attributedefinitions( + ( NEW /aws1/cl_dynattributedefn( iv_attributename = 'year' + iv_attributetype = 'N' ) ) + ( NEW /aws1/cl_dynattributedefn( iv_attributename = 'title' + iv_attributetype = 'S' ) ) ). + + " Adjust read/write capacities as desired. + DATA(lo_dynprovthroughput) = NEW /aws1/cl_dynprovthroughput( + iv_readcapacityunits = 5 + iv_writecapacityunits = 5 ). + ao_dyn->createtable( + it_keyschema = lt_keyschema + iv_tablename = av_table_name + it_attributedefinitions = lt_attributedefinitions + io_provisionedthroughput = lo_dynprovthroughput ). + ao_dyn->get_waiter( )->tableexists( + iv_max_wait_time = 200 + iv_tablename = av_table_name ). + CATCH /aws1/cx_rt_service_generic INTO DATA(lo_genericex). + DATA(lv_error) = |"{ lo_genericex->av_err_code }" - { lo_genericex->av_err_msg }|. + MESSAGE lv_error TYPE 'E'. + ENDTRY. + ENDMETHOD. + + METHOD query_table_local. + TRY. + DATA(lt_attributelist) = VALUE /aws1/cl_dynattributevalue=>tt_attributevaluelist( + ( NEW /aws1/cl_dynattributevalue( iv_n = |{ iv_year }| ) ) ). + DATA(lt_key_conditions) = VALUE /aws1/cl_dyncondition=>tt_keyconditions( + ( VALUE /aws1/cl_dyncondition=>ts_keyconditions_maprow( + key = 'year' + value = NEW /aws1/cl_dyncondition( + it_attributevaluelist = lt_attributelist + iv_comparisonoperator = |EQ| + ) ) ) ). + DATA(lo_result) = ao_dyn->query( + iv_tablename = av_table_name + it_keyconditions = lt_key_conditions ). + ot_items = lo_result->get_items( ). + CATCH /aws1/cx_rt_service_generic INTO DATA(lo_genericex). + DATA(lv_error) = |"{ lo_genericex->av_err_code }" - { lo_genericex->av_err_msg }|. + MESSAGE lv_error TYPE 'E'. + ENDTRY. + ENDMETHOD. +ENDCLASS. diff --git a/sap-abap/services/dyn/zcl_aws1_dyn_actions.clas.xml b/sap-abap/services/dyn/zcl_aws1_dyn_actions.clas.xml new file mode 100644 index 00000000000..366ccc5b968 --- /dev/null +++ b/sap-abap/services/dyn/zcl_aws1_dyn_actions.clas.xml @@ -0,0 +1,79 @@ + + + + + + ZCL_AWS1_DYN_ACTIONS + E + Dynamo DB Code Example + 1 + X + X + X + X + + + + ZCL_AWS1_DYN_ACTIONS + CREATE_TABLE + E + Create Dynamo DB Table + + + ZCL_AWS1_DYN_ACTIONS + DELETE_ITEM + E + Delete item from example-table + + + ZCL_AWS1_DYN_ACTIONS + DELETE_TABLE + E + Delete table + + + ZCL_AWS1_DYN_ACTIONS + DESCRIBE_TABLE + E + Describe table + + + ZCL_AWS1_DYN_ACTIONS + GET_ITEM + E + Get item from example-table + + + ZCL_AWS1_DYN_ACTIONS + LIST_TABLES + E + List tables + + + ZCL_AWS1_DYN_ACTIONS + PUT_ITEM + E + Put item into example-table + + + ZCL_AWS1_DYN_ACTIONS + QUERY_TABLE + E + Query items from example-table + + + ZCL_AWS1_DYN_ACTIONS + SCAN_ITEMS + E + Scan example-table + + + ZCL_AWS1_DYN_ACTIONS + UPDATE_ITEM + E + Update item in example-table + + + + + diff --git a/sap-abap/services/dyn/zcl_aws1_dyn_scenario.clas.abap b/sap-abap/services/dyn/zcl_aws1_dyn_scenario.clas.abap new file mode 100644 index 00000000000..7cc95165cbe --- /dev/null +++ b/sap-abap/services/dyn/zcl_aws1_dyn_scenario.clas.abap @@ -0,0 +1,219 @@ +" """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +" " Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights +" " Reserved. +" " SPDX-License-Identifier: MIT-0 +" """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +CLASS zcl_aws1_dyn_scenario DEFINITION + PUBLIC + FINAL + CREATE PUBLIC . + + PUBLIC SECTION. + PROTECTED SECTION. + PRIVATE SECTION. + + METHODS getting_started_with_tables + IMPORTING + VALUE(iv_table_name) TYPE /aws1/dyntablename . +ENDCLASS. + + + +CLASS ZCL_AWS1_DYN_SCENARIO IMPLEMENTATION. + + + METHOD getting_started_with_tables. + CONSTANTS cv_pfl TYPE /aws1/rt_profile_id VALUE 'ZCODE_DEMO'. + + " snippet-start:[dyn.abapv1.getting_started_with_tables] + " Create an Amazon Dynamo DB table + + TRY. + DATA(lo_session) = /aws1/cl_rt_session_aws=>create( cv_pfl ). + DATA(lo_dyn) = /aws1/cl_dyn_factory=>create( lo_session ). + DATA(lt_keyschema) = VALUE /aws1/cl_dynkeyschemaelement=>tt_keyschema( + ( NEW /aws1/cl_dynkeyschemaelement( iv_attributename = 'year' + iv_keytype = 'HASH' ) ) + ( NEW /aws1/cl_dynkeyschemaelement( iv_attributename = 'title' + iv_keytype = 'RANGE' ) ) ). + DATA(lt_attributedefinitions) = VALUE /aws1/cl_dynattributedefn=>tt_attributedefinitions( + ( NEW /aws1/cl_dynattributedefn( iv_attributename = 'year' + iv_attributetype = 'N' ) ) + ( NEW /aws1/cl_dynattributedefn( iv_attributename = 'title' + iv_attributetype = 'S' ) ) ). + + " Adjust read/write capacities as desired. + DATA(lo_dynprovthroughput) = NEW /aws1/cl_dynprovthroughput( + iv_readcapacityunits = 5 + iv_writecapacityunits = 5 ). + DATA(oo_result) = lo_dyn->createtable( + it_keyschema = lt_keyschema + iv_tablename = iv_table_name + it_attributedefinitions = lt_attributedefinitions + io_provisionedthroughput = lo_dynprovthroughput ). + " Table creation can take some time. Wait till table exists before returning. + lo_dyn->get_waiter( )->tableexists( + iv_max_wait_time = 200 + iv_tablename = iv_table_name ). + MESSAGE 'DynamoDB Table' && iv_table_name && 'created.' TYPE 'I'. + " It throws exception if the table already exists. + CATCH /aws1/cx_dynresourceinuseex INTO DATA(lo_resourceinuseex). + DATA(lv_error) = |"{ lo_resourceinuseex->av_err_code }" - { lo_resourceinuseex->av_err_msg }|. + MESSAGE lv_error TYPE 'E'. + ENDTRY. + + " Describe table + TRY. + DATA(lo_table) = lo_dyn->describetable( iv_tablename = iv_table_name ). + DATA(lv_tablename) = lo_table->get_table( )->ask_tablename( ). + MESSAGE 'The table name is ' && lv_tablename TYPE 'I'. + CATCH /aws1/cx_dynresourcenotfoundex. + MESSAGE 'The table does not exist' TYPE 'E'. + ENDTRY. + + " Put items into the table + TRY. + DATA(lo_resp_putitem) = lo_dyn->putitem( + iv_tablename = iv_table_name + it_item = VALUE /aws1/cl_dynattributevalue=>tt_putiteminputattributemap( + ( VALUE /aws1/cl_dynattributevalue=>ts_putiteminputattrmap_maprow( + key = 'title' value = NEW /aws1/cl_dynattributevalue( iv_s = 'Jaws' ) ) ) + ( VALUE /aws1/cl_dynattributevalue=>ts_putiteminputattrmap_maprow( + key = 'year' value = NEW /aws1/cl_dynattributevalue( iv_n = |{ '1975' }| ) ) ) + ( VALUE /aws1/cl_dynattributevalue=>ts_putiteminputattrmap_maprow( + key = 'rating' value = NEW /aws1/cl_dynattributevalue( iv_n = |{ '7.5' }| ) ) ) + ) ). + lo_resp_putitem = lo_dyn->putitem( + iv_tablename = iv_table_name + it_item = VALUE /aws1/cl_dynattributevalue=>tt_putiteminputattributemap( + ( VALUE /aws1/cl_dynattributevalue=>ts_putiteminputattrmap_maprow( + key = 'title' value = NEW /aws1/cl_dynattributevalue( iv_s = 'Star Wars' ) ) ) + ( VALUE /aws1/cl_dynattributevalue=>ts_putiteminputattrmap_maprow( + key = 'year' value = NEW /aws1/cl_dynattributevalue( iv_n = |{ '1978' }| ) ) ) + ( VALUE /aws1/cl_dynattributevalue=>ts_putiteminputattrmap_maprow( + key = 'rating' value = NEW /aws1/cl_dynattributevalue( iv_n = |{ '8.1' }| ) ) ) + ) ). + lo_resp_putitem = lo_dyn->putitem( + iv_tablename = iv_table_name + it_item = VALUE /aws1/cl_dynattributevalue=>tt_putiteminputattributemap( + ( VALUE /aws1/cl_dynattributevalue=>ts_putiteminputattrmap_maprow( + key = 'title' value = NEW /aws1/cl_dynattributevalue( iv_s = 'Speed' ) ) ) + ( VALUE /aws1/cl_dynattributevalue=>ts_putiteminputattrmap_maprow( + key = 'year' value = NEW /aws1/cl_dynattributevalue( iv_n = |{ '1994' }| ) ) ) + ( VALUE /aws1/cl_dynattributevalue=>ts_putiteminputattrmap_maprow( + key = 'rating' value = NEW /aws1/cl_dynattributevalue( iv_n = |{ '7.9' }| ) ) ) + ) ). + " TYPE REF TO ZCL_AWS1_dyn_PUT_ITEM_OUTPUT + MESSAGE '3 rows inserted into DynamoDB Table' && iv_table_name TYPE 'I'. + CATCH /aws1/cx_dyncondalcheckfaile00. + MESSAGE 'A condition specified in the operation could not be evaluated.' TYPE 'E'. + CATCH /aws1/cx_dynresourcenotfoundex. + MESSAGE 'The table or index does not exist' TYPE 'E'. + CATCH /aws1/cx_dyntransactconflictex. + MESSAGE 'Another transaction is using the item' TYPE 'E'. + ENDTRY. + + " Get item from table + TRY. + DATA(lo_resp_getitem) = lo_dyn->getitem( + iv_tablename = iv_table_name + it_key = VALUE /aws1/cl_dynattributevalue=>tt_key( + ( VALUE /aws1/cl_dynattributevalue=>ts_key_maprow( + key = 'title' value = NEW /aws1/cl_dynattributevalue( iv_s = 'Jaws' ) ) ) + ( VALUE /aws1/cl_dynattributevalue=>ts_key_maprow( + key = 'year' value = NEW /aws1/cl_dynattributevalue( iv_n = '1975' ) ) ) + ) ). + DATA(lt_attr) = lo_resp_getitem->get_item( ). + DATA(lo_title) = lt_attr[ key = 'title' ]-value. + DATA(lo_year) = lt_attr[ key = 'year' ]-value. + DATA(lo_rating) = lt_attr[ key = 'year' ]-value. + MESSAGE 'Movie name is: ' && lo_title->get_s( ) TYPE 'I'. + MESSAGE 'Movie year is: ' && lo_year->get_n( ) TYPE 'I'. + MESSAGE 'Movie rating is: ' && lo_rating->get_n( ) TYPE 'I'. + CATCH /aws1/cx_dynresourcenotfoundex. + MESSAGE 'The table or index does not exist' TYPE 'E'. + ENDTRY. + + " Query item from table + TRY. + DATA(lt_attributelist) = VALUE /aws1/cl_dynattributevalue=>tt_attributevaluelist( + ( NEW /aws1/cl_dynattributevalue( iv_n = '1975' ) ) ). + DATA(lt_keyconditions) = VALUE /aws1/cl_dyncondition=>tt_keyconditions( + ( VALUE /aws1/cl_dyncondition=>ts_keyconditions_maprow( + key = 'year' + value = NEW /aws1/cl_dyncondition( + it_attributevaluelist = lt_attributelist + iv_comparisonoperator = |EQ| + ) ) ) ). + DATA(lo_query_result) = lo_dyn->query( + iv_tablename = iv_table_name + it_keyconditions = lt_keyconditions ). + DATA(lt_items) = lo_query_result->get_items( ). + READ TABLE lo_query_result->get_items( ) INTO DATA(lt_item) INDEX 1. + lo_title = lt_item[ key = 'title' ]-value. + lo_year = lt_item[ key = 'year' ]-value. + lo_rating = lt_item[ key = 'rating' ]-value. + MESSAGE 'Movie name is: ' && lo_title->get_s( ) TYPE 'I'. + MESSAGE 'Movie year is: ' && lo_year->get_n( ) TYPE 'I'. + MESSAGE 'Movie rating is: ' && lo_rating->get_n( ) TYPE 'I'. + CATCH /aws1/cx_dynresourcenotfoundex. + MESSAGE 'The table or index does not exist' TYPE 'E'. + ENDTRY. + + " Scan items from table + TRY. + DATA(lo_scan_result) = lo_dyn->scan( iv_tablename = iv_table_name ). + lt_items = lo_scan_result->get_items( ). + " Read the first item and display the attributes. + READ TABLE lo_query_result->get_items( ) INTO lt_item INDEX 1. + lo_title = lt_item[ key = 'title' ]-value. + lo_year = lt_item[ key = 'year' ]-value. + lo_rating = lt_item[ key = 'rating' ]-value. + MESSAGE 'Movie name is: ' && lo_title->get_s( ) TYPE 'I'. + MESSAGE 'Movie year is: ' && lo_year->get_n( ) TYPE 'I'. + MESSAGE 'Movie rating is: ' && lo_rating->get_n( ) TYPE 'I'. + CATCH /aws1/cx_dynresourcenotfoundex. + MESSAGE 'The table or index does not exist' TYPE 'E'. + ENDTRY. + + " Update items from table + TRY. + DATA(lt_attributeupdates) = VALUE /aws1/cl_dynattrvalueupdate=>tt_attributeupdates( + ( VALUE /aws1/cl_dynattrvalueupdate=>ts_attributeupdates_maprow( + key = 'rating' value = NEW /aws1/cl_dynattrvalueupdate( + io_value = NEW /aws1/cl_dynattributevalue( iv_n = '7.6' ) + iv_action = |PUT| ) ) ) ). + DATA(lt_key) = VALUE /aws1/cl_dynattributevalue=>tt_key( + ( VALUE /aws1/cl_dynattributevalue=>ts_key_maprow( + key = 'year' value = NEW /aws1/cl_dynattributevalue( iv_n = '1975' ) ) ) + ( VALUE /aws1/cl_dynattributevalue=>ts_key_maprow( + key = 'title' value = NEW /aws1/cl_dynattributevalue( iv_s = '1980' ) ) ) ). + DATA(lo_resp) = lo_dyn->updateitem( + iv_tablename = iv_table_name + it_key = lt_key + it_attributeupdates = lt_attributeupdates ). + MESSAGE '1 item updated in DynamoDB Table' && iv_table_name TYPE 'I'. + CATCH /aws1/cx_dyncondalcheckfaile00. + MESSAGE 'A condition specified in the operation could not be evaluated.' TYPE 'E'. + CATCH /aws1/cx_dynresourcenotfoundex. + MESSAGE 'The table or index does not exist' TYPE 'E'. + CATCH /aws1/cx_dyntransactconflictex. + MESSAGE 'Another transaction is using the item' TYPE 'E'. + ENDTRY. + + " Delete table + TRY. + lo_dyn->deletetable( iv_tablename = iv_table_name ). + lo_dyn->get_waiter( )->tablenotexists( + iv_max_wait_time = 200 + iv_tablename = iv_table_name ). + MESSAGE 'DynamoDB Table deleted.' TYPE 'I'. + CATCH /aws1/cx_dynresourcenotfoundex. + MESSAGE 'The table or index does not exist' TYPE 'E'. + CATCH /aws1/cx_dynresourceinuseex. + MESSAGE 'The table cannot be deleted as it is in use' TYPE 'E'. + ENDTRY. + " snippet-end:[dyn.abapv1.getting_started_with_tables] + ENDMETHOD. +ENDCLASS. diff --git a/sap-abap/services/dyn/zcl_aws1_dyn_scenario.clas.testclasses.abap b/sap-abap/services/dyn/zcl_aws1_dyn_scenario.clas.testclasses.abap new file mode 100644 index 00000000000..53c1d6ffd8c --- /dev/null +++ b/sap-abap/services/dyn/zcl_aws1_dyn_scenario.clas.testclasses.abap @@ -0,0 +1,57 @@ +" """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +" " Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights +" " Reserved. +" " SPDX-License-Identifier: MIT-0 +" """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +CLASS ltc_zcl_aws1_dyn_scenario DEFINITION DEFERRED. +CLASS zcl_aws1_dyn_scenario DEFINITION LOCAL FRIENDS ltc_zcl_aws1_dyn_scenario. + +CLASS ltc_zcl_aws1_dyn_scenario DEFINITION FOR TESTING + DURATION LONG + RISK LEVEL HARMLESS. + + PROTECTED SECTION. + METHODS test_dyn FOR TESTING RAISING /aws1/cx_rt_generic. + + PRIVATE SECTION. + CONSTANTS cv_pfl TYPE /aws1/rt_profile_id VALUE 'ZCODE_DEMO'. + + DATA ao_dyn TYPE REF TO /aws1/if_dyn. + DATA ao_session TYPE REF TO /aws1/cl_rt_session_base. + DATA ao_dyn_scenario TYPE REF TO zcl_aws1_dyn_scenario. + DATA av_table_name TYPE /aws1/dyntablename. + + METHODS setup RAISING /aws1/cx_rt_generic. + + METHODS assert_table_not_exist + IMPORTING iv_table_name TYPE string + RAISING /aws1/cx_rt_generic. + +ENDCLASS. + +CLASS ltc_zcl_aws1_dyn_scenario IMPLEMENTATION. + + METHOD setup. + ao_session = /aws1/cl_rt_session_aws=>create( iv_profile_id = cv_pfl ). + ao_dyn = /aws1/cl_dyn_factory=>create( ao_session ). + ao_dyn_scenario = NEW zcl_aws1_dyn_scenario( ). + ENDMETHOD. + + METHOD test_dyn. + DATA(av_table_name) = |code-example-getting-startted-with-tables|. + ao_dyn_scenario->getting_started_with_tables( av_table_name ). + assert_table_not_exist( iv_table_name = av_table_name ). + ENDMETHOD. + + METHOD assert_table_not_exist. + TRY. + DATA(lv_status) = ao_dyn->describetable( iv_tablename = iv_table_name )->get_table( )->get_tablestatus( ). + " expecting an exception + /aws1/cl_rt_assert_abap=>assert_missed_exception( iv_exception = |/AWS1/CX_DYNRESOURCENOTFOUNDEX| ). + CATCH /aws1/cx_dynresourcenotfoundex. + " good, it is deleted + ENDTRY. + ENDMETHOD. + +ENDCLASS. diff --git a/sap-abap/services/dyn/zcl_aws1_dyn_scenario.clas.xml b/sap-abap/services/dyn/zcl_aws1_dyn_scenario.clas.xml new file mode 100644 index 00000000000..fd80fd10035 --- /dev/null +++ b/sap-abap/services/dyn/zcl_aws1_dyn_scenario.clas.xml @@ -0,0 +1,25 @@ + + + + + + ZCL_AWS1_DYN_SCENARIO + E + Amazon example of Dynamo DB Scenario + 1 + X + X + X + X + + + + ZCL_AWS1_DYN_SCENARIO + GETTING_STARTED_WITH_TABLES + E + Amazon Dynamo DB Scenario. Getting started with tables + + + + + From 09dddedce200a803241d01e8228e90d79477030c Mon Sep 17 00:00:00 2001 From: Laren-AWS <57545972+Laren-AWS@users.noreply.github.com> Date: Wed, 4 Oct 2023 13:33:42 -0700 Subject: [PATCH 2/2] Apply suggestions from code review Co-authored-by: Steven Meyer <108885656+meyertst-aws@users.noreply.github.com> --- .../services/dyn/zcl_aws1_dyn_actions.clas.abap | 6 +++--- .../services/dyn/zcl_aws1_dyn_scenario.clas.abap | 14 +++++++------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/sap-abap/services/dyn/zcl_aws1_dyn_actions.clas.abap b/sap-abap/services/dyn/zcl_aws1_dyn_actions.clas.abap index 41e8a6f5e65..6f174b834c9 100644 --- a/sap-abap/services/dyn/zcl_aws1_dyn_actions.clas.abap +++ b/sap-abap/services/dyn/zcl_aws1_dyn_actions.clas.abap @@ -102,7 +102,7 @@ CLASS ZCL_AWS1_DYN_ACTIONS IMPLEMENTATION. iv_max_wait_time = 200 iv_tablename = iv_table_name ). MESSAGE 'DynamoDB Table' && iv_table_name && 'created.' TYPE 'I'. - " This exception can happen if the table already exists + " This exception can happen if the table already exists. CATCH /aws1/cx_dynresourceinuseex INTO DATA(lo_resourceinuseex). DATA(lv_error) = |"{ lo_resourceinuseex->av_err_code }" - { lo_resourceinuseex->av_err_msg }|. MESSAGE lv_error TYPE 'E'. @@ -218,7 +218,7 @@ CLASS ZCL_AWS1_DYN_ACTIONS IMPLEMENTATION. " snippet-start:[dyn.abapv1.list_tables] TRY. oo_result = lo_dyn->listtables( ). - " You can loop over the oo_result to get table properties like this + " You can loop over the oo_result to get table properties like this. LOOP AT oo_result->get_tablenames( ) INTO DATA(lo_table_name). DATA(lv_tablename) = lo_table_name->get_value( ). ENDLOOP. @@ -280,7 +280,7 @@ CLASS ZCL_AWS1_DYN_ACTIONS IMPLEMENTATION. iv_tablename = iv_table_name it_keyconditions = lt_key_conditions ). DATA(lt_items) = oo_result->get_items( ). - "You can loop over the results to get item attributes + "You can loop over the results to get item attributes. LOOP AT lt_items INTO DATA(lt_item). DATA(lo_title) = lt_item[ key = 'title' ]-value. DATA(lo_year) = lt_item[ key = 'year' ]-value. diff --git a/sap-abap/services/dyn/zcl_aws1_dyn_scenario.clas.abap b/sap-abap/services/dyn/zcl_aws1_dyn_scenario.clas.abap index 7cc95165cbe..ada51fc89e0 100644 --- a/sap-abap/services/dyn/zcl_aws1_dyn_scenario.clas.abap +++ b/sap-abap/services/dyn/zcl_aws1_dyn_scenario.clas.abap @@ -27,7 +27,7 @@ CLASS ZCL_AWS1_DYN_SCENARIO IMPLEMENTATION. CONSTANTS cv_pfl TYPE /aws1/rt_profile_id VALUE 'ZCODE_DEMO'. " snippet-start:[dyn.abapv1.getting_started_with_tables] - " Create an Amazon Dynamo DB table + " Create an Amazon Dynamo DB table. TRY. DATA(lo_session) = /aws1/cl_rt_session_aws=>create( cv_pfl ). @@ -72,7 +72,7 @@ CLASS ZCL_AWS1_DYN_SCENARIO IMPLEMENTATION. MESSAGE 'The table does not exist' TYPE 'E'. ENDTRY. - " Put items into the table + " Put items into the table. TRY. DATA(lo_resp_putitem) = lo_dyn->putitem( iv_tablename = iv_table_name @@ -114,7 +114,7 @@ CLASS ZCL_AWS1_DYN_SCENARIO IMPLEMENTATION. MESSAGE 'Another transaction is using the item' TYPE 'E'. ENDTRY. - " Get item from table + " Get item from table. TRY. DATA(lo_resp_getitem) = lo_dyn->getitem( iv_tablename = iv_table_name @@ -135,7 +135,7 @@ CLASS ZCL_AWS1_DYN_SCENARIO IMPLEMENTATION. MESSAGE 'The table or index does not exist' TYPE 'E'. ENDTRY. - " Query item from table + " Query item from table. TRY. DATA(lt_attributelist) = VALUE /aws1/cl_dynattributevalue=>tt_attributevaluelist( ( NEW /aws1/cl_dynattributevalue( iv_n = '1975' ) ) ). @@ -161,7 +161,7 @@ CLASS ZCL_AWS1_DYN_SCENARIO IMPLEMENTATION. MESSAGE 'The table or index does not exist' TYPE 'E'. ENDTRY. - " Scan items from table + " Scan items from table. TRY. DATA(lo_scan_result) = lo_dyn->scan( iv_tablename = iv_table_name ). lt_items = lo_scan_result->get_items( ). @@ -177,7 +177,7 @@ CLASS ZCL_AWS1_DYN_SCENARIO IMPLEMENTATION. MESSAGE 'The table or index does not exist' TYPE 'E'. ENDTRY. - " Update items from table + " Update items from table. TRY. DATA(lt_attributeupdates) = VALUE /aws1/cl_dynattrvalueupdate=>tt_attributeupdates( ( VALUE /aws1/cl_dynattrvalueupdate=>ts_attributeupdates_maprow( @@ -202,7 +202,7 @@ CLASS ZCL_AWS1_DYN_SCENARIO IMPLEMENTATION. MESSAGE 'Another transaction is using the item' TYPE 'E'. ENDTRY. - " Delete table + " Delete table. TRY. lo_dyn->deletetable( iv_tablename = iv_table_name ). lo_dyn->get_waiter( )->tablenotexists(