Запустите Dynamodb local как часть проекта Gradle Java

Я пытаюсь запустить DynamodB локально для целей тестирования. Я следовал инструкциям amazon по настройке и запуску фляги самостоятельно (ссылка на учебник amazon здесь). Тем не менее, учебник не распространяется на запуск jar в вашем собственном проекте. Я не хочу, чтобы все другие разработчики брали флягу и запускали ее локально каждый раз, когда тестируют свой код.

Вот тут и возникает мой вопрос. Мне было очень тяжело найти в Интернете какие-либо примеры того, как настроить gradle-проект для запуска локального сервера DynamodB в рамках моих тестов. Я нашел следующий пример 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 операторы импорта, которые они используют. Ошибки в том, что ресурс не может быть найден.

Я вошел в pom их проекта и вставил следующее в мой файл gradle.build, чтобы эмулировать его.

//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')

Операторы импорта по-прежнему не выполняются. Вот пример одного, который терпит неудачу.

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

TL; DR

Кто-нибудь смог заставить локальный jar-файл динамодба выполняться как часть проекта gradle или иметь ссылку на хороший учебник (это не обязательно должен быть учебник, с которым я связан).

7 ответов

У нас есть локальный DynamoDB, работающий с Gradle. Вот что вам нужно добавить в ваш файл gradle.build:

1) Добавьте в раздел репозитории:

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

2) Добавьте в раздел зависимостей (если вы используете это для своих тестов):

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

3) Эти следующие два шага - сложная часть. Сначала скопируйте собственные файлы в каталог:

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

4) Затем убедитесь, что вы включили этот каталог (в нашем случае build/libs) в путь к библиотеке Java следующим образом:

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

Теперь у вас должна быть возможность запустить тест./gradlew, и ваши тесты попадут в вашу локальную DynamoDB.

Для 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'
}

Я столкнулся с той же проблемой и сначала попытался добавить sqlite4java.library.path к скрипту Gradle, как это было упомянуто в других комментариях.

Это работало для командной строки, но не работало, когда я запускал тесты из IDE (IntelliJ IDEA), поэтому, наконец, я придумаю простой метод init, который вызывается в начале каждого из интеграционных тестов:

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

Реализация может быть найдена здесь: https://github.com/redskap/aws-dynamodb-java-example-local-testing/blob/master/src/test/java/io/redskap/java/aws/dynamodb/example/local/testing/AwsDynamoDbHelper.java#L20

Я положил целый пример на GitHub, это может быть полезно: https://github.com/redskap/aws-dynamodb-java-example-local-testing

В августе 2018 года Amazon анонсировала новый образ Docker со встроенным Amazon DynamoDB Local. Он не требует загрузки и запуска каких-либо JAR, а также добавления с использованием сторонних двоичных файлов для ОС, таких какsqlite4java.

Это так же просто, как запустить Docker-контейнер перед тестами:

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

Вы можете сделать это вручную для локальной разработки, как описано выше, или использовать в своем конвейере CI. Многие службы CI предоставляют возможность запускать дополнительные контейнеры во время конвейера, которые могут предоставлять зависимости для ваших тестов. Вот пример Gitlab CI/CD:

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

Итак, во время test задача DynamoDB будет доступна на http://dynamodb-local:8000.

Другой, более мощный инструмент - localstack. Он поддерживает два десятка сервисов AWS, DynamoDB - один из них. Isage очень похож, вы должны запустить его перед запуском тестов, и он предоставит AWS-совместимые API на заданных портах:

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

Идея состоит в том, чтобы переместить всю конфигурацию из вашего инструмента сборки и тестов и обеспечить внешнюю зависимость. Думайте об этом как о внедрении зависимостей / IoC, но для всего сервиса, а не только для одного bean-компонента. Таким образом, ваш код будет более чистым и удобным в обслуживании. Вы можете видеть это даже в приведенных выше примерах: вы можете переключить фиктивную реализацию с DynamoDB Local на localstack, просто изменивimage часть!

На мой взгляд, самый простой способ:

  1. Загрузите файл JAR здесь: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBLocal.html

  2. Затем разархивируйте загруженную папку и добавьте ее содержимое в папку / libs в проекте (до этого создайте папку / libs)

  3. Наконец, добавьте в build.gradle:

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

Я не хотел создавать конкретную конфигурацию для динамо для Gradle 6+, поэтому я изменил исходные инструкции ответа. Кроме того, это в 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") }
}

Используя testRuntimeClasspathконфигурации, gradle может найти для вас соответствующие файлы без необходимости создавать настраиваемую конфигурацию. Очевидно, это имеет побочный эффект: если в вашей тестовой среде выполнения много собственных зависимостей, они также будут скопированы, что сделает подход пользовательской конфигурации более идеальным.

Решение для Gradle 8

Адаптация решения @togise и объединение с другим вопросом SO .

      // ... Source set, plugins...

// Define a custom configuration set to allow us to configure DynamoDb local.
configurations {
    dynamoDbLocal
}


repositories {
    mavenCentral()
    // Add another Maven source
    maven {
        name "DynamoDB Local Release Repository"
        url "https://s3-us-west-2.amazonaws.com/dynamodb-local/release"
    }
}

dependencies {
    // Adds a locally running DynamoDB instance
    testImplementation 'com.amazonaws:DynamoDBLocal:2.0.0'
    configurations.dynamoDbLocal { fileTree(dir: 'lib', include: ["*.dylib", "*.so", "*.dll"]) }
    configurations.dynamoDbLocal { 'com.amazonaws:DynamoDBLocal:2.0.0' }

    // Other dependencies...
}

// Register a new Gradle task that may be called by others tasks
tasks.register('copyNativeDeps', Copy) {
    from configurations.dynamoDbLocal
    into "$project.buildDir/libs/"
}

test {
    // These two statements are required to set up DynamoDb local
    dependsOn copyNativeDeps
    doFirst {
        systemProperty "java.library.path", 'build/libs'
    }

    // Other test configuration, like useJUnitPlatform()
}

Другие вопросы по тегам