Запустите 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
часть!
На мой взгляд, самый простой способ:
Загрузите файл JAR здесь: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBLocal.html
Затем разархивируйте загруженную папку и добавьте ее содержимое в папку / libs в проекте (до этого создайте папку / libs)
Наконец, добавьте в 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()
}