简体   繁体   English

作为 Gradle Java 项目的一部分在本地运行 Dynamodb

[英]Run Dynamodb local as part of a Gradle Java project

I am trying to run DynamoDB local for testing purposes.我正在尝试在本地运行 DynamoDB 以进行测试。 I followed the steps amazon provides for setting it up and running the jar by itself works fine (link to amazon's tutorial Here ).我按照亚马逊提供的步骤进行设置并自行运行 jar 工作正常(链接到亚马逊的教程Here )。 However, the tutorial doesn't go over running the jar within your own project.但是,本教程不会在您自己的项目中运行 jar。 I don't want all the other developers to have to grab a jar and run it locally every time they test their code.我不希望所有其他开发人员每次测试他们的代码时都必须抓起一个 jar 并在本地运行它。

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.这就是我的问题所在。我真的很难在网上找到任何关于如何配置 Gradle 项目以运行 DynamoDB 本地服务器作为我测试的一部分的示例。 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.我找到了以下 Maven 示例https://github.com/awslabs/aws-dynamodb-examples/blob/master/src/test/java/com/amazonaws/services/dynamodbv2/DynamoDBLocalFixture.java#L32并尝试转换它到 Gradle,但我收到了他们正在使用的所有com.amazonaws.services.dynamodbv2.local导入语句的错误。 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.我进入了他们项目的 pom 并将以下内容放入我的build.gradle文件中以模拟它。

 //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).有没有人设法让 DynamoDB 本地 JAR 作为 Gradle 项目的一部分执行,或者有一个好的教程的链接(它不一定是我链接到的教程)。

We have DynamoDB local working with gradle.我们有本地的 DynamoDB 与 gradle 一起工作。 Here's what you need to add to your gradle.build file:以下是您需要添加到 gradle.build 文件中的内容:

For gradle 4.x and below versions对于 gradle 4.x 及以下版本

1) Add to the repositories section: 1)添加到存储库部分:

    maven {
        url 'http://dynamodb-local.s3-website-us-west-2.amazonaws.com/release'
    }

2) Add to the dependencies section (assuming you're using this for your tests): 2)添加到依赖项部分(假设您将其用于测试):

    testCompile group: 'com.amazonaws', name: 'DynamoDBLocal', version: 1.11.0

3) These next two steps are the tricky part. 3)接下来的两个步骤是棘手的部分。 First copy the native files to a directory:首先将本机文件复制到一个目录:

task copyNativeDeps(type: Copy) {
    from (configurations.testCompile) {
        include "*.dylib"
        include "*.so"
        include "*.dll"
    }
    into 'build/libs'
}

4) Then make sure you include this directory (build/libs in our case) in the java library path like so: 4) 然后确保在 java 库路径中包含此目录(在我们的例子中为 build/libs),如下所示:

test.dependsOn copyNativeDeps
test.doFirst {
    systemProperty "java.library.path", 'build/libs'
}

Now you should be able to run./gradlew test and have your tests hit your local DynamoDB.现在您应该能够运行 ./gradlew test 并让您的测试命中本地 DynamoDB。

For Gradle 5.x the below solution works对于 Gradle 5.x ,以下解决方案有效

 maven {
        url 'http://dynamodb-local.s3-website-us-west-2.amazonaws.com/release'
    }

configurations {
        dynamodb
    }

dependencies {
    testImplementation 'com.amazonaws:DynamoDBLocal:1.11.477'
    dynamodb fileTree (dir: 'lib', include: ["*.dylib", "*.so", "*.dll"])
    dynamodb 'com.amazonaws:DynamoDBLocal:1.11.477'
}

task copyNativeDeps(type: Copy) {
    from configurations.dynamodb
    into "$project.buildDir/libs/"
}

test.dependsOn copyNativeDeps
test.doFirst {
    systemProperty "java.library.path", 'build/libs'
}

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.我遇到了同样的问题,首先我尝试将 sqlite4java.library.path 添加到 Gradle 脚本中,正如其他评论中提到的那样。

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:这适用于命令行,但当我从 IDE (IntelliJ IDEA) 运行测试时不起作用,所以最后我想出了一个简单的 init 方法,它在每个集成测试开始时调用:

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实现可以在这里找到: https ://github.com/redskap/aws-dynamodb-java-example-local-testing/blob/master/src/test/java/io/redskap/java/aws/dynamodb/example/ 本地/测试/AwsDynamoDbLocalTestUtils.java

I put a whole example to GitHub, it might be helpful: https://github.com/redskap/aws-dynamodb-java-example-local-testing我在 GitHub 上放了一个完整的例子,它可能会有帮助: https ://github.com/redskap/aws-dynamodb-java-example-local-testing

In August 2018 Amazon announced new Docker image with Amazon DynamoDB Local onboard. 2018 年 8 月, 亚马逊宣布推出新的Docker 镜像,其中搭载了 Amazon DynamoDB Local。 It does not require downloading and running any JARs as well as adding using third-party OS-specific binaries like sqlite4java .它不需要下载和运行任何 JAR,也不需要使用第三方特定于操作系统的二进制文件(如sqlite4java

It is as simple as starting a Docker container before the tests:它就像在测试前启动 Docker 容器一样简单:

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.如上所述,您可以手动为本地开发执行此操作,或者在您的 CI 管道中使用它。 Many CI services provide an ability to start additional containers during the pipeline that can provide dependencies for your tests.许多 CI 服务提供了在管道期间启动额外容器的能力,这些容器可以为您的测试提供依赖项。 Here is an example for Gitlab CI/CD:这是 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 .因此,在test任务期间,DynamoDB 将在http://dynamodb-local:8000上可用。

Another, more powerful tool is localstack .另一个更强大的工具是localstack It supports two dozen of AWS services, DynamoDB is one of them.它支持两打 AWS 服务,DynamoDB 就是其中之一。 The isage is very similar, you have to start it before running the tests and it will expose AWS-compatible APIs on given ports : isage 非常相似,您必须在运行测试之前启动它,它会在给定端口上公开与 AWS 兼容的 API:

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.将其视为依赖注入/IoC,但对于整个服务,而不仅仅是单个 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!您甚至可以在上面的示例中看到:您可以通过简单地更改image部分来将模拟实现从 DynamoDB Local 切换到 localstack!

The easiest way, in my opinion, is to:在我看来,最简单的方法是:

  1. Download the JAR from here: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBLocal.html#DynamoDBLocal.DownloadingAndRunning从这里下载 JAR:http: //docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBLocal.html#DynamoDBLocal.DownloadingAndRunning

  2. Then unzip the downloaded folder and add its content to the /libs folder in the project (create the /libs folder before that)然后解压下载的文件夹,将其内容添加到项目中的/libs文件夹中(在此之前创建/libs文件夹)

  3. Finally, add to the build.gradle:最后,添加到build.gradle:

     dependencies { runtime files('libs/DynamoDBLocal.jar') }

I didn't want to create a specific configuration for dynamo for gradle 6+ so I tweaked the original answer instructions.我不想为 gradle 6+ 的发电机创建特定配置,所以我调整了原始答案说明。 Also, this is in kotlin gradle DSL rather than groovy.此外,这是在 kotlin gradle DSL 而不是 groovy 中。

val copyNativeDeps by tasks.creating(Copy::class) {
    from(configurations.testRuntimeClasspath) {
        include("*.dylib")
        include("*.so")
        include("*.dll")
    }
    into("$buildDir/libs")
}

tasks.withType<Test> {
    dependsOn.add(copyNativeDeps)
    doFirst { systemProperty("java.library.path", "$buildDir/libs") }
}

By leveraging the testRuntimeClasspath configuration, gradle is able to locate the relevant files for you without needing to create a custom configuration.通过利用testRuntimeClasspath配置,gradle 能够为您找到相关文件,而无需创建自定义配置。 Obviously this has the side effect that if your test runtime has many native deps, they will also be copied which would make the custom configuration approach more ideal.显然这会产生副作用,如果您的测试运行时有许多本机 dep,它们也会被复制,这将使自定义配置方法更加理想。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM