1

我正在编写一个功能测试用例并连接到其中的本地 DyanmoDB 实例。

这就是我创建 DynamoDB 客户端的方式:

private static final String table_name = "table-A";
private static String aws_region = "us-west-2";
private static AmazonDynamoDB amazonDynamoDBClient;
private static DynamoDB dynamoDB;


public static void initDB() {
    amazonDynamoDBClient = AmazonDynamoDBClientBuilder.standard().withEndpointConfiguration(
      new AwsClientBuilder.EndpointConfiguration("http://localhost:8000", aws_region)).build();
    dynamoDB = new DynamoDB(amazonDynamoDBClient);
}

这就是我试图创建表的方式:

Table table = dynamoDB.createTable(table_name,
                Arrays.asList(new KeySchemaElement("row_name", KeyType.HASH),
                        new KeySchemaElement("row_id", KeyType.RANGE)),
                Arrays.asList(new AttributeDefinition("row_name", ScalarAttributeType.S),
                        new AttributeDefinition("row_id", ScalarAttributeType.S)),
                new ProvisionedThroughput(10L, 10L));

但是,我得到以下异常:

com.amazonaws.SdkClientException: Unable to load AWS credentials from any provider in the chain
        at com.amazonaws.auth.AWSCredentialsProviderChain.getCredentials(AWSCredentialsProviderChain.java:131)
        at com.amazonaws.http.AmazonHttpClient$RequestExecutor.getCredentialsFromContext(AmazonHttpClient.java:1115)
        at com.amazonaws.http.AmazonHttpClient$RequestExecutor.runBeforeRequestHandlers(AmazonHttpClient.java:764)
        at com.amazonaws.http.AmazonHttpClient$RequestExecutor.doExecute(AmazonHttpClient.java:728)
        at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeWithTimer(AmazonHttpClient.java:721)
        at com.amazonaws.http.AmazonHttpClient$RequestExecutor.execute(AmazonHttpClient.java:704)
        at com.amazonaws.http.AmazonHttpClient$RequestExecutor.access$500(AmazonHttpClient.java:672)
        at com.amazonaws.http.AmazonHttpClient$RequestExecutionBuilderImpl.execute(AmazonHttpClient.java:654)
        at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:518)
        at com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient.doInvoke(AmazonDynamoDBClient.java:1831)
        at com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient.invoke(AmazonDynamoDBClient.java:1807)
        at com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient.createTable(AmazonDynamoDBClient.java:636)
        at com.amazonaws.services.dynamodbv2.document.DynamoDB.createTable(DynamoDB.java:96)
        at com.amazonaws.services.dynamodbv2.document.DynamoDB.createTable(DynamoDB.java:108)
        at util.DBUtil.createAndInsertTestCases(DBUtil.java:24)
        at test.DocumentTest.createAndInsertDataInDB(DocumentTest.java:37)

问题是什么?

4

1 回答 1

2

看起来您从未在您的机器上为 AWS 设置任何凭证以供 SDK 使用。


如果您使用的是本地或远程云版本的 DynamoDB,DynamoDB 开发工具包不会注意到。这意味着它仍然会在发送请求之前检查凭据是否存在。

由于大多数人将使用 DDB 的远程云版本,这需要凭据,这允许客户端在知道请求将失败时不调用远程服务器 - 更快的错误处理,没有网络成本等。

您可以看到堆栈跟踪显示AmazonHttpClient.java正在尝试使用getCredentialsFromContext.


必须为所有请求设置访问密钥 ID 和秘密访问密钥,但对于本地 DDB,这些可以设置为任何伪值。

这应该有效,例如:

EndpointConfiguration endpointConfig = new EndpointConfiguration("http://localhost:8000", aws_region);

AWSStaticCredentialsProvider awsCredProvider = new AWSStaticCredentialsProvider(new BasicAWSCredentials("fakeMyKeyId", "fakeSecretAccessKey"));

AmazonDynamoDB ddb = AmazonDynamoDBClientBuilder
    .standard()
    .withCredentials(awsCredProvider)
    .withEndpointConfiguration(endpointConfig)
    .build();

正如@jarmod 在评论中指出的那样,如果您由于某种原因无法提供凭据,您也可以使用AnonymousAWSCredentials(假设本地 DDB 实际上不需要签名的 API 请求)。

指定凭据提供程序AnonymousCredentialsProvider可能有效:

EndpointConfiguration endpointConfig = new EndpointConfiguration("http://localhost:8000", aws_region);

AnonymousCredentialsProvider awsCredProvider = new AnonymousCredentialsProvider();

AmazonDynamoDB ddb = AmazonDynamoDBClientBuilder
    .standard()
    .withCredentials(awsCredProvider)
    .withEndpointConfiguration(endpointConfig)
    .build();
于 2021-11-03T11:43:52.923 回答