/* * Copyright 2014-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"). * You may not use this file except in compliance with the License. * A copy of the License is located at * * http://aws.amazon.com/apache2.0 * * or in the "license" file accompanying this file. This file is distributed * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. See the License for the specific language governing * permissions and limitations under the License. */ package com.amazonaws.codesamples.lowlevel; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import com.amazonaws.auth.profile.ProfileCredentialsProvider; import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient; import com.amazonaws.services.dynamodbv2.model.AttributeDefinition; 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.CreateTableRequest; import com.amazonaws.services.dynamodbv2.model.DeleteTableRequest; import com.amazonaws.services.dynamodbv2.model.DescribeTableRequest; import com.amazonaws.services.dynamodbv2.model.GlobalSecondaryIndex; import com.amazonaws.services.dynamodbv2.model.KeySchemaElement; import com.amazonaws.services.dynamodbv2.model.KeyType; import com.amazonaws.services.dynamodbv2.model.Projection; import com.amazonaws.services.dynamodbv2.model.ProvisionedThroughput; import com.amazonaws.services.dynamodbv2.model.PutItemRequest; import com.amazonaws.services.dynamodbv2.model.QueryRequest; import com.amazonaws.services.dynamodbv2.model.QueryResult; import com.amazonaws.services.dynamodbv2.model.ResourceNotFoundException; import com.amazonaws.services.dynamodbv2.model.Select; import com.amazonaws.services.dynamodbv2.model.TableDescription; import com.amazonaws.services.dynamodbv2.model.TableStatus; public class LowLevelGlobalSecondaryIndexExample { static AmazonDynamoDBClient client = new AmazonDynamoDBClient(new ProfileCredentialsProvider()); public static String tableName = "Issues"; public static void main(String[] args) throws Exception { createTable(); loadData(); queryIndex("CreateDateIndex"); queryIndex("TitleIndex"); queryIndex("DueDateIndex"); deleteTable(tableName); } public static void createTable() { // Attribute definitions ArrayList<AttributeDefinition> attributeDefinitions = new ArrayList<AttributeDefinition>(); attributeDefinitions.add(new AttributeDefinition() .withAttributeName("IssueId").withAttributeType("S")); attributeDefinitions.add(new AttributeDefinition() .withAttributeName("Title").withAttributeType("S")); attributeDefinitions.add(new AttributeDefinition() .withAttributeName("CreateDate").withAttributeType("S")); attributeDefinitions.add(new AttributeDefinition() .withAttributeName("DueDate").withAttributeType("S")); // Key schema for table ArrayList<KeySchemaElement> tableKeySchema = new ArrayList<KeySchemaElement>(); tableKeySchema.add(new KeySchemaElement() .withAttributeName("IssueId").withKeyType(KeyType.HASH)); tableKeySchema.add(new KeySchemaElement() .withAttributeName("Title").withKeyType(KeyType.RANGE)); // Initial provisioned throughput settings for the indexes ProvisionedThroughput ptIndex = new ProvisionedThroughput() .withReadCapacityUnits(1L).withWriteCapacityUnits(1L); // CreateDateIndex GlobalSecondaryIndex createDateIndex = new GlobalSecondaryIndex() .withIndexName("CreateDateIndex") .withProvisionedThroughput(ptIndex) .withKeySchema( new KeySchemaElement() .withAttributeName("CreateDate").withKeyType(KeyType.HASH), new KeySchemaElement() .withAttributeName("IssueId") .withKeyType(KeyType.RANGE)) .withProjection(new Projection() .withProjectionType("INCLUDE") .withNonKeyAttributes("Description", "Status")); // TitleIndex GlobalSecondaryIndex titleIndex = new GlobalSecondaryIndex() .withIndexName("TitleIndex") .withProvisionedThroughput(ptIndex) .withKeySchema( new KeySchemaElement() .withAttributeName("Title") .withKeyType(KeyType.HASH), new KeySchemaElement() .withAttributeName("IssueId") .withKeyType(KeyType.RANGE)) .withProjection(new Projection() .withProjectionType("KEYS_ONLY")); // DueDateIndex GlobalSecondaryIndex dueDateIndex = new GlobalSecondaryIndex() .withIndexName("DueDateIndex") .withProvisionedThroughput(ptIndex) .withKeySchema( new KeySchemaElement() .withAttributeName("DueDate") .withKeyType(KeyType.HASH)) .withProjection(new Projection() .withProjectionType("ALL")); CreateTableRequest createTableRequest = new CreateTableRequest() .withTableName(tableName) .withProvisionedThroughput( new ProvisionedThroughput() .withReadCapacityUnits( (long) 1) .withWriteCapacityUnits( (long) 1)) .withAttributeDefinitions(attributeDefinitions) .withKeySchema(tableKeySchema) .withGlobalSecondaryIndexes(createDateIndex, titleIndex, dueDateIndex); System.out.println("Creating table " + tableName + "..."); System.out.println(client.createTable(createTableRequest)); waitForTableToBecomeAvailable(tableName); } public static void queryIndex(String indexName) { System.out.println ("\n***********************************************************\n"); System.out.print("Querying index " + indexName + "..."); QueryRequest queryRequest = new QueryRequest() .withTableName(tableName) .withIndexName(indexName) .withScanIndexForward(true); HashMap<String, Condition> keyConditions = new HashMap<String, Condition>(); if (indexName == "CreateDateIndex") { System.out.println("Issues filed on 2013-11-01"); keyConditions.put("CreateDate",new Condition() .withComparisonOperator(ComparisonOperator.EQ) .withAttributeValueList(new AttributeValue() .withS("2013-11-01"))); keyConditions.put("IssueId",new Condition() .withComparisonOperator(ComparisonOperator.BEGINS_WITH) .withAttributeValueList(new AttributeValue().withS("A-"))); } else if (indexName == "TitleIndex") { System.out.println("Compilation errors"); keyConditions.put("Title",new Condition() .withComparisonOperator( ComparisonOperator.EQ) .withAttributeValueList(new AttributeValue() .withS("Compilation error"))); keyConditions.put("IssueId", new Condition() .withComparisonOperator(ComparisonOperator.BEGINS_WITH) .withAttributeValueList(new AttributeValue().withS("A-"))); // Select queryRequest.setSelect(Select.ALL_PROJECTED_ATTRIBUTES); } else if (indexName == "DueDateIndex") { System.out.println("Items that are due on 2013-11-30"); keyConditions.put("DueDate",new Condition() .withComparisonOperator(ComparisonOperator.EQ) .withAttributeValueList(new AttributeValue().withS("2013-11-30"))); // Select queryRequest.setSelect(Select.ALL_PROJECTED_ATTRIBUTES); } else { System.out.println("\nNo valid index name provided"); return; } queryRequest.setKeyConditions(keyConditions); QueryResult result = client.query(queryRequest); List<Map<String, AttributeValue>> items = result.getItems(); Iterator<Map<String, AttributeValue>> itemsIter = items.iterator(); System.out.println(); while (itemsIter.hasNext()) { Map<String, AttributeValue> currentItem = itemsIter.next(); Iterator<String> currentItemIter = currentItem.keySet().iterator(); while (currentItemIter.hasNext()) { String attr = (String) currentItemIter.next(); if (attr == "Priority" ) { System.out.println(attr + "---> " + currentItem.get(attr).getN()); } else { System.out.println(attr + "---> " + currentItem.get(attr).getS()); } } System.out.println(); } } public static void deleteTable(String tableName) { System.out.println("Deleting table " + tableName + "..."); client.deleteTable(new DeleteTableRequest().withTableName(tableName)); waitForTableToBeDeleted(tableName); } public static void loadData() { System.out.println("Loading data into table " + tableName + "..."); // IssueId, Title, // Description, // CreateDate, LastUpdateDate, DueDate, // Priority, Status putItem("A-101","Compilation error", "Can't compile Project X - bad version number. What does this mean?", "2013-11-01", "2013-11-02", "2013-11-10", 1, "Assigned"); putItem("A-102","Can't read data file", "The main data file is missing, or the permissions are incorrect", "2013-11-01", "2013-11-04", "2013-11-30", 2, "In progress"); putItem("A-103", "Test failure", "Functional test of Project X produces errors", "2013-11-01", "2013-11-02", "2013-11-10", 1, "In progress"); putItem("A-104", "Compilation error", "Variable 'messageCount' was not initialized.", "2013-11-15", "2013-11-16", "2013-11-30", 3, "Assigned"); putItem("A-105", "Network issue", "Can't ping IP address 127.0.0.1. Please fix this.", "2013-11-15", "2013-11-16", "2013-11-19", 5, "Assigned"); } public static void putItem( String issueId, String title, String description, String createDate, String lastUpdateDate,String dueDate, Integer priority, String status) { HashMap<String, AttributeValue> item = new HashMap<String, AttributeValue>(); item.put("IssueId", new AttributeValue().withS(issueId)); item.put("Title", new AttributeValue().withS(title)); item.put("Description", new AttributeValue().withS(description)); item.put("CreateDate", new AttributeValue().withS(createDate)); item.put("LastUpdateDate", new AttributeValue().withS(lastUpdateDate)); item.put("DueDate", new AttributeValue().withS(dueDate)); item.put("Priority", new AttributeValue().withN(priority.toString())); item.put("Status", new AttributeValue().withS(status)); try { client.putItem(new PutItemRequest() .withTableName(tableName) .withItem(item)); } catch (Exception e) { e.printStackTrace(); } } private static void waitForTableToBecomeAvailable(String tableName) { System.out.println("Waiting for " + tableName + " to become ACTIVE..."); long startTime = System.currentTimeMillis(); long endTime = startTime + (10 * 60 * 1000); while (System.currentTimeMillis() < endTime) { DescribeTableRequest request = new DescribeTableRequest().withTableName(tableName); TableDescription tableDescription = client.describeTable(request).getTable(); String tableStatus = tableDescription.getTableStatus(); System.out.println(" - current state: " + tableStatus); if (tableStatus.equals(TableStatus.ACTIVE.toString())) return; try { Thread.sleep(1000 * 20); } catch (Exception e) { e.printStackTrace(); } } throw new RuntimeException("Table " + tableName + " never went active"); } private static void waitForTableToBeDeleted(String tableName) { System.out.println("Waiting for " + tableName + " while status DELETING..."); long startTime = System.currentTimeMillis(); long endTime = startTime + (10 * 60 * 1000); while (System.currentTimeMillis() < endTime) { try { DescribeTableRequest request = new DescribeTableRequest() .withTableName(tableName); TableDescription tableDescription = client.describeTable(request).getTable(); String tableStatus = tableDescription.getTableStatus(); System.out.println(" - current state: " + tableStatus); if (tableStatus.equals(TableStatus.ACTIVE.toString())) return; } catch (ResourceNotFoundException e) { System.out.println( "Table " + tableName + " is not found. It was deleted."); return; } try { Thread.sleep(1000 * 20); } catch (Exception e) { e.printStackTrace(); } } throw new RuntimeException("Table " + tableName + " was never deleted"); } }