diff --git a/README.md b/README.md index 30ddee8..c0d6d60 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ OpenTracing instrumentation for AWS clients. ## Installation -### Maven +### AWS SDK 1 pom.xml ```xml @@ -15,26 +15,14 @@ pom.xml ``` -You most likely need to exclude aws-java-sdk dependency and add own: +### AWS SDK 2 +pom.xml ```xml io.opentracing.contrib - opentracing-aws-sdk + opentracing-aws-sdk-2 VERSION - - - com.amazonaws - aws-java-sdk - - - - - - com.amazonaws - aws-java-sdk - {required version} - ``` ## Usage @@ -42,10 +30,11 @@ You most likely need to exclude aws-java-sdk dependency and add own: ```java // Instantiate tracer Tracer tracer = ... +``` -// Optionally register tracer with GlobalTracer -GlobalTracer.register(tracer); +### AWS SDK 1 +```java // Build AWS client with TracingRequestHandler e.g. AmazonS3 s3Client = AmazonS3ClientBuilder.standard() .withRegion(Regions.US_WEST_2) @@ -54,6 +43,13 @@ AmazonS3 s3Client = AmazonS3ClientBuilder.standard() ``` +### AWS SDK 2 +```java +// Build AWS client with TracingExecutionInterceptor e.g. +S3Client s3Client = S3Client.builder().overrideConfiguration( + builder -> builder.addExecutionInterceptor(new TracingExecutionInterceptor(tracer))) + .build(); +``` ## License diff --git a/mvnw b/mvnw index 6ecc150..22fc3ae 100755 --- a/mvnw +++ b/mvnw @@ -34,151 +34,158 @@ # MAVEN_SKIP_RC - flag to disable loading of mavenrc files # ---------------------------------------------------------------------------- -if [ -z "$MAVEN_SKIP_RC" ] ; then +if [ -z "$MAVEN_SKIP_RC" ]; then - if [ -f /etc/mavenrc ] ; then + if [ -f /etc/mavenrc ]; then . /etc/mavenrc fi - if [ -f "$HOME/.mavenrc" ] ; then + if [ -f "$HOME/.mavenrc" ]; then . "$HOME/.mavenrc" fi fi # OS specific support. $var _must_ be set to either true or false. -cygwin=false; -darwin=false; +cygwin=false +darwin=false mingw=false -case "`uname`" in - CYGWIN*) cygwin=true ;; - MINGW*) mingw=true;; - Darwin*) darwin=true - # - # Look for the Apple JDKs first to preserve the existing behaviour, and then look - # for the new JDKs provided by Oracle. - # - if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK ] ; then - # - # Apple JDKs - # - export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home - fi - - if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Java/JavaVirtualMachines/CurrentJDK ] ; then - # - # Apple JDKs - # - export JAVA_HOME=/System/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home - fi - - if [ -z "$JAVA_HOME" ] && [ -L "/Library/Java/JavaVirtualMachines/CurrentJDK" ] ; then - # - # Oracle JDKs - # - export JAVA_HOME=/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home - fi - - if [ -z "$JAVA_HOME" ] && [ -x "/usr/libexec/java_home" ]; then - # - # Apple JDKs - # - export JAVA_HOME=`/usr/libexec/java_home` - fi - ;; +case "$(uname)" in +CYGWIN*) cygwin=true ;; +MINGW*) mingw=true ;; +Darwin*) + darwin=true + # + # Look for the Apple JDKs first to preserve the existing behaviour, and then look + # for the new JDKs provided by Oracle. + # + if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK ]; then + # + # Apple JDKs + # + export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home + fi + + if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Java/JavaVirtualMachines/CurrentJDK ]; then + # + # Apple JDKs + # + export JAVA_HOME=/System/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home + fi + + if [ -z "$JAVA_HOME" ] && [ -L "/Library/Java/JavaVirtualMachines/CurrentJDK" ]; then + # + # Oracle JDKs + # + export JAVA_HOME=/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home + fi + + if [ -z "$JAVA_HOME" ] && [ -x "/usr/libexec/java_home" ]; then + # + # Apple JDKs + # + export JAVA_HOME=$(/usr/libexec/java_home) + fi + ;; esac -if [ -z "$JAVA_HOME" ] ; then - if [ -r /etc/gentoo-release ] ; then - JAVA_HOME=`java-config --jre-home` +if [ -z "$JAVA_HOME" ]; then + if [ -r /etc/gentoo-release ]; then + JAVA_HOME=$(java-config --jre-home) fi fi -if [ -z "$M2_HOME" ] ; then +if [ -z "$M2_HOME" ]; then ## resolve links - $0 may be a link to maven's home PRG="$0" # need this for relative symlinks - while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then + while [ -h "$PRG" ]; do + ls=$(ls -ld "$PRG") + link=$(expr "$ls" : '.*-> \(.*\)$') + if expr "$link" : '/.*' >/dev/null; then PRG="$link" else - PRG="`dirname "$PRG"`/$link" + PRG="$(dirname "$PRG")/$link" fi done - saveddir=`pwd` + saveddir=$(pwd) - M2_HOME=`dirname "$PRG"`/.. + M2_HOME=$(dirname "$PRG")/.. # make it fully qualified - M2_HOME=`cd "$M2_HOME" && pwd` + M2_HOME=$(cd "$M2_HOME" && pwd) cd "$saveddir" # echo Using m2 at $M2_HOME fi # For Cygwin, ensure paths are in UNIX format before anything is touched -if $cygwin ; then +if $cygwin; then [ -n "$M2_HOME" ] && - M2_HOME=`cygpath --unix "$M2_HOME"` + M2_HOME=$(cygpath --unix "$M2_HOME") [ -n "$JAVA_HOME" ] && - JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + JAVA_HOME=$(cygpath --unix "$JAVA_HOME") [ -n "$CLASSPATH" ] && - CLASSPATH=`cygpath --path --unix "$CLASSPATH"` + CLASSPATH=$(cygpath --path --unix "$CLASSPATH") fi # For Migwn, ensure paths are in UNIX format before anything is touched -if $mingw ; then +if $mingw; then [ -n "$M2_HOME" ] && - M2_HOME="`(cd "$M2_HOME"; pwd)`" + M2_HOME="$( ( + cd "$M2_HOME" + pwd + ))" [ -n "$JAVA_HOME" ] && - JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" + JAVA_HOME="$( ( + cd "$JAVA_HOME" + pwd + ))" # TODO classpath? fi if [ -z "$JAVA_HOME" ]; then - javaExecutable="`which javac`" - if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then + javaExecutable="$(which javac)" + if [ -n "$javaExecutable" ] && ! [ "$(expr \"$javaExecutable\" : '\([^ ]*\)')" = "no" ]; then # readlink(1) is not available as standard on Solaris 10. - readLink=`which readlink` - if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then - if $darwin ; then - javaHome="`dirname \"$javaExecutable\"`" - javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" + readLink=$(which readlink) + if [ ! $(expr "$readLink" : '\([^ ]*\)') = "no" ]; then + if $darwin; then + javaHome="$(dirname \"$javaExecutable\")" + javaExecutable="$(cd \"$javaHome\" && pwd -P)/javac" else - javaExecutable="`readlink -f \"$javaExecutable\"`" + javaExecutable="$(readlink -f \"$javaExecutable\")" fi - javaHome="`dirname \"$javaExecutable\"`" - javaHome=`expr "$javaHome" : '\(.*\)/bin'` + javaHome="$(dirname \"$javaExecutable\")" + javaHome=$(expr "$javaHome" : '\(.*\)/bin') JAVA_HOME="$javaHome" export JAVA_HOME fi fi fi -if [ -z "$JAVACMD" ] ; then - if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then +if [ -z "$JAVACMD" ]; then + if [ -n "$JAVA_HOME" ]; then + if [ -x "$JAVA_HOME/jre/sh/java" ]; then # IBM's JDK on AIX uses strange locations for the executables JAVACMD="$JAVA_HOME/jre/sh/java" else JAVACMD="$JAVA_HOME/bin/java" fi else - JAVACMD="`which java`" + JAVACMD="$(which java)" fi fi -if [ ! -x "$JAVACMD" ] ; then +if [ ! -x "$JAVACMD" ]; then echo "Error: JAVA_HOME is not defined correctly." >&2 echo " We cannot execute $JAVACMD" >&2 exit 1 fi -if [ -z "$JAVA_HOME" ] ; then +if [ -z "$JAVA_HOME" ]; then echo "Warning: JAVA_HOME environment variable is not set." fi @@ -189,12 +196,15 @@ CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher find_maven_basedir() { local basedir=$(pwd) local wdir=$(pwd) - while [ "$wdir" != '/' ] ; do - if [ -d "$wdir"/.mvn ] ; then + while [ "$wdir" != '/' ]; do + if [ -d "$wdir"/.mvn ]; then basedir=$wdir break fi - wdir=$(cd "$wdir/.."; pwd) + wdir=$( + cd "$wdir/.." + pwd + ) done echo "${basedir}" } @@ -202,7 +212,7 @@ find_maven_basedir() { # concatenates all lines of a file concat_lines() { if [ -f "$1" ]; then - echo "$(tr -s '\n' ' ' < "$1")" + echo "$(tr -s '\n' ' ' <"$1")" fi } @@ -212,13 +222,13 @@ MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" # For Cygwin, switch paths to Windows format before running java if $cygwin; then [ -n "$M2_HOME" ] && - M2_HOME=`cygpath --path --windows "$M2_HOME"` + M2_HOME=$(cygpath --path --windows "$M2_HOME") [ -n "$JAVA_HOME" ] && - JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + JAVA_HOME=$(cygpath --path --windows "$JAVA_HOME") [ -n "$CLASSPATH" ] && - CLASSPATH=`cygpath --path --windows "$CLASSPATH"` + CLASSPATH=$(cygpath --path --windows "$CLASSPATH") [ -n "$MAVEN_PROJECTBASEDIR" ] && - MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` + MAVEN_PROJECTBASEDIR=$(cygpath --path --windows "$MAVEN_PROJECTBASEDIR") fi # Provide a "standardized" way to retrieve the CLI args that will diff --git a/opentracing-aws-sdk-1/pom.xml b/opentracing-aws-sdk-1/pom.xml new file mode 100644 index 0000000..cb3685f --- /dev/null +++ b/opentracing-aws-sdk-1/pom.xml @@ -0,0 +1,72 @@ + + + + 4.0.0 + + io.opentracing.contrib + opentracing-aws-sdk-parent + 0.1.2-SNAPSHOT + + opentracing-aws-sdk-1 + + ${project.groupId}:${project.artifactId} + OpenTracing Instrumentation for AWS SDK + + + + com.amazonaws + aws-java-sdk + 1.11.600 + + + + io.opentracing + opentracing-api + + + + io.opentracing + opentracing-mock + test + + + + junit + junit + test + + + + com.amazonaws + DynamoDBLocal + test + + + com.amazonaws + aws-java-sdk-core + + + com.amazonaws + aws-java-sdk-dynamodb + + + + + + diff --git a/src/main/java/io/opentracing/contrib/aws/SpanDecorator.java b/opentracing-aws-sdk-1/src/main/java/io/opentracing/contrib/aws/SpanDecorator.java similarity index 100% rename from src/main/java/io/opentracing/contrib/aws/SpanDecorator.java rename to opentracing-aws-sdk-1/src/main/java/io/opentracing/contrib/aws/SpanDecorator.java diff --git a/src/main/java/io/opentracing/contrib/aws/TracingRequestHandler.java b/opentracing-aws-sdk-1/src/main/java/io/opentracing/contrib/aws/TracingRequestHandler.java similarity index 89% rename from src/main/java/io/opentracing/contrib/aws/TracingRequestHandler.java rename to opentracing-aws-sdk-1/src/main/java/io/opentracing/contrib/aws/TracingRequestHandler.java index be1701b..4a79e09 100644 --- a/src/main/java/io/opentracing/contrib/aws/TracingRequestHandler.java +++ b/opentracing-aws-sdk-1/src/main/java/io/opentracing/contrib/aws/TracingRequestHandler.java @@ -24,7 +24,6 @@ import io.opentracing.propagation.Format; import io.opentracing.propagation.TextMapAdapter; import io.opentracing.tag.Tags; -import io.opentracing.util.GlobalTracer; /** * Tracing Request Handler @@ -40,13 +39,6 @@ public TracingRequestHandler(Tracer tracer) { this.tracer = tracer; } - /** - * GlobalTracer is used to get tracer - */ - public TracingRequestHandler() { - this(GlobalTracer.get()); - } - /** * In case of Async Client: beforeRequest runs in separate thread therefore we need to inject * parent context to build chain @@ -58,13 +50,6 @@ public TracingRequestHandler(SpanContext parentContext, Tracer tracer) { this.tracer = tracer; } - /** - * GlobalTracer is used to get tracer - */ - public TracingRequestHandler(SpanContext parentContext) { - this(parentContext, GlobalTracer.get()); - } - /** * {@inheritDoc} */ diff --git a/src/test/java/io/opentracing/contrib/aws/TracingRequestHandlerTest.java b/opentracing-aws-sdk-1/src/test/java/io/opentracing/contrib/aws/TracingRequestHandlerTest.java similarity index 98% rename from src/test/java/io/opentracing/contrib/aws/TracingRequestHandlerTest.java rename to opentracing-aws-sdk-1/src/test/java/io/opentracing/contrib/aws/TracingRequestHandlerTest.java index 9d487a4..8345403 100644 --- a/src/test/java/io/opentracing/contrib/aws/TracingRequestHandlerTest.java +++ b/opentracing-aws-sdk-1/src/test/java/io/opentracing/contrib/aws/TracingRequestHandlerTest.java @@ -37,7 +37,6 @@ import io.opentracing.mock.MockSpan; import io.opentracing.mock.MockTracer; import io.opentracing.tag.Tags; -import io.opentracing.util.ThreadLocalScopeManager; import java.util.List; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; @@ -48,8 +47,7 @@ public class TracingRequestHandlerTest { - private static final MockTracer mockTracer = new MockTracer(new ThreadLocalScopeManager(), - MockTracer.Propagator.TEXT_MAP); + private static final MockTracer mockTracer = new MockTracer(); private DynamoDBProxyServer server; @Before diff --git a/src/test/resources/libs/libsqlite4java-linux-amd64.so b/opentracing-aws-sdk-1/src/test/resources/libs/libsqlite4java-linux-amd64.so similarity index 100% rename from src/test/resources/libs/libsqlite4java-linux-amd64.so rename to opentracing-aws-sdk-1/src/test/resources/libs/libsqlite4java-linux-amd64.so diff --git a/src/test/resources/libs/libsqlite4java-linux-i386.so b/opentracing-aws-sdk-1/src/test/resources/libs/libsqlite4java-linux-i386.so similarity index 100% rename from src/test/resources/libs/libsqlite4java-linux-i386.so rename to opentracing-aws-sdk-1/src/test/resources/libs/libsqlite4java-linux-i386.so diff --git a/src/test/resources/libs/libsqlite4java-osx.dylib b/opentracing-aws-sdk-1/src/test/resources/libs/libsqlite4java-osx.dylib similarity index 100% rename from src/test/resources/libs/libsqlite4java-osx.dylib rename to opentracing-aws-sdk-1/src/test/resources/libs/libsqlite4java-osx.dylib diff --git a/src/test/resources/libs/sqlite4java-win32-x64.dll b/opentracing-aws-sdk-1/src/test/resources/libs/sqlite4java-win32-x64.dll similarity index 100% rename from src/test/resources/libs/sqlite4java-win32-x64.dll rename to opentracing-aws-sdk-1/src/test/resources/libs/sqlite4java-win32-x64.dll diff --git a/src/test/resources/libs/sqlite4java-win32-x86.dll b/opentracing-aws-sdk-1/src/test/resources/libs/sqlite4java-win32-x86.dll similarity index 100% rename from src/test/resources/libs/sqlite4java-win32-x86.dll rename to opentracing-aws-sdk-1/src/test/resources/libs/sqlite4java-win32-x86.dll diff --git a/opentracing-aws-sdk-2/pom.xml b/opentracing-aws-sdk-2/pom.xml new file mode 100644 index 0000000..aebea0f --- /dev/null +++ b/opentracing-aws-sdk-2/pom.xml @@ -0,0 +1,66 @@ + + + + 4.0.0 + + io.opentracing.contrib + opentracing-aws-sdk-parent + 0.1.2-SNAPSHOT + + opentracing-aws-sdk-2 + + ${project.groupId}:${project.artifactId} + OpenTracing Instrumentation for AWS SDK 2 + + + + software.amazon.awssdk + aws-sdk-java + 2.7.15 + + + + io.opentracing + opentracing-api + + + + io.opentracing + opentracing-mock + test + + + + junit + junit + test + + + org.assertj + assertj-core + test + + + com.amazonaws + DynamoDBLocal + test + + + + diff --git a/opentracing-aws-sdk-2/src/main/java/io/opentracing/contrib/aws2/TracingExecutionInterceptor.java b/opentracing-aws-sdk-2/src/main/java/io/opentracing/contrib/aws2/TracingExecutionInterceptor.java new file mode 100644 index 0000000..e9b85c9 --- /dev/null +++ b/opentracing-aws-sdk-2/src/main/java/io/opentracing/contrib/aws2/TracingExecutionInterceptor.java @@ -0,0 +1,99 @@ +/* + * Copyright 2017-2019 The OpenTracing Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ +package io.opentracing.contrib.aws2; + +import io.opentracing.Span; +import io.opentracing.Tracer; +import io.opentracing.tag.Tags; +import java.util.HashMap; +import java.util.Map; +import software.amazon.awssdk.core.interceptor.Context.AfterExecution; +import software.amazon.awssdk.core.interceptor.Context.AfterMarshalling; +import software.amazon.awssdk.core.interceptor.Context.BeforeExecution; +import software.amazon.awssdk.core.interceptor.Context.FailedExecution; +import software.amazon.awssdk.core.interceptor.ExecutionAttribute; +import software.amazon.awssdk.core.interceptor.ExecutionAttributes; +import software.amazon.awssdk.core.interceptor.ExecutionInterceptor; +import software.amazon.awssdk.core.interceptor.SdkExecutionAttribute; +import software.amazon.awssdk.http.SdkHttpRequest; + +public class TracingExecutionInterceptor implements ExecutionInterceptor { + private static final String COMPONENT_NAME = "java-aws-sdk"; + private static final ExecutionAttribute SPAN_ATTRIBUTE = new ExecutionAttribute<>( + "ot-span"); + private final Tracer tracer; + + public TracingExecutionInterceptor(Tracer tracer) { + this.tracer = tracer; + } + + @Override + public void beforeExecution(BeforeExecution context, ExecutionAttributes executionAttributes) { + final Span span = tracer.buildSpan(context.request().getClass().getSimpleName()) + .withTag(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_CLIENT) + .withTag(Tags.PEER_SERVICE, + executionAttributes.getAttribute(SdkExecutionAttribute.SERVICE_NAME)) + .withTag(Tags.COMPONENT, COMPONENT_NAME).start(); + + executionAttributes.putAttribute(SPAN_ATTRIBUTE, span); + } + + @Override + public void afterMarshalling(final AfterMarshalling context, + final ExecutionAttributes executionAttributes) { + final Span span = executionAttributes.getAttribute(SPAN_ATTRIBUTE); + final SdkHttpRequest httpRequest = context.httpRequest(); + + span.setTag(Tags.HTTP_METHOD, httpRequest.method().name()); + span.setTag(Tags.HTTP_URL, httpRequest.getUri().toString()); + span.setTag(Tags.PEER_HOSTNAME, httpRequest.host()); + if (httpRequest.port() > 0) { + span.setTag(Tags.PEER_PORT, httpRequest.port()); + } + } + + @Override + public void afterExecution(final AfterExecution context, + final ExecutionAttributes executionAttributes) { + final Span span = executionAttributes.getAttribute(SPAN_ATTRIBUTE); + if (span == null) { + return; + } + + executionAttributes.putAttribute(SPAN_ATTRIBUTE, null); + span.setTag(Tags.HTTP_STATUS, context.httpResponse().statusCode()); + span.finish(); + } + + @Override + public void onExecutionFailure(final FailedExecution context, + final ExecutionAttributes executionAttributes) { + final Span span = executionAttributes.getAttribute(SPAN_ATTRIBUTE); + if (span == null) { + return; + } + + executionAttributes.putAttribute(SPAN_ATTRIBUTE, null); + Tags.ERROR.set(span, Boolean.TRUE); + span.log(errorLogs(context.exception())); + span.finish(); + } + + private static Map errorLogs(final Throwable ex) { + Map errorLogs = new HashMap<>(2); + errorLogs.put("event", Tags.ERROR.getKey()); + errorLogs.put("error.object", ex); + return errorLogs; + } +} \ No newline at end of file diff --git a/opentracing-aws-sdk-2/src/test/java/io/opentracing/contrib/aws2/Aws2Test.java b/opentracing-aws-sdk-2/src/test/java/io/opentracing/contrib/aws2/Aws2Test.java new file mode 100644 index 0000000..1e1c45b --- /dev/null +++ b/opentracing-aws-sdk-2/src/test/java/io/opentracing/contrib/aws2/Aws2Test.java @@ -0,0 +1,189 @@ +/* + * Copyright 2017-2019 The OpenTracing Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ +package io.opentracing.contrib.aws2; + + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import com.amazonaws.services.dynamodbv2.local.main.ServerRunner; +import com.amazonaws.services.dynamodbv2.local.server.DynamoDBProxyServer; +import io.opentracing.Scope; +import io.opentracing.mock.MockSpan; +import io.opentracing.mock.MockTracer; +import java.net.URI; +import java.time.Duration; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ThreadLocalRandom; +import java.util.concurrent.TimeUnit; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import software.amazon.awssdk.auth.credentials.AwsSessionCredentials; +import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider; +import software.amazon.awssdk.core.client.config.ClientOverrideConfiguration; +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.AttributeDefinition; +import software.amazon.awssdk.services.dynamodb.model.CreateTableRequest; +import software.amazon.awssdk.services.dynamodb.model.CreateTableResponse; +import software.amazon.awssdk.services.dynamodb.model.KeySchemaElement; +import software.amazon.awssdk.services.dynamodb.model.KeyType; +import software.amazon.awssdk.services.dynamodb.model.ProvisionedThroughput; + +public class Aws2Test { + private static final MockTracer tracer = new MockTracer(); + private DynamoDBProxyServer server; + + @Before + public void before() throws Exception { + System.getProperties().setProperty("sqlite4java.library.path", "src/test/resources/libs"); + System.getProperties().setProperty("aws.region", "us-west-2"); + tracer.reset(); + + final String[] localArgs = {"-inMemory", "-port", "8000"}; + server = ServerRunner.createServerFromCommandLineArgs(localArgs); + server.start(); + } + + @After + public void after() throws Exception { + server.stop(); + } + + @Test + public void testSyncClient() { + final DynamoDbClient dbClient = buildClient(); + createTable(dbClient, "table-" + ThreadLocalRandom.current().nextInt(Integer.MAX_VALUE)); + + final List spans = tracer.finishedSpans(); + assertEquals(1, spans.size()); + assertEquals("CreateTableRequest", spans.get(0).operationName()); + + assertNull(tracer.activeSpan()); + } + + @Test + public void twoRequestsWithParent() { + final DynamoDbClient dbClient = buildClient(); + + final MockSpan parent = tracer.buildSpan("parent-sync").start(); + try (Scope ignore = tracer.activateSpan(parent)) { + createTable(dbClient, + "with-parent-1-" + ThreadLocalRandom.current().nextInt(Integer.MAX_VALUE)); + createTable(dbClient, + "with-parent-2-" + ThreadLocalRandom.current().nextInt(Integer.MAX_VALUE)); + } + parent.finish(); + + List spans = tracer.finishedSpans(); + assertEquals(3, spans.size()); + + for (MockSpan span : spans) { + if (parent.operationName().equals(span.operationName())) { + continue; + } + assertEquals(parent.context().traceId(), span.context().traceId()); + assertEquals(parent.context().spanId(), span.parentId()); + } + + assertNull(tracer.activeSpan()); + } + + @Test + public void testAsyncClient() throws Exception { + final DynamoDbAsyncClient dbClient = buildAsyncClient(); + final String tableName = + "asyncRequest-" + ThreadLocalRandom.current().nextInt(Integer.MAX_VALUE); + final CompletableFuture createTableResultFuture = createTableAsync( + dbClient, tableName); + final CreateTableResponse result = createTableResultFuture.get(10, TimeUnit.SECONDS); + assertThat(result.tableDescription().tableName()).isEqualTo(tableName); + + final List spans = tracer.finishedSpans(); + assertEquals(1, spans.size()); + assertEquals("CreateTableRequest", spans.get(0).operationName()); + + assertNull(tracer.activeSpan()); + } + + private static DynamoDbClient buildClient() { + final AwsSessionCredentials awsCreds = AwsSessionCredentials + .create("access_key_id", "secret_key_id", "session_token"); + return DynamoDbClient + .builder() + .endpointOverride(URI.create("http://localhost:8000")) + .region(Region.US_WEST_2) + .credentialsProvider(StaticCredentialsProvider.create(awsCreds)) + .overrideConfiguration( + ClientOverrideConfiguration.builder().apiCallTimeout(Duration.ofSeconds(1)).build()) + .overrideConfiguration( + builder -> builder.addExecutionInterceptor(new TracingExecutionInterceptor( + tracer))) + .build(); + } + + private static DynamoDbAsyncClient buildAsyncClient() { + final AwsSessionCredentials awsCreds = AwsSessionCredentials + .create("access_key_id", "secret_key_id", "session_token"); + final DynamoDbAsyncClient build = DynamoDbAsyncClient + .builder() + .endpointOverride(URI.create("http://localhost:8000")) + .region(Region.US_WEST_2) + .credentialsProvider(StaticCredentialsProvider.create(awsCreds)) + .overrideConfiguration(ClientOverrideConfiguration.builder() + .apiCallTimeout(Duration.ofSeconds(1)).build()) + .overrideConfiguration( + builder -> builder.addExecutionInterceptor(new TracingExecutionInterceptor(tracer))) + .build(); + return build; + } + + private static void createTable(final DynamoDbClient dbClient, final String tableName) { + final String partitionKeyName = tableName + "Id"; + final CreateTableRequest createTableRequest = CreateTableRequest.builder() + .tableName(tableName) + .keySchema(KeySchemaElement.builder().attributeName(partitionKeyName).keyType(KeyType.HASH) + .build()) + .attributeDefinitions( + AttributeDefinition.builder().attributeName(partitionKeyName).attributeType("S") + .build()) + .provisionedThroughput( + ProvisionedThroughput.builder().readCapacityUnits(10L).writeCapacityUnits(5L).build()) + .build(); + + dbClient.createTable(createTableRequest); + } + + private static CompletableFuture createTableAsync( + final DynamoDbAsyncClient dbClient, final String tableName) { + final String partitionKeyName = tableName + "Id"; + final CreateTableRequest createTableRequest = CreateTableRequest + .builder() + .tableName(tableName).keySchema( + KeySchemaElement.builder().attributeName(partitionKeyName).keyType(KeyType.HASH) + .build()) + .attributeDefinitions( + AttributeDefinition.builder().attributeName(partitionKeyName).attributeType("S") + .build()) + .provisionedThroughput( + ProvisionedThroughput.builder().readCapacityUnits(10L).writeCapacityUnits(5L).build()) + .build(); + + return dbClient.createTable(createTableRequest); + } +} diff --git a/opentracing-aws-sdk-2/src/test/resources/libs/libsqlite4java-linux-amd64.so b/opentracing-aws-sdk-2/src/test/resources/libs/libsqlite4java-linux-amd64.so new file mode 100644 index 0000000..8846157 Binary files /dev/null and b/opentracing-aws-sdk-2/src/test/resources/libs/libsqlite4java-linux-amd64.so differ diff --git a/opentracing-aws-sdk-2/src/test/resources/libs/libsqlite4java-linux-i386.so b/opentracing-aws-sdk-2/src/test/resources/libs/libsqlite4java-linux-i386.so new file mode 100644 index 0000000..15e7469 Binary files /dev/null and b/opentracing-aws-sdk-2/src/test/resources/libs/libsqlite4java-linux-i386.so differ diff --git a/opentracing-aws-sdk-2/src/test/resources/libs/libsqlite4java-osx.dylib b/opentracing-aws-sdk-2/src/test/resources/libs/libsqlite4java-osx.dylib new file mode 100644 index 0000000..0276162 Binary files /dev/null and b/opentracing-aws-sdk-2/src/test/resources/libs/libsqlite4java-osx.dylib differ diff --git a/opentracing-aws-sdk-2/src/test/resources/libs/sqlite4java-win32-x64.dll b/opentracing-aws-sdk-2/src/test/resources/libs/sqlite4java-win32-x64.dll new file mode 100644 index 0000000..70d258f Binary files /dev/null and b/opentracing-aws-sdk-2/src/test/resources/libs/sqlite4java-win32-x64.dll differ diff --git a/opentracing-aws-sdk-2/src/test/resources/libs/sqlite4java-win32-x86.dll b/opentracing-aws-sdk-2/src/test/resources/libs/sqlite4java-win32-x86.dll new file mode 100644 index 0000000..c988e5a Binary files /dev/null and b/opentracing-aws-sdk-2/src/test/resources/libs/sqlite4java-win32-x86.dll differ diff --git a/pom.xml b/pom.xml index 3c60e6b..045c5e5 100644 --- a/pom.xml +++ b/pom.xml @@ -14,11 +14,14 @@ the License. --> - + 4.0.0 io.opentracing.contrib - opentracing-aws-sdk + opentracing-aws-sdk-parent 0.1.2-SNAPSHOT + pom ${project.groupId}:${project.artifactId} OpenTracing Instrumentation for AWS SDK @@ -55,7 +58,7 @@ - 1.7 + 1.8 UTF-8 UTF-8 @@ -64,46 +67,44 @@ 0.8.4 - - - io.opentracing - opentracing-util - ${opentracing.version} - - - - com.amazonaws - aws-java-sdk - 1.11.600 - - - - io.opentracing - opentracing-mock - ${opentracing.version} - test - - - - junit - junit - 4.12 - test - - - - com.amazonaws - DynamoDBLocal - 1.11.475 - test - - - com.amazonaws - aws-java-sdk - - - - + + opentracing-aws-sdk-1 + opentracing-aws-sdk-2 + + + + + + io.opentracing + opentracing-api + ${opentracing.version} + + + io.opentracing + opentracing-mock + ${opentracing.version} + test + + + junit + junit + 4.12 + test + + + org.assertj + assertj-core + 3.13.2 + test + + + com.amazonaws + DynamoDBLocal + 1.11.475 + test + + + diff --git a/travis/publish.sh b/travis/publish.sh index d4e4c5f..bb049d0 100755 --- a/travis/publish.sh +++ b/travis/publish.sh @@ -59,20 +59,20 @@ check_travis_branch_equals_travis_tag() { } check_release_tag() { - tag="${TRAVIS_TAG}" - if [[ "$tag" =~ ^[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+(\-RC[[:digit:]]+)?$ ]]; then - echo "Build started by version tag $tag. During the release process tags like this" - echo "are created by the 'release' Maven plugin. Nothing to do here." - exit 0 - elif [[ ! "$tag" =~ ^release-[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+(\-RC[[:digit:]]+)?$ ]]; then - echo "You must specify a tag of the format 'release-0.0.0' or 'release-0.0.0-RC0' to release this project." - echo "The provided tag ${tag} doesn't match that. Aborting." - exit 1 - fi + tag="${TRAVIS_TAG}" + if [[ "$tag" =~ ^[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+(\-RC[[:digit:]]+)?$ ]]; then + echo "Build started by version tag $tag. During the release process tags like this" + echo "are created by the 'release' Maven plugin. Nothing to do here." + exit 0 + elif [[ ! "$tag" =~ ^release-[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+(\-RC[[:digit:]]+)?$ ]]; then + echo "You must specify a tag of the format 'release-0.0.0' or 'release-0.0.0-RC0' to release this project." + echo "The provided tag ${tag} doesn't match that. Aborting." + exit 1 + fi } is_release_commit() { - project_version=$(./mvnw help:evaluate -N -Dexpression=project.version|sed -n '/^[0-9]/p') + project_version=$(./mvnw help:evaluate -N -Dexpression=project.version | sed -n '/^[0-9]/p') if [[ "$project_version" =~ ^[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+(\-RC[[:digit:]]+)?$ ]]; then echo "Build started by release commit $project_version. Will synchronize to maven central." return 0 @@ -82,7 +82,7 @@ is_release_commit() { } release_version() { - echo "${TRAVIS_TAG}" | sed 's/^release-//' + echo "${TRAVIS_TAG}" | sed 's/^release-//' } safe_checkout_remote_branch() { @@ -92,7 +92,7 @@ safe_checkout_remote_branch() { # so we verify that the remote branch is where our tag is. checkoutBranch=master if [[ "${TRAVIS_BRANCH}" =~ ^release-[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+\-RC[[:digit:]]+$ ]]; then - checkoutBranch=v`release_version | sed 's/-RC[[:digit:]]\+//'` + checkoutBranch=v$(release_version | sed 's/-RC[[:digit:]]\+//') fi git checkout -B "${checkoutBranch}" git fetch origin "${checkoutBranch}":origin/"${checkoutBranch}"