

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 遷移至 DynamoDB Java 用戶端加密程式庫的 3.x 版
<a name="ddb-java-migrate"></a>


****  

|  | 
| --- |
| 我們的用戶端加密程式庫已重新命名為 AWS 資料庫加密 SDK。此開發人員指南仍提供有關 [DynamoDB 加密用戶端](legacy-dynamodb-encryption-client.md)的資訊。 | 

適用於 DynamoDB 的 Java 用戶端加密程式庫 3.*x* 版是 2.*x* 程式碼基礎的主要重寫。它包含許多更新，例如新的結構化資料格式、改善的多租戶支援、無縫結構描述變更，以及可搜尋的加密支援。本主題提供如何將程式碼遷移至 3.*x* 版的指引。

## 從 1.x 版遷移至 2.x 版
<a name="ddb-java-v1-to-v2"></a>

遷移至 2.*x* 版，然後再遷移至 3.*x* 版。2.*x* 版將最近提供者的符號從 變更為 `MostRecentProvider` `CachingMostRecentProvider`。如果您目前使用適用於 DynamoDB 的 Java 用戶端加密程式庫 1.*x* 版搭配 `MostRecentProvider`符號，則必須將程式碼中的符號名稱更新為 `CachingMostRecentProvider`。如需詳細資訊，請參閱[最近供應商的更新](most-recent-provider.md#mrp-versions)。

## 從 2.x 版遷移至 3.x
<a name="ddb-java-v2-to-v3"></a>

下列程序說明如何將程式碼從 2.*x* 版遷移至 DynamoDB Java 用戶端加密程式庫的 3.*x* 版。

### 步驟 1. 準備讀取新格式的項目
<a name="ddb-java-migrate-step1"></a>

請完成下列步驟，以準備您的 AWS Database Encryption SDK 用戶端以讀取新格式的項目。部署下列變更之後，您的用戶端會繼續以與 2.*x* 版相同的方式運作。您的用戶端將繼續讀取和寫入 2.*x* 版格式的項目，但這些變更可讓用戶端準備好[讀取新格式的項目](#ddb-java-migrate-step2)。

**將 更新 適用於 Java 的 AWS SDK 至 2.x 版**  
DynamoDB 的 Java 用戶端加密程式庫版本 3.*x* 需要 [DynamoDB 增強型用戶端](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/dynamodb-enhanced-client.html)。DynamoDB 增強型用戶端會取代先前版本中使用的 [DynamoDBMapper](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBMapper.Methods.html)。若要使用增強型用戶端，您必須使用 AWS SDK for Java 2.x。  
遵循[從 1.x 版遷移至 2.x 版 適用於 Java 的 AWS SDK](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/migration.html)的指示。  
如需需要哪些 AWS SDK for Java 2.x 模組的詳細資訊，請參閱 [先決條件](ddb-java.md#ddb-java-prerequisites)。

**將用戶端設定為讀取舊版加密的項目**  
下列程序提供以下程式碼範例中示範的步驟概觀。  

1. 建立 [keyring](keyrings.md)。

   Keyring 和[密碼編譯資料管理員](concepts.md#crypt-materials-manager)會取代 DynamoDB 舊版 Java 用戶端加密程式庫中使用的密碼編譯資料提供者。
**重要**  
您在建立 keyring 時指定的包裝金鑰，必須與您在 2.*x* 版中與密碼編譯資料提供者搭配使用的包裝金鑰相同。

1. 在註釋的類別上建立資料表結構描述。

   此步驟定義了當您開始以新格式寫入項目時將使用的屬性動作。

   如需使用新 DynamoDB 增強型用戶端的指引，請參閱《 *適用於 Java 的 AWS SDK 開發人員指南*》中的[產生 `TableSchema`](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/ddb-en-client-gs-tableschema.html)。

   下列範例假設您使用新的屬性動作註釋，從 2.*x* 版更新您的註釋類別。如需註釋屬性動作的更多指引，請參閱 [使用標註的資料類別](ddb-java-using.md#ddb-attribute-actions-annotated-data-class)。
**注意**  
如果您指定任何`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`屬性，則分割區和排序屬性也必須是 `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`。如需顯示用於定義 之註釋的範例`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`，請參閱 [SimpleClass4.java](https://github.com/aws/aws-database-encryption-sdk-dynamodb//blob/main/Examples/runtimes/java/DynamoDbEncryption/src/main/java/software/amazon/cryptography/examples/enhanced/SimpleClass4.java)。

1. 定義[要從簽章中排除哪些屬性](ddb-java-using.md#allowed-unauth)。

1. 設定 2.x 版模型化類別中所設定屬性動作的明確映射。

   此步驟定義用於以舊格式寫入項目的屬性動作。

1. 設定`DynamoDBEncryptor`您在 DynamoDB 的 Java 用戶端加密程式庫 2.*x* 版中使用的 。

1. 設定舊版行為。

1. 建立 `DynamoDbEncryptionInterceptor`。

1. 建立新的 AWS SDK DynamoDB 用戶端。

1. 建立 `DynamoDBEnhancedClient`並使用模型化類別建立資料表。

   如需 DynamoDB 增強型用戶端的詳細資訊，請參閱[建立增強型用戶端](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/ddb-en-client-getting-started-dynamodbTable.html#ddb-en-client-getting-started-dynamodbTable-eclient)。

```
public class MigrationExampleStep1 {

    public static void MigrationStep1(String kmsKeyId, String ddbTableName, int sortReadValue) {
        // 1. Create a Keyring.
        //    This example creates an AWS KMS Keyring that specifies the 
        //    same kmsKeyId previously used in the version 2.x configuration.
        //    It uses the 'CreateMrkMultiKeyring' method to create the 
        //    keyring, so that the keyring can correctly handle both single
        //    region and Multi-Region KMS Keys.
        //    Note that this example uses the AWS SDK for Java v2 KMS client.
        final MaterialProviders matProv = MaterialProviders.builder()
                .MaterialProvidersConfig(MaterialProvidersConfig.builder().build())
                .build();
        final CreateAwsKmsMrkMultiKeyringInput keyringInput = CreateAwsKmsMrkMultiKeyringInput.builder()
                .generator(kmsKeyId)
                .build();
        final IKeyring kmsKeyring = matProv.CreateAwsKmsMrkMultiKeyring(keyringInput);

        // 2. Create a Table Schema over your annotated class.
        //    For guidance on using the new attribute actions 
        //    annotations, see SimpleClass.java in the 
        //    aws-database-encryption-sdk-dynamodb GitHub repository. 
        //    All primary key attributes must be signed but not encrypted 
        //    and by default all non-primary key attributes 
        //    are encrypted and signed (ENCRYPT_AND_SIGN).
        //    If you want a particular non-primary key attribute to be signed but
        //    not encrypted, use the 'DynamoDbEncryptionSignOnly' annotation.
        //    If you want a particular attribute to be neither signed nor encrypted
        //    (DO_NOTHING), use the 'DynamoDbEncryptionDoNothing' annotation.
        final TableSchema<SimpleClass> schemaOnEncrypt = TableSchema.fromBean(SimpleClass.class);

        // 3. Define which attributes the client should expect to be excluded 
        //    from the signature when reading items.
        //    This value represents all unsigned attributes across the entire 
        //    dataset.
        final List<String> allowedUnsignedAttributes = Arrays.asList("attribute3");

        // 4. Configure an explicit map of the attribute actions configured 
        //    in your version 2.x modeled class.
        final Map<String, CryptoAction> legacyActions = new HashMap<>();
        legacyActions.put("partition_key", CryptoAction.SIGN_ONLY);
        legacyActions.put("sort_key", CryptoAction.SIGN_ONLY);
        legacyActions.put("attribute1", CryptoAction.ENCRYPT_AND_SIGN);
        legacyActions.put("attribute2", CryptoAction.SIGN_ONLY);
        legacyActions.put("attribute3", CryptoAction.DO_NOTHING);

        // 5. Configure the DynamoDBEncryptor that you used in version 2.x.
        final AWSKMS kmsClient = AWSKMSClientBuilder.defaultClient();
        final DirectKmsMaterialProvider cmp = new DirectKmsMaterialProvider(kmsClient, kmsKeyId);
        final DynamoDBEncryptor oldEncryptor = DynamoDBEncryptor.getInstance(cmp);

        // 6. Configure the legacy behavior.
        //    Input the DynamoDBEncryptor and attribute actions created in 
        //    the previous steps. For Legacy Policy, use 
        //    'FORCE_LEGACY_ENCRYPT_ALLOW_LEGACY_DECRYPT'. This policy continues to read 
        //    and write items using the old format, but will be able to read
        //    items written in the new format as soon as they appear.
        final LegacyOverride legacyOverride = LegacyOverride
                .builder()
                .encryptor(oldEncryptor)
                .policy(LegacyPolicy.FORCE_LEGACY_ENCRYPT_ALLOW_LEGACY_DECRYPT)
                .attributeActionsOnEncrypt(legacyActions)
                .build();

        // 7. Create a DynamoDbEncryptionInterceptor with the above configuration.
        final Map<String, DynamoDbEnhancedTableEncryptionConfig> tableConfigs = new HashMap<>();
        tableConfigs.put(ddbTableName,
                DynamoDbEnhancedTableEncryptionConfig.builder()
                        .logicalTableName(ddbTableName)
                        .keyring(kmsKeyring)
                        .allowedUnsignedAttributes(allowedUnsignedAttributes)
                        .schemaOnEncrypt(tableSchema)
                        .legacyOverride(legacyOverride)
                        .build());
        final DynamoDbEncryptionInterceptor interceptor =
                DynamoDbEnhancedClientEncryption.CreateDynamoDbEncryptionInterceptor(
                        CreateDynamoDbEncryptionInterceptorInput.builder()
                                .tableEncryptionConfigs(tableConfigs)
                                .build()
                );

        // 8. Create a new AWS SDK DynamoDb client using the 
        //    interceptor from Step 7.
        final DynamoDbClient ddb = DynamoDbClient.builder()
                .overrideConfiguration(
                        ClientOverrideConfiguration.builder()
                                .addExecutionInterceptor(interceptor)
                                .build())
                .build();

        // 9. Create the DynamoDbEnhancedClient using the AWS SDK DynamoDb client 
        //    created in Step 8, and create a table with your modeled class.
        final DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.builder()
                .dynamoDbClient(ddb)
                .build();
        final DynamoDbTable<SimpleClass> table = enhancedClient.table(ddbTableName, tableSchema);
    }
}
```

### 步驟 2. 以新格式寫入項目
<a name="ddb-java-migrate-step2"></a>

將步驟 1 的變更部署到所有讀取器之後，請完成下列步驟，以設定 AWS 資料庫加密 SDK 用戶端以新格式寫入項目。部署下列變更後，用戶端會繼續讀取舊格式的項目，並開始寫入和讀取新格式的項目。

下列程序提供以下程式碼範例中示範的步驟概觀。

1. 繼續設定 keyring、資料表結構描述、舊版屬性動作、 和 `allowedUnsignedAttributes`，`DynamoDBEncryptor`如您在[**步驟 1 **](#ddb-java-migrate-step1)中所執行。

1. 更新您的舊版行為，只使用新格式撰寫新項目。

1. 建立 `DynamoDbEncryptionInterceptor `

1. 建立新的 AWS SDK DynamoDB 用戶端。

1. 建立 `DynamoDBEnhancedClient`並使用模型化類別建立資料表。

   如需 DynamoDB 增強型用戶端的詳細資訊，請參閱[建立增強型用戶端](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/ddb-en-client-getting-started-dynamodbTable.html#ddb-en-client-getting-started-dynamodbTable-eclient)。

```
public class MigrationExampleStep2 {

    public static void MigrationStep2(String kmsKeyId, String ddbTableName, int sortReadValue) {
        // 1. Continue to configure your keyring, table schema, legacy 
        //    attribute actions, allowedUnsignedAttributes, and 
        //    DynamoDBEncryptor as you did in Step 1.
        final MaterialProviders matProv = MaterialProviders.builder()
                .MaterialProvidersConfig(MaterialProvidersConfig.builder().build())
                .build();
        final CreateAwsKmsMrkMultiKeyringInput keyringInput = CreateAwsKmsMrkMultiKeyringInput.builder()
                .generator(kmsKeyId)
                .build();
        final IKeyring kmsKeyring = matProv.CreateAwsKmsMrkMultiKeyring(keyringInput);

        final TableSchema<SimpleClass> schemaOnEncrypt = TableSchema.fromBean(SimpleClass.class);

        final List<String> allowedUnsignedAttributes = Arrays.asList("attribute3");

        final Map<String, CryptoAction> legacyActions = new HashMap<>();
        legacyActions.put("partition_key", CryptoAction.SIGN_ONLY);
        legacyActions.put("sort_key", CryptoAction.SIGN_ONLY);
        legacyActions.put("attribute1", CryptoAction.ENCRYPT_AND_SIGN);
        legacyActions.put("attribute2", CryptoAction.SIGN_ONLY);
        legacyActions.put("attribute3", CryptoAction.DO_NOTHING);

        final AWSKMS kmsClient = AWSKMSClientBuilder.defaultClient();
        final DirectKmsMaterialProvider cmp = new DirectKmsMaterialProvider(kmsClient, kmsKeyId);
        final DynamoDBEncryptor oldEncryptor = DynamoDBEncryptor.getInstance(cmp);

        // 2. Update your legacy behavior to only write new items using the new
        //    format. 
        //    For Legacy Policy, use 'FORBID_LEGACY_ENCRYPT_ALLOW_LEGACY_DECRYPT'. This policy
        //    continues to read items in both formats, but will only write items
        //    using the new format.
        final LegacyOverride legacyOverride = LegacyOverride
                .builder()
                .encryptor(oldEncryptor)
                .policy(LegacyPolicy.FORBID_LEGACY_ENCRYPT_ALLOW_LEGACY_DECRYPT)
                .attributeActionsOnEncrypt(legacyActions)
                .build();

        // 3. Create a DynamoDbEncryptionInterceptor with the above configuration.
        final Map<String, DynamoDbEnhancedTableEncryptionConfig> tableConfigs = new HashMap<>();
        tableConfigs.put(ddbTableName,
                DynamoDbEnhancedTableEncryptionConfig.builder()
                        .logicalTableName(ddbTableName)
                        .keyring(kmsKeyring)
                        .allowedUnsignedAttributes(allowedUnsignedAttributes)
                        .schemaOnEncrypt(tableSchema)
                        .legacyOverride(legacyOverride)
                        .build());
        final DynamoDbEncryptionInterceptor interceptor =
                DynamoDbEnhancedClientEncryption.CreateDynamoDbEncryptionInterceptor(
                        CreateDynamoDbEncryptionInterceptorInput.builder()
                                .tableEncryptionConfigs(tableConfigs)
                                .build()
                );

        // 4. Create a new AWS SDK DynamoDb client using the 
        //    interceptor from Step 3.
        final DynamoDbClient ddb = DynamoDbClient.builder()
                .overrideConfiguration(
                        ClientOverrideConfiguration.builder()
                                .addExecutionInterceptor(interceptor)
                                .build())
                .build();

        // 5. Create the DynamoDbEnhancedClient using the AWS SDK DynamoDb Client created
        //    in Step 4, and create a table with your modeled class.
        final DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.builder()
                .dynamoDbClient(ddb)
                .build();
        final DynamoDbTable<SimpleClass> table = enhancedClient.table(ddbTableName, tableSchema);
    }
}
```

部署步驟 2 變更後，您必須使用新格式重新加密資料表中的所有舊項目，才能繼續進行[步驟 3](#ddb-java-migrate-step3)。沒有您可以執行的單一指標或查詢，以快速加密現有的項目。使用對您的系統最有意義的程序。例如，您可以使用慢速掃描資料表的非同步程序，並使用您定義的新屬性動作和加密組態重寫項目。

### 步驟 3。僅讀取和寫入新格式的項目
<a name="ddb-java-migrate-step3"></a>

使用新格式重新加密資料表中的所有項目之後，您可以從組態中移除舊版行為。完成下列步驟，將用戶端設定為僅讀取和寫入新格式的項目。

下列程序提供以下程式碼範例中示範的步驟概觀。

1. 繼續設定 keyring、資料表結構描述，`allowedUnsignedAttributes`如您在[**步驟 1 **](#ddb-java-migrate-step1)中所執行。`DynamoDBEncryptor` 從組態中移除舊版屬性動作 和 。

1. 建立 `DynamoDbEncryptionInterceptor`。

1. 建立新的 AWS SDK DynamoDB 用戶端。

1. 建立 `DynamoDBEnhancedClient`並使用模型化類別建立資料表。

   如需 DynamoDB 增強型用戶端的詳細資訊，請參閱[建立增強型用戶端](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/ddb-en-client-getting-started-dynamodbTable.html#ddb-en-client-getting-started-dynamodbTable-eclient)。

```
public class MigrationExampleStep3 {

    public static void MigrationStep3(String kmsKeyId, String ddbTableName, int sortReadValue) {
        // 1. Continue to configure your keyring, table schema,
        //    and allowedUnsignedAttributes as you did in Step 1.
        //    Do not include the configurations for the DynamoDBEncryptor or 
        //    the legacy attribute actions.
        final MaterialProviders matProv = MaterialProviders.builder()
                .MaterialProvidersConfig(MaterialProvidersConfig.builder().build())
                .build();
        final CreateAwsKmsMrkMultiKeyringInput keyringInput = CreateAwsKmsMrkMultiKeyringInput.builder()
                .generator(kmsKeyId)
                .build();
        final IKeyring kmsKeyring = matProv.CreateAwsKmsMrkMultiKeyring(keyringInput);

        final TableSchema<SimpleClass> schemaOnEncrypt = TableSchema.fromBean(SimpleClass.class);

        final List<String> allowedUnsignedAttributes = Arrays.asList("attribute3");


        // 3. Create a DynamoDbEncryptionInterceptor with the above configuration.
        //    Do not configure any legacy behavior.
        final Map<String, DynamoDbEnhancedTableEncryptionConfig> tableConfigs = new HashMap<>();
        tableConfigs.put(ddbTableName,
                DynamoDbEnhancedTableEncryptionConfig.builder()
                        .logicalTableName(ddbTableName)
                        .keyring(kmsKeyring)
                        .allowedUnsignedAttributes(allowedUnsignedAttributes)
                        .schemaOnEncrypt(tableSchema)
                        .build());
        final DynamoDbEncryptionInterceptor interceptor =
                DynamoDbEnhancedClientEncryption.CreateDynamoDbEncryptionInterceptor(
                        CreateDynamoDbEncryptionInterceptorInput.builder()
                                .tableEncryptionConfigs(tableConfigs)
                                .build()
                );

        // 4. Create a new AWS SDK DynamoDb client using the 
        //    interceptor from Step 3.
        final DynamoDbClient ddb = DynamoDbClient.builder()
                .overrideConfiguration(
                        ClientOverrideConfiguration.builder()
                                .addExecutionInterceptor(interceptor)
                                .build())
                .build();

        // 5. Create the DynamoDbEnhancedClient using the AWS SDK Client 
        //    created in Step 4, and create a table with your modeled class.
        final DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.builder()
                .dynamoDbClient(ddb)
                .build();
        final DynamoDbTable<SimpleClass> table = enhancedClient.table(ddbTableName, tableSchema);
    }
}
```