为什么在 Java 中本地使用 DynamoDB 时得到 "Unable to load AWS credentials"?
Why do I get "Unable to load AWS credentials" when using DynamoDB locally in Java?
我正在编写功能测试用例并连接到其中的本地 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 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.access0(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)
问题是什么?
您似乎从未在您的计算机上为 AWS 设置任何凭证以供 SDK 使用。
如果您使用的是 DynamoDB 的本地或远程云版本,DynamoDB SDK 不会在意。这意味着它仍将在发送请求之前检查凭据是否存在。
由于大多数人将使用需要凭据的 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();
我正在编写功能测试用例并连接到其中的本地 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 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.access0(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)
问题是什么?
您似乎从未在您的计算机上为 AWS 设置任何凭证以供 SDK 使用。
如果您使用的是 DynamoDB 的本地或远程云版本,DynamoDB SDK 不会在意。这意味着它仍将在发送请求之前检查凭据是否存在。
由于大多数人将使用需要凭据的 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();