Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .doc_gen/metadata/s3_metadata.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2462,6 +2462,14 @@ s3_ListBuckets:
snippet_tags:
- s3.swift.import
- s3.swift.listbuckets.ListBuckets
SAP ABAP:
versions:
- sdk_version: 1
github: sap-abap/services/s3
excerpts:
- description:
snippet_tags:
- s3.abapv1.list_buckets
services:
s3: {ListBuckets}
s3_PutObjectAcl:
Expand Down
23 changes: 23 additions & 0 deletions sap-abap/services/s3/#awsex#cl_s3_actions.clas.abap
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,10 @@ CLASS /awsex/cl_s3_actions DEFINITION
EXPORTING
!oo_result TYPE REF TO /aws1/cl_s3_headbucketoutput
RAISING /aws1/cx_rt_generic.
METHODS list_buckets
EXPORTING
!oo_result TYPE REF TO /aws1/cl_s3_listbucketsoutput
RAISING /aws1/cx_rt_generic.
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
Expand Down Expand Up @@ -815,4 +819,23 @@ CLASS /AWSEX/CL_S3_ACTIONS IMPLEMENTATION.
ENDTRY.
" snippet-end:[s3.abapv1.head_bucket]
ENDMETHOD.


METHOD list_buckets.
CONSTANTS cv_pfl TYPE /aws1/rt_profile_id VALUE 'ZCODE_DEMO'.

DATA(lo_session) = /aws1/cl_rt_session_aws=>create( cv_pfl ).
DATA(lo_s3) = /aws1/cl_s3_factory=>create( lo_session ).

" snippet-start:[s3.abapv1.list_buckets]
TRY.
oo_result = lo_s3->listbuckets( " oo_result is returned for testing purposes. "
).
DATA(lv_bucket_count) = lines( oo_result->get_buckets( ) ).
MESSAGE |Retrieved { lv_bucket_count } buckets in all regions.| TYPE 'I'.
CATCH /aws1/cx_rt_generic.
MESSAGE 'Unable to list buckets.' TYPE 'E'.
ENDTRY.
" snippet-end:[s3.abapv1.list_buckets]
ENDMETHOD.
ENDCLASS.
211 changes: 179 additions & 32 deletions sap-abap/services/s3/#awsex#cl_s3_actions.clas.testclasses.abap
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ CLASS ltc_awsex_cl_s3_actions DEFINITION FOR TESTING DURATION SHORT RISK LEVEL D
put_object_legal_hold FOR TESTING RAISING /aws1/cx_rt_generic,
put_object_retention FOR TESTING RAISING /aws1/cx_rt_generic,
get_object_lock_conf FOR TESTING RAISING /aws1/cx_rt_generic,
put_object_lock_conf FOR TESTING RAISING /aws1/cx_rt_generic.
put_object_lock_conf FOR TESTING RAISING /aws1/cx_rt_generic,
list_buckets FOR TESTING RAISING /aws1/cx_rt_generic.

CLASS-METHODS class_setup RAISING /aws1/cx_rt_generic /awsex/cx_generic.
CLASS-METHODS class_teardown RAISING /aws1/cx_rt_generic /awsex/cx_generic.
Expand Down Expand Up @@ -459,6 +460,8 @@ CLASS ltc_awsex_cl_s3_actions IMPLEMENTATION.
DATA lt_cors_rules TYPE /aws1/cl_s3_corsrule=>tt_corsrules.
DATA lt_methods TYPE /aws1/cl_s3_allowedmethods_w=>tt_allowedmethods.
DATA lt_origins TYPE /aws1/cl_s3_allowedorigins_w=>tt_allowedorigins.
DATA lv_retry TYPE i.
DATA lv_cors_set TYPE abap_bool VALUE abap_false.

APPEND NEW /aws1/cl_s3_allowedmethods_w( iv_value = 'GET' ) TO lt_methods.
APPEND NEW /aws1/cl_s3_allowedorigins_w( iv_value = '*' ) TO lt_origins.
Expand All @@ -467,30 +470,73 @@ CLASS ltc_awsex_cl_s3_actions IMPLEMENTATION.
it_allowedmethods = lt_methods
it_allowedorigins = lt_origins ) TO lt_cors_rules.

ao_s3->putbucketcors(
iv_bucket = av_bucket
io_corsconfiguration = NEW /aws1/cl_s3_corsconfiguration( it_corsrules = lt_cors_rules ) ).
" Set CORS configuration and retry if needed
DO 3 TIMES.
lv_retry = sy-index.
TRY.
ao_s3->putbucketcors(
iv_bucket = av_bucket
io_corsconfiguration = NEW /aws1/cl_s3_corsconfiguration( it_corsrules = lt_cors_rules ) ).

" Wait for CORS configuration to propagate
WAIT UP TO 2 SECONDS.

" Verify CORS was set by reading it back
DATA(lo_verify) = ao_s3->getbucketcors( iv_bucket = av_bucket ).
IF lo_verify IS BOUND AND lo_verify->get_corsrules( ) IS NOT INITIAL.
lv_cors_set = abap_true.
EXIT.
ENDIF.

CATCH /aws1/cx_s3_clientexc INTO DATA(lo_setup_ex).
" Retry on client exception
IF lv_retry = 3.
cl_abap_unit_assert=>fail( msg = |Failed to set CORS configuration after 3 attempts: { lo_setup_ex->get_text( ) }| ).
ENDIF.
WAIT UP TO 1 SECONDS.
ENDTRY.
ENDDO.

" Now test getting the CORS configuration
" Verify CORS was successfully set
cl_abap_unit_assert=>assert_true(
act = lv_cors_set
msg = |CORS configuration was not set after 3 attempts| ).

" Now test getting the CORS configuration using the action method
DATA lo_result TYPE REF TO /aws1/cl_s3_getbktcorsoutput.
ao_s3_actions->get_bucket_cors(
EXPORTING
iv_bucket_name = av_bucket
IMPORTING
oo_result = lo_result ).
TRY.
ao_s3_actions->get_bucket_cors(
EXPORTING
iv_bucket_name = av_bucket
IMPORTING
oo_result = lo_result ).

cl_abap_unit_assert=>assert_bound(
act = lo_result
msg = |Could not get bucket CORS configuration| ).
cl_abap_unit_assert=>assert_bound(
act = lo_result
msg = |Could not get bucket CORS configuration| ).

cl_abap_unit_assert=>assert_not_initial(
act = lo_result->get_corsrules( )
msg = |CORS rules are empty| ).

CATCH /aws1/cx_s3_clientexc INTO DATA(lo_ex).
cl_abap_unit_assert=>fail( msg = |CORS configuration test failed: { lo_ex->get_text( ) }| ).
ENDTRY.

" Cleanup
ao_s3->deletebucketcors( iv_bucket = av_bucket ).
TRY.
ao_s3->deletebucketcors( iv_bucket = av_bucket ).
CATCH /aws1/cx_rt_generic.
" Ignore cleanup errors
ENDTRY.
ENDMETHOD.

METHOD put_bucket_cors.
DATA lt_cors_rules TYPE /aws1/cl_s3_corsrule=>tt_corsrules.
DATA lt_methods TYPE /aws1/cl_s3_allowedmethods_w=>tt_allowedmethods.
DATA lt_origins TYPE /aws1/cl_s3_allowedorigins_w=>tt_allowedorigins.
DATA lv_retry TYPE i.
DATA lv_cors_set TYPE abap_bool VALUE abap_false.

APPEND NEW /aws1/cl_s3_allowedmethods_w( iv_value = 'PUT' ) TO lt_methods.
APPEND NEW /aws1/cl_s3_allowedmethods_w( iv_value = 'POST' ) TO lt_methods.
Expand All @@ -501,18 +547,54 @@ CLASS ltc_awsex_cl_s3_actions IMPLEMENTATION.
it_allowedmethods = lt_methods
it_allowedorigins = lt_origins ) TO lt_cors_rules.

ao_s3_actions->put_bucket_cors(
iv_bucket_name = av_bucket
it_cors_rules = lt_cors_rules ).
" Set CORS configuration with retry logic
DO 3 TIMES.
lv_retry = sy-index.
TRY.
ao_s3_actions->put_bucket_cors(
iv_bucket_name = av_bucket
it_cors_rules = lt_cors_rules ).

" Verify CORS was set
DATA(lo_cors) = ao_s3->getbucketcors( iv_bucket = av_bucket ).
cl_abap_unit_assert=>assert_not_initial(
act = lo_cors->get_corsrules( )
msg = |CORS configuration was not set| ).
" Wait for CORS configuration to propagate
WAIT UP TO 2 SECONDS.

" Verify CORS was set by reading it back
DATA(lo_cors) = ao_s3->getbucketcors( iv_bucket = av_bucket ).
IF lo_cors IS BOUND AND lo_cors->get_corsrules( ) IS NOT INITIAL.
lv_cors_set = abap_true.
EXIT.
ENDIF.

CATCH /aws1/cx_s3_clientexc INTO DATA(lo_ex).
" Retry on client exception
IF lv_retry = 3.
cl_abap_unit_assert=>fail( msg = |Failed to set CORS configuration after 3 attempts: { lo_ex->get_text( ) }| ).
ENDIF.
WAIT UP TO 1 SECONDS.
ENDTRY.
ENDDO.

" Verify CORS was successfully set
cl_abap_unit_assert=>assert_true(
act = lv_cors_set
msg = |CORS configuration was not set after 3 attempts| ).

" Verify the CORS rules content
TRY.
DATA(lo_verify) = ao_s3->getbucketcors( iv_bucket = av_bucket ).
cl_abap_unit_assert=>assert_not_initial(
act = lo_verify->get_corsrules( )
msg = |CORS configuration rules are empty| ).
CATCH /aws1/cx_s3_clientexc INTO DATA(lo_verify_ex).
cl_abap_unit_assert=>fail( msg = |Could not verify CORS configuration: { lo_verify_ex->get_text( ) }| ).
ENDTRY.

" Cleanup
ao_s3->deletebucketcors( iv_bucket = av_bucket ).
TRY.
ao_s3->deletebucketcors( iv_bucket = av_bucket ).
CATCH /aws1/cx_rt_generic.
" Ignore cleanup errors
ENDTRY.
ENDMETHOD.

METHOD delete_bucket_cors.
Expand Down Expand Up @@ -679,24 +761,63 @@ CLASS ltc_awsex_cl_s3_actions IMPLEMENTATION.

METHOD put_bucket_lifecycle_conf.
DATA lt_rules TYPE /aws1/cl_s3_lifecyclerule=>tt_lifecyclerules.
DATA lv_retry TYPE i.
DATA lv_lifecycle_set TYPE abap_bool VALUE abap_false.

APPEND NEW /aws1/cl_s3_lifecyclerule(
iv_id = 'TestRule'
iv_status = 'Enabled'
io_filter = NEW /aws1/cl_s3_lcrulefilter( iv_prefix = 'archive/' )
io_expiration = NEW /aws1/cl_s3_lifecycleexpir( iv_days = 60 ) ) TO lt_rules.

ao_s3_actions->put_bucket_lifecycle_conf(
iv_bucket_name = av_bucket
it_lifecycle_rule = lt_rules ).
" Set lifecycle configuration with retry logic
DO 3 TIMES.
lv_retry = sy-index.
TRY.
ao_s3_actions->put_bucket_lifecycle_conf(
iv_bucket_name = av_bucket
it_lifecycle_rule = lt_rules ).

" Verify lifecycle was set
DATA(lo_lc) = ao_s3->getbucketlifecycleconf( iv_bucket = av_bucket ).
cl_abap_unit_assert=>assert_not_initial(
act = lo_lc->get_rules( )
msg = |Lifecycle configuration was not set| ).
" Wait for lifecycle configuration to propagate
WAIT UP TO 2 SECONDS.

" Verify lifecycle was set by reading it back
DATA(lo_lc) = ao_s3->getbucketlifecycleconf( iv_bucket = av_bucket ).
IF lo_lc IS BOUND AND lo_lc->get_rules( ) IS NOT INITIAL.
lv_lifecycle_set = abap_true.
EXIT.
ENDIF.

CATCH /aws1/cx_s3_clientexc INTO DATA(lo_ex).
" Retry on client exception
IF lv_retry = 3.
cl_abap_unit_assert=>fail( msg = |Failed to set lifecycle configuration after 3 attempts: { lo_ex->get_text( ) }| ).
ENDIF.
WAIT UP TO 1 SECONDS.
ENDTRY.
ENDDO.

" Verify lifecycle was successfully set
cl_abap_unit_assert=>assert_true(
act = lv_lifecycle_set
msg = |Lifecycle configuration was not set after 3 attempts| ).

" Verify the rules content
TRY.
DATA(lo_verify) = ao_s3->getbucketlifecycleconf( iv_bucket = av_bucket ).
cl_abap_unit_assert=>assert_not_initial(
act = lo_verify->get_rules( )
msg = |Lifecycle configuration rules are empty| ).
CATCH /aws1/cx_s3_clientexc INTO DATA(lo_verify_ex).
cl_abap_unit_assert=>fail( msg = |Could not verify lifecycle configuration: { lo_verify_ex->get_text( ) }| ).
ENDTRY.

" Cleanup
ao_s3->deletebucketlifecycle( iv_bucket = av_bucket ).
TRY.
ao_s3->deletebucketlifecycle( iv_bucket = av_bucket ).
CATCH /aws1/cx_rt_generic.
" Ignore cleanup errors
ENDTRY.
ENDMETHOD.

METHOD delete_bucket_lifecycle.
Expand Down Expand Up @@ -1103,4 +1224,30 @@ CLASS ltc_awsex_cl_s3_actions IMPLEMENTATION.
ENDTRY.
ENDMETHOD.

METHOD list_buckets.
DATA lo_result TYPE REF TO /aws1/cl_s3_listbucketsoutput.

ao_s3_actions->list_buckets(
IMPORTING
oo_result = lo_result ).

" Verify we got buckets back
cl_abap_unit_assert=>assert_bound(
act = lo_result
msg = |Could not list buckets| ).

" Verify that our test buckets are in the list
DATA(lv_found_bucket) = abap_false.
LOOP AT lo_result->get_buckets( ) INTO DATA(lo_bucket).
IF lo_bucket->get_name( ) = av_bucket.
lv_found_bucket = abap_true.
EXIT.
ENDIF.
ENDLOOP.

cl_abap_unit_assert=>assert_true(
act = lv_found_bucket
msg = |Test bucket { av_bucket } not found in bucket list| ).
ENDMETHOD.

ENDCLASS.
59 changes: 30 additions & 29 deletions sap-abap/services/s3/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,35 +40,36 @@ Code examples that show you how to perform the essential operations within a ser

Code excerpts that show you how to call individual service functions.

- [CopyObject](%23awsex%23cl_s3_actions.clas.abap#L194)
- [CreateBucket](%23awsex%23cl_s3_actions.clas.abap#L217)
- [DeleteBucket](%23awsex%23cl_s3_actions.clas.abap#L250)
- [DeleteBucketCors](%23awsex%23cl_s3_actions.clas.abap#L475)
- [DeleteBucketLifecycle](%23awsex%23cl_s3_actions.clas.abap#L590)
- [DeleteBucketPolicy](%23awsex%23cl_s3_actions.clas.abap#L533)
- [DeleteObject](%23awsex%23cl_s3_actions.clas.abap#L270)
- [DeleteObjects](%23awsex%23cl_s3_actions.clas.abap#L378)
- [GetBucketAcl](%23awsex%23cl_s3_actions.clas.abap#L397)
- [GetBucketCors](%23awsex%23cl_s3_actions.clas.abap#L436)
- [GetBucketLifecycleConfiguration](%23awsex%23cl_s3_actions.clas.abap#L551)
- [GetBucketPolicy](%23awsex%23cl_s3_actions.clas.abap#L493)
- [GetObject](%23awsex%23cl_s3_actions.clas.abap#L289)
- [GetObjectAcl](%23awsex%23cl_s3_actions.clas.abap#L608)
- [GetObjectLegalHold](%23awsex%23cl_s3_actions.clas.abap#L653)
- [GetObjectLockConfiguration](%23awsex%23cl_s3_actions.clas.abap#L727)
- [HeadBucket](%23awsex%23cl_s3_actions.clas.abap#L808)
- [ListObjectVersions](%23awsex%23cl_s3_actions.clas.abap#L789)
- [ListObjectsV2](%23awsex%23cl_s3_actions.clas.abap#L330)
- [PutBucketAcl](%23awsex%23cl_s3_actions.clas.abap#L415)
- [PutBucketCors](%23awsex%23cl_s3_actions.clas.abap#L454)
- [PutBucketLifecycleConfiguration](%23awsex%23cl_s3_actions.clas.abap#L569)
- [PutBucketPolicy](%23awsex%23cl_s3_actions.clas.abap#L512)
- [PutBucketVersioning](%23awsex%23cl_s3_actions.clas.abap#L767)
- [PutObject](%23awsex%23cl_s3_actions.clas.abap#L349)
- [PutObjectAcl](%23awsex%23cl_s3_actions.clas.abap#L629)
- [PutObjectLegalHold](%23awsex%23cl_s3_actions.clas.abap#L674)
- [PutObjectLockConfiguration](%23awsex%23cl_s3_actions.clas.abap#L745)
- [PutObjectRetention](%23awsex%23cl_s3_actions.clas.abap#L699)
- [CopyObject](%23awsex%23cl_s3_actions.clas.abap#L198)
- [CreateBucket](%23awsex%23cl_s3_actions.clas.abap#L221)
- [DeleteBucket](%23awsex%23cl_s3_actions.clas.abap#L254)
- [DeleteBucketCors](%23awsex%23cl_s3_actions.clas.abap#L479)
- [DeleteBucketLifecycle](%23awsex%23cl_s3_actions.clas.abap#L594)
- [DeleteBucketPolicy](%23awsex%23cl_s3_actions.clas.abap#L537)
- [DeleteObject](%23awsex%23cl_s3_actions.clas.abap#L274)
- [DeleteObjects](%23awsex%23cl_s3_actions.clas.abap#L382)
- [GetBucketAcl](%23awsex%23cl_s3_actions.clas.abap#L401)
- [GetBucketCors](%23awsex%23cl_s3_actions.clas.abap#L440)
- [GetBucketLifecycleConfiguration](%23awsex%23cl_s3_actions.clas.abap#L555)
- [GetBucketPolicy](%23awsex%23cl_s3_actions.clas.abap#L497)
- [GetObject](%23awsex%23cl_s3_actions.clas.abap#L293)
- [GetObjectAcl](%23awsex%23cl_s3_actions.clas.abap#L612)
- [GetObjectLegalHold](%23awsex%23cl_s3_actions.clas.abap#L657)
- [GetObjectLockConfiguration](%23awsex%23cl_s3_actions.clas.abap#L731)
- [HeadBucket](%23awsex%23cl_s3_actions.clas.abap#L812)
- [ListBuckets](%23awsex%23cl_s3_actions.clas.abap#L830)
- [ListObjectVersions](%23awsex%23cl_s3_actions.clas.abap#L793)
- [ListObjectsV2](%23awsex%23cl_s3_actions.clas.abap#L334)
- [PutBucketAcl](%23awsex%23cl_s3_actions.clas.abap#L419)
- [PutBucketCors](%23awsex%23cl_s3_actions.clas.abap#L458)
- [PutBucketLifecycleConfiguration](%23awsex%23cl_s3_actions.clas.abap#L573)
- [PutBucketPolicy](%23awsex%23cl_s3_actions.clas.abap#L516)
- [PutBucketVersioning](%23awsex%23cl_s3_actions.clas.abap#L771)
- [PutObject](%23awsex%23cl_s3_actions.clas.abap#L353)
- [PutObjectAcl](%23awsex%23cl_s3_actions.clas.abap#L633)
- [PutObjectLegalHold](%23awsex%23cl_s3_actions.clas.abap#L678)
- [PutObjectLockConfiguration](%23awsex%23cl_s3_actions.clas.abap#L749)
- [PutObjectRetention](%23awsex%23cl_s3_actions.clas.abap#L703)

### Scenarios

Expand Down
Loading