Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Run Dynamodb local as part of a Gradle Java project

I am trying to run DynamoDB local for testing purposes. I followed the steps amazon provides for setting it up and running the jar by itself works fine (link to amazon's tutorial Here). However, the tutorial doesn't go over running the jar within your own project. I don't want all the other developers to have to grab a jar and run it locally every time they test their code.

That is where my question comes in. I've had a real hard time finding any examples online of how to configure a Gradle project to run the DynamoDB local server as part of my tests. I found the following maven example https://github.com/awslabs/aws-dynamodb-examples/blob/master/src/test/java/com/amazonaws/services/dynamodbv2/DynamoDBLocalFixture.java#L32 and am trying to convert it to a Gradle, but am getting errors for all of com.amazonaws.services.dynamodbv2.local import statements they are using. The errors are that the resource cannot be found.

I went into their project's pom and put the following into my build.gradle file to emulate it.

//dynamodb local dependencies
testCompile('com.amazonaws:aws-java-sdk-dynamodb:1.10.42')
testCompile('com.amazonaws:aws-java-sdk-cloudwatch:1.10.42')
testCompile('com.amazonaws:aws-java-sdk:1.3.0')
testCompile('com.amazonaws:amazon-kinesis-client:1.6.1')
testCompile('com.amazonaws:amazon-kinesis-connectors:1.1.1')
testCompile('com.amazonaws:dynamodb-streams-kinesis-adapter:1.0.2')
testCompile('com.amazonaws:DynamoDBLocal:1.10.5.1')

The import statements still fail. Here is an example of one that fails.

import com.amazonaws.services.dynamodbv2.local.embedded.DynamoDBEmbedded;

TL;DR

Has anyone managed to get the DynamoDB local JAR to execute as part of a Gradle project or have a link to a good tutorial (it doesn't have to be the tutorial I linked to).

like image 272
OrwellHindenberg Avatar asked Dec 21 '15 17:12

OrwellHindenberg


People also ask

Can I run DynamoDB locally?

DynamoDB Local is available as a download (requires JRE), as an Apache Maven dependency, or as a Docker image. If you prefer to use the Amazon DynamoDB web service instead, see Setting up DynamoDB (web service).

How do I run DynamoDB locally with different ports?

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.

How does DynamoDB store data in Java?

Select Dynamo DB and then in Access Level section select GetItem and PutItem. Select Resources. Click on Add ARN. Fill Region where your Dynamo Db table is and enter name of your table and click Add.


2 Answers

In August 2018 Amazon announced new Docker image with Amazon DynamoDB Local onboard. It does not require downloading and running any JARs as well as adding using third-party OS-specific binaries like sqlite4java.

It is as simple as starting a Docker container before the tests:

docker run -p 8000:8000 amazon/dynamodb-local

You can do that manually for local development, as described above, or use it in your CI pipeline. Many CI services provide an ability to start additional containers during the pipeline that can provide dependencies for your tests. Here is an example for Gitlab CI/CD:

test:
  stage: test
  image: openjdk:8-alpine
  services:
    - name: amazon/dynamodb-local
      alias: dynamodb-local
  script:
    - ./gradlew clean test

So, during the test task DynamoDB will be available on http://dynamodb-local:8000.

Another, more powerful tool is localstack. It supports two dozen of AWS services, DynamoDB is one of them. The isage is very similar, you have to start it before running the tests and it will expose AWS-compatible APIs on given ports:

test:
  stage: test
  image: openjdk:8-alpine
  services:
    - name: localstack/localstack
    alias: localstack
  script:
    - ./gradlew clean test

The idea is to move all the configuration out of your build tool and tests and provide the dependency externally. Think of it as of dependency injection / IoC but for the whole service, not just a single bean. This way, you code is more clean and maintainable. You can see that even in the examples above: you can switch mock implementation from DynamoDB Local to localstack by simply changing the image part!

like image 182
madhead - StandWithUkraine Avatar answered Sep 19 '22 19:09

madhead - StandWithUkraine


I run into the same problem and first I tried to add sqlite4java.library.path to the Gradle script as it has been mentioned in the other comments.

This worked for command line, but were not working when I was running the tests from IDE (IntelliJ IDEA), so finally I come up with a simple init method, that is called at the beginning of each of integration tests:

AwsDynamoDbLocalTestUtils.initSqLite();
AmazonDynamoDBLocal amazonDynamoDBLocal = DynamoDBEmbedded.create();

Implementation can be found here: https://github.com/redskap/aws-dynamodb-java-example-local-testing/blob/master/src/test/java/io/redskap/java/aws/dynamodb/example/local/testing/AwsDynamoDbLocalTestUtils.java

I put a whole example to GitHub, it might be helpful: https://github.com/redskap/aws-dynamodb-java-example-local-testing

like image 20
Balazs Mracsko Avatar answered Sep 22 '22 19:09

Balazs Mracsko