2019
Jul
09

Create a Table with global secondary index on local dynamodb

Unit test Create Table
  1. AmazonDynamoDB ddb = DynamoDBEmbedded.create().amazonDynamoDB();
  2.  
  3. String tableName = "users";
  4. String hashKeyName = "id";
  5. String gsiIndexName = "usersIndex";
  6. String gsiIndexHashKeyName = "id2";
  7. CreateTableResult res = createTable(ddb, tableName, hashKeyName);
  8.  
  9. public CreateTableResult createTable(AmazonDynamoDB ddb, String tableName, String hashKeyName, String rangeKeyName) {
  10.  
  11. TableDescription tableDesc = res.getTableDescription();
  12. List<AttributeDefinition> attributeDefinitions = new ArrayList<AttributeDefinition>();
  13. attributeDefinitions.add(new AttributeDefinition(hashKeyName, ScalarAttributeType.S));
  14. attributeDefinitions.add(new AttributeDefinition(gsiIndexHashKeyName, ScalarAttributeType.S));
  15. List<KeySchemaElement> ks = new ArrayList<KeySchemaElement>();
  16. ks.add(new KeySchemaElement(hashKeyName, KeyType.HASH));
  17. ProvisionedThroughput provisionedthroughput = new ProvisionedThroughput(1000L, 1000L);
  18.  
  19.  
  20. # add global secondary index
  21. List<GlobalSecondaryIndex> gsi = new ArrayList<GlobalSecondaryIndex>();
  22. gsi.add(new GlobalSecondaryIndex()
  23. .withIndexName(gsiIndexName)
  24. .withKeySchema(new KeySchemaElement(gsiIndexHashKeyName, KeyType.HASH))
  25. .withProjection(new Projection().withProjectionType(ProjectionType.ALL))
  26. .withProvisionedThroughput(provisionedthroughput)
  27. );
  28.  
  29. CreateTableRequest request =
  30. new CreateTableRequest()
  31. .withTableName(tableName)
  32. .withAttributeDefinitions(attributeDefinitions)
  33. .withKeySchema(ks)
  34. .withProvisionedThroughput(provisionedthroughput);
  35. request.setGlobalSecondaryIndexes(gsi);
  36. ddb.createTable(request);
  37.  
  38. }

Add local secondary index

local secondary index
  1. List<LocalSecondaryIndex> lsi = new ArrayList<LocalSecondaryIndex>();
  2.  
  3. lsi.add(new LocalSecondaryIndex()
  4. .withIndexName(lsiIndexName)
  5. .withKeySchema(new KeySchemaElement(lsiIndexHashKeyName, KeyType.HASH, lsiRangeKeyName, KeyType.RANGE))
  6. .withProjection(new Projection().withProjectionType(ProjectionType.ALL));
  7.  
  8. createTableRequest.setLocalSecondaryIndexes(lsi);

Insert new data into local dynamodb

Insert
  1. DynamoDB dynamoDB = new DynamoDB(ddb);
  2. Table table = dynamoDB.getTable(tableName);
  3. String userId = "user0001";
  4. String userName = "puritys";
  5. UpdateItemSpec updateItemSpec = new UpdateItemSpec()
  6. .withPrimaryKey("id", userId);
  7.  
  8. StringBuilder updateStr = new StringBuilder("set #userName = :userName");
  9. ValueMap value = new ValueMap();
  10. NameMap name = new NameMap();
  11. name.with("#userName", "userName");
  12. value.withString(":userName", userName);
  13.  
  14.  
  15. updateItemSpec.withUpdateExpression(updateStr.toString())
  16. .withNameMap(name)
  17. .withValueMap(value)
  18. .withReturnValues(ReturnValue.UPDATED_NEW);

Package version use gradle

build.gradle
  1. repositories {
  2. mavenLocal()
  3. mavenCentral()
  4. maven {
  5. url "https://s3-us-west-2.amazonaws.com/dynamodb-local/release"
  6. content {
  7. includeModule "com.amazonaws", "DynamoDBLocal"
  8. }
  9. }
  10.  
  11. }
  12.  
  13. dependencies {
  14. compile (
  15. "org.slf4j:slf4j-api:1.7.25",
  16. )
  17.  
  18. testCompile (
  19. "junit:junit:4.8.1",
  20. "org.mockito:mockito-all:1.9.5",
  21. "com.almworks.sqlite4java:sqlite4java:1.0.392",
  22. "com.almworks.sqlite4java:libsqlite4java-linux-amd64:1.0.392",
  23. "com.amazonaws:DynamoDBLocal:1.11.119"
  24. )
  25.  
  26. }

import class

import
  1. import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
  2. import com.amazonaws.services.dynamodbv2.document.DynamoDB;
  3. import com.amazonaws.services.dynamodbv2.document.spec.UpdateItemSpec;
  4. import com.amazonaws.services.dynamodbv2.document.Table;
  5. import com.amazonaws.services.dynamodbv2.document.utils.NameMap;
  6. import com.amazonaws.services.dynamodbv2.document.utils.ValueMap;
  7. import com.amazonaws.services.dynamodbv2.local.embedded.DynamoDBEmbedded;
  8. import com.amazonaws.services.dynamodbv2.model.AttributeDefinition;
  9. import com.amazonaws.services.dynamodbv2.model.CreateTableRequest;
  10. import com.amazonaws.services.dynamodbv2.model.CreateTableResult;
  11. import com.amazonaws.services.dynamodbv2.model.KeySchemaElement;
  12. import com.amazonaws.services.dynamodbv2.model.KeyType;
  13. import com.amazonaws.services.dynamodbv2.model.ListTablesResult;
  14. import com.amazonaws.services.dynamodbv2.model.ProvisionedThroughput;
  15. import com.amazonaws.services.dynamodbv2.model.ReturnValue;
  16. import com.amazonaws.services.dynamodbv2.model.ScalarAttributeType;
  17. import com.amazonaws.services.dynamodbv2.model.TableDescription;
  18. import com.amazonaws.services.dynamodbv2.model.GlobalSecondaryIndex;
  19. import com.amazonaws.services.dynamodbv2.model.Projection;
  20. import com.amazonaws.services.dynamodbv2.model.ProjectionType;
  21.  
  22. System.setProperty("sqlite4java.library.path", "native-libs");

pom.xml

pom
  1. <dependency>
  2. <groupId>com.amazonaws</groupId>
  3. <artifactId>DynamoDBLocal</artifactId>
  4. <version>1.11.86</version>
  5. <scope>test</scope>
  6. <exclusions>
  7. <exclusion>
  8. <groupId>org.eclipse.jetty</groupId>
  9. <artifactId>jetty-util</artifactId>
  10. </exclusion>
  11. <exclusion>
  12. <groupId>org.eclipse.jetty</groupId>
  13. <artifactId>jetty-server</artifactId>
  14. </exclusion>
  15. </exclusions>
  16. </dependency>
  17. <dependency>
  18. <groupId>com.almworks.sqlite4java</groupId>
  19. <artifactId>sqlite4java</artifactId>
  20. <version>1.0.392</version>
  21. <scope>test</scope>
  22. </dependency>
  23. <dependency>
  24. <groupId>com.almworks.sqlite4java</groupId>
  25. <artifactId>libsqlite4java-linux-amd64</artifactId>
  26. <version>1.0.392</version>
  27. <type>so</type>
  28. <scope>test</scope>
  29. </dependency>
  30. <dependency>
  31. <groupId>com.almworks.sqlite4java</groupId>
  32. <artifactId>libsqlite4java-osx</artifactId>
  33. <version>1.0.392</version>
  34. <type>dylib</type>
  35. <scope>test</scope>
  36. </dependency>
  37.  
  38.  
  39. <repositories>
  40. <repository>
  41. <id>dynamodb-local-oregon</id>
  42. <name>DynamoDB Local Release Repository</name>
  43. <url>https://s3-us-west-2.amazonaws.com/dynamodb-local/release</url>
  44. </repository>
  45. </repositories>
  46.  
  47.  
  48.  
  49. <plugin>
  50. <groupId>org.apache.maven.plugins</groupId>
  51. <artifactId>maven-dependency-plugin</artifactId>
  52. <version>2.10</version>
  53. <executions>
  54. <execution>
  55. <id>copy</id>
  56. <phase>test-compile</phase>
  57. <goals>
  58. <goal>copy-dependencies</goal>
  59. </goals>
  60. <configuration>
  61. <!-- copy sqlite binary to correct dir for unit tests -->
  62. <includeScope>test</includeScope>
  63. <includeTypes>so,dll,dylib</includeTypes>
  64. <outputDirectory>${project.basedir}/native-libs</outputDirectory>
  65. </configuration>
  66. </execution>
  67. </executions>
  68. </plugin>

目前回應 Comments(1 comments)

  • sanjay 2021/05/05

    The heading shows unit test, but code looks like its insert and create table functionalities, where the unit test cases? I am looking for JUnit test cases for DynamoDB, something you can give examples. why do i need to connect local server for JUnit Test?

    Reply

    Admin

    I will update this article later to make it more clear.
     
    About your question, DynamodbDbEmbedded uses SQLite to implement a fake Dynamodb for testing only.
    You have to use  DynamoDBEmbedded to create the table and insert data for testing, in this article I only paste the example code.

回應 (Leave a comment)