

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# Amazon S3 示例程序
<a name="example-program"></a>

本节将使用简单的示例程序引导您调用 `ListObjectsV2`，以列出 Amazon S3 存储桶中的内容。

**Topics**
+ [

## 先决条件
](#prerequisites-example-program)
+ [

## 代码
](#code-example-program)
+ [

## 代码部分
](#code-sections)

## 先决条件
<a name="prerequisites-example-program"></a>

您必须满足以下先决条件才能运行此示例程序。
+ 您拥有 Amazon S3 存储桶。将本教程中的存储桶命名为 `demo-invoices.customer.com`。
+ `/AWS1/IMG` 事务：
  + 将已定义的 SDK 配置文件命名为 `DEMO_S3`。
    + 必须将 SDK 配置文件中的 IAM 逻辑角色 `TESTUSER` 映射到 IAM 角色，如 `arn:aws:iam::111122223333:role/SapDemoFinance`，其授予该角色列出 Amazon S3 存储桶内容的 `s3:ListBucket` 权限。
  + 将逻辑资源命名为 `DEMO_BUCKET`，其通过 SAP 系统的 SID 和客户端映射到 Amazon S3 存储桶。
+ 您的用户拥有 PFCG 角色，其：
  + 授予用户通过身份验证对象 `/AWS1/SESS` 访问 `DEMO_S3` SDK 配置文件的权限。
  + 授予用户通过身份验证对象 `/AWS1/LROL` 访问 IAM 逻辑角色 `TESTUSER` 的权限。
+ 您的 SAP 系统可以 AWS 使用 SDK 配置文件中定义的方法进行身份验证。
+ 您的 Amazon EC2 实例配置文件授予您的 SAP 系统使用`sts:assumeRole`软件开发工具包配置文件中`arn:aws:iam::111122223333:role/SapDemoFinance`映射的 IAM 角色的权利。

## 代码
<a name="code-example-program"></a>

以下代码块展示了您的代码情况。

```
REPORT  zdemo_s3_listbuckets.

START-OF-SELECTION.
  PARAMETERS pv_lres TYPE  /aws1/rt_resource_logical
                     DEFAULT 'DEMO_BUCKET' OBLIGATORY.

  DATA(go_session) = /aws1/cl_rt_session_aws=>create( 'DEMO_S3'  ).
  DATA(gv_bucket)   = go_session->resolve_lresource( pv_lres ).

  DATA(go_s3)       = /aws1/cl_s3_factory=>create( go_session ).

  TRY.
      DATA(lo_output) = go_s3->listobjectsv2(
            iv_bucket = CONV string( gv_bucket )
            iv_maxkeys = 100
      ).
      LOOP AT lo_output->get_contents(  ) INTO DATA(lo_object).
        DATA lv_mdate TYPE datum.
        CONVERT TIME STAMP lo_object->get_lastmodified( )
                TIME ZONE 'UTC'
                INTO DATE lv_mdate.
        WRITE: /  CONV text30( lo_object->get_key( ) ),
                 lv_mdate, lo_object->get_size( ).
      ENDLOOP.
    CATCH /aws1/cx_rt_generic INTO DATA(lo_ex).
      DATA(lv_msg) = lo_ex->if_message~get_text(  ).
      MESSAGE lv_msg TYPE 'I'.
  ENDTRY.
```

## 代码部分
<a name="code-sections"></a>

各部分的代码情况审查如下。

```
  PARAMETERS pv_lres TYPE  /aws1/rt_resource_logical
                     DEFAULT 'DEMO_BUCKET' OBLIGATORY.
```

用户无法指定物理存储桶名称，但可以指定逻辑存储桶与配合 AWS 管理员工作的系统管理员（尤其是业务分析师），从而向 `/AWS1/IMG` 中的物理存储桶映射逻辑存储桶。在大多数业务场景中，逻辑资源 ID 会在代码中进行硬编码或在自定义配置表中进行配置，因此用户没有机会选择逻辑存储桶。

```
  DATA(go_session) = /aws1/cl_rt_session_aws=>create( 'DEMO_S3'  ).
```

使用此行建立安全会话并声明 ABAP 程序期望使用 `DEMO_S3` SDK 配置文件。执行调用操作，以建立 SDK 配置连接并提取默认区域、身份验证设置和所需的 IAM 角色。自动调用 `AUTHORIZATION-CHECK`，以确保满足授权对象 `/AWS1/SESS` 的要求。此外，基于授权对象 `/AWS1/LROL` 执行 `AUTHORIZATION-CHECK` 调用操作，以确定授予用户的功能最强大（序列号较小）的 IAM 逻辑角色。SDK 会假设 IAM 角色已映射到适用于 SID 和客户端的 IAM 逻辑角色。随后，会话对象将根据 `IMG` 跟踪设置激活跟踪。

如果用户无权使用请求的 SDK 配置文件或任何可用的 IAM 逻辑角色，则会发生异常。

```
DATA(gv_bucket)   = go_session->resolve_lresource( pv_lres ).
```

此行将逻辑资源解析为物理存储桶名称。如果因为配置缺乏适用于 SID/客户端组合的映射而无法解析逻辑资源，则会发生异常。

```
  DATA(go_s3)       = /aws1/cl_s3_factory=>create( go_session ).
```

此行使用 `/aws1/cl_s3_factory` 方法的 `create()`，创建适用于 Amazon S3 的 API 对象。返回 `/aws1/if_s3` 类型的对象作为 Amazon S3 的 API 接口。必须为每项服务创建单独的 API 对象。例如，如果 ABAP 程序正在使用 Amazon S3 AWS Lambda、和 DynamoDB，则它会从、和创建 API 对象`/aws1/cl_s3_factory`。`/aws1/cl_lmd_factory` `/aws1/cl_dyn_factory`

如需覆盖经过默认区域配置的 `IMG`，则可以在支持区域指定的构造函数中选择部分可选参数。这样，您就能拥有两个 `/aws1/if_s3` 实例，分别用于 `us-east-1` 和 `us-west-2`，以便在不同区域的存储桶之间复制对象。同样，如果要通过报告读取财务相关存储桶中的数据并向物流相关存储桶写入对象，您可以创建两个不同的安全会话对象，用于创建两个单独的 `/aws1/cl_s3` 实例。

```
      DATA(lo_output) = go_s3->listobjectsv2(
            iv_bucket = CONV string( gv_bucket )
            iv_maxkeys = 100
      ).
```

 此行表示 `ListObjectsV2` 调用。输入简单参数后，此行会返回单一对象。这些对象可能表示 JSON 和 XML 深层数据，将其反序列化为面向 ABAP 对象的构造。某些情况下可能非常复杂。您现在只需处理输出内容，列出存储桶内容。

```
      LOOP AT lo_output->get_contents(  ) INTO DATA(lo_object).
        DATA lv_mdate TYPE datum.
        CONVERT TIME STAMP lo_object->get_lastmodified( )
                TIME ZONE 'UTC'
                INTO DATE lv_mdate.
        WRITE: /  CONV text30( lo_object->get_key( ) ),
                 lv_mdate, lo_object->get_size( ).
      ENDLOOP.
```

使用隐藏数据内部表示方式的 `GET...()` 样式法，即可访问数据。`GET_CONTENTS( )` 会返回 ABAP 表，其中每一行都含有表示 Amazon S3 单一条目的对象。在大多数情况下， AWS SDK 采用这种面向对象的方法，所有数据都以对象和表格的形式表示。 该`LastModified`字段以时间戳表示，可以使用 abap-native `CONVERT TIME STAMP` 命令将其转换为日期。为了便于数学运算和格式化操作，会`GET_SIZE()`返回一个`INT4`。

```
    CATCH /aws1/cx_rt_generic INTO DATA(lo_ex).
      DATA(lv_msg) = lo_ex->if_message~get_text(  ).
      MESSAGE lv_msg TYPE 'I'.
```

所有错误：连接错误、4xx 客户端错误、5xx 服务器错误或任何 ABAP 错误（如授权或配置错误）均表示为异常。这些异常可以单独解决。您可以决定是将异常作为信息性错误、重试、警告、Short Dump 还是作为其他任意类型的错误进行处理。