Set up DynamoDB on local environment

Posted in Programming on November 05, 2015 by manhhomienbienthuy Comments
Set up DynamoDB on local environment

Would you like to be able to write and test code that uses the Amazon DynamoDB API even if you have no network connection and without incurring any usage charges.

If so, you are in need of DynamoDB local test tool. DynamoDB Local is a client-side database that supports the complete DynamoDB API.

Install JRE

You can download and install Java Runtime Environment from its official website. Follow the instruction to install it on your computer.

If you are using Ubuntu, you can install JRE with the following command. It will install OpenJDK 6 on Ubuntu 12.04 and OpenJDK 7 for Ubuntu 12.10+.

$ sudo apt-get install default-jre

If you want to install OpenJDK 7, execute the following command:

$ sudo apt-get install openjdk-7-jre

Download and instal DynamoDB Local

DynamoDB Local is available as an executable Java archive (JAR) file. That's the reason why you need JRE on you computer. Make sure you install the latest version of JRE.

Download DynamoDB for free using one of these links:

Download the format that your computer is familiar with. I recommend you to download .tar.gz file because of smaller file size (28.11MB instead of 28.15MB of .zip file).

After you have downloaded the archive to your computer, extract the contents and copy the extracted directory to a location of your choice.

Set up on local environment

To start DynamoDB on your local environment, open Terminal on folder you put extracted files, and execute the command like this:

$ java -jar DynamoDBLocal.jar
Initializing DynamoDB Local with the following configuration:
Port:   8000
InMemory:   false
DbPath: null
SharedDb:   false
shouldDelayTransientStatuses:   false
CorsParams: *

DynamoDB Local will create a local database in the same directory as the JAR. The file name will have the form MyAccessKeyId_Region.db, where MyAccessKeyId is the AWS access key used to access DynamoDB Local and Region is the target region.

DynamoDB Local listens on port 8000 by default; you can change this by specifying the –port option when you start it. If you are using the default port, the local endpoint will be localhost:8000.

DynamoDB will process incoming requests until you stop it. To stop DynamoDB, type Ctrl+C in the command prompt window.

Set up Rails to connect to DynamoDB Local

DynamoDB Local will listen on port 8000 so you have to set endpoint of DynamoDB client of Rails application connect the that endpoint (localhost:8000).

Modify app/models/concerns/dynamodb/model.rb as the following:

def client
  @client ||= Aws::DynamoDB::Client.new(
    region: "localhost",
    access_key_id: "access-key-id-of-your-choice",
    secret_access_key: "secret-key-of-your-choice",
    endpoint: "http://localhost:8000"
  )
end

Now, you can interact with DynamoDB local.

Note: Don't commit that file and push it to github or other places. Keep it on your local only.

If you want to configure DynamoDB Local to use for RSpec only, there is not need of modify app/models/concerns/dynamodb/model.rb. This file is very important for the system. There is another way.

Create a file named spec/support/dynamodb_helper.rb with the following content:

def dynamodb_local
  @client ||= Aws::DynamoDB::Client.new region: "localhost",
    endpoint: "http://localhost:8000", access_key_id: "x",
    secret_access_key: "x"
end

def delete_table table_name
  dynamodb_local.delete_table table_name: table_name
rescue
end

def create_table table_name
  Rake::Task["dynamodb:create_table"].reenable
  Rake::Task["dynamodb:create_table"].invoke table_name
end

Configure spec_helper to load that file automatically by adding this line to spec/rails_helper.rb

require "rake"
Rails.application.load_tasks

Dir[Rails.root.join('spec/support/**/*.rb')].each{|f| require f}

If you want to test a DynamoDB model, add the following lines before any lines of test code:

before do
  allow(Dynamodb::Base).to receive(:client).and_return dynamodb_local
  create_table "table-name"
end

after{delete_table "table-name"}

To create and delete DynamoDB on local, you have to add rake tasks for those operations. Add create_table tasks to file lib/tasks/dynamodb.rake

  task :create_table, [:table_name] => :environment do |_, args|
    table_json = # JSON params for creating table
    Dynamodb::Base.__create_table table_json if table_json.present?
  end

Notes

The downloadable version of DynamoDB attempts to emulate the Amazon DynamoDB web service as closely as possible. However, it does differ from the Amazon DynamoDB service in the following ways:

  • Regions and distinct AWS accounts are not supported at the client level.
  • Provisioned throughput settings are ignored, even though the API requires them. For CreateTable, you can specify any numbers you want for provisioned read and write throughput, even though these numbers will not be used. You can call UpdateTable as many times as you like per day; however, any changes to provisioned throughput values are ignored.
  • The speed of read and write operations on table data are limited only by the speed of your computer. CreateTableUpdateTable and DeleteTable operations occur immediately, and table state is always ACTIVE. UpdateTable operations that only change the provisioned throughput settings on tables and/or global secondary indexes will occur immediately. If an UpdateTable operation creates or deletes any global secondary indexes, then those indexes transition through normal states (such as CREATING and DELETING, respectively) before they become ACTIVE state. The table remains ACTIVE during this time.
  • Read operations are eventually consistent. However, due to the speed of DynamoDB running on your computer, most reads will actually appear to be strongly consistent.
  • Consumed capacity units are not tracked. In API responses, nulls are returned instead of capacity units.
  • Item collection metrics are not tracked; nor are item collection sizes. In API responses, nulls are returned instead of item collection metrics.
  • In the DynamoDB API, there is a 1 MB limit on data returned per result set. The DynamoDB web service enforces this limit, and so does the downloadable version of DynamoDB. However, when querying an index, the DynamoDB service only calculates the size of the projected key and attributes. By contrast, the downloadable version of DynamoDB calculates the size of the entire item.
  • If you are leveraging DynamoDB Streams, the rate at which shards are created might differ: In the DynamoDB web service, shard creation behavior is partially influenced by table partition activity; however, when you run DynamoDB locally, there is no table partitioning. In either case, shards are ephemeral, so your application should not be dependent on shard behavior.

References

I apologise for any typos. If you notice a problem, please let me know.

Thank you all for your attention.