mirror of
https://github.com/jlengrand/quarkus.git
synced 2026-03-10 08:41:22 +00:00
AWS SDK2 - Dynamodb extension
This commit is contained in:
@@ -36,11 +36,14 @@ jobs:
|
||||
- script: docker run --rm --publish 5432:5432 --name build-postgres -e POSTGRES_USER=hibernate_orm_test -e POSTGRES_PASSWORD=hibernate_orm_test -e POSTGRES_DB=hibernate_orm_test -d postgres:10.5
|
||||
displayName: 'start postgres'
|
||||
|
||||
- script: docker run --rm --publish 8000:8000 --name build-dynamodb -d amazon/dynamodb-local:1.11.477
|
||||
displayName: 'start dynamodb'
|
||||
|
||||
- task: Maven@3
|
||||
displayName: 'Maven Build'
|
||||
inputs:
|
||||
goals: 'install'
|
||||
options: '-B --settings azure-mvn-settings.xml -Dnative-image.docker-build -Dtest-postgresql -Dtest-elasticsearch -Dnative-image.xmx=6g -Dnative -Dno-format'
|
||||
options: '-B --settings azure-mvn-settings.xml -Dnative-image.docker-build -Dtest-postgresql -Dtest-elasticsearch -Dtest-dynamodb -Ddynamodb-local.port=8000 -Dnative-image.xmx=6g -Dnative -Dno-format'
|
||||
|
||||
- job: Windows_Build
|
||||
timeoutInMinutes: 60
|
||||
|
||||
28
bom/pom.xml
28
bom/pom.xml
@@ -71,6 +71,7 @@
|
||||
<jackson.version>2.9.9</jackson.version>
|
||||
<commons-beanutils.version>1.9.3</commons-beanutils.version>
|
||||
<commons-logging.version>1.2</commons-logging.version>
|
||||
<commons-logging-jboss-logging.version>1.0.0.Final</commons-logging-jboss-logging.version>
|
||||
<commons-lang3.version>3.8.1</commons-lang3.version>
|
||||
<commons-codec.version>1.11</commons-codec.version>
|
||||
<validation-api.version>2.0.1.Final</validation-api.version>
|
||||
@@ -130,6 +131,7 @@
|
||||
<aws-lambda-java.version>1.1.0</aws-lambda-java.version>
|
||||
<aws-lambda-java-events.version>2.2.5</aws-lambda-java-events.version>
|
||||
<aws-lambda-serverless-java-container.version>1.3.1</aws-lambda-serverless-java-container.version>
|
||||
<awssdk.version>2.7.0</awssdk.version>
|
||||
<kotlin.version>1.3.31</kotlin.version>
|
||||
<camel.version>3.0.0-M2</camel.version>
|
||||
<dekorate.version>0.6.1</dekorate.version>
|
||||
@@ -519,6 +521,11 @@
|
||||
<artifactId>quarkus-amazon-lambda-resteasy</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-amazon-dynamodb</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-kubernetes</artifactId>
|
||||
@@ -683,6 +690,11 @@
|
||||
<artifactId>jboss-logging</artifactId>
|
||||
<version>${jboss-logging.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jboss.logging</groupId>
|
||||
<artifactId>commons-logging-jboss-logging</artifactId>
|
||||
<version>${commons-logging-jboss-logging.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jboss.logmanager</groupId>
|
||||
<artifactId>jboss-logmanager-embedded</artifactId>
|
||||
@@ -1932,6 +1944,22 @@
|
||||
<version>${aws-lambda-serverless-java-container.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>software.amazon.awssdk</groupId>
|
||||
<artifactId>dynamodb</artifactId>
|
||||
<version>${awssdk.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>software.amazon.awssdk</groupId>
|
||||
<artifactId>netty-nio-client</artifactId>
|
||||
<version>${awssdk.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>software.amazon.awssdk</groupId>
|
||||
<artifactId>apache-client</artifactId>
|
||||
<version>${awssdk.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.maven.shared</groupId>
|
||||
<artifactId>maven-artifact-transfer</artifactId>
|
||||
|
||||
@@ -686,6 +686,16 @@
|
||||
<artifactId>quarkus-amazon-lambda-resteasy-deployment</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-amazon-dynamodb</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-amazon-dynamodb-deployment</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-kotlin</artifactId>
|
||||
@@ -795,6 +805,12 @@
|
||||
<version>${project.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-test-dynamodb</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-junit5-internal</artifactId>
|
||||
|
||||
@@ -20,6 +20,7 @@ public final class FeatureBuildItem extends MultiBuildItem {
|
||||
public static final String CAMEL_SALESFORCE = "camel-salesforce";
|
||||
public static final String CAMEL_SERVLET = "camel-servlet";
|
||||
public static final String CDI = "cdi";
|
||||
public static final String DYNAMODB = "dynamodb";
|
||||
public static final String ELASTICSEARCH_REST_CLIENT = "elasticsearch-rest-client";
|
||||
public static final String FLYWAY = "flyway";
|
||||
public static final String HIBERNATE_ORM = "hibernate-orm";
|
||||
|
||||
63
extensions/amazon-dynamodb/deployment/pom.xml
Normal file
63
extensions/amazon-dynamodb/deployment/pom.xml
Normal file
@@ -0,0 +1,63 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-amazon-dynamodb-parent</artifactId>
|
||||
<version>999-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<artifactId>quarkus-amazon-dynamodb-deployment</artifactId>
|
||||
<name>Quarkus - Amazon DynamoDB - Deployment</name>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-core-deployment</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-arc-deployment</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-netty-deployment</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-amazon-dynamodb</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-junit5-internal</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.rest-assured</groupId>
|
||||
<artifactId>rest-assured</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<annotationProcessorPaths>
|
||||
<path>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-extension-processor</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</path>
|
||||
</annotationProcessorPaths>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -0,0 +1,52 @@
|
||||
package io.quarkus.dynamodb.deployment;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import io.quarkus.deployment.annotations.BuildProducer;
|
||||
import io.quarkus.deployment.annotations.BuildStep;
|
||||
import io.quarkus.deployment.builditem.ExtensionSslNativeSupportBuildItem;
|
||||
import io.quarkus.deployment.builditem.FeatureBuildItem;
|
||||
import io.quarkus.deployment.builditem.substrate.ReflectiveClassBuildItem;
|
||||
import io.quarkus.deployment.builditem.substrate.ServiceProviderBuildItem;
|
||||
import io.quarkus.deployment.builditem.substrate.SubstrateProxyDefinitionBuildItem;
|
||||
import software.amazon.awssdk.http.SdkHttpService;
|
||||
import software.amazon.awssdk.http.apache.ApacheSdkHttpService;
|
||||
import software.amazon.awssdk.http.async.SdkAsyncHttpService;
|
||||
import software.amazon.awssdk.http.nio.netty.NettySdkAsyncHttpService;
|
||||
|
||||
public class DynamodbProcessor {
|
||||
public static final String AWS_SDK_APPLICATION_ARCHIVE_MARKERS = "software/amazon/awssdk";
|
||||
|
||||
@Inject
|
||||
BuildProducer<ExtensionSslNativeSupportBuildItem> extensionSslNativeSupport;
|
||||
|
||||
@BuildStep
|
||||
void build(BuildProducer<FeatureBuildItem> feature) {
|
||||
feature.produce(new FeatureBuildItem(FeatureBuildItem.DYNAMODB));
|
||||
}
|
||||
|
||||
@BuildStep
|
||||
void setupDynamoDb() {
|
||||
// Indicates that this extension would like the SSL support to be enabled
|
||||
extensionSslNativeSupport.produce(new ExtensionSslNativeSupportBuildItem(FeatureBuildItem.DYNAMODB));
|
||||
}
|
||||
|
||||
@BuildStep
|
||||
SubstrateProxyDefinitionBuildItem httpProxies() {
|
||||
return new SubstrateProxyDefinitionBuildItem("org.apache.http.conn.HttpClientConnectionManager",
|
||||
"org.apache.http.pool.ConnPoolControl", "software.amazon.awssdk.http.apache.internal.conn.Wrapped");
|
||||
}
|
||||
|
||||
@BuildStep(applicationArchiveMarkers = { AWS_SDK_APPLICATION_ARCHIVE_MARKERS })
|
||||
void setupSdkAsyncHttpService(BuildProducer<ServiceProviderBuildItem> serviceProvider,
|
||||
BuildProducer<ReflectiveClassBuildItem> reflectiveClass) {
|
||||
|
||||
//Register netty as async client
|
||||
serviceProvider.produce(
|
||||
new ServiceProviderBuildItem(SdkAsyncHttpService.class.getName(), NettySdkAsyncHttpService.class.getName()));
|
||||
|
||||
//Register Apache client as sync client
|
||||
serviceProvider.produce(
|
||||
new ServiceProviderBuildItem(SdkHttpService.class.getName(), ApacheSdkHttpService.class.getName()));
|
||||
}
|
||||
}
|
||||
23
extensions/amazon-dynamodb/pom.xml
Normal file
23
extensions/amazon-dynamodb/pom.xml
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<artifactId>quarkus-build-parent</artifactId>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<version>999-SNAPSHOT</version>
|
||||
<relativePath>../../build-parent/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<artifactId>quarkus-amazon-dynamodb-parent</artifactId>
|
||||
<name>Quarkus - Amazon DynamoDB</name>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<modules>
|
||||
<module>runtime</module>
|
||||
<module>deployment</module>
|
||||
</modules>
|
||||
|
||||
</project>
|
||||
70
extensions/amazon-dynamodb/runtime/pom.xml
Normal file
70
extensions/amazon-dynamodb/runtime/pom.xml
Normal file
@@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-amazon-dynamodb-parent</artifactId>
|
||||
<version>999-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<artifactId>quarkus-amazon-dynamodb</artifactId>
|
||||
<name>Quarkus - Amazon DynamoDB - Runtime</name>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-netty</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>software.amazon.awssdk</groupId>
|
||||
<artifactId>dynamodb</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>software.amazon.awssdk</groupId>
|
||||
<artifactId>netty-nio-client</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>software.amazon.awssdk</groupId>
|
||||
<artifactId>apache-client</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>commons-logging</groupId>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jboss.logging</groupId>
|
||||
<artifactId>commons-logging-jboss-logging</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-bootstrap-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<annotationProcessorPaths>
|
||||
<path>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-extension-processor</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</path>
|
||||
</annotationProcessorPaths>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -86,6 +86,7 @@
|
||||
<!-- Integrations -->
|
||||
<module>amazon-lambda</module>
|
||||
<module>amazon-lambda-resteasy</module>
|
||||
<module>amazon-dynamodb</module>
|
||||
|
||||
<!-- Camel -->
|
||||
<module>camel</module>
|
||||
|
||||
38
integration-tests/amazon-dynamodb/README.md
Normal file
38
integration-tests/amazon-dynamodb/README.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# Example with AWS DynamoDB
|
||||
|
||||
## Running the tests
|
||||
|
||||
By default, the tests of this module are disabled.
|
||||
|
||||
To run the tests in a standard JVM with DynamoDB started as a Docker container, you can run the following command:
|
||||
|
||||
```
|
||||
mvn clean install -Dtest-dynamodb -Ddocker
|
||||
```
|
||||
|
||||
Additionally, you can generate a native image and run the tests for this native image by adding `-Dnative`:
|
||||
|
||||
```
|
||||
mvn clean install -Dtest-dynamodb -Ddocker -Dnative
|
||||
```
|
||||
|
||||
If you don't want to run DynamoDB as a Docker container, you can start your own [DynamoDB local server](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBLocal.DownloadingAndRunning.html) on any port.
|
||||
|
||||
Then you can define a specific connection URL with `-Ddynamodb-local.port=8888`
|
||||
|
||||
You can then run the tests as follows (either with `-Dnative` or not):
|
||||
|
||||
```
|
||||
mvn clean install -Dtest-dynamodb -Ddynamodb-local.port=8888
|
||||
```
|
||||
|
||||
Alternatively, you can run the tests against your AWS account.
|
||||
AWS access key ID and secret key set to your AWS account set as environment variables
|
||||
```
|
||||
export AWS_ACCESS_KEY_ID='YOUR_KEY'
|
||||
export AWS_SECRET_ACCESS_KEY='YOUR_SECRET_KEY'
|
||||
```
|
||||
You can then run the tests as follows (either with `-Dnative` or not):
|
||||
```
|
||||
mvn clean install -Dtest-dynamodb -Ddynamodb.aws=true
|
||||
```
|
||||
255
integration-tests/amazon-dynamodb/pom.xml
Normal file
255
integration-tests/amazon-dynamodb/pom.xml
Normal file
@@ -0,0 +1,255 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>quarkus-integration-tests-parent</artifactId>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<version>999-SNAPSHOT</version>
|
||||
<relativePath>../</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>quarkus-integration-test-amazon-dynamodb</artifactId>
|
||||
<name>Quarkus - Integration Tests - AWS DynamoDB</name>
|
||||
<description>The AWS DynamoDB integration tests</description>
|
||||
|
||||
<properties>
|
||||
<dynamodb.aws>false</dynamodb.aws>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-arc</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-resteasy</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-core</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-amazon-dynamodb</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.jboss.slf4j</groupId>
|
||||
<artifactId>slf4j-jboss-logging</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- test dependencies -->
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-junit5</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.glassfish</groupId>
|
||||
<artifactId>javax.json</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.rest-assured</groupId>
|
||||
<artifactId>rest-assured</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-failsafe-plugin</artifactId>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>quarkus-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>build</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>test-dynamodb</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>test-dynamodb</name>
|
||||
</property>
|
||||
</activation>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>build-helper-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>reserve-network-port</id>
|
||||
<goals>
|
||||
<goal>reserve-network-port</goal>
|
||||
</goals>
|
||||
<phase>initialize</phase>
|
||||
<configuration>
|
||||
<portNames>
|
||||
<portName>dynamodb-local.port</portName>
|
||||
</portNames>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<skip>false</skip>
|
||||
<argLine>-Ddynamodb.port=${dynamodb-local.port}</argLine>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-failsafe-plugin</artifactId>
|
||||
<configuration>
|
||||
<skip>false</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>native-image</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>native</name>
|
||||
</property>
|
||||
</activation>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-failsafe-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>integration-test</goal>
|
||||
<goal>verify</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<environmentVariables>
|
||||
<DYNAMODB_PORT>${dynamodb-local.port}</DYNAMODB_PORT>
|
||||
<DYNAMODB_AWS>${dynamodb.aws}</DYNAMODB_AWS>
|
||||
</environmentVariables>
|
||||
<systemProperties>
|
||||
<native.image.path>${project.build.directory}/${project.build.finalName}-runner</native.image.path>
|
||||
</systemProperties>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>quarkus-maven-plugin</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>native-image</id>
|
||||
<goals>
|
||||
<goal>native-image</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<reportErrorsAtRuntime>false</reportErrorsAtRuntime>
|
||||
<cleanupServer>true</cleanupServer>
|
||||
<enableHttpUrlHandler>true</enableHttpUrlHandler>
|
||||
<enableServer>false</enableServer>
|
||||
<dumpProxies>false</dumpProxies>
|
||||
<graalvmHome>${graalvmHome}</graalvmHome>
|
||||
<enableJni>true</enableJni>
|
||||
<enableAllSecurityServices>true</enableAllSecurityServices>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>docker-dynamodb</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>docker</name>
|
||||
</property>
|
||||
</activation>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>io.fabric8</groupId>
|
||||
<artifactId>docker-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<images>
|
||||
<image>
|
||||
<name>amazon/dynamodb-local:1.11.477</name>
|
||||
<alias>dynamodb-local</alias>
|
||||
<run>
|
||||
<ports>
|
||||
<port>${dynamodb-local.port}:8000</port>
|
||||
</ports>
|
||||
<wait>
|
||||
<http>
|
||||
<url>http://localhost:${dynamodb-local.port}/shell/</url>
|
||||
</http>
|
||||
<time>10000</time>
|
||||
</wait>
|
||||
</run>
|
||||
</image>
|
||||
</images>
|
||||
<!--Stops all dynamodb images currently running, not just those we just started.
|
||||
Useful to stop processes still running from a previously failed integration test run -->
|
||||
<allContainers>true</allContainers>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>docker-start</id>
|
||||
<phase>compile</phase>
|
||||
<goals>
|
||||
<goal>stop</goal>
|
||||
<goal>start</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>docker-stop</id>
|
||||
<phase>post-integration-test</phase>
|
||||
<goals>
|
||||
<goal>stop</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,8 @@
|
||||
package io.quarkus.it.dynamodb;
|
||||
|
||||
import javax.ws.rs.ApplicationPath;
|
||||
import javax.ws.rs.core.Application;
|
||||
|
||||
@ApplicationPath("/test")
|
||||
public class DynamoDBApplication extends Application {
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
package io.quarkus.it.dynamodb;
|
||||
|
||||
import static javax.ws.rs.core.MediaType.TEXT_PLAIN;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletionStage;
|
||||
|
||||
import javax.enterprise.event.Observes;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.Produces;
|
||||
|
||||
import org.eclipse.microprofile.config.inject.ConfigProperty;
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import io.quarkus.runtime.StartupEvent;
|
||||
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
|
||||
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
|
||||
import software.amazon.awssdk.regions.Region;
|
||||
import software.amazon.awssdk.services.dynamodb.DynamoDbAsyncClient;
|
||||
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
|
||||
import software.amazon.awssdk.services.dynamodb.model.GetItemResponse;
|
||||
|
||||
@Path("/")
|
||||
public class DynamoDBResource {
|
||||
private final static String ASYNC_TABLE = "async";
|
||||
private final static String BLOCKING_TABLE = "blocking";
|
||||
|
||||
private static final Logger LOG = Logger.getLogger(DynamoDBResource.class);
|
||||
|
||||
@ConfigProperty(name = "dynamodb.port", defaultValue = "8000")
|
||||
String dynamoDbPort;
|
||||
|
||||
@ConfigProperty(name = "dynamodb.aws", defaultValue = "false")
|
||||
Boolean useAwsAccount;
|
||||
|
||||
private DynamoDbAsyncClient asyncClient;
|
||||
|
||||
private DynamoDbClient client;
|
||||
|
||||
void onStart(@Observes StartupEvent ev) {
|
||||
if (useAwsAccount) {
|
||||
asyncClient = DynamoDbAsyncClient.create();
|
||||
client = DynamoDbClient.create();
|
||||
} else {
|
||||
asyncClient = DynamoDbAsyncClient.builder()
|
||||
.credentialsProvider(
|
||||
StaticCredentialsProvider.create(AwsBasicCredentials.create("test-key", "test-secret")))
|
||||
.region(Region.of("localhost"))
|
||||
.endpointOverride(URI.create("http://localhost:" + dynamoDbPort))
|
||||
.build();
|
||||
|
||||
client = DynamoDbClient.builder()
|
||||
.credentialsProvider(
|
||||
StaticCredentialsProvider.create(AwsBasicCredentials.create("test-key", "test-secret")))
|
||||
.region(Region.of("localhost"))
|
||||
.endpointOverride(URI.create("http://localhost:" + dynamoDbPort))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("async")
|
||||
@Produces(TEXT_PLAIN)
|
||||
public CompletionStage<String> testAsync() {
|
||||
LOG.info("Testing Async client with table: " + ASYNC_TABLE);
|
||||
String keyValue = UUID.randomUUID().toString();
|
||||
String rangeValue = UUID.randomUUID().toString();
|
||||
|
||||
return DynamoDBUtils.createTableIfNotExistsAsync(asyncClient, ASYNC_TABLE)
|
||||
.thenCompose(t -> asyncClient.putItem(DynamoDBUtils.createPutRequest(ASYNC_TABLE, keyValue, rangeValue, "OK")))
|
||||
.thenCompose(p -> asyncClient.getItem(DynamoDBUtils.createGetRequest(ASYNC_TABLE, keyValue, rangeValue)))
|
||||
.thenApply(p -> p.item().get(DynamoDBUtils.PAYLOAD_NAME).s());
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("blocking")
|
||||
@Produces(TEXT_PLAIN)
|
||||
public String testBlocking() {
|
||||
LOG.info("Testing Blocking client with table: " + BLOCKING_TABLE);
|
||||
|
||||
String keyValue = UUID.randomUUID().toString();
|
||||
String rangeValue = UUID.randomUUID().toString();
|
||||
GetItemResponse item = null;
|
||||
|
||||
if (DynamoDBUtils.createTableIfNotExists(client, BLOCKING_TABLE)) {
|
||||
if (client.putItem(DynamoDBUtils.createPutRequest(BLOCKING_TABLE, keyValue, rangeValue, "OK")) != null) {
|
||||
item = client.getItem(DynamoDBUtils.createGetRequest(BLOCKING_TABLE, keyValue, rangeValue));
|
||||
}
|
||||
}
|
||||
|
||||
if (item != null) {
|
||||
return item.item().get(DynamoDBUtils.PAYLOAD_NAME).s();
|
||||
} else {
|
||||
return "ERROR";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
package io.quarkus.it.dynamodb;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import software.amazon.awssdk.services.dynamodb.DynamoDbAsyncClient;
|
||||
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
|
||||
import software.amazon.awssdk.services.dynamodb.model.AttributeDefinition;
|
||||
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
|
||||
import software.amazon.awssdk.services.dynamodb.model.CreateTableRequest;
|
||||
import software.amazon.awssdk.services.dynamodb.model.DescribeTableRequest;
|
||||
import software.amazon.awssdk.services.dynamodb.model.DescribeTableResponse;
|
||||
import software.amazon.awssdk.services.dynamodb.model.GetItemRequest;
|
||||
import software.amazon.awssdk.services.dynamodb.model.KeySchemaElement;
|
||||
import software.amazon.awssdk.services.dynamodb.model.KeyType;
|
||||
import software.amazon.awssdk.services.dynamodb.model.ProvisionedThroughput;
|
||||
import software.amazon.awssdk.services.dynamodb.model.PutItemRequest;
|
||||
import software.amazon.awssdk.services.dynamodb.model.ResourceInUseException;
|
||||
import software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException;
|
||||
import software.amazon.awssdk.services.dynamodb.model.ScalarAttributeType;
|
||||
import software.amazon.awssdk.services.dynamodb.model.TableDescription;
|
||||
import software.amazon.awssdk.services.dynamodb.model.TableStatus;
|
||||
|
||||
public class DynamoDBUtils {
|
||||
private static final Logger LOG = Logger.getLogger(DynamoDBUtils.class);
|
||||
|
||||
private final static String KEY_NAME = "keyId";
|
||||
private final static String RANGE_NAME = "rangeId";
|
||||
public final static String PAYLOAD_NAME = "payload";
|
||||
|
||||
private static final int DEFAULT_WAIT_TIMEOUT = 10 * 60 * 1000; //10 minutes
|
||||
private static final int DEFAULT_WAIT_INTERVAL = 5 * 1000; //5 seconds
|
||||
|
||||
public static boolean createTableIfNotExists(final DynamoDbClient dynamo, final String tableName) {
|
||||
try {
|
||||
dynamo.createTable(createTableRequest(tableName));
|
||||
return waitUntilTableActive(dynamo, tableName);
|
||||
} catch (ResourceInUseException e) {
|
||||
LOG.info("Reused existing table");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static CompletableFuture<Boolean> createTableIfNotExistsAsync(final DynamoDbAsyncClient dynamo, String table) {
|
||||
return dynamo.createTable(DynamoDBUtils.createTableRequest(table))
|
||||
.thenCompose(resp -> DynamoDBUtils.waitUntilTableActiveAsync(dynamo, table))
|
||||
.exceptionally(th -> {
|
||||
if (th.getCause() instanceof ResourceInUseException) {
|
||||
LOG.info("Reused existing table");
|
||||
return true;
|
||||
} else {
|
||||
LOG.error("Failed table creation", th);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static boolean waitUntilTableActive(final DynamoDbClient dynamo, final String tableName) {
|
||||
long startTime = System.currentTimeMillis();
|
||||
long endTime = startTime + DEFAULT_WAIT_TIMEOUT;
|
||||
|
||||
while (System.currentTimeMillis() < endTime) {
|
||||
try {
|
||||
TableDescription table = dynamo.describeTable(DescribeTableRequest.builder().tableName(tableName).build())
|
||||
.table();
|
||||
if (table.tableStatus().equals(TableStatus.ACTIVE)) {
|
||||
return true;
|
||||
|
||||
}
|
||||
} catch (ResourceNotFoundException e) {
|
||||
// Table doesn't exist yet. Keep pooling
|
||||
}
|
||||
|
||||
try {
|
||||
Thread.sleep(DEFAULT_WAIT_INTERVAL);
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
LOG.info(tableName + " table - Retry table created status");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static CompletableFuture<Boolean> waitUntilTableActiveAsync(final DynamoDbAsyncClient dynamo,
|
||||
final String table) {
|
||||
final long startTime = System.currentTimeMillis();
|
||||
final long endTime = startTime + DEFAULT_WAIT_TIMEOUT;
|
||||
|
||||
return retryAsync(() -> dynamo.describeTable(DescribeTableRequest.builder().tableName(table).build()), endTime);
|
||||
}
|
||||
|
||||
private static CompletableFuture<Boolean> retryAsync(Supplier<CompletableFuture<DescribeTableResponse>> action,
|
||||
final long endTime) {
|
||||
|
||||
return action.get()
|
||||
.thenComposeAsync(result -> {
|
||||
if (result.table().tableStatus() == TableStatus.ACTIVE) {
|
||||
return CompletableFuture.completedFuture(true);
|
||||
} else {
|
||||
try {
|
||||
Thread.sleep(DEFAULT_WAIT_INTERVAL);
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
LOG.info("Async table - Retry table created status");
|
||||
if (System.currentTimeMillis() < endTime) {
|
||||
return retryAsync(action, endTime);
|
||||
} else {
|
||||
return CompletableFuture.completedFuture(false);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static CreateTableRequest createTableRequest(String table) {
|
||||
List<AttributeDefinition> attributeDefinitions = new ArrayList<>();
|
||||
attributeDefinitions
|
||||
.add(AttributeDefinition.builder().attributeName(KEY_NAME).attributeType(ScalarAttributeType.S).build());
|
||||
attributeDefinitions.add(
|
||||
AttributeDefinition.builder().attributeName(RANGE_NAME).attributeType(ScalarAttributeType.S).build());
|
||||
|
||||
List<KeySchemaElement> ks = new ArrayList<>();
|
||||
ks.add(KeySchemaElement.builder().attributeName(KEY_NAME).keyType(KeyType.HASH).build());
|
||||
ks.add(KeySchemaElement.builder().attributeName(RANGE_NAME).keyType(KeyType.RANGE).build());
|
||||
|
||||
ProvisionedThroughput provisionedthroughput = ProvisionedThroughput.builder().readCapacityUnits(1000L)
|
||||
.writeCapacityUnits(1000L).build();
|
||||
|
||||
return CreateTableRequest.builder()
|
||||
.tableName(table)
|
||||
.attributeDefinitions(attributeDefinitions)
|
||||
.keySchema(ks)
|
||||
.provisionedThroughput(provisionedthroughput)
|
||||
.build();
|
||||
}
|
||||
|
||||
public static PutItemRequest createPutRequest(String table, String keyValue, String rangeValue, String payLoad) {
|
||||
Map<String, AttributeValue> item = new HashMap<>();
|
||||
item.put(KEY_NAME, AttributeValue.builder().s(keyValue).build());
|
||||
item.put(RANGE_NAME, AttributeValue.builder().s(rangeValue).build());
|
||||
item.put(PAYLOAD_NAME, AttributeValue.builder().s(payLoad).build());
|
||||
|
||||
return PutItemRequest.builder()
|
||||
.tableName(table)
|
||||
.item(item)
|
||||
.build();
|
||||
}
|
||||
|
||||
public static GetItemRequest createGetRequest(String table, String keyValue, String rangeValue) {
|
||||
Map<String, AttributeValue> key = new HashMap<>();
|
||||
key.put(KEY_NAME, AttributeValue.builder().s(keyValue).build());
|
||||
key.put(RANGE_NAME, AttributeValue.builder().s(rangeValue).build());
|
||||
|
||||
return GetItemRequest.builder()
|
||||
.tableName(table)
|
||||
.key(key)
|
||||
.attributesToGet(PAYLOAD_NAME)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
quarkus.log.category.\"software.amazon.awssdk\".level=WARN
|
||||
quarkus.log.category.\"software.amazon.awssdk.request\".level=DEBUG
|
||||
quarkus.log.category.\"org.apache.http.wire\".level=DEBUG
|
||||
@@ -0,0 +1,7 @@
|
||||
package io.quarkus.it.dynamodb;
|
||||
|
||||
import io.quarkus.test.junit.SubstrateTest;
|
||||
|
||||
@SubstrateTest
|
||||
public class DynamoDbFunctionalityITCase extends DynamoDbFunctionalityTest {
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package io.quarkus.it.dynamodb;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import io.quarkus.test.junit.QuarkusTest;
|
||||
import io.restassured.RestAssured;
|
||||
|
||||
/**
|
||||
* Test connecting DynamoDB client to local Dynamodb.
|
||||
*
|
||||
*/
|
||||
@QuarkusTest
|
||||
public class DynamoDbFunctionalityTest {
|
||||
|
||||
@Test
|
||||
public void testDynamoDbAsync() {
|
||||
RestAssured.when().get("/test/async").then().body(is("OK"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDynamoDbBlocking() {
|
||||
RestAssured.when().get("/test/blocking").then().body(is("OK"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -48,6 +48,7 @@
|
||||
<module>flyway</module>
|
||||
<module>keycloak</module>
|
||||
<module>reactive-pg-client</module>
|
||||
<module>amazon-dynamodb</module>
|
||||
<module>test-extension</module>
|
||||
<module>amazon-lambda</module>
|
||||
<module>kogito</module>
|
||||
|
||||
Reference in New Issue
Block a user