Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert aws 1.11 client tests from groovy to java #12606

Merged
merged 8 commits into from
Nov 12, 2024
Merged
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.javaagent.instrumentation.awssdk.v1_11;

import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
import io.opentelemetry.instrumentation.awssdk.v1_11.AbstractDynamoDbClientTest;
import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension;
import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
import org.junit.jupiter.api.extension.RegisterExtension;

class DynamoDbClientTest extends AbstractDynamoDbClientTest {
@RegisterExtension
static final InstrumentationExtension testing = AgentInstrumentationExtension.create();

@Override
protected InstrumentationExtension testing() {
return testing;
}

@Override
public AmazonDynamoDBClientBuilder configureClient(AmazonDynamoDBClientBuilder clientBuilder) {
return clientBuilder;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.javaagent.instrumentation.awssdk.v1_11;

import com.amazonaws.services.ec2.AmazonEC2ClientBuilder;
import io.opentelemetry.instrumentation.awssdk.v1_11.AbstractEc2ClientTest;
import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension;
import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
import org.junit.jupiter.api.extension.RegisterExtension;

class Ec2ClientTest extends AbstractEc2ClientTest {
@RegisterExtension
static final InstrumentationExtension testing = AgentInstrumentationExtension.create();

@Override
protected InstrumentationExtension testing() {
return testing;
}

@Override
public AmazonEC2ClientBuilder configureClient(AmazonEC2ClientBuilder clientBuilder) {
return clientBuilder;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.javaagent.instrumentation.awssdk.v1_11;

import com.amazonaws.services.kinesis.AmazonKinesisClientBuilder;
import io.opentelemetry.instrumentation.awssdk.v1_11.AbstractKinesisClientTest;
import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension;
import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
import org.junit.jupiter.api.extension.RegisterExtension;

class KinesisClientTest extends AbstractKinesisClientTest {
@RegisterExtension
static final InstrumentationExtension testing = AgentInstrumentationExtension.create();

@Override
protected InstrumentationExtension testing() {
return testing;
}

@Override
public AmazonKinesisClientBuilder configureClient(AmazonKinesisClientBuilder clientBuilder) {
return clientBuilder;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.javaagent.instrumentation.awssdk.v1_11;

import com.amazonaws.services.rds.AmazonRDSClientBuilder;
import io.opentelemetry.instrumentation.awssdk.v1_11.AbstractRdsClientTest;
import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension;
import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
import org.junit.jupiter.api.extension.RegisterExtension;

class RdsClientTest extends AbstractRdsClientTest {
@RegisterExtension
static final InstrumentationExtension testing = AgentInstrumentationExtension.create();

@Override
protected InstrumentationExtension testing() {
return testing;
}

@Override
public AmazonRDSClientBuilder configureClient(AmazonRDSClientBuilder client) {
return client;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.javaagent.instrumentation.awssdk.v1_11;

import static io.opentelemetry.api.common.AttributeKey.stringKey;
import static io.opentelemetry.api.trace.SpanKind.CLIENT;
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo;
import static io.opentelemetry.semconv.ErrorAttributes.ERROR_TYPE;
import static io.opentelemetry.semconv.HttpAttributes.HTTP_REQUEST_METHOD;
import static io.opentelemetry.semconv.ServerAttributes.SERVER_ADDRESS;
import static io.opentelemetry.semconv.UrlAttributes.URL_FULL;
import static io.opentelemetry.semconv.incubating.RpcIncubatingAttributes.RPC_METHOD;
import static io.opentelemetry.semconv.incubating.RpcIncubatingAttributes.RPC_SERVICE;
import static io.opentelemetry.semconv.incubating.RpcIncubatingAttributes.RPC_SYSTEM;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
import static org.assertj.core.api.AssertionsForClassTypes.catchThrowable;

import com.amazonaws.ClientConfiguration;
import com.amazonaws.Request;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.auth.NoOpSigner;
import com.amazonaws.auth.SignerFactory;
import com.amazonaws.handlers.RequestHandler2;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.instrumentation.awssdk.v1_11.AbstractS3ClientTest;
import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension;
import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
import io.opentelemetry.sdk.trace.data.StatusData;
import java.util.Date;
import java.util.List;
import java.util.stream.Stream;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;

@SuppressWarnings("deprecation") // AmazonS3Client constructor is deprecated
class S3ClientTest extends AbstractS3ClientTest {
@RegisterExtension
static final InstrumentationExtension testing = AgentInstrumentationExtension.create();

@Override
protected InstrumentationExtension testing() {
return testing;
}

@Override
public AmazonS3ClientBuilder configureClient(AmazonS3ClientBuilder client) {
return client;
}

// Verify agent instruments old and new construction patterns.
@ParameterizedTest
@MethodSource("provideS3Arguments")
void testRequestHandlerIsHookedUpWithBuilder(boolean addHandler, int size, int position)
throws Exception {
AmazonS3ClientBuilder builder = AmazonS3ClientBuilder.standard().withRegion(Regions.US_EAST_1);

if (addHandler) {
builder.withRequestHandlers(new RequestHandler2() {});
}
AmazonS3 client = builder.build();

List<RequestHandler2> requestHandler2s = extractRequestHandlers(client);
assertThat(requestHandler2s).isNotNull();
assertThat(requestHandler2s.size()).isEqualTo(size);
assertThat(requestHandler2s.get(position).getClass().getSimpleName())
.isEqualTo("TracingRequestHandler");
}

private static Stream<Arguments> provideS3Arguments() {
return Stream.of(Arguments.of(true, 2, 1), Arguments.of(false, 1, 0));
}

@ParameterizedTest
@MethodSource("provideS3Arguments")
void testRequestHandlerIsHookedUpWithConstructor(boolean addHandler, int size) throws Exception {
String accessKey = "asdf";
String secretKey = "qwerty";
BasicAWSCredentials credentials = new BasicAWSCredentials(accessKey, secretKey);
AmazonS3Client client = new AmazonS3Client(credentials);
if (addHandler) {
client.addRequestHandler(new RequestHandler2() {});
}

List<RequestHandler2> requestHandler2s = extractRequestHandlers(client);

assertThat(requestHandler2s).isNotNull();
assertThat(requestHandler2s.size()).isEqualTo(size);
assertThat(requestHandler2s.get(0).getClass().getSimpleName())
.isEqualTo("TracingRequestHandler");
}

@Test
void testNaughtyRequestHandlerDoesntBreakTheTrace() {
AmazonS3Client client = new AmazonS3Client(credentialsProvider);
client.addRequestHandler(
new RequestHandler2() {
@Override
public void beforeRequest(Request<?> request) {
throw new IllegalStateException("bad handler");
}
});

Throwable caught = catchThrowable(() -> client.getObject("someBucket", "someKey"));

assertThat(caught).isInstanceOf(IllegalStateException.class);
assertThat(Span.current().getSpanContext().isValid()).isFalse();

testing()
.waitAndAssertTraces(
trace ->
trace.hasSpansSatisfyingExactly(
span ->
span.hasName("S3.HeadBucket")
.hasKind(CLIENT)
.hasStatus(StatusData.error())
.hasException(caught)
.hasNoParent()
.hasAttributesSatisfyingExactly(
equalTo(URL_FULL, "https://s3.amazonaws.com"),
equalTo(HTTP_REQUEST_METHOD, "HEAD"),
equalTo(SERVER_ADDRESS, "s3.amazonaws.com"),
equalTo(RPC_SYSTEM, "aws-api"),
equalTo(RPC_SERVICE, "Amazon S3"),
equalTo(RPC_METHOD, "HeadBucket"),
equalTo(stringKey("aws.endpoint"), "https://s3.amazonaws.com"),
equalTo(stringKey("aws.agent"), "java-aws-sdk"),
equalTo(stringKey("aws.bucket.name"), "someBucket"),
equalTo(ERROR_TYPE, IllegalStateException.class.getName()))));
}

@Test
void testCallingGeneratePresignedUrlDoesNotLeakContext() {
SignerFactory.registerSigner("noop", NoOpSigner.class);
AmazonS3 client =
AmazonS3ClientBuilder.standard()
.withRegion(Regions.US_EAST_1)
.withClientConfiguration(new ClientConfiguration().withSignerOverride("noop"))
.build();

client.generatePresignedUrl("someBucket", "someKey", new Date());

assertThat(Span.current().getSpanContext().isValid()).isFalse();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.javaagent.instrumentation.awssdk.v1_11;

import com.amazonaws.services.sns.AmazonSNSClientBuilder;
import io.opentelemetry.instrumentation.awssdk.v1_11.AbstractSnsClientTest;
import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension;
import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
import org.junit.jupiter.api.extension.RegisterExtension;

class SnsClientTest extends AbstractSnsClientTest {
@RegisterExtension
static final InstrumentationExtension testing = AgentInstrumentationExtension.create();

@Override
protected InstrumentationExtension testing() {
return testing;
}

@Override
public AmazonSNSClientBuilder configureClient(AmazonSNSClientBuilder clientBuilder) {
return clientBuilder;
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.javaagent.instrumentation.awssdk.v1_11;

import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
import io.opentelemetry.instrumentation.awssdk.v1_11.AbstractDynamoDbClientTest;
import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
import io.opentelemetry.instrumentation.testing.junit.LibraryInstrumentationExtension;
import org.junit.jupiter.api.extension.RegisterExtension;

class DynamoDbClientTest extends AbstractDynamoDbClientTest {
@RegisterExtension
static final InstrumentationExtension testing = LibraryInstrumentationExtension.create();

@Override
protected InstrumentationExtension testing() {
return testing;
}

@Override
public AmazonDynamoDBClientBuilder configureClient(AmazonDynamoDBClientBuilder client) {
return client;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.javaagent.instrumentation.awssdk.v1_11;

import com.amazonaws.services.ec2.AmazonEC2ClientBuilder;
import io.opentelemetry.instrumentation.awssdk.v1_11.AbstractEc2ClientTest;
import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
import io.opentelemetry.instrumentation.testing.junit.LibraryInstrumentationExtension;
import org.junit.jupiter.api.extension.RegisterExtension;

class Ec2ClientTest extends AbstractEc2ClientTest {
@RegisterExtension
static final InstrumentationExtension testing = LibraryInstrumentationExtension.create();

@Override
protected InstrumentationExtension testing() {
return testing;
}

@Override
public AmazonEC2ClientBuilder configureClient(AmazonEC2ClientBuilder clientBuilder) {
return clientBuilder;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.javaagent.instrumentation.awssdk.v1_11;

import com.amazonaws.services.kinesis.AmazonKinesisClientBuilder;
import io.opentelemetry.instrumentation.awssdk.v1_11.AbstractKinesisClientTest;
import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
import io.opentelemetry.instrumentation.testing.junit.LibraryInstrumentationExtension;
import org.junit.jupiter.api.extension.RegisterExtension;

class KinesisClientTest extends AbstractKinesisClientTest {
@RegisterExtension
static final InstrumentationExtension testing = LibraryInstrumentationExtension.create();

@Override
protected InstrumentationExtension testing() {
return testing;
}

@Override
public AmazonKinesisClientBuilder configureClient(AmazonKinesisClientBuilder clientBuilder) {
return clientBuilder;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.javaagent.instrumentation.awssdk.v1_11;

import com.amazonaws.services.rds.AmazonRDSClientBuilder;
import io.opentelemetry.instrumentation.awssdk.v1_11.AbstractRdsClientTest;
import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
import io.opentelemetry.instrumentation.testing.junit.LibraryInstrumentationExtension;
import org.junit.jupiter.api.extension.RegisterExtension;

class RdsClientTest extends AbstractRdsClientTest {
@RegisterExtension
static final InstrumentationExtension testing = LibraryInstrumentationExtension.create();

@Override
protected InstrumentationExtension testing() {
return testing;
}

@Override
public AmazonRDSClientBuilder configureClient(AmazonRDSClientBuilder client) {
return client;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.javaagent.instrumentation.awssdk.v1_11;

import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import io.opentelemetry.instrumentation.awssdk.v1_11.AbstractS3ClientTest;
import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
import io.opentelemetry.instrumentation.testing.junit.LibraryInstrumentationExtension;
import org.junit.jupiter.api.extension.RegisterExtension;

class S3ClientTest extends AbstractS3ClientTest {
@RegisterExtension
static final InstrumentationExtension testing = LibraryInstrumentationExtension.create();

@Override
protected InstrumentationExtension testing() {
return testing;
}

@Override
public AmazonS3ClientBuilder configureClient(AmazonS3ClientBuilder client) {
return client;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.javaagent.instrumentation.awssdk.v1_11;

import com.amazonaws.services.sns.AmazonSNSClientBuilder;
import io.opentelemetry.instrumentation.awssdk.v1_11.AbstractSnsClientTest;
import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
import io.opentelemetry.instrumentation.testing.junit.LibraryInstrumentationExtension;
import org.junit.jupiter.api.extension.RegisterExtension;

class SnsClientTest extends AbstractSnsClientTest {
@RegisterExtension
static final InstrumentationExtension testing = LibraryInstrumentationExtension.create();

@Override
protected InstrumentationExtension testing() {
return testing;
}

@Override
public AmazonSNSClientBuilder configureClient(AmazonSNSClientBuilder clientBuilder) {
return clientBuilder;
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.awssdk.v1_11;

import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
import io.opentelemetry.instrumentation.testing.junit.LibraryInstrumentationExtension;
import org.junit.jupiter.api.extension.RegisterExtension;

class DynamoDbClientTest extends AbstractDynamoDbClientTest {
@RegisterExtension
private static final InstrumentationExtension testing = LibraryInstrumentationExtension.create();

@Override
protected InstrumentationExtension testing() {
return testing;
}

@Override
public AmazonDynamoDBClientBuilder configureClient(AmazonDynamoDBClientBuilder clientBuilder) {
return clientBuilder.withRequestHandlers(
AwsSdkTelemetry.builder(testing().getOpenTelemetry())
.setCaptureExperimentalSpanAttributes(true)
.build()
.newRequestHandler());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.awssdk.v1_11;

import com.amazonaws.services.ec2.AmazonEC2ClientBuilder;
import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
import io.opentelemetry.instrumentation.testing.junit.LibraryInstrumentationExtension;
import org.junit.jupiter.api.extension.RegisterExtension;

class Ec2ClientTest extends AbstractEc2ClientTest {
@RegisterExtension
private static final InstrumentationExtension testing = LibraryInstrumentationExtension.create();

@Override
protected InstrumentationExtension testing() {
return testing;
}

@Override
public AmazonEC2ClientBuilder configureClient(AmazonEC2ClientBuilder clientBuilder) {
return clientBuilder.withRequestHandlers(
AwsSdkTelemetry.builder(testing().getOpenTelemetry())
.setCaptureExperimentalSpanAttributes(true)
.build()
.newRequestHandler());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.awssdk.v1_11;

import com.amazonaws.services.kinesis.AmazonKinesisClientBuilder;
import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
import io.opentelemetry.instrumentation.testing.junit.LibraryInstrumentationExtension;
import org.junit.jupiter.api.extension.RegisterExtension;

class KinesisClientTest extends AbstractKinesisClientTest {
@RegisterExtension
private static final InstrumentationExtension testing = LibraryInstrumentationExtension.create();

@Override
protected InstrumentationExtension testing() {
return testing;
}

@Override
public AmazonKinesisClientBuilder configureClient(AmazonKinesisClientBuilder clientBuilder) {
return clientBuilder.withRequestHandlers(
AwsSdkTelemetry.builder(testing().getOpenTelemetry())
.setCaptureExperimentalSpanAttributes(true)
.build()
.newRequestHandler());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.awssdk.v1_11;

import com.amazonaws.services.rds.AmazonRDSClientBuilder;
import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
import io.opentelemetry.instrumentation.testing.junit.LibraryInstrumentationExtension;
import org.junit.jupiter.api.extension.RegisterExtension;

class RdsClientTest extends AbstractRdsClientTest {
@RegisterExtension
private static final InstrumentationExtension testing = LibraryInstrumentationExtension.create();

@Override
protected InstrumentationExtension testing() {
return testing;
}

@Override
public AmazonRDSClientBuilder configureClient(AmazonRDSClientBuilder clientBuilder) {
return clientBuilder.withRequestHandlers(
AwsSdkTelemetry.builder(testing().getOpenTelemetry())
.setCaptureExperimentalSpanAttributes(true)
.build()
.newRequestHandler());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.awssdk.v1_11;

import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
import io.opentelemetry.instrumentation.testing.junit.LibraryInstrumentationExtension;
import org.junit.jupiter.api.extension.RegisterExtension;

class S3ClientTest extends AbstractS3ClientTest {
@RegisterExtension
private static final InstrumentationExtension testing = LibraryInstrumentationExtension.create();

@Override
protected InstrumentationExtension testing() {
return testing;
}

@Override
public AmazonS3ClientBuilder configureClient(AmazonS3ClientBuilder clientBuilder) {
return clientBuilder.withRequestHandlers(
AwsSdkTelemetry.builder(testing().getOpenTelemetry())
.setCaptureExperimentalSpanAttributes(true)
.build()
.newRequestHandler());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.awssdk.v1_11;

import com.amazonaws.services.sns.AmazonSNSClientBuilder;
import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
import io.opentelemetry.instrumentation.testing.junit.LibraryInstrumentationExtension;
import org.junit.jupiter.api.extension.RegisterExtension;

class SnsClientTest extends AbstractSnsClientTest {
@RegisterExtension
private static final InstrumentationExtension testing = LibraryInstrumentationExtension.create();

@Override
protected InstrumentationExtension testing() {
return testing;
}

@Override
public AmazonSNSClientBuilder configureClient(AmazonSNSClientBuilder clientBuilder) {
return clientBuilder.withRequestHandlers(
AwsSdkTelemetry.builder(testing().getOpenTelemetry())
.setCaptureExperimentalSpanAttributes(true)
.build()
.newRequestHandler());
}
}
Original file line number Diff line number Diff line change
@@ -20,7 +20,5 @@ dependencies {

implementation("com.google.guava:guava")

implementation("org.apache.groovy:groovy")
implementation("io.opentelemetry:opentelemetry-api")
implementation("org.spockframework:spock-core")
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.awssdk.v1_11;

import static io.opentelemetry.api.common.AttributeKey.stringKey;
import static io.opentelemetry.api.trace.SpanKind.CLIENT;
import static io.opentelemetry.api.trace.SpanKind.PRODUCER;
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo;
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.satisfies;
import static io.opentelemetry.semconv.HttpAttributes.HTTP_REQUEST_METHOD;
import static io.opentelemetry.semconv.HttpAttributes.HTTP_RESPONSE_STATUS_CODE;
import static io.opentelemetry.semconv.NetworkAttributes.NETWORK_PROTOCOL_VERSION;
import static io.opentelemetry.semconv.ServerAttributes.SERVER_ADDRESS;
import static io.opentelemetry.semconv.ServerAttributes.SERVER_PORT;
import static io.opentelemetry.semconv.UrlAttributes.URL_FULL;
import static io.opentelemetry.semconv.incubating.RpcIncubatingAttributes.RPC_METHOD;
import static io.opentelemetry.semconv.incubating.RpcIncubatingAttributes.RPC_SERVICE;
import static io.opentelemetry.semconv.incubating.RpcIncubatingAttributes.RPC_SYSTEM;
import static java.util.Arrays.asList;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;

import com.amazonaws.AmazonWebServiceClient;
import com.amazonaws.SDKGlobalConfiguration;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.AnonymousAWSCredentials;
import com.amazonaws.client.builder.AwsClientBuilder;
import com.amazonaws.handlers.RequestHandler2;
import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
import io.opentelemetry.sdk.testing.assertj.AttributeAssertion;
import io.opentelemetry.testing.internal.armeria.testing.junit5.server.mock.MockWebServerExtension;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;

public abstract class AbstractBaseAwsClientTest {
protected abstract InstrumentationExtension testing();

protected abstract boolean hasRequestId();

protected static MockWebServerExtension server = new MockWebServerExtension();
protected static AwsClientBuilder.EndpointConfiguration endpoint;
protected static final AWSStaticCredentialsProvider credentialsProvider =
new AWSStaticCredentialsProvider(new AnonymousAWSCredentials());

@BeforeAll
public static void setUp() {
System.setProperty(SDKGlobalConfiguration.ACCESS_KEY_SYSTEM_PROPERTY, "my-access-key");
System.setProperty(SDKGlobalConfiguration.SECRET_KEY_SYSTEM_PROPERTY, "my-secret-key");
server.start();
endpoint = new AwsClientBuilder.EndpointConfiguration(server.httpUri().toString(), "us-west-2");
server.beforeTestExecution(null);
}

@AfterAll
public static void cleanUp() {
System.clearProperty(SDKGlobalConfiguration.ACCESS_KEY_SYSTEM_PROPERTY);
System.clearProperty(SDKGlobalConfiguration.SECRET_KEY_SYSTEM_PROPERTY);
server.stop();
}

public void assertRequestWithMockedResponse(
Object response,
Object client,
String service,
String operation,
String method,
Map<String, String> additionalAttributes)
throws Exception {

assertThat(response).isNotNull();

List<RequestHandler2> requestHandler2s = extractRequestHandlers(client);
assertThat(requestHandler2s).isNotNull();
assertThat(
requestHandler2s.stream()
.filter(h -> "TracingRequestHandler".equals(h.getClass().getSimpleName())))
.isNotNull();

testing()
.waitAndAssertTraces(
trace ->
trace.hasSpansSatisfyingExactly(
span -> {
List<AttributeAssertion> attributes =
new ArrayList<>(
asList(
equalTo(URL_FULL, server.httpUri().toString()),
equalTo(HTTP_REQUEST_METHOD, method),
equalTo(HTTP_RESPONSE_STATUS_CODE, 200),
equalTo(NETWORK_PROTOCOL_VERSION, "1.1"),
equalTo(SERVER_PORT, server.httpPort()),
equalTo(SERVER_ADDRESS, "127.0.0.1"),
equalTo(RPC_SYSTEM, "aws-api"),
satisfies(RPC_SERVICE, v -> v.contains(service)),
equalTo(RPC_METHOD, operation),
equalTo(stringKey("aws.endpoint"), endpoint.getServiceEndpoint()),
equalTo(stringKey("aws.agent"), "java-aws-sdk")));

if (hasRequestId()) {
attributes.add(
satisfies(
stringKey("aws.request_id"), v -> v.isInstanceOf(String.class)));
}

additionalAttributes.forEach(
(k, v) -> attributes.add(equalTo(stringKey(k), v)));

span.hasName(service + "." + operation)
.hasKind(operation.equals("SendMessage") ? PRODUCER : CLIENT)
.hasNoParent()
.hasAttributesSatisfyingExactly(attributes);
}));
}

@SuppressWarnings("unchecked")
protected List<RequestHandler2> extractRequestHandlers(Object client) throws Exception {
Field requestHandler2sField = AmazonWebServiceClient.class.getDeclaredField("requestHandler2s");
requestHandler2sField.setAccessible(true);
return (List<RequestHandler2>) requestHandler2sField.get(client);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.awssdk.v1_11;

import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
import com.amazonaws.services.dynamodbv2.model.CreateTableRequest;
import com.google.common.collect.ImmutableMap;
import io.opentelemetry.testing.internal.armeria.common.HttpResponse;
import io.opentelemetry.testing.internal.armeria.common.HttpStatus;
import io.opentelemetry.testing.internal.armeria.common.MediaType;
import org.junit.jupiter.api.Test;

public abstract class AbstractDynamoDbClientTest extends AbstractBaseAwsClientTest {

public abstract AmazonDynamoDBClientBuilder configureClient(AmazonDynamoDBClientBuilder client);

@Override
protected boolean hasRequestId() {
return false;
}

@Test
public void sendRequestWithMockedResponse() throws Exception {
AmazonDynamoDBClientBuilder clientBuilder = AmazonDynamoDBClientBuilder.standard();
AmazonDynamoDB client =
configureClient(clientBuilder)
.withEndpointConfiguration(endpoint)
.withCredentials(credentialsProvider)
.build();

server.enqueue(HttpResponse.of(HttpStatus.OK, MediaType.PLAIN_TEXT_UTF_8, ""));

Object response = client.createTable(new CreateTableRequest("sometable", null));
assertRequestWithMockedResponse(
response,
client,
"DynamoDBv2",
"CreateTable",
"POST",
ImmutableMap.of("aws.table.name", "sometable"));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.awssdk.v1_11;

import com.amazonaws.services.ec2.AmazonEC2;
import com.amazonaws.services.ec2.AmazonEC2ClientBuilder;
import io.opentelemetry.testing.internal.armeria.common.HttpResponse;
import io.opentelemetry.testing.internal.armeria.common.HttpStatus;
import io.opentelemetry.testing.internal.armeria.common.MediaType;
import java.util.Collections;
import org.junit.jupiter.api.Test;

public abstract class AbstractEc2ClientTest extends AbstractBaseAwsClientTest {

public abstract AmazonEC2ClientBuilder configureClient(AmazonEC2ClientBuilder client);

@Override
protected boolean hasRequestId() {
return true;
}

@Test
public void sendRequestWithMockedResponse() throws Exception {
AmazonEC2ClientBuilder clientBuilder = AmazonEC2ClientBuilder.standard();
AmazonEC2 client =
configureClient(clientBuilder)
.withEndpointConfiguration(endpoint)
.withCredentials(credentialsProvider)
.build();

String body =
"<AllocateAddressResponse xmlns=\"http://ec2.amazonaws.com/doc/2016-11-15/\">"
+ " <requestId>59dbff89-35bd-4eac-99ed-be587EXAMPLE</requestId>"
+ " <publicIp>192.0.2.1</publicIp>"
+ " <domain>standard</domain>"
+ "</AllocateAddressResponse>";
server.enqueue(HttpResponse.of(HttpStatus.OK, MediaType.PLAIN_TEXT_UTF_8, body));

Object response = client.allocateAddress();
assertRequestWithMockedResponse(
response, client, "EC2", "AllocateAddress", "POST", Collections.emptyMap());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.awssdk.v1_11;

import com.amazonaws.services.kinesis.AmazonKinesis;
import com.amazonaws.services.kinesis.AmazonKinesisClientBuilder;
import com.amazonaws.services.kinesis.model.DeleteStreamRequest;
import com.google.common.collect.ImmutableMap;
import io.opentelemetry.testing.internal.armeria.common.HttpResponse;
import io.opentelemetry.testing.internal.armeria.common.HttpStatus;
import io.opentelemetry.testing.internal.armeria.common.MediaType;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Stream;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;

public abstract class AbstractKinesisClientTest extends AbstractBaseAwsClientTest {

public abstract AmazonKinesisClientBuilder configureClient(AmazonKinesisClientBuilder client);

@Override
protected boolean hasRequestId() {
return false;
}

@ParameterizedTest
@MethodSource("provideArguments")
public void testSendRequestWithMockedResponse(
String operation, Function<AmazonKinesis, Object> call) throws Exception {
AmazonKinesisClientBuilder clientBuilder = AmazonKinesisClientBuilder.standard();

AmazonKinesis client =
configureClient(clientBuilder)
.withEndpointConfiguration(endpoint)
.withCredentials(credentialsProvider)
.build();

server.enqueue(HttpResponse.of(HttpStatus.OK, MediaType.PLAIN_TEXT_UTF_8, ""));

Map<String, String> additionalAttributes = ImmutableMap.of("aws.stream.name", "somestream");
Object response = call.apply(client);
assertRequestWithMockedResponse(
response, client, "Kinesis", operation, "POST", additionalAttributes);
}

private static Stream<Arguments> provideArguments() {
return Stream.of(
Arguments.of(
"DeleteStream",
(Function<AmazonKinesis, Object>)
c -> c.deleteStream(new DeleteStreamRequest().withStreamName("somestream"))),
// Some users may implicitly subclass the request object to mimic a fluent style
Arguments.of(
"CustomDeleteStream",
(Function<AmazonKinesis, Object>)
c -> c.deleteStream(new CustomDeleteStreamRequest("somestream"))));
}

public static class CustomDeleteStreamRequest extends DeleteStreamRequest {
public CustomDeleteStreamRequest(String streamName) {
withStreamName(streamName);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.awssdk.v1_11;

import com.amazonaws.services.rds.AmazonRDS;
import com.amazonaws.services.rds.AmazonRDSClientBuilder;
import com.amazonaws.services.rds.model.DeleteOptionGroupRequest;
import io.opentelemetry.testing.internal.armeria.common.HttpResponse;
import io.opentelemetry.testing.internal.armeria.common.HttpStatus;
import io.opentelemetry.testing.internal.armeria.common.MediaType;
import java.util.Collections;
import org.junit.jupiter.api.Test;

public abstract class AbstractRdsClientTest extends AbstractBaseAwsClientTest {

public abstract AmazonRDSClientBuilder configureClient(AmazonRDSClientBuilder client);

@Override
protected boolean hasRequestId() {
return true;
}

@Test
public void sendRequestWithMockedResponse() throws Exception {
AmazonRDSClientBuilder clientBuilder = AmazonRDSClientBuilder.standard();
AmazonRDS client =
configureClient(clientBuilder)
.withEndpointConfiguration(endpoint)
.withCredentials(credentialsProvider)
.build();

String body =
"<DeleteOptionGroupResponse xmlns=\"http://rds.amazonaws.com/doc/2014-09-01/\">"
+ " <ResponseMetadata>"
+ " <RequestId>0ac9cda2-bbf4-11d3-f92b-31fa5e8dbc99</RequestId>"
+ " </ResponseMetadata>"
+ "</DeleteOptionGroupResponse>";
server.enqueue(HttpResponse.of(HttpStatus.OK, MediaType.PLAIN_TEXT_UTF_8, body));

Object response = client.deleteOptionGroup(new DeleteOptionGroupRequest());
assertRequestWithMockedResponse(
response, client, "RDS", "DeleteOptionGroup", "POST", Collections.emptyMap());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.awssdk.v1_11;

import static io.opentelemetry.api.common.AttributeKey.stringKey;
import static io.opentelemetry.api.trace.SpanKind.CLIENT;
import static io.opentelemetry.instrumentation.test.utils.PortUtils.UNUSABLE_PORT;
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo;
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.satisfies;
import static io.opentelemetry.semconv.ErrorAttributes.ERROR_TYPE;
import static io.opentelemetry.semconv.HttpAttributes.HTTP_REQUEST_METHOD;
import static io.opentelemetry.semconv.ServerAttributes.SERVER_ADDRESS;
import static io.opentelemetry.semconv.ServerAttributes.SERVER_PORT;
import static io.opentelemetry.semconv.UrlAttributes.URL_FULL;
import static io.opentelemetry.semconv.incubating.RpcIncubatingAttributes.RPC_METHOD;
import static io.opentelemetry.semconv.incubating.RpcIncubatingAttributes.RPC_SERVICE;
import static io.opentelemetry.semconv.incubating.RpcIncubatingAttributes.RPC_SYSTEM;
import static org.assertj.core.api.Assertions.catchThrowable;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;

import com.amazonaws.AmazonClientException;
import com.amazonaws.ClientConfiguration;
import com.amazonaws.SdkClientException;
import com.amazonaws.client.builder.AwsClientBuilder;
import com.amazonaws.retry.PredefinedRetryPolicies;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.google.common.collect.ImmutableMap;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.sdk.trace.data.StatusData;
import io.opentelemetry.testing.internal.armeria.common.HttpResponse;
import io.opentelemetry.testing.internal.armeria.common.HttpStatus;
import io.opentelemetry.testing.internal.armeria.common.MediaType;
import java.time.Duration;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Stream;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;

public abstract class AbstractS3ClientTest extends AbstractBaseAwsClientTest {

public abstract AmazonS3ClientBuilder configureClient(AmazonS3ClientBuilder client);

private final AmazonS3ClientBuilder clientBuilder =
AmazonS3ClientBuilder.standard().withPathStyleAccessEnabled(true);

@Override
protected boolean hasRequestId() {
return false;
}

@ParameterizedTest
@MethodSource("provideArguments")
public void testSendRequestWithMockedResponse(
String operation,
String method,
Function<AmazonS3, Object> call,
Map<String, String> additionalAttributes)
throws Exception {

AmazonS3 client =
configureClient(clientBuilder)
.withEndpointConfiguration(endpoint)
.withCredentials(credentialsProvider)
.build();

server.enqueue(HttpResponse.of(HttpStatus.OK, MediaType.PLAIN_TEXT_UTF_8, ""));

Object response = call.apply(client);
assertRequestWithMockedResponse(
response, client, "S3", operation, method, additionalAttributes);
}

private static Stream<Arguments> provideArguments() {
return Stream.of(
Arguments.of(
"CreateBucket",
"PUT",
(Function<AmazonS3, Object>) c -> c.createBucket("testbucket"),
ImmutableMap.of("aws.bucket.name", "testbucket")),
Arguments.of(
"GetObject",
"GET",
(Function<AmazonS3, Object>) c -> c.getObject("someBucket", "someKey"),
ImmutableMap.of("aws.bucket.name", "someBucket")));
}

@Test
public void testSendRequestToClosedPort() {
server.enqueue(HttpResponse.of(HttpStatus.OK, MediaType.PLAIN_TEXT_UTF_8, ""));

AmazonS3 client =
configureClient(clientBuilder)
.withCredentials(credentialsProvider)
.withClientConfiguration(
new ClientConfiguration()
.withRetryPolicy(
PredefinedRetryPolicies.getDefaultRetryPolicyWithCustomMaxRetries(0)))
.withEndpointConfiguration(
new AwsClientBuilder.EndpointConfiguration(
"http://127.0.0.1:" + UNUSABLE_PORT, "us-east-1"))
.build();

Throwable caught = catchThrowable(() -> client.getObject("someBucket", "someKey"));
assertThat(caught).isInstanceOf(SdkClientException.class);

testing()
.waitAndAssertTraces(
trace ->
trace.hasSpansSatisfyingExactly(
span ->
span.hasName("S3.GetObject")
.hasKind(CLIENT)
.hasStatus(StatusData.error())
.hasException(caught)
.hasNoParent()
.hasAttributesSatisfyingExactly(
equalTo(URL_FULL, "http://127.0.0.1:" + UNUSABLE_PORT),
equalTo(HTTP_REQUEST_METHOD, "GET"),
equalTo(SERVER_ADDRESS, "127.0.0.1"),
equalTo(SERVER_PORT, 61),
equalTo(RPC_SYSTEM, "aws-api"),
equalTo(RPC_SERVICE, "Amazon S3"),
equalTo(RPC_METHOD, "GetObject"),
equalTo(
stringKey("aws.endpoint"), "http://127.0.0.1:" + UNUSABLE_PORT),
equalTo(stringKey("aws.agent"), "java-aws-sdk"),
equalTo(stringKey("aws.bucket.name"), "someBucket"),
equalTo(ERROR_TYPE, SdkClientException.class.getName()))));
}

@Test
void testTimeoutAndRetryErrorsNotCaptured() {
server.enqueue(HttpResponse.delayed(HttpResponse.of(HttpStatus.OK), Duration.ofSeconds(5)));
server.enqueue(HttpResponse.delayed(HttpResponse.of(HttpStatus.OK), Duration.ofSeconds(5)));
AmazonS3 client =
configureClient(AmazonS3ClientBuilder.standard())
.withClientConfiguration(
new ClientConfiguration()
.withRequestTimeout(50 /* ms */)
.withRetryPolicy(
PredefinedRetryPolicies.getDefaultRetryPolicyWithCustomMaxRetries(1)))
.withEndpointConfiguration(
new AwsClientBuilder.EndpointConfiguration(
server.httpUri().toString(), "us-east-1"))
.build();

Throwable caught = catchThrowable(() -> client.getObject("someBucket", "someKey"));
assertThat(caught).isInstanceOf(AmazonClientException.class);
assertThat(Span.current().getSpanContext().isValid()).isFalse();

testing()
.waitAndAssertTraces(
trace ->
trace.hasSpansSatisfyingExactly(
span -> {
span.hasName("S3.GetObject")
.hasKind(CLIENT)
.hasStatus(StatusData.error())
.hasNoParent()
.hasAttributesSatisfyingExactly(
equalTo(URL_FULL, server.httpUri().toString()),
equalTo(HTTP_REQUEST_METHOD, "GET"),
equalTo(SERVER_PORT, server.httpPort()),
equalTo(SERVER_ADDRESS, "127.0.0.1"),
equalTo(RPC_SYSTEM, "aws-api"),
equalTo(RPC_SERVICE, "Amazon S3"),
equalTo(RPC_METHOD, "GetObject"),
equalTo(stringKey("aws.endpoint"), server.httpUri().toString()),
equalTo(stringKey("aws.agent"), "java-aws-sdk"),
equalTo(stringKey("aws.bucket.name"), "someBucket"),
satisfies(
ERROR_TYPE,
val ->
val.satisfiesAnyOf(
v ->
assertThat(v)
.isEqualTo(SdkClientException.class.getName()),
v ->
assertThat(v)
.isEqualTo(
AmazonClientException.class.getName()))));

try {
span.hasException(
new AmazonClientException("Unable to execute HTTP request"));
} catch (AssertionError e) {
span.hasException(
new SdkClientException(
"Unable to execute HTTP request: Request did not complete before the request timeout configuration."));
}
}));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you know when it gets which exception? If the exception depends on whether it is regular or latest dep test then we could simplify this and the ERROR_TYPE assertion.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems like its always SdkClientException, so I was able to simplify. great catch!

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.awssdk.v1_11;

import static io.opentelemetry.semconv.incubating.MessagingIncubatingAttributes.MESSAGING_DESTINATION_NAME;

import com.amazonaws.services.sns.AmazonSNS;
import com.amazonaws.services.sns.AmazonSNSClientBuilder;
import com.amazonaws.services.sns.model.PublishRequest;
import com.google.common.collect.ImmutableMap;
import io.opentelemetry.testing.internal.armeria.common.HttpResponse;
import io.opentelemetry.testing.internal.armeria.common.HttpStatus;
import io.opentelemetry.testing.internal.armeria.common.MediaType;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Stream;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;

public abstract class AbstractSnsClientTest extends AbstractBaseAwsClientTest {

public abstract AmazonSNSClientBuilder configureClient(AmazonSNSClientBuilder client);

@Override
protected boolean hasRequestId() {
return true;
}

@ParameterizedTest
@MethodSource("provideArguments")
public void testSendRequestWithMockedResponse(Function<AmazonSNS, Object> call) throws Exception {
AmazonSNSClientBuilder clientBuilder = AmazonSNSClientBuilder.standard();
AmazonSNS client =
configureClient(clientBuilder)
.withEndpointConfiguration(endpoint)
.withCredentials(credentialsProvider)
.build();

String body =
"<PublishResponse xmlns=\"https://sns.amazonaws.com/doc/2010-03-31/\">"
+ " <PublishResult>"
+ " <MessageId>567910cd-659e-55d4-8ccb-5aaf14679dc0</MessageId>"
+ " </PublishResult>"
+ " <ResponseMetadata>"
+ " <RequestId>d74b8436-ae13-5ab4-a9ff-ce54dfea72a0</RequestId>"
+ " </ResponseMetadata>"
+ "</PublishResponse>";

server.enqueue(HttpResponse.of(HttpStatus.OK, MediaType.PLAIN_TEXT_UTF_8, body));

Map<String, String> additionalAttributes =
ImmutableMap.of(MESSAGING_DESTINATION_NAME.toString(), "somearn");

Object response = call.apply(client);
assertRequestWithMockedResponse(
response, client, "SNS", "Publish", "POST", additionalAttributes);
}

private static Stream<Arguments> provideArguments() {
return Stream.of(
Arguments.of(
(Function<AmazonSNS, Object>)
c ->
c.publish(
new PublishRequest().withMessage("somemessage").withTopicArn("somearn"))),
Arguments.of(
(Function<AmazonSNS, Object>)
c ->
c.publish(
new PublishRequest().withMessage("somemessage").withTargetArn("somearn"))));
}
}