diff --git a/.doc_gen/metadata/s3_metadata.yaml b/.doc_gen/metadata/s3_metadata.yaml index b3e0532a61e..690b616c405 100644 --- a/.doc_gen/metadata/s3_metadata.yaml +++ b/.doc_gen/metadata/s3_metadata.yaml @@ -2952,6 +2952,14 @@ s3_Scenario_PresignedUrl: - snippet_tags: - s3.php.presigned_url.complete - php.example_code.s3.service.S3Service + SAP ABAP: + versions: + - sdk_version: 1 + github: sap-abap/services/s3 + excerpts: + - description: Create presigned requests to GET S3 objects. + snippet_tags: + - s3.abapv1.s3_presigned_url_get services: s3: {} s3_Scenario_ObjectVersioningUsage: diff --git a/sap-abap/services/s3/README.md b/sap-abap/services/s3/README.md index d8454a2bec8..bb0fd168e11 100644 --- a/sap-abap/services/s3/README.md +++ b/sap-abap/services/s3/README.md @@ -48,6 +48,13 @@ Code excerpts that show you how to call individual service functions. - [ListObjectsV2](zcl_aws1_s3_actions.clas.abap#L197) - [PutObject](zcl_aws1_s3_actions.clas.abap#L216) +### Scenarios + +Code examples that show you how to accomplish a specific task by calling multiple +functions within the same service. + +- [Create a presigned URL](zcl_aws1_s3_scenario.clas.abap) + @@ -79,6 +86,18 @@ This example shows you how to do the following: +#### Create a presigned URL + +This example shows you how to create a presigned URL for Amazon S3 and upload an object. + + + + + + + + + ### Tests ⚠ Running tests might result in charges to your AWS account. diff --git a/sap-abap/services/s3/zcl_aws1_s3_scenario.clas.abap b/sap-abap/services/s3/zcl_aws1_s3_scenario.clas.abap index 0857d599654..1921a5dc280 100644 --- a/sap-abap/services/s3/zcl_aws1_s3_scenario.clas.abap +++ b/sap-abap/services/s3/zcl_aws1_s3_scenario.clas.abap @@ -10,11 +10,25 @@ CLASS zcl_aws1_s3_scenario DEFINITION METHODS getting_started_with_s3 IMPORTING - !iv_bucket_name TYPE /aws1/s3_bucketname - !iv_key TYPE /aws1/s3_objectkey - !iv_copy_to_folder TYPE /aws1/s3_bucketname + !iv_bucket_name TYPE /aws1/s3_bucketname + !iv_key TYPE /aws1/s3_objectkey + !iv_copy_to_folder TYPE /aws1/s3_bucketname EXPORTING - !oo_result TYPE REF TO /aws1/cl_knsputrecordoutput . + !oo_result TYPE REF TO /aws1/cl_knsputrecordoutput + RAISING + /aws1/cx_rt_service_generic + /aws1/cx_rt_technical_generic + /aws1/cx_rt_no_auth_generic . + METHODS presigner_get + IMPORTING + !iv_bucket_name TYPE /aws1/s3_bucketname + !iv_key TYPE /aws1/s3_objectkey + RETURNING + VALUE(ov_url) TYPE string + RAISING + /aws1/cx_rt_service_generic + /aws1/cx_rt_technical_generic + /aws1/cx_rt_no_auth_generic . PROTECTED SECTION. PRIVATE SECTION. ENDCLASS. @@ -140,4 +154,44 @@ CLASS ZCL_AWS1_S3_SCENARIO IMPLEMENTATION. "snippet-end:[s3.abapv1.getting_started_with_s3] ENDMETHOD. + + + METHOD presigner_get. + CONSTANTS cv_pfl TYPE /aws1/rt_profile_id VALUE 'ZCODE_DEMO'. + + "snippet-start:[s3.abapv1.s3_presigned_url_get] + " iv_bucket_name is the bucket name + " iv_key is the object name like "myfile.txt" + + DATA(lo_session) = /aws1/cl_rt_session_aws=>create( cv_pfl ). + DATA(lo_s3) = /aws1/cl_s3_factory=>create( lo_session ). + + "Upload a nice Hello World file to an S3 bucket." + TRY. + DATA(lv_contents) = cl_abap_codepage=>convert_to( 'Hello, World' ). + lo_s3->putobject( + iv_bucket = iv_bucket_name + iv_key = iv_key + iv_body = lv_contents + iv_contenttype = 'text/plain' ). + MESSAGE 'Object uploaded to S3 bucket.' TYPE 'I'. + CATCH /aws1/cx_s3_nosuchbucket. + MESSAGE 'Bucket does not exist.' TYPE 'E'. + ENDTRY. + + " now generate a presigned URL with a 600-second expiration + DATA(lo_presigner) = lo_s3->get_presigner( iv_expires_sec = 600 ). + " the presigner getobject() method has the same signature as + " lo_s3->getobject(), but it doesn't actually make the call. + " to the service. It just prepares a presigned URL for a future call + DATA(lo_presigned_req) = lo_presigner->getobject( + iv_bucket = iv_bucket_name + iv_key = iv_key ). + + " You can provide this URL to a web page, user, email etc so they + " can retrieve the file. The URL will expire in 10 minutes. + ov_url = lo_presigned_req->get_url( ). + "snippet-end:[s3.abapv1.s3_presigned_url_get] + + ENDMETHOD. ENDCLASS. diff --git a/sap-abap/services/s3/zcl_aws1_s3_scenario.clas.testclasses.abap b/sap-abap/services/s3/zcl_aws1_s3_scenario.clas.testclasses.abap index a2f5cb9fc97..5ffd5c8e5f8 100644 --- a/sap-abap/services/s3/zcl_aws1_s3_scenario.clas.testclasses.abap +++ b/sap-abap/services/s3/zcl_aws1_s3_scenario.clas.testclasses.abap @@ -18,7 +18,7 @@ CLASS ltc_zcl_aws1_s3_scenario DEFINITION FOR TESTING DURATION SHORT RISK LEVEL DATA ao_s3_scenario TYPE REF TO zcl_aws1_s3_scenario. METHODS getting_started_scenario FOR TESTING RAISING /aws1/cx_rt_generic. - + METHODS presigner_get_scenario FOR TESTING RAISING /aws1/cx_rt_generic cx_uuid_error. METHODS setup RAISING /aws1/cx_rt_generic zcx_aws1_ex_generic. METHODS teardown RAISING /aws1/cx_rt_generic zcx_aws1_ex_generic. @@ -75,4 +75,39 @@ CLASS ltc_zcl_aws1_s3_scenario IMPLEMENTATION. act = lv_found msg = |Bucket { av_bucket } should have been deleted| ). ENDMETHOD. + + METHOD presigner_get_scenario. + " we don't show the customer the bucket creation in this scenario. + " So we'll create a separate bucket just for this scenario + DATA(lo_session) = /aws1/cl_rt_session_aws=>create( cv_pfl ). + DATA(lo_s3) = /aws1/cl_s3_factory=>create( lo_session ). + + DATA(lv_region) = CONV /aws1/s3_bucketlocationcnstrnt( lo_session->get_region( ) ). + DATA lo_constraint TYPE REF TO /aws1/cl_s3_createbucketconf. + IF lv_region = 'us-east-1'. + CLEAR lo_constraint. + ELSE. + lo_constraint = NEW /aws1/cl_s3_createbucketconf( lv_region ). + ENDIF. + + DATA(lv_uuid) = cl_system_uuid=>if_system_uuid_static~create_uuid_c32( ). + TRANSLATE lv_uuid TO LOWER CASE. + DATA(lv_bucket_name) = |sap-abap-s3-scenario-presigner-{ lv_uuid }|. + + lo_s3->createbucket( + iv_bucket = lv_bucket_name + io_createbucketconfiguration = lo_constraint ). + + + DATA(lv_url) = ao_s3_scenario->presigner_get( + iv_bucket_name = lv_bucket_name + iv_key = cv_file ). + ASSERT lv_url IS NOT INITIAL. + + " cleanup + lo_s3->deleteobject( iv_bucket = lv_bucket_name iv_key = cv_file ). + lo_s3->deletebucket( iv_bucket = lv_bucket_name ). + + ENDMETHOD. + ENDCLASS. diff --git a/sap-abap/services/s3/zcl_aws1_s3_scenario.clas.xml b/sap-abap/services/s3/zcl_aws1_s3_scenario.clas.xml index 97af3930292..6bae44f2d78 100644 --- a/sap-abap/services/s3/zcl_aws1_s3_scenario.clas.xml +++ b/sap-abap/services/s3/zcl_aws1_s3_scenario.clas.xml @@ -18,7 +18,56 @@ E Getting started with Amazon S3 buckets and objects. + + PRESIGNER_GET + E + Getting started with Amazon S3 buckets and objects. + + + + GETTING_STARTED_WITH_S3 + /AWS1/CX_RT_NO_AUTH_GENERIC + E + Generic lack of authorization + + + GETTING_STARTED_WITH_S3 + /AWS1/CX_RT_SERVICE_GENERIC + E + Generic Service call error + + + GETTING_STARTED_WITH_S3 + /AWS1/CX_RT_TECHNICAL_GENERIC + E + Technical errors + + + PRESIGNER_GET + /AWS1/CX_RT_NO_AUTH_GENERIC + E + Generic lack of authorization + + + PRESIGNER_GET + /AWS1/CX_RT_SERVICE_GENERIC + E + Generic Service call error + + + PRESIGNER_GET + /AWS1/CX_RT_TECHNICAL_GENERIC + E + Technical errors + + + PRESIGNER_GET + IV_KEY + E + Object Key + +