NoSQL Zone is brought to you in partnership with:

Gopal Sharma is Senior Architect and technology consultant. He has more than 16 years of proven experience solving challenging business problems with innovative enterprise solutions aligning business needs to IT capabilities. Though mainly experienced with Java technologies (16+ years), he has also credible experience with databases, open source stacks and unix. He has unique blend of business and technical skill sets resulting from a diverse professional background, a solid educational foundation, and several industry-recognized certifications. In between he had dabbled with entrepreneurship as well. He holds B. Tech (H) from IIT, India’s topmost engineering university. He can also be found at LinkedIn (in.linkedin.com/in/gopsprofile ). Gopal has posted 2 posts at DZone. You can read more from them at their website. View Full User Profile

Prop Up Development and Testing with DynamoDB Local in Java

10.04.2013
| 1037 views |
  • submit to reddit
Recently there was some good news for developers who want to develop and test DynamoDB applications locally without using Amazon's payable services: Amazon has released a local version of the DynamoDB NoSQL database. According to the AWS blog, this offline, local database supports the complete DynamoDB API, but doesn’t impact any tables or data in DynamoDB itself. That means you can play around with the local DynamoDB instance, and when you are ready and satisified with your work, deploy it to the actual DynamoDB instance. And it just needs a change in the DynamoDB end point.DynamoDB Local is an executable Java archive (JAR) file that runs on Windows, Mac, and Linux systems and requires version 7 of the Java Runtime Environment (JRE).

Setting Up: The download and deployment instructions are mentioned in the AWS blog. Here we are going to show you how to use DynamoDB locally in java.

First, get the local dynamodb client:

	public static AmazonDynamoDBClient getDynamoDBLocalClient(){
		dbLocalClient = new AmazonDynamoDBClient(new BasicAWSCredentials("TestAccessKey","TestSecretKey"));
		dbLocalClient.setEndpoint("http://localhost:8000");
		return dbLocalClient;
	}

You may also want to replicate the tables from the actual DynamoDB to the local DynamoDB, assuming that you have already done work in remote DynamoDB. For this, get the remote DynamoDB client:

	public static AmazonDynamoDBClient getDynamoDBRemoteClient(){
		dbRemoteClient = new AmazonDynamoDBClient(new BasicAWSCredentials("**************","***************************"));
		return dbRemoteClient;
	}

Since local DynamoDB does not have a web interface yet, the tables can be created programmatically only. To simplify this process, the below code connects to the remote DynamoDB, collects metadata from the tables, and uses them to create tables in the local DynamoDB. Just like we do in RDBMS, like:

"CREATE TABLE new_table AS (SELECT * FROM old_table);".

   static void createTablesFromRemote(){
        String lastEvaluatedTableName = null;
        do {
            
            ListTablesRequest listTablesRequest = new ListTablesRequest().withLimit(10)
            .withExclusiveStartTableName(lastEvaluatedTableName);
            
            ListTablesResult result = dbRemoteClient.listTables(listTablesRequest);
            lastEvaluatedTableName = result.getLastEvaluatedTableName();
            
            for (String name : result.getTableNames()) {            	
				TableDescription tableDescription = dbRemoteClient.describeTable(
						new DescribeTableRequest().withTableName(name)).getTable();
				createTables(tableDescription);
				System.out.println(name);            	                
            }
            
        } while (lastEvaluatedTableName != null);    	
    }
    
    private static void createTables(TableDescription desc){ 	

        
        // Provide the initial provisioned throughput values as Java long data types
        ProvisionedThroughput provisionedThroughput = new ProvisionedThroughput()
            .withReadCapacityUnits(desc.getProvisionedThroughput().getReadCapacityUnits())
            .withWriteCapacityUnits(desc.getProvisionedThroughput().getWriteCapacityUnits());
        CreateTableRequest request = new CreateTableRequest()
            .withTableName(desc.getTableName())
            .withProvisionedThroughput(provisionedThroughput);        

		request.setAttributeDefinitions(desc.getAttributeDefinitions());
		request.setKeySchema(desc.getKeySchema());
		
		List<LocalSecondaryIndexDescription> listIdxDesc = desc.getLocalSecondaryIndexes();
		if(listIdxDesc != null){
			List<LocalSecondaryIndex> listIdx = new ArrayList<LocalSecondaryIndex>();
			for(LocalSecondaryIndexDescription idxDesc: listIdxDesc){
				LocalSecondaryIndex idx = new LocalSecondaryIndex();
				idx.setIndexName(idxDesc.getIndexName());
				idx.setKeySchema(idxDesc.getKeySchema());
				idx.setProjection(idxDesc.getProjection());
				listIdx.add(idx);
			}
			request.setLocalSecondaryIndexes(listIdx);
		}
  
        CreateTableResult result = dbLocalClient.createTable(request); 
        
    }

Similarly, if you want to populate your newly created tables in the local DynamoDB with data from the remote DynamoDB, you can do so programmatically using Batch operations from AWS SDK. Though, you need to take care of this limitation: "A single call to BatchWriteItem can write up to 1 MB of data, which can comprise as many as 25 put or delete requests. Individual items to be written can be as large as 64 KB."

Hopefully, this quick introduction will be helpful in bringing you up to speed with DynamoDB local in Java.



Published at DZone with permission of its author, Gopal Sharma.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)