Search code examples
javaamazon-dynamodbdynamo-local

Is it possible to create a Global Secondary Index on a JVM-based DynamoDB Local instance


I'm new to DynamoDB and I have a local instance inside the JVM running, but when I try and create an index defined like

GlobalSecondaryIndexUpdate stockIndex = new GlobalSecondaryIndexUpdate()
        .withCreate(new CreateGlobalSecondaryIndexAction()
                .withIndexName("StockIndex")
                .withKeySchema(new KeySchemaElement().withAttributeName("stock").withKeyType(KeyType.RANGE), // Partition key
                        new KeySchemaElement().withAttributeName("date").withKeyType(KeyType.RANGE)) // Compound key?
                .withProjection(new Projection().withProjectionType(projectionType)));

I get an unknown internal failure like:

Caused by: com.amazonaws.services.dynamodbv2.model.AmazonDynamoDBException: The request processing has failed because of an unknown error, exception or failure. (Service: AmazonDynamoDBv2; Status Code: 500; Error Code: InternalFailure; Request ID: dccfbf27-2e33-463c-b36e-97a432f4cd6b)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.handleErrorResponse(AmazonHttpClient.java:1588)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeOneRequest(AmazonHttpClient.java:1258)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeHelper(AmazonHttpClient.java:1030)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.doExecute(AmazonHttpClient.java:742)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeWithTimer(AmazonHttpClient.java:716)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.execute(AmazonHttpClient.java:699)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.access$500(AmazonHttpClient.java:667)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutionBuilderImpl.execute(AmazonHttpClient.java:649)
    at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:513)
    at com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient.doInvoke(AmazonDynamoDBClient.java:2089)
    at com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient.invoke(AmazonDynamoDBClient.java:2065)
    at com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient.executeUpdateTable(AmazonDynamoDBClient.java:1921)

when trying to create a GSI. Am I defining the index wrong, or is this not supported in DynamoDB Local ?

Update 2018-07-30:

I tested using:

// StockIndex
GlobalSecondaryIndexUpdate stockIndex = new GlobalSecondaryIndexUpdate()
        .withCreate(new CreateGlobalSecondaryIndexAction()
                .withIndexName("StockIndex")
                .withKeySchema(
                        new KeySchemaElement().withAttributeName("stock").withKeyType(KeyType.HASH)) // Partition key
                        new KeySchemaElement().withAttributeName("date").withKeyType(KeyType.RANGE)) // Compound key?
                .withProjection(new Projection().withProjectionType(ProjectionType.ALL)));

as well as without the RANGE key on date, but both times I got the same vague InternalFailure. I suspect that GSIs are simply not supported by the DynamoDB Local instance (although nothing in the Usage Notes mentions secondary indexes at all)


Solution

  • It turns out there there were two problems: (1) the lack of a HASH/partition key and (2) I wasn't specifying an explicit "provisioned throughput". The following code worked:

    CreateGlobalSecondaryIndexAction stockIndex = new CreateGlobalSecondaryIndexAction()
                .withIndexName("StockIndex")
                .withKeySchema(
                        new KeySchemaElement().withAttributeName("stock").withKeyType(KeyType.HASH), // Partition key
                        new KeySchemaElement().withAttributeName("date").withKeyType(KeyType.RANGE)) // Sort key             
                .withProvisionedThroughput(new ProvisionedThroughput(20L, 20L))
                .withProjection(new Projection().withProjectionType(ProjectionType.KEYS_ONLY));
    

    Note the withProvisionedThroughput call.