Aws-sdk-java: Best way to set a region when using Amazon DynamoDB local?

Created on 22 Dec 2014  路  14Comments  路  Source: aws/aws-sdk-java

Hi

I am using Dynamo DB local for local development in my machine and I was wondering which is the best way to "specify a region" which will end up being the filename of the SQLite database.

From what I have seen if I use this code:

AmazonDynamoDBClient dynamoDB = new AmazonDynamoDBClient();
dynamoDB.setEndpoint("http://127.0.0.1:8000");

It defaults to us-east-1 even if try to specify a region before or after calling setEndpoint

So, something like this

AmazonDynamoDBClient dynamoDB = new AmazonDynamoDBClient();
dynamoDB.setEndpoint("http://127.0.0.1:8000");
dynamoDB.setRegion(Region.getRegion(Regions.EU_WEST_1));

or

AmazonDynamoDBClient dynamoDB = new AmazonDynamoDBClient();
dynamoDB.setRegion(Region.getRegion(Regions.EU_WEST_1));
dynamoDB.setEndpoint("http://127.0.0.1:8000");

Will still try to use us-east-1

I have seen another method in the SDK which works for my purpose, mainly:

AmazonDynamoDBClient dynamoDB = new AmazonDynamoDBClient();
dynamoDB.setEndpoint("http://127.0.0.1:8000", "dynamo", "eu-west-1");

which works, but I see that the setEndpoint method with 3 arguments is marked as deprecated in AmazonWebServiceClient

And you may wonder why do I care about the region for local development... well... I have got eu-west-1 region configured in .aws/config so the AWS CLI tool takes this to create the tables so I would like to prevent having to change it whenever I want to mess around with the local Dynamo schema

Of course, if there are better ways of doing all this, happy to hear about them

Most helpful comment

Gotcha!!

Maybe the dynamodb doc needs to reflect this for local development?

All 14 comments

Hi @ricardclau,

The 3-arg setEndpoint method has indeed been deprecated, and should no longer be used. In this case, you can instead override both the endpoint and the signer region explicitly using the respective 1-arg methods:

dynamoDB.setEndpoint("http://127.0.0.1:8000");
dynamoDB.setSignerRegionOverride("eu-west-1");

Hope this helps.

Hi @hansonchar

Yes, it works flawlessly, this is the method I was looking for and could not find :)

Thanks for the quick response!

java.lang.NullPointerException
    at com.amazonaws.util.AwsHostNameUtils.parseRegionNameByInternalConfig(AwsHostNameUtils.java:154)
    at com.amazonaws.util.AwsHostNameUtils.parseRegionName(AwsHostNameUtils.java:58)
    at com.amazonaws.AmazonWebServiceClient.computeSignerByURI(AmazonWebServiceClient.java:280)
    at com.amazonaws.AmazonWebServiceClient.setEndpoint(AmazonWebServiceClient.java:170)
    at com.application.config.AwsBeanConfig.dynamoDbClient(AwsBeanConfig.java:51)

Hi, I have this exception when setting endpoint with custom hostname. In my case it is a docker hostname: http://dynamodb:2700, but when I used the deprecated setEndpoint method, it works okay.

wow! what a subtle issue!!!!

I wanted to use dynamodb javascript shell but could never query my tables! javascript shell defaults to us-west-2.

So when i configured my client i set the region to us-west-2.

But in my app, when i debugged the requests, they were signed with region us-east-1 !!!!!

Only after I override the signer region does it work!!

 AmazonDynamoDBClient amazonDynamoDB = new AmazonDynamoDBClient(amazonAWSCredentials());

        amazonDynamoDB.setRegion(Region.getRegion(Regions.fromName(dynamoDBProperties.getRegion())));
        amazonDynamoDB.setSignerRegionOverride("us-west-2");

why is the regions different?

Thanks,
Shane.

@shavo007 Are you using DynamoDB local?

Yep. This is for local dev using dynamodb local

Ok gotcha. When the SDK is given just an endpoint we try and parse the region from the endpoint. If the endpoint does not follow normal AWS conventions (i.e. https://service.region.amazonaws.com) then we fallback to us-east-1 so that is most likely what you are seeing. The signer region override can be used to customize the signing region when the SDK guesses incorrectly.

Gotcha!!

Maybe the dynamodb doc needs to reflect this for local development?

Agreed. Which doc did you refer to?

@shorea @shavo007 - Thanks so much for clarifying. This was driving me crazy.

I noticed that DynamoDB local was using different credentials in certain cases - sometimes using the endpoint and region I provided in my code, and other times finding credentials through the credential provider chain (e.g., looking in ~/.aws/credentials or environment vars). I couldn't be sure whether I'd be doing operations on my local or on my provisioned instance. And then, I noticed that I couldn't get certain operations to work unless I had a valid AWS region.

It would be good to have some documentation for Dynamo local that provides a sure-fire way to override any of other sources of credentials.

Glad to help @aneilbaboo

Here's a node.js setup that overrides ~/.aws and env credentials and gives nicely named dynamo database files:

var config = {
   test: {
      endpoint: 'http://localhost:8000',
      accessKeyId: 'dynamo',
      region: 'test',
      apiVersion: '2012-08-10',
      secretAccessKey: 'testDummyKey'
  },
  dev: {
      endpoint: 'http://localhost:8000',
      accessKeyId: 'dynamo',
      region: 'dev',
      apiVersion: '2012-08-10',
      secretAccessKey: 'devDummyKey'
    }
};

function dynamoDriver(params) {
   var dynamo = new AWS.DynamoDB(params); 
   return dynamoDriver.config.credentials = new AWS.Credentials(params); 
}

dynamoDriver(config.test); // db file => dynamo_test.db
dynamoDriver(config.dev); // db file => dynamo_dev.db

And I start dynamo without the shared DB option:

java -Djava.library.path=~/bin/dynamolib/DynamoDBLocal_lib -jar ~/bin/dynamolib/DynamoDBLocal.jar

@aneilbaboo Aware it's a while ago that you posted it, and thank you, but I think return dynamoDriver. should be return dynamo.

Was this page helpful?
0 / 5 - 0 ratings