Простой запрос DynamoDB с ResourceNotFoundException
Я просто запускаюсь с DynamoDB, используя Java SDK (v1.8). Я создал очень простую таблицу с помощью консоли AWS. В моей таблице есть первичный хеш-ключ, который является строкой (без диапазона). Я поместил один элемент в таблицу с 4 другими значениями атрибутов (все строки).
Я делаю простой Java-запрос для этого элемента в таблице, но он не работает с ResourceNotFoundException
. Я абсолютно уверен, что имя таблицы, которую я поставляю, является правильным, так же как и имя основного хеш-ключа, который я использую для запроса элемента. Состояние таблицы отображается в консоли AWS как Active
и я также вижу элемент и его значения.
Это ошибка, которую я получаю:
Requested resource not found (Service: AmazonDynamoDB; Status Code: 400; Error Code: ResourceNotFoundException; Request ID: ...)
Я пробовал следующее (используя версии классов dynamodbv2
):
Map<String, AttributeValue> key = new HashMap<String, AttributeValue>();
key.put(PRIMARY_KEY, new AttributeValue().withS(value));
GetItemRequest request = new GetItemRequest()
.withTableName(TABLE_NAME)
.withKey(key);
GetItemResult result = client.getItem(request);
Я также пытался использовать старые, устаревшие версии всех этих классов, например:
GetItemRequest request = new GetItemRequest()
.withTableName(TABLE_NAME)
.withKey(new Key().withHashKeyElement(new AttributeValue().withS(value)));
GetItemResult result = client.getItem(request);
... но это тот же результат.
Мое понимание ResourceNotFoundException
заключается в том, что это означает, что имя таблицы или атрибут, на которые ссылается, является недопустимым, что не так. Он также может быть сброшен, если таблица слишком рано в состоянии Creating
, но моя таблица Active
.
Ответы
Ответ 1
Запрос был неудачным, потому что я не настраивал регион для клиента, прежде чем делать запрос. По умолчанию регион, вероятно, находится в США, и мой стол настроен на Западе ЕС. Это фиксировало это:
import com.amazonaws.regions.Region;
import com.amazonaws.regions.Regions;
client.setRegion(Region.getRegion(Regions.EU_WEST_1));
Ответ 2
полный код может выглядеть так:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient;
import com.amazonaws.services.dynamodbv2.model.AttributeValue;
import com.amazonaws.services.dynamodbv2.model.ComparisonOperator;
import com.amazonaws.services.dynamodbv2.model.Condition;
import com.amazonaws.services.dynamodbv2.model.QueryRequest;
import com.amazonaws.services.dynamodbv2.model.QueryResult;
import com.amazonaws.regions.Region;
import com.amazonaws.regions.Regions;
public final class LogFetcher {
static AmazonDynamoDBClient client = new AmazonDynamoDBClient();
static String tableName = "<TABLE_NAME>";
public static ArrayList<Object> findLogsForDeviceWithMacID(String macID) {
client.setRegion(Region.getRegion(Regions.EU_WEST_1));
Condition hashKeyCondition = new Condition()
.withComparisonOperator(ComparisonOperator.EQ)
.withAttributeValueList(new AttributeValue().withS(macID));
Map<String, Condition> keyConditions = new HashMap<String, Condition>();
keyConditions.put("parentKey", hashKeyCondition);
QueryRequest queryRequest = new QueryRequest()
.withTableName(tableName)
.withKeyConditions(keyConditions);
QueryResult result = client.query(queryRequest);
ArrayList<Object> data = new ArrayList<Object>();
for (Map<String, AttributeValue> item : result.getItems()) {
// printItem(item);
data.add(item);
}
return data;
}
private static void printItem(Map<String, AttributeValue> attributeList) {
for (Map.Entry<String, AttributeValue> item : attributeList.entrySet()) {
String attributeName = item.getKey();
AttributeValue value = item.getValue();
System.out.println(attributeName + " "
+ (value.getS() == null ? "" : "S=[" + value.getS() + "]")
+ (value.getN() == null ? "" : "N=[" + value.getN() + "]")
+ (value.getB() == null ? "" : "B=[" + value.getB() + "]")
+ (value.getSS() == null ? "" : "SS=[" + value.getSS() + "]")
+ (value.getNS() == null ? "" : "NS=[" + value.getNS() + "]")
+ (value.getBS() == null ? "" : "BS=[" + value.getBS() + "] \n"));
}
}
}
Ответ 3
Если вы используете Spring Boot, вы можете сделать следующее:
@Configuration
@EnableDynamoDBRepositories(basePackages = "com.test.repository")
@EntityScan("com.test.entity")
public class DynamoDBConfig {
@Value("${amazon.dynamodb.endpoint}")
private String amazonDynamoDBEndpoint;
@Value("${amazon.aws.accesskey}")
private String amazonAWSAccessKey;
@Value("${amazon.aws.secretkey}")
private String amazonAWSSecretKey;
@Bean
public AmazonDynamoDB amazonDynamoDB() {
AwsClientBuilder.EndpointConfiguration endpointConfiguration = new AwsClientBuilder.EndpointConfiguration(
amazonDynamoDBEndpoint, Regions.AP_SOUTHEAST_2.getName());
AWSStaticCredentialsProvider credentialsProvider = new AWSStaticCredentialsProvider(amazonAWSCredentials());
AmazonDynamoDB amazonDynamoDB = AmazonDynamoDBClientBuilder.standard().withEndpointConfiguration(
endpointConfiguration).withCredentials(credentialsProvider).build();
return amazonDynamoDB;
}
@Bean
public AWSCredentials amazonAWSCredentials() {
return new BasicAWSCredentials(amazonAWSAccessKey, amazonAWSSecretKey);
}}