web-dev-qa-db-fra.com

Échec d'une demande DynamoDB simple avec une exception ResourceNotFoundException

Je commence à utiliser DynamoDB à l’aide du SDK Java (v1.8). J'ai créé un tableau très simple à l'aide de la console AWS. Ma table a une clé de hachage primaire, qui est une chaîne (aucune plage). J'ai mis un seul élément dans la table avec 4 autres valeurs d'attribut (toutes les chaînes).

Je fais une simple requête Java pour cet élément de la table, mais elle échoue avec ResourceNotFoundException. Je suis absolument convaincu que le nom de la table que je fournis est correct, tout comme le nom de la clé de hachage principale que j'utilise pour interroger l'élément. L'état de la table est répertorié dans la console AWS sous la forme Active et je peux également voir l'élément et ses valeurs.

C'est l'erreur que j'obtiens:

Requested resource not found (Service: AmazonDynamoDB; Status Code: 400; Error Code: ResourceNotFoundException; Request ID: ...)

J'ai essayé ce qui suit (en utilisant les versions dynamodbv2 des classes):

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);

J'ai aussi essayé d'utiliser les anciennes versions obsolètes de toutes ces classes, comme ceci:

GetItemRequest request = new GetItemRequest()
        .withTableName(TABLE_NAME)
        .withKey(new Key().withHashKeyElement(new AttributeValue().withS(value)));
GetItemResult result = client.getItem(request);

... mais c'est le même résultat.
D'après moi, la variable ResourceNotFoundException signifie que cela signifie que le nom de la table ou l'attribut référencé n'est pas valide, ce qui n'est pas le cas. Il peut également être lancé si la table est trop tôt dans l'état Creating, mais ma table est Active.

13
RTF

La demande échouait car je ne définissais pas la région du client avant de faire la demande. La région par défaut est probablement l’est des États-Unis et ma table est installée dans l’Europe occidentale. Cela l'a corrigé:

import com.amazonaws.regions.Region;
import com.amazonaws.regions.Regions;

client.setRegion(Region.getRegion(Regions.EU_WEST_1));
33
RTF

le code complet peut ressembler à:

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"));
        }
    }
}
0
gbk

Si vous utilisez Spring Boot, vous pouvez procéder comme suit:

@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);
}}
0
sendon1982