Stop publishing opentelemetry-sdk-extension-aws artifact (#4830)

This commit is contained in:
jack-berg 2022-10-14 07:51:17 -05:00 committed by GitHub
parent ebb97dad81
commit cc22880bb8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
37 changed files with 21 additions and 2303 deletions

View File

@ -271,7 +271,6 @@ dependency as follows, replacing `{{artifact-id}}` with the value from the "Arti
| [SDK Autoconfigure Extension](./sdk-extensions/autoconfigure) | Autoconfigure OpenTelemetry SDK from env vars, system properties, and SPI | `opentelemetry-sdk-extension-autoconfigure` | <!--VERSION_UNSTABLE-->1.19.0-alpha<!--/VERSION_UNSTABLE--> |
| [SDK Autoconfigure SPI](./sdk-extensions/autoconfigure-spi) | Service Provider Interface (SPI) definitions for autoconfigure | `opentelemetry-sdk-extension-autoconfigure-spi` | <!--VERSION_STABLE-->1.19.0<!--/VERSION_STABLE--> |
| [SDK Resources Extension](./sdk-extensions/resources) | Resource providers, including container, host, os, and process (deprecated) | `opentelemetry-sdk-extension-resources` | <!--VERSION_STABLE-->1.19.0<!--/VERSION_STABLE--> |
| [SDK AWS Extension](./sdk-extensions/aws) | AWS resource providers, including beanstalk, ec2, ecs, eks, and lambda (deprecated) | `opentelemetry-sdk-extension-aws` | <!--VERSION_STABLE-->1.19.0<!--/VERSION_STABLE--> |
| [SDK Jaeger Remote Sampler Extension](./sdk-extensions/jaeger-remote-sampler) | Sampler which obtains sampling configuration from remote Jaeger server | `opentelemetry-sdk-extension-jaeger-remote-sampler` | <!--VERSION_STABLE-->1.19.0<!--/VERSION_STABLE--> |
| [SDK Incubator](./sdk-extensions/incubator) | SDK incubator, including YAML based view configuration, LeakDetectingSpanProcessor, and zPages | `opentelemetry-sdk-extension-incubator` | <!--VERSION_UNSTABLE-->1.19.0-alpha<!--/VERSION_UNSTABLE--> |

View File

@ -48,6 +48,7 @@ dependencies {
testImplementation("io.grpc:grpc-protobuf")
testImplementation("io.grpc:grpc-stub")
testImplementation("io.opentelemetry:opentelemetry-extension-annotations")
testImplementation("io.opentelemetry:opentelemetry-sdk-extension-aws")
testImplementation("com.tngtech.archunit:archunit-junit5")
}

View File

@ -8,6 +8,10 @@ package io.opentelemetry.all;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
/**
* This test asserts that artifacts which are no longer published continue to be referenced in
* {@code opentelemetry-bom}.
*/
class FallbackArtifactsTest {
@Test
@ -23,6 +27,21 @@ class FallbackArtifactsTest {
classAvailable("io.opentelemetry.extension.annotations.SpanAttribute");
}
@Test
void sdkExtensionAws() {
classAvailable("io.opentelemetry.sdk.extension.aws.resource.BeanstalkResource");
classAvailable("io.opentelemetry.sdk.extension.aws.resource.BeanstalkResourceProvider");
classAvailable("io.opentelemetry.sdk.extension.aws.resource.Ec2Resource");
classAvailable("io.opentelemetry.sdk.extension.aws.resource.Ec2ResourceProvider");
classAvailable("io.opentelemetry.sdk.extension.aws.resource.EcsResource");
classAvailable("io.opentelemetry.sdk.extension.aws.resource.EcsResourceProvider");
classAvailable("io.opentelemetry.sdk.extension.aws.resource.EksResource");
classAvailable("io.opentelemetry.sdk.extension.aws.resource.EksResourceProvider");
classAvailable("io.opentelemetry.sdk.extension.aws.resource.LambdaResource");
classAvailable("io.opentelemetry.sdk.extension.aws.resource.LambdaResourceProvider");
classAvailable("io.opentelemetry.sdk.extension.aws.trace.AwsXrayIdGenerator");
}
private static void classAvailable(String fqcn) {
Assertions.assertThatCode(() -> Class.forName(fqcn)).doesNotThrowAnyException();
}

View File

@ -11,3 +11,4 @@ otelBom.projectFilter.set { !it.hasProperty("otel.release") }
// Artifacts that were previously published and included in the BOM for backwards compatibility
otelBom.addFallback("opentelemetry-exporter-jaeger-proto", "1.17.0")
otelBom.addFallback("opentelemetry-extension-annotations", "1.18.0")
otelBom.addFallback("opentelemetry-sdk-extension-aws", "1.19.0")

View File

@ -1,2 +0,0 @@
Comparing source compatibility of against
No changes.

View File

@ -1,18 +0,0 @@
# OpenTelemetry AWS Utils
[![Javadocs][javadoc-image]][javadoc-url]
> **NOTICE**: This artifact is deprecated and its contents have been moved
> to [io.opentelemetry.contrib:opentelemetry-aws-resources](https://github.com/open-telemetry/opentelemetry-java-contrib/tree/main/aws-resources).
> Version 1.19.0 will be the last minor version published. However, it will continue to receive
> patches for security vulnerabilities, and`io.opentelemetry:opentelemetry-bom` will reference the
> last published version.
---
#### Running micro-benchmarks
From the root of the repo run `./gradlew clean :opentelemetry-sdk-extension-aws:jmh` to run all the benchmarks
or run `./gradlew clean :opentelemetry-sdk-extension-aws:jmh -PjmhIncludeSingleClass=<ClassNameHere>`
to run a specific benchmark class.
[javadoc-image]: https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-aws.svg
[javadoc-url]: https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-aws

View File

@ -1,32 +0,0 @@
plugins {
id("otel.java-conventions")
id("otel.publish-conventions")
id("otel.jmh-conventions")
}
description = "OpenTelemetry SDK AWS Instrumentation Support"
otelJava.moduleName.set("io.opentelemetry.sdk.extension.trace.aws")
dependencies {
api(project(":api:all"))
api(project(":sdk:all"))
compileOnly(project(":sdk-extensions:autoconfigure"))
annotationProcessor("com.google.auto.value:auto-value")
implementation(project(":semconv"))
implementation("com.fasterxml.jackson.core:jackson-core")
implementation("com.squareup.okhttp3:okhttp")
testImplementation(project(":sdk:testing"))
testImplementation(project(":sdk-extensions:autoconfigure"))
testImplementation("com.linecorp.armeria:armeria-junit5")
testRuntimeOnly("org.bouncycastle:bcpkix-jdk15on")
testImplementation("com.google.guava:guava")
testImplementation("org.skyscreamer:jsonassert")
}

View File

@ -1,44 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.sdk.extension.aws;
import java.util.concurrent.TimeUnit;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Warmup;
@State(Scope.Benchmark)
@SuppressWarnings("deprecation") // Moved to contrib
public class AwsXrayIdGeneratorBenchmark {
private final io.opentelemetry.sdk.extension.aws.trace.AwsXrayIdGenerator idGenerator =
io.opentelemetry.sdk.extension.aws.trace.AwsXrayIdGenerator.getInstance();
@Benchmark
@Measurement(iterations = 15, time = 1)
@Warmup(iterations = 5, time = 1)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@BenchmarkMode(Mode.AverageTime)
@Fork(1)
public String generateTraceId() {
return idGenerator.generateTraceId();
}
@Benchmark
@Measurement(iterations = 15, time = 1)
@Warmup(iterations = 5, time = 1)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@BenchmarkMode(Mode.AverageTime)
@Fork(1)
public String generateSpanId() {
return idGenerator.generateSpanId();
}
}

View File

@ -1,99 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.sdk.extension.aws.resource;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.semconv.resource.attributes.ResourceAttributes;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* A factory for a {@link Resource} which provides information about the current EC2 instance if
* running on AWS Elastic Beanstalk.
*
* @deprecated Moved to <a
* href="https://github.com/open-telemetry/opentelemetry-java-contrib/tree/main/aws-resources">io.opentelemetry.contrib:opentelemetry-aws-resources</a>.
*/
@Deprecated
public final class BeanstalkResource {
private static final Logger logger = Logger.getLogger(BeanstalkResource.class.getName());
private static final String DEVELOPMENT_ID = "deployment_id";
private static final String VERSION_LABEL = "version_label";
private static final String ENVIRONMENT_NAME = "environment_name";
private static final String BEANSTALK_CONF_PATH = "/var/elasticbeanstalk/xray/environment.conf";
private static final JsonFactory JSON_FACTORY = new JsonFactory();
private static final Resource INSTANCE = buildResource();
/**
* Returns a factory for a {@link Resource} which provides information about the current EC2
* instance if running on AWS Elastic Beanstalk.
*/
public static Resource get() {
return INSTANCE;
}
private static Resource buildResource() {
return buildResource(BEANSTALK_CONF_PATH);
}
// Visible for testing
static Resource buildResource(String configPath) {
File configFile = new File(configPath);
if (!configFile.exists()) {
return Resource.empty();
}
AttributesBuilder attrBuilders = Attributes.builder();
try (JsonParser parser = JSON_FACTORY.createParser(configFile)) {
parser.nextToken();
if (!parser.isExpectedStartObjectToken()) {
logger.log(Level.WARNING, "Invalid Beanstalk config: ", configPath);
return Resource.create(attrBuilders.build(), ResourceAttributes.SCHEMA_URL);
}
while (parser.nextToken() != JsonToken.END_OBJECT) {
parser.nextValue();
String value = parser.getText();
switch (parser.getCurrentName()) {
case DEVELOPMENT_ID:
attrBuilders.put(ResourceAttributes.SERVICE_INSTANCE_ID, value);
break;
case VERSION_LABEL:
attrBuilders.put(ResourceAttributes.SERVICE_VERSION, value);
break;
case ENVIRONMENT_NAME:
attrBuilders.put(ResourceAttributes.SERVICE_NAMESPACE, value);
break;
default:
parser.skipChildren();
}
}
} catch (IOException e) {
logger.log(Level.WARNING, "Could not parse Beanstalk config.", e);
return Resource.empty();
}
attrBuilders.put(ResourceAttributes.CLOUD_PROVIDER, ResourceAttributes.CloudProviderValues.AWS);
attrBuilders.put(
ResourceAttributes.CLOUD_PLATFORM,
ResourceAttributes.CloudPlatformValues.AWS_ELASTIC_BEANSTALK);
return Resource.create(attrBuilders.build(), ResourceAttributes.SCHEMA_URL);
}
private BeanstalkResource() {}
}

View File

@ -1,24 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.sdk.extension.aws.resource;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
import io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider;
import io.opentelemetry.sdk.resources.Resource;
/**
* {@link ResourceProvider} for automatically configuring {@link BeanstalkResource}.
*
* @deprecated Moved to <a
* href="https://github.com/open-telemetry/opentelemetry-java-contrib/tree/main/aws-resources">io.opentelemetry.contrib:opentelemetry-aws-resources</a>.
*/
@Deprecated
public final class BeanstalkResourceProvider implements ResourceProvider {
@Override
public Resource createResource(ConfigProperties config) {
return BeanstalkResource.get();
}
}

View File

@ -1,54 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.sdk.extension.aws.resource;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
class DockerHelper {
private static final Logger logger = Logger.getLogger(DockerHelper.class.getName());
private static final int CONTAINER_ID_LENGTH = 64;
private static final String DEFAULT_CGROUP_PATH = "/proc/self/cgroup";
private final String cgroupPath;
DockerHelper() {
this(DEFAULT_CGROUP_PATH);
}
// Visible for testing
DockerHelper(String cgroupPath) {
this.cgroupPath = cgroupPath;
}
/**
* Get docker container id from local cgroup file.
*
* @return docker container ID. Empty string if it can`t be found.
*/
@SuppressWarnings("DefaultCharset")
public String getContainerId() {
try (BufferedReader br = new BufferedReader(new FileReader(cgroupPath))) {
String line;
while ((line = br.readLine()) != null) {
if (line.length() > CONTAINER_ID_LENGTH) {
return line.substring(line.length() - CONTAINER_ID_LENGTH);
}
}
} catch (FileNotFoundException e) {
logger.log(Level.WARNING, "Failed to read container id, cgroup file does not exist.");
} catch (IOException e) {
logger.log(Level.WARNING, "Unable to read container id: " + e.getMessage());
}
return "";
}
}

View File

@ -1,159 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.sdk.extension.aws.resource;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.semconv.resource.attributes.ResourceAttributes;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* A factory for a {@link Resource} which provides information about the current EC2 instance if
* running on AWS EC2.
*
* @deprecated Moved to <a
* href="https://github.com/open-telemetry/opentelemetry-java-contrib/tree/main/aws-resources">io.opentelemetry.contrib:opentelemetry-aws-resources</a>.
*/
@Deprecated
public final class Ec2Resource {
private static final Logger logger = Logger.getLogger(Ec2Resource.class.getName());
private static final JsonFactory JSON_FACTORY = new JsonFactory();
private static final String DEFAULT_IMDS_ENDPOINT = "169.254.169.254";
private static final Resource INSTANCE = buildResource();
/**
* Returns a @link Resource} which provides information about the current EC2 instance if running
* on AWS EC2.
*/
public static Resource get() {
return INSTANCE;
}
private static Resource buildResource() {
// This property is only for testing e.g., with a mock IMDS server and never in production so we
// just
// read from a system property. This is similar to the AWS SDK.
return buildResource(
System.getProperty("otel.aws.imds.endpointOverride", DEFAULT_IMDS_ENDPOINT));
}
// Visible for testing
static Resource buildResource(String endpoint) {
String urlBase = "http://" + endpoint;
URL identityDocumentUrl;
URL hostnameUrl;
URL tokenUrl;
try {
identityDocumentUrl = new URL(urlBase + "/latest/dynamic/instance-identity/document");
hostnameUrl = new URL(urlBase + "/latest/meta-data/hostname");
tokenUrl = new URL(urlBase + "/latest/api/token");
} catch (MalformedURLException e) {
// Can only happen when overriding the endpoint in testing so just throw.
throw new IllegalArgumentException("Illegal endpoint: " + endpoint, e);
}
String token = fetchToken(tokenUrl);
// If token is empty, either IMDSv2 isn't enabled or an unexpected failure happened. We can
// still get data if IMDSv1 is enabled.
String identity = fetchIdentity(identityDocumentUrl, token);
if (identity.isEmpty()) {
// If no identity document, assume we are not actually running on EC2.
return Resource.empty();
}
String hostname = fetchHostname(hostnameUrl, token);
AttributesBuilder attrBuilders = Attributes.builder();
attrBuilders.put(ResourceAttributes.CLOUD_PROVIDER, ResourceAttributes.CloudProviderValues.AWS);
attrBuilders.put(
ResourceAttributes.CLOUD_PLATFORM, ResourceAttributes.CloudPlatformValues.AWS_EC2);
try (JsonParser parser = JSON_FACTORY.createParser(identity)) {
parser.nextToken();
if (!parser.isExpectedStartObjectToken()) {
throw new IOException("Invalid JSON:" + identity);
}
while (parser.nextToken() != JsonToken.END_OBJECT) {
String value = parser.nextTextValue();
switch (parser.getCurrentName()) {
case "instanceId":
attrBuilders.put(ResourceAttributes.HOST_ID, value);
break;
case "availabilityZone":
attrBuilders.put(ResourceAttributes.CLOUD_AVAILABILITY_ZONE, value);
break;
case "instanceType":
attrBuilders.put(ResourceAttributes.HOST_TYPE, value);
break;
case "imageId":
attrBuilders.put(ResourceAttributes.HOST_IMAGE_ID, value);
break;
case "accountId":
attrBuilders.put(ResourceAttributes.CLOUD_ACCOUNT_ID, value);
break;
case "region":
attrBuilders.put(ResourceAttributes.CLOUD_REGION, value);
break;
default:
parser.skipChildren();
}
}
} catch (IOException e) {
logger.log(Level.WARNING, "Could not parse identity document, resource not filled.", e);
return Resource.empty();
}
attrBuilders.put(ResourceAttributes.HOST_NAME, hostname);
return Resource.create(attrBuilders.build(), ResourceAttributes.SCHEMA_URL);
}
private static String fetchToken(URL tokenUrl) {
return fetchString("PUT", tokenUrl, "", /* includeTtl= */ true);
}
private static String fetchIdentity(URL identityDocumentUrl, String token) {
return fetchString("GET", identityDocumentUrl, token, /* includeTtl= */ false);
}
private static String fetchHostname(URL hostnameUrl, String token) {
return fetchString("GET", hostnameUrl, token, /* includeTtl= */ false);
}
// Generic HTTP fetch function for IMDS.
private static String fetchString(String httpMethod, URL url, String token, boolean includeTtl) {
SimpleHttpClient client = new SimpleHttpClient();
Map<String, String> headers = new HashMap<>();
if (includeTtl) {
headers.put("X-aws-ec2-metadata-token-ttl-seconds", "60");
}
if (!token.isEmpty()) {
headers.put("X-aws-ec2-metadata-token", token);
}
return client.fetchString(httpMethod, url.toString(), headers, null);
}
private Ec2Resource() {}
}

View File

@ -1,24 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.sdk.extension.aws.resource;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
import io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider;
import io.opentelemetry.sdk.resources.Resource;
/**
* {@link ResourceProvider} for automatically configuring {@link Ec2Resource}.
*
* @deprecated Moved to <a
* href="https://github.com/open-telemetry/opentelemetry-java-contrib/tree/main/aws-resources">io.opentelemetry.contrib:opentelemetry-aws-resources</a>.
*/
@Deprecated
public final class Ec2ResourceProvider implements ResourceProvider {
@Override
public Resource createResource(ConfigProperties config) {
return Ec2Resource.get();
}
}

View File

@ -1,270 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.sdk.extension.aws.resource;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.semconv.resource.attributes.ResourceAttributes;
import java.io.IOException;
import java.util.Collections;
import java.util.Map;
import java.util.Optional;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.annotation.Nullable;
/**
* A factory for a {@link Resource} which provides information about the current ECS container if
* running on AWS ECS.
*
* @deprecated Moved to <a
* href="https://github.com/open-telemetry/opentelemetry-java-contrib/tree/main/aws-resources">io.opentelemetry.contrib:opentelemetry-aws-resources</a>.
*/
@Deprecated
public final class EcsResource {
private static final Logger logger = Logger.getLogger(EcsResource.class.getName());
private static final JsonFactory JSON_FACTORY = new JsonFactory();
private static final String ECS_METADATA_KEY_V4 = "ECS_CONTAINER_METADATA_URI_V4";
private static final String ECS_METADATA_KEY_V3 = "ECS_CONTAINER_METADATA_URI";
private static final Resource INSTANCE = buildResource();
/**
* Returns a factory for a {@link Resource} which provides information about the current ECS
* container if running on AWS ECS.
*/
public static Resource get() {
return INSTANCE;
}
private static Resource buildResource() {
return buildResource(System.getenv(), new SimpleHttpClient());
}
// Visible for testing
static Resource buildResource(Map<String, String> sysEnv, SimpleHttpClient httpClient) {
// Note: If V4 is set V3 is set as well, so check V4 first.
String ecsMetadataUrl =
sysEnv.getOrDefault(ECS_METADATA_KEY_V4, sysEnv.getOrDefault(ECS_METADATA_KEY_V3, ""));
if (!ecsMetadataUrl.isEmpty()) {
AttributesBuilder attrBuilders = Attributes.builder();
fetchMetadata(httpClient, ecsMetadataUrl, attrBuilders);
// For TaskARN, Family, Revision.
// May put the same attribute twice but that shouldn't matter.
fetchMetadata(httpClient, ecsMetadataUrl + "/task", attrBuilders);
return Resource.create(attrBuilders.build(), ResourceAttributes.SCHEMA_URL);
}
// Not running on ECS
return Resource.empty();
}
static void fetchMetadata(
SimpleHttpClient httpClient, String url, AttributesBuilder attrBuilders) {
String json = httpClient.fetchString("GET", url, Collections.emptyMap(), null);
if (json.isEmpty()) {
return;
}
attrBuilders.put(ResourceAttributes.CLOUD_PROVIDER, ResourceAttributes.CloudProviderValues.AWS);
attrBuilders.put(
ResourceAttributes.CLOUD_PLATFORM, ResourceAttributes.CloudPlatformValues.AWS_ECS);
try (JsonParser parser = JSON_FACTORY.createParser(json)) {
parser.nextToken();
LogArnBuilder logArnBuilder = new LogArnBuilder();
parseResponse(parser, attrBuilders, logArnBuilder);
logArnBuilder
.getLogGroupArn()
.ifPresent(
logGroupArn -> {
attrBuilders.put(
ResourceAttributes.AWS_LOG_GROUP_ARNS, Collections.singletonList(logGroupArn));
});
logArnBuilder
.getLogStreamArn()
.ifPresent(
logStreamArn -> {
attrBuilders.put(
ResourceAttributes.AWS_LOG_STREAM_ARNS,
Collections.singletonList(logStreamArn));
});
} catch (IOException e) {
logger.log(Level.WARNING, "Can't get ECS metadata", e);
}
}
static void parseResponse(
JsonParser parser, AttributesBuilder attrBuilders, LogArnBuilder logArnBuilder)
throws IOException {
if (!parser.isExpectedStartObjectToken()) {
logger.log(Level.WARNING, "Couldn't parse ECS metadata, invalid JSON");
return;
}
while (parser.nextToken() != JsonToken.END_OBJECT) {
String value = parser.nextTextValue();
switch (parser.getCurrentName()) {
case "DockerId":
attrBuilders.put(ResourceAttributes.CONTAINER_ID, value);
break;
case "DockerName":
attrBuilders.put(ResourceAttributes.CONTAINER_NAME, value);
break;
case "ContainerARN":
attrBuilders.put(ResourceAttributes.AWS_ECS_CONTAINER_ARN, value);
logArnBuilder.setContainerArn(value);
break;
case "Image":
DockerImage parsedImage = DockerImage.parse(value);
if (parsedImage != null) {
attrBuilders.put(ResourceAttributes.CONTAINER_IMAGE_NAME, parsedImage.getRepository());
attrBuilders.put(ResourceAttributes.CONTAINER_IMAGE_TAG, parsedImage.getTag());
}
break;
case "ImageID":
attrBuilders.put("aws.ecs.container.image.id", value);
break;
case "LogOptions":
// Recursively parse LogOptions
parseResponse(parser, attrBuilders, logArnBuilder);
break;
case "awslogs-group":
attrBuilders.put(ResourceAttributes.AWS_LOG_GROUP_NAMES, value);
logArnBuilder.setLogGroupName(value);
break;
case "awslogs-stream":
attrBuilders.put(ResourceAttributes.AWS_LOG_STREAM_NAMES, value);
logArnBuilder.setLogStreamName(value);
break;
case "awslogs-region":
logArnBuilder.setRegion(value);
break;
case "TaskARN":
attrBuilders.put(ResourceAttributes.AWS_ECS_TASK_ARN, value);
break;
case "LaunchType":
attrBuilders.put(ResourceAttributes.AWS_ECS_LAUNCHTYPE, value.toLowerCase());
break;
case "Family":
attrBuilders.put(ResourceAttributes.AWS_ECS_TASK_FAMILY, value);
break;
case "Revision":
attrBuilders.put(ResourceAttributes.AWS_ECS_TASK_REVISION, value);
break;
default:
parser.skipChildren();
break;
}
}
}
private EcsResource() {}
/**
* This builder can piece together the ARN of a log group or a log stream from region, account,
* group name and stream name as the ARN isn't part of the ECS metadata.
*
* <p>If we just set AWS_LOG_GROUP_NAMES then the CloudWatch X-Ray traces view displays "An error
* occurred fetching your data". That's why it's important we set the ARN.
*/
private static class LogArnBuilder {
@Nullable String region;
@Nullable String account;
@Nullable String logGroupName;
@Nullable String logStreamName;
void setRegion(@Nullable String region) {
this.region = region;
}
void setLogGroupName(@Nullable String logGroupName) {
this.logGroupName = logGroupName;
}
void setLogStreamName(@Nullable String logStreamName) {
this.logStreamName = logStreamName;
}
void setContainerArn(@Nullable String containerArn) {
if (containerArn != null) {
account = containerArn.split(":")[4];
}
}
Optional<String> getLogGroupArn() {
if (region == null || account == null || logGroupName == null) {
return Optional.empty();
}
return Optional.of("arn:aws:logs:" + region + ":" + account + ":log-group:" + logGroupName);
}
Optional<String> getLogStreamArn() {
if (region == null || account == null || logGroupName == null || logStreamName == null) {
return Optional.empty();
}
return Optional.of(
"arn:aws:logs:"
+ region
+ ":"
+ account
+ ":log-group:"
+ logGroupName
+ ":log-stream:"
+ logStreamName);
}
}
/** This can parse a Docker image name into its parts: repository, tag and sha256. */
private static class DockerImage {
private static final Pattern imagePattern =
Pattern.compile(
"^(?<repository>([^/\\s]+/)?([^:\\s]+))(:(?<tag>[^@\\s]+))?(@sha256:(?<sha256>\\d+))?$");
final String repository;
final String tag;
private DockerImage(String repository, String tag) {
this.repository = repository;
this.tag = tag;
}
String getRepository() {
return repository;
}
String getTag() {
return tag;
}
@Nullable
static DockerImage parse(@Nullable String image) {
if (image == null || image.isEmpty()) {
return null;
}
Matcher matcher = imagePattern.matcher(image);
if (!matcher.matches()) {
logger.log(Level.WARNING, "Couldn't parse image '" + image + "'");
return null;
}
String repository = matcher.group("repository");
String tag = matcher.group("tag");
if (tag == null || tag.isEmpty()) {
tag = "latest";
}
return new DockerImage(repository, tag);
}
}
}

View File

@ -1,24 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.sdk.extension.aws.resource;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
import io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider;
import io.opentelemetry.sdk.resources.Resource;
/**
* {@link ResourceProvider} for automatically configuring {@link EcsResource}.
*
* @deprecated Moved to <a
* href="https://github.com/open-telemetry/opentelemetry-java-contrib/tree/main/aws-resources">io.opentelemetry.contrib:opentelemetry-aws-resources</a>.
*/
@Deprecated
public final class EcsResourceProvider implements ResourceProvider {
@Override
public Resource createResource(ConfigProperties config) {
return EcsResource.get();
}
}

View File

@ -1,163 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.sdk.extension.aws.resource;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.semconv.resource.attributes.ResourceAttributes;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* A factory for a {@link Resource} which provides information about the current ECS container if
* running on AWS EKS.
*
* @deprecated Moved to <a
* href="https://github.com/open-telemetry/opentelemetry-java-contrib/tree/main/aws-resources">io.opentelemetry.contrib:opentelemetry-aws-resources</a>.
*/
@Deprecated
public final class EksResource {
private static final Logger logger = Logger.getLogger(EksResource.class.getName());
private static final JsonFactory JSON_FACTORY = new JsonFactory();
static final String K8S_SVC_URL = "https://kubernetes.default.svc";
static final String AUTH_CONFIGMAP_PATH = "/api/v1/namespaces/kube-system/configmaps/aws-auth";
static final String CW_CONFIGMAP_PATH =
"/api/v1/namespaces/amazon-cloudwatch/configmaps/cluster-info";
private static final String K8S_TOKEN_PATH =
"/var/run/secrets/kubernetes.io/serviceaccount/token";
private static final String K8S_CERT_PATH =
"/var/run/secrets/kubernetes.io/serviceaccount/ca.crt";
private static final Resource INSTANCE = buildResource();
/**
* Returns a factory for a {@link Resource} which provides information about the current ECS
* container if running on AWS EKS.
*/
public static Resource get() {
return INSTANCE;
}
private static Resource buildResource() {
return buildResource(new SimpleHttpClient(), new DockerHelper(), K8S_TOKEN_PATH, K8S_CERT_PATH);
}
// Visible for testing
static Resource buildResource(
SimpleHttpClient httpClient,
DockerHelper dockerHelper,
String k8sTokenPath,
String k8sKeystorePath) {
if (!isEks(k8sTokenPath, k8sKeystorePath, httpClient)) {
return Resource.empty();
}
AttributesBuilder attrBuilders = Attributes.builder();
attrBuilders.put(ResourceAttributes.CLOUD_PROVIDER, ResourceAttributes.CloudProviderValues.AWS);
attrBuilders.put(
ResourceAttributes.CLOUD_PLATFORM, ResourceAttributes.CloudPlatformValues.AWS_EKS);
String clusterName = getClusterName(httpClient);
if (clusterName != null && !clusterName.isEmpty()) {
attrBuilders.put(ResourceAttributes.K8S_CLUSTER_NAME, clusterName);
}
String containerId = dockerHelper.getContainerId();
if (containerId != null && !containerId.isEmpty()) {
attrBuilders.put(ResourceAttributes.CONTAINER_ID, containerId);
}
return Resource.create(attrBuilders.build(), ResourceAttributes.SCHEMA_URL);
}
private static boolean isEks(
String k8sTokenPath, String k8sKeystorePath, SimpleHttpClient httpClient) {
if (!isK8s(k8sTokenPath, k8sKeystorePath)) {
logger.log(Level.FINE, "Not running on k8s.");
return false;
}
Map<String, String> requestProperties = new HashMap<>();
requestProperties.put("Authorization", getK8sCredHeader());
String awsAuth =
httpClient.fetchString(
"GET", K8S_SVC_URL + AUTH_CONFIGMAP_PATH, requestProperties, K8S_CERT_PATH);
return awsAuth != null && !awsAuth.isEmpty();
}
private static boolean isK8s(String k8sTokenPath, String k8sKeystorePath) {
File k8sTokeyFile = new File(k8sTokenPath);
File k8sKeystoreFile = new File(k8sKeystorePath);
return k8sTokeyFile.exists() && k8sKeystoreFile.exists();
}
private static String getClusterName(SimpleHttpClient httpClient) {
Map<String, String> requestProperties = new HashMap<>();
requestProperties.put("Authorization", getK8sCredHeader());
String json =
httpClient.fetchString(
"GET", K8S_SVC_URL + CW_CONFIGMAP_PATH, requestProperties, K8S_CERT_PATH);
try (JsonParser parser = JSON_FACTORY.createParser(json)) {
parser.nextToken();
if (!parser.isExpectedStartObjectToken()) {
throw new IOException("Invalid JSON:" + json);
}
while (parser.nextToken() != JsonToken.END_OBJECT) {
parser.nextToken();
if (!parser.getCurrentName().equals("data")) {
parser.skipChildren();
continue;
}
if (!parser.isExpectedStartObjectToken()) {
throw new IOException("Invalid JSON:" + json);
}
while (parser.nextToken() != JsonToken.END_OBJECT) {
String value = parser.nextTextValue();
if (!parser.getCurrentName().equals("cluster.name")) {
parser.skipChildren();
continue;
}
return value;
}
}
} catch (IOException e) {
logger.log(Level.WARNING, "Can't get cluster name on EKS.", e);
}
return "";
}
private static String getK8sCredHeader() {
try {
String content =
new String(Files.readAllBytes(Paths.get(K8S_TOKEN_PATH)), StandardCharsets.UTF_8);
return "Bearer " + content;
} catch (IOException e) {
logger.log(Level.WARNING, "Unable to load K8s client token.", e);
}
return "";
}
private EksResource() {}
}

View File

@ -1,24 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.sdk.extension.aws.resource;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
import io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider;
import io.opentelemetry.sdk.resources.Resource;
/**
* {@link ResourceProvider} for automatically configuring {@link EksResource}.
*
* @deprecated Moved to <a
* href="https://github.com/open-telemetry/opentelemetry-java-contrib/tree/main/aws-resources">io.opentelemetry.contrib:opentelemetry-aws-resources</a>.
*/
@Deprecated
public final class EksResourceProvider implements ResourceProvider {
@Override
public Resource createResource(ConfigProperties config) {
return EksResource.get();
}
}

View File

@ -1,72 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.sdk.extension.aws.resource;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.semconv.resource.attributes.ResourceAttributes;
import java.util.Map;
import java.util.stream.Stream;
/**
* A factory for a {@link Resource} which provides information about the AWS Lambda function.
*
* @deprecated Moved to <a
* href="https://github.com/open-telemetry/opentelemetry-java-contrib/tree/main/aws-resources">io.opentelemetry.contrib:opentelemetry-aws-resources</a>.
*/
@Deprecated
public final class LambdaResource {
private static final Resource INSTANCE = buildResource();
/**
* Returns a factory for a {@link Resource} which provides information about the AWS Lambda
* function.
*/
public static Resource get() {
return INSTANCE;
}
private static Resource buildResource() {
return buildResource(System.getenv());
}
// Visible for testing
static Resource buildResource(Map<String, String> environmentVariables) {
String region = environmentVariables.getOrDefault("AWS_REGION", "");
String functionName = environmentVariables.getOrDefault("AWS_LAMBDA_FUNCTION_NAME", "");
String functionVersion = environmentVariables.getOrDefault("AWS_LAMBDA_FUNCTION_VERSION", "");
if (!isLambda(functionName, functionVersion)) {
return Resource.empty();
}
AttributesBuilder builder =
Attributes.builder()
.put(ResourceAttributes.CLOUD_PROVIDER, ResourceAttributes.CloudProviderValues.AWS);
builder.put(
ResourceAttributes.CLOUD_PLATFORM, ResourceAttributes.CloudPlatformValues.AWS_LAMBDA);
if (!region.isEmpty()) {
builder.put(ResourceAttributes.CLOUD_REGION, region);
}
if (!functionName.isEmpty()) {
builder.put(ResourceAttributes.FAAS_NAME, functionName);
}
if (!functionVersion.isEmpty()) {
builder.put(ResourceAttributes.FAAS_VERSION, functionVersion);
}
return Resource.create(builder.build(), ResourceAttributes.SCHEMA_URL);
}
private static boolean isLambda(String... envVariables) {
return Stream.of(envVariables).anyMatch(v -> !v.isEmpty());
}
private LambdaResource() {}
}

View File

@ -1,24 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.sdk.extension.aws.resource;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
import io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider;
import io.opentelemetry.sdk.resources.Resource;
/**
* {@link ResourceProvider} for automatically configuring {@link LambdaResource}.
*
* @deprecated Moved to <a
* href="https://github.com/open-telemetry/opentelemetry-java-contrib/tree/main/aws-resources">io.opentelemetry.contrib:opentelemetry-aws-resources</a>.
*/
@Deprecated
public final class LambdaResourceProvider implements ResourceProvider {
@Override
public Resource createResource(ConfigProperties config) {
return LambdaResource.get();
}
}

View File

@ -1,145 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.sdk.extension.aws.resource;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.time.Duration;
import java.util.Collection;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.Nullable;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.ResponseBody;
/** A simple HTTP client based on OkHttp. Not meant for high throughput. */
final class SimpleHttpClient {
private static final Logger logger = Logger.getLogger(SimpleHttpClient.class.getName());
private static final Duration TIMEOUT = Duration.ofSeconds(2);
private static final RequestBody EMPTY_BODY = RequestBody.create(new byte[0]);
/** Fetch a string from a remote server. */
public String fetchString(
String httpMethod, String urlStr, Map<String, String> headers, @Nullable String certPath) {
OkHttpClient.Builder clientBuilder =
new OkHttpClient.Builder()
.callTimeout(TIMEOUT)
.connectTimeout(TIMEOUT)
.readTimeout(TIMEOUT);
if (urlStr.startsWith("https") && certPath != null) {
KeyStore keyStore = getKeystoreForTrustedCert(certPath);
X509TrustManager trustManager = buildTrustManager(keyStore);
SSLSocketFactory socketFactory = buildSslSocketFactory(trustManager);
if (socketFactory != null) {
clientBuilder.sslSocketFactory(socketFactory, trustManager);
}
}
OkHttpClient client = clientBuilder.build();
// AWS incorrectly uses PUT despite having no request body, OkHttp will only allow us to send
// GET with null body or PUT with empty string body
RequestBody requestBody = null;
if (httpMethod.equals("PUT")) {
requestBody = EMPTY_BODY;
}
Request.Builder requestBuilder =
new Request.Builder().url(urlStr).method(httpMethod, requestBody);
headers.forEach(requestBuilder::addHeader);
try (Response response = client.newCall(requestBuilder.build()).execute()) {
int responseCode = response.code();
if (responseCode != 200) {
logger.log(
Level.FINE,
"Error response from "
+ urlStr
+ " code ("
+ responseCode
+ ") text "
+ response.message());
return "";
}
ResponseBody body = response.body();
return body != null ? body.string() : "";
} catch (IOException e) {
logger.log(Level.FINE, "SimpleHttpClient fetch string failed.", e);
}
return "";
}
@Nullable
private static X509TrustManager buildTrustManager(@Nullable KeyStore keyStore) {
if (keyStore == null) {
return null;
}
try {
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);
return (X509TrustManager) tmf.getTrustManagers()[0];
} catch (Exception e) {
logger.log(Level.WARNING, "Build SslSocketFactory for K8s restful client exception.", e);
return null;
}
}
@Nullable
private static SSLSocketFactory buildSslSocketFactory(@Nullable TrustManager trustManager) {
if (trustManager == null) {
return null;
}
try {
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, new TrustManager[] {trustManager}, null);
return context.getSocketFactory();
} catch (Exception e) {
logger.log(Level.WARNING, "Build SslSocketFactory for K8s restful client exception.", e);
}
return null;
}
@Nullable
private static KeyStore getKeystoreForTrustedCert(String certPath) {
try (FileInputStream fis = new FileInputStream(certPath)) {
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(null, null);
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
Collection<? extends Certificate> certificates = certificateFactory.generateCertificates(fis);
int i = 0;
for (Certificate certificate : certificates) {
trustStore.setCertificateEntry("cert_" + i, certificate);
i++;
}
return trustStore;
} catch (Exception e) {
logger.log(Level.WARNING, "Cannot load KeyStore from " + certPath);
return null;
}
}
}

View File

@ -1,13 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
/**
* {@link io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider} implementations for inferring
* resource information for AWS services.
*/
@ParametersAreNonnullByDefault
package io.opentelemetry.sdk.extension.aws.resource;
import javax.annotation.ParametersAreNonnullByDefault;

View File

@ -1,59 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.sdk.extension.aws.trace;
import io.opentelemetry.api.trace.TraceId;
import io.opentelemetry.sdk.trace.IdGenerator;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
/**
* Generates tracing ids compatible with the AWS X-Ray tracing service. In the X-Ray system the
* first 32 bits of the trace id are the Unix epoch time in secords. Spans (AWS calls them segments)
* submit with trace id timestamps outside of the last 30 days are rejected.
*
* @see <a
* href="https://docs.aws.amazon.com/xray/latest/devguide/xray-api-sendingdata.html#xray-api-traceids">Generating
* Trace IDs</a>
* @deprecated Use the AwsXrayIdGenerator provided in the <a
* href="https://github.com/open-telemetry/opentelemetry-java-contrib/tree/main/aws-xray">
* io.opentelemetry.contrib:opentelemetry-aws-xray</a> artifact instead of this one.
*/
@Deprecated
public final class AwsXrayIdGenerator implements IdGenerator {
private static final AwsXrayIdGenerator INSTANCE = new AwsXrayIdGenerator();
private static final IdGenerator RANDOM_ID_GENERATOR = IdGenerator.random();
/** Returns a singleton instance of {@link AwsXrayIdGenerator}. */
public static AwsXrayIdGenerator getInstance() {
return INSTANCE;
}
@Override
public String generateSpanId() {
return RANDOM_ID_GENERATOR.generateSpanId();
}
@Override
public String generateTraceId() {
// hi - 4 bytes timestamp, 4 bytes random
// low - 8 bytes random.
// Since we include timestamp, impossible to be invalid.
Random random = ThreadLocalRandom.current();
long timestampSecs = TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis());
long hiRandom = random.nextInt() & 0xFFFFFFFFL;
long lowRandom = random.nextLong();
return TraceId.fromLongs(timestampSecs << 32 | hiRandom, lowRandom);
}
private AwsXrayIdGenerator() {}
}

View File

@ -1,10 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
/** Provides implementations of SDK interfaces which integrate natively with AWS infrastructure. */
@ParametersAreNonnullByDefault
package io.opentelemetry.sdk.extension.aws.trace;
import javax.annotation.ParametersAreNonnullByDefault;

View File

@ -1,5 +0,0 @@
io.opentelemetry.sdk.extension.aws.resource.BeanstalkResourceProvider
io.opentelemetry.sdk.extension.aws.resource.Ec2ResourceProvider
io.opentelemetry.sdk.extension.aws.resource.EcsResourceProvider
io.opentelemetry.sdk.extension.aws.resource.EksResourceProvider
io.opentelemetry.sdk.extension.aws.resource.LambdaResourceProvider

View File

@ -1,72 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.sdk.extension.aws.resource;
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat;
import static org.assertj.core.api.Assertions.entry;
import com.google.common.base.Charsets;
import com.google.common.io.Files;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.internal.testing.slf4j.SuppressLogger;
import io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.semconv.resource.attributes.ResourceAttributes;
import java.io.File;
import java.io.IOException;
import java.util.ServiceLoader;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
@SuppressWarnings("deprecation") // Moved to contrib
class BeanstalkResourceTest {
@Test
void testCreateAttributes(@TempDir File tempFolder) throws IOException {
File file = new File(tempFolder, "beanstalk.config");
String content =
"{\"noise\": \"noise\", \"deployment_id\":4,\""
+ "version_label\":\"2\",\"environment_name\":\"HttpSubscriber-env\"}";
Files.write(content.getBytes(Charsets.UTF_8), file);
Resource resource = BeanstalkResource.buildResource(file.getPath());
Attributes attributes = resource.getAttributes();
assertThat(attributes)
.containsOnly(
entry(ResourceAttributes.CLOUD_PROVIDER, "aws"),
entry(ResourceAttributes.CLOUD_PLATFORM, "aws_elastic_beanstalk"),
entry(ResourceAttributes.SERVICE_INSTANCE_ID, "4"),
entry(ResourceAttributes.SERVICE_VERSION, "2"),
entry(ResourceAttributes.SERVICE_NAMESPACE, "HttpSubscriber-env"));
assertThat(resource.getSchemaUrl()).isEqualTo(ResourceAttributes.SCHEMA_URL);
}
@Test
void testConfigFileMissing() {
Attributes attributes =
BeanstalkResource.buildResource("a_file_never_existing").getAttributes();
assertThat(attributes).isEmpty();
}
@Test
@SuppressLogger(BeanstalkResource.class)
void testBadConfigFile(@TempDir File tempFolder) throws IOException {
File file = new File(tempFolder, "beanstalk.config");
String content =
"\"deployment_id\":4,\"version_label\":\"2\",\""
+ "environment_name\":\"HttpSubscriber-env\"}";
Files.write(content.getBytes(Charsets.UTF_8), file);
Attributes attributes = BeanstalkResource.buildResource(file.getPath()).getAttributes();
assertThat(attributes).isEmpty();
}
@Test
void inServiceLoader() {
// No practical way to test the attributes themselves so at least check the service loader picks
// it up.
assertThat(ServiceLoader.load(ResourceProvider.class))
.anyMatch(BeanstalkResourceProvider.class::isInstance);
}
}

View File

@ -1,47 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.sdk.extension.aws.resource;
import static org.assertj.core.api.Assertions.assertThat;
import com.google.common.base.Charsets;
import com.google.common.io.Files;
import io.opentelemetry.internal.testing.slf4j.SuppressLogger;
import java.io.File;
import java.io.IOException;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
class DockerHelperTest {
@Test
@SuppressLogger(DockerHelper.class)
void testCgroupFileMissing() {
DockerHelper dockerHelper = new DockerHelper("a_file_never_existing");
assertThat(dockerHelper.getContainerId()).isEmpty();
}
@Test
void testContainerIdMissing(@TempDir File tempFolder) throws IOException {
File file = new File(tempFolder, "no_container_id");
String content = "13:pids:/\n" + "12:hugetlb:/\n" + "11:net_prio:/";
Files.write(content.getBytes(Charsets.UTF_8), file);
DockerHelper dockerHelper = new DockerHelper(file.getPath());
assertThat(dockerHelper.getContainerId()).isEmpty();
}
@Test
void testGetContainerId(@TempDir File tempFolder) throws IOException {
File file = new File(tempFolder, "cgroup");
String expected = "386a1920640799b5bf5a39bd94e489e5159a88677d96ca822ce7c433ff350163";
String content = "dummy\n11:devices:/ecs/bbc36dd0-5ee0-4007-ba96-c590e0b278d2/" + expected;
Files.write(content.getBytes(Charsets.UTF_8), file);
DockerHelper dockerHelper = new DockerHelper(file.getPath());
assertThat(dockerHelper.getContainerId()).isEqualTo(expected);
}
}

View File

@ -1,142 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.sdk.extension.aws.resource;
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat;
import static org.assertj.core.api.Assertions.entry;
import com.linecorp.armeria.common.AggregatedHttpRequest;
import com.linecorp.armeria.common.HttpResponse;
import com.linecorp.armeria.common.HttpStatus;
import com.linecorp.armeria.common.MediaType;
import com.linecorp.armeria.testing.junit5.server.mock.MockWebServerExtension;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.internal.testing.slf4j.SuppressLogger;
import io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.semconv.resource.attributes.ResourceAttributes;
import java.util.ServiceLoader;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
@SuppressWarnings("deprecation") // Moved to contrib
class Ec2ResourceTest {
// From https://docs.amazonaws.cn/en_us/AWSEC2/latest/UserGuide/instance-identity-documents.html
private static final String IDENTITY_DOCUMENT =
"{\n"
+ " \"devpayProductCodes\" : null,\n"
+ " \"marketplaceProductCodes\" : [ \"1abc2defghijklm3nopqrs4tu\" ], \n"
+ " \"availabilityZone\" : \"us-west-2b\",\n"
+ " \"privateIp\" : \"10.158.112.84\",\n"
+ " \"version\" : \"2017-09-30\",\n"
+ " \"instanceId\" : \"i-1234567890abcdef0\",\n"
+ " \"billingProducts\" : null,\n"
+ " \"instanceType\" : \"t2.micro\",\n"
+ " \"accountId\" : \"123456789012\",\n"
+ " \"imageId\" : \"ami-5fb8c835\",\n"
+ " \"pendingTime\" : \"2016-11-19T16:32:11Z\",\n"
+ " \"architecture\" : \"x86_64\",\n"
+ " \"kernelId\" : null,\n"
+ " \"ramdiskId\" : null,\n"
+ " \"region\" : \"us-west-2\"\n"
+ "}";
@RegisterExtension public static MockWebServerExtension server = new MockWebServerExtension();
@Test
void imdsv2() {
server.enqueue(HttpResponse.of("token"));
server.enqueue(HttpResponse.of(MediaType.JSON_UTF_8, IDENTITY_DOCUMENT));
server.enqueue(HttpResponse.of("ec2-1-2-3-4"));
Resource resource = Ec2Resource.buildResource("localhost:" + server.httpPort());
assertThat(resource.getSchemaUrl()).isEqualTo(ResourceAttributes.SCHEMA_URL);
Attributes attributes = resource.getAttributes();
assertThat(attributes)
.containsOnly(
entry(ResourceAttributes.CLOUD_PROVIDER, "aws"),
entry(ResourceAttributes.CLOUD_PLATFORM, "aws_ec2"),
entry(ResourceAttributes.HOST_ID, "i-1234567890abcdef0"),
entry(ResourceAttributes.CLOUD_AVAILABILITY_ZONE, "us-west-2b"),
entry(ResourceAttributes.HOST_TYPE, "t2.micro"),
entry(ResourceAttributes.HOST_IMAGE_ID, "ami-5fb8c835"),
entry(ResourceAttributes.CLOUD_ACCOUNT_ID, "123456789012"),
entry(ResourceAttributes.CLOUD_REGION, "us-west-2"),
entry(ResourceAttributes.HOST_NAME, "ec2-1-2-3-4"));
AggregatedHttpRequest request1 = server.takeRequest().request();
assertThat(request1.path()).isEqualTo("/latest/api/token");
assertThat(request1.headers().get("X-aws-ec2-metadata-token-ttl-seconds")).isEqualTo("60");
AggregatedHttpRequest request2 = server.takeRequest().request();
assertThat(request2.path()).isEqualTo("/latest/dynamic/instance-identity/document");
assertThat(request2.headers().get("X-aws-ec2-metadata-token")).isEqualTo("token");
AggregatedHttpRequest request3 = server.takeRequest().request();
assertThat(request3.path()).isEqualTo("/latest/meta-data/hostname");
assertThat(request3.headers().get("X-aws-ec2-metadata-token")).isEqualTo("token");
}
@Test
void imdsv1() {
server.enqueue(HttpResponse.of(HttpStatus.NOT_FOUND));
server.enqueue(HttpResponse.of(MediaType.JSON_UTF_8, IDENTITY_DOCUMENT));
server.enqueue(HttpResponse.of("ec2-1-2-3-4"));
Resource resource = Ec2Resource.buildResource("localhost:" + server.httpPort());
assertThat(resource.getSchemaUrl()).isEqualTo(ResourceAttributes.SCHEMA_URL);
Attributes attributes = resource.getAttributes();
assertThat(attributes)
.containsOnly(
entry(ResourceAttributes.CLOUD_PROVIDER, "aws"),
entry(ResourceAttributes.CLOUD_PLATFORM, "aws_ec2"),
entry(ResourceAttributes.HOST_ID, "i-1234567890abcdef0"),
entry(ResourceAttributes.CLOUD_AVAILABILITY_ZONE, "us-west-2b"),
entry(ResourceAttributes.HOST_TYPE, "t2.micro"),
entry(ResourceAttributes.HOST_IMAGE_ID, "ami-5fb8c835"),
entry(ResourceAttributes.CLOUD_ACCOUNT_ID, "123456789012"),
entry(ResourceAttributes.CLOUD_REGION, "us-west-2"),
entry(ResourceAttributes.HOST_NAME, "ec2-1-2-3-4"));
AggregatedHttpRequest request1 = server.takeRequest().request();
assertThat(request1.path()).isEqualTo("/latest/api/token");
assertThat(request1.headers().get("X-aws-ec2-metadata-token-ttl-seconds")).isEqualTo("60");
AggregatedHttpRequest request2 = server.takeRequest().request();
assertThat(request2.path()).isEqualTo("/latest/dynamic/instance-identity/document");
assertThat(request2.headers().get("X-aws-ec2-metadata-token")).isNull();
}
@Test
@SuppressLogger(Ec2Resource.class)
void badJson() {
server.enqueue(HttpResponse.of(HttpStatus.NOT_FOUND));
server.enqueue(HttpResponse.of(MediaType.JSON_UTF_8, "I'm not JSON"));
Attributes attributes =
Ec2Resource.buildResource("localhost:" + server.httpPort()).getAttributes();
assertThat(attributes).isEmpty();
AggregatedHttpRequest request1 = server.takeRequest().request();
assertThat(request1.path()).isEqualTo("/latest/api/token");
assertThat(request1.headers().get("X-aws-ec2-metadata-token-ttl-seconds")).isEqualTo("60");
AggregatedHttpRequest request2 = server.takeRequest().request();
assertThat(request2.path()).isEqualTo("/latest/dynamic/instance-identity/document");
assertThat(request2.headers().get("X-aws-ec2-metadata-token")).isNull();
}
@Test
void inServiceLoader() {
// No practical way to test the attributes themselves so at least check the service loader picks
// it up.
assertThat(ServiceLoader.load(ResourceProvider.class))
.anyMatch(Ec2ResourceProvider.class::isInstance);
}
}

View File

@ -1,144 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.sdk.extension.aws.resource;
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat;
import static org.assertj.core.api.Assertions.entry;
import static org.mockito.Mockito.when;
import com.google.common.io.Resources;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.semconv.resource.attributes.ResourceAttributes;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.ServiceLoader;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
@SuppressWarnings("deprecation") // Moved to contrib
@ExtendWith(MockitoExtension.class)
class EcsResourceTest {
private static final String ECS_METADATA_KEY_V4 = "ECS_CONTAINER_METADATA_URI_V4";
private static final String ECS_METADATA_KEY_V3 = "ECS_CONTAINER_METADATA_URI";
@Mock private SimpleHttpClient mockHttpClient;
@Test
void testCreateAttributesV3() throws IOException {
Map<String, String> mockSysEnv = new HashMap<>();
mockSysEnv.put(ECS_METADATA_KEY_V3, "ecs_metadata_v3_uri");
when(mockHttpClient.fetchString("GET", "ecs_metadata_v3_uri", Collections.emptyMap(), null))
.thenReturn(readResourceJson("ecs-container-metadata-v3.json"));
when(mockHttpClient.fetchString(
"GET", "ecs_metadata_v3_uri/task", Collections.emptyMap(), null))
.thenReturn(readResourceJson("ecs-task-metadata-v3.json"));
Resource resource = EcsResource.buildResource(mockSysEnv, mockHttpClient);
Attributes attributes = resource.getAttributes();
assertThat(resource.getSchemaUrl()).isEqualTo(ResourceAttributes.SCHEMA_URL);
assertThat(attributes)
.containsOnly(
entry(ResourceAttributes.CLOUD_PROVIDER, "aws"),
entry(ResourceAttributes.CLOUD_PLATFORM, "aws_ecs"),
entry(ResourceAttributes.CONTAINER_NAME, "ecs-nginx-5-nginx-curl-ccccb9f49db0dfe0d901"),
entry(
ResourceAttributes.CONTAINER_ID,
"43481a6ce4842eec8fe72fc28500c6b52edcc0917f105b83379f88cac1ff3946"),
entry(ResourceAttributes.CONTAINER_IMAGE_NAME, "nrdlngr/nginx-curl"),
entry(ResourceAttributes.CONTAINER_IMAGE_TAG, "latest"),
entry(
AttributeKey.stringKey("aws.ecs.container.image.id"),
"sha256:2e00ae64383cfc865ba0a2ba37f61b50a120d2d9378559dcd458dc0de47bc165"),
entry(
ResourceAttributes.AWS_ECS_TASK_ARN,
"arn:aws:ecs:us-east-2:012345678910:task/9781c248-0edd-4cdb-9a93-f63cb662a5d3"),
entry(ResourceAttributes.AWS_ECS_TASK_FAMILY, "nginx"),
entry(ResourceAttributes.AWS_ECS_TASK_REVISION, "5"));
}
@Test
void testCreateAttributesV4() throws IOException {
Map<String, String> mockSysEnv = new HashMap<>();
mockSysEnv.put(ECS_METADATA_KEY_V4, "ecs_metadata_v4_uri");
when(mockHttpClient.fetchString("GET", "ecs_metadata_v4_uri", Collections.emptyMap(), null))
.thenReturn(readResourceJson("ecs-container-metadata-v4.json"));
when(mockHttpClient.fetchString(
"GET", "ecs_metadata_v4_uri/task", Collections.emptyMap(), null))
.thenReturn(readResourceJson("ecs-task-metadata-v4.json"));
Resource resource = EcsResource.buildResource(mockSysEnv, mockHttpClient);
Attributes attributes = resource.getAttributes();
assertThat(resource.getSchemaUrl()).isEqualTo(ResourceAttributes.SCHEMA_URL);
assertThat(attributes)
.containsOnly(
entry(ResourceAttributes.CLOUD_PROVIDER, "aws"),
entry(ResourceAttributes.CLOUD_PLATFORM, "aws_ecs"),
entry(ResourceAttributes.CONTAINER_NAME, "ecs-curltest-26-curl-cca48e8dcadd97805600"),
entry(
ResourceAttributes.CONTAINER_ID,
"ea32192c8553fbff06c9340478a2ff089b2bb5646fb718b4ee206641c9086d66"),
entry(
ResourceAttributes.CONTAINER_IMAGE_NAME,
"111122223333.dkr.ecr.us-west-2.amazonaws.com/curltest"),
entry(ResourceAttributes.CONTAINER_IMAGE_TAG, "latest"),
entry(
AttributeKey.stringKey("aws.ecs.container.image.id"),
"sha256:d691691e9652791a60114e67b365688d20d19940dde7c4736ea30e660d8d3553"),
entry(
ResourceAttributes.AWS_ECS_CONTAINER_ARN,
"arn:aws:ecs:us-west-2:111122223333:container/0206b271-b33f-47ab-86c6-a0ba208a70a9"),
entry(
ResourceAttributes.AWS_LOG_GROUP_NAMES, Collections.singletonList("/ecs/metadata")),
entry(
ResourceAttributes.AWS_LOG_GROUP_ARNS,
Collections.singletonList(
"arn:aws:logs:us-west-2:111122223333:log-group:/ecs/metadata")),
entry(
ResourceAttributes.AWS_LOG_STREAM_NAMES,
Collections.singletonList("ecs/curl/8f03e41243824aea923aca126495f665")),
entry(
ResourceAttributes.AWS_LOG_STREAM_ARNS,
Collections.singletonList(
"arn:aws:logs:us-west-2:111122223333:log-group:/ecs/metadata:log-stream:ecs/curl/8f03e41243824aea923aca126495f665")),
entry(
ResourceAttributes.AWS_ECS_TASK_ARN,
"arn:aws:ecs:us-west-2:111122223333:task/default/158d1c8083dd49d6b527399fd6414f5c"),
entry(ResourceAttributes.AWS_ECS_LAUNCHTYPE, "ec2"),
entry(ResourceAttributes.AWS_ECS_TASK_FAMILY, "curltest"),
entry(ResourceAttributes.AWS_ECS_TASK_REVISION, "26"));
}
@Test
void testNotOnEcs() {
Map<String, String> mockSysEnv = new HashMap<>();
mockSysEnv.put(ECS_METADATA_KEY_V3, "");
mockSysEnv.put(ECS_METADATA_KEY_V4, "");
Attributes attributes = EcsResource.buildResource(mockSysEnv, mockHttpClient).getAttributes();
assertThat(attributes).isEmpty();
}
@Test
void inServiceLoader() {
// No practical way to test the attributes themselves so at least check the service loader picks
// it up.
assertThat(ServiceLoader.load(ResourceProvider.class))
.anyMatch(EcsResourceProvider.class::isInstance);
}
String readResourceJson(String resourceName) throws IOException {
return Resources.toString(Resources.getResource(resourceName), StandardCharsets.UTF_8);
}
}

View File

@ -1,97 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.sdk.extension.aws.resource;
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat;
import static org.assertj.core.api.Assertions.entry;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
import com.google.common.base.Charsets;
import com.google.common.io.Files;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.internal.testing.slf4j.SuppressLogger;
import io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.semconv.resource.attributes.ResourceAttributes;
import java.io.File;
import java.io.IOException;
import java.util.ServiceLoader;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.api.io.TempDir;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
@SuppressWarnings("deprecation") // Moved to contrib
@ExtendWith(MockitoExtension.class)
public class EksResourceTest {
@Mock private DockerHelper mockDockerHelper;
@Mock private SimpleHttpClient httpClient;
@Test
@SuppressLogger(EksResource.class)
void testEks(@TempDir File tempFolder) throws IOException {
File mockK8sTokenFile = new File(tempFolder, "k8sToken");
String token = "token123";
Files.write(token.getBytes(Charsets.UTF_8), mockK8sTokenFile);
File mockK8sKeystoreFile = new File(tempFolder, "k8sCert");
String truststore = "truststore123";
Files.write(truststore.getBytes(Charsets.UTF_8), mockK8sKeystoreFile);
when(httpClient.fetchString(
any(),
Mockito.eq(
io.opentelemetry.sdk.extension.aws.resource.EksResource.K8S_SVC_URL
+ io.opentelemetry.sdk.extension.aws.resource.EksResource.AUTH_CONFIGMAP_PATH),
any(),
any()))
.thenReturn("not empty");
when(httpClient.fetchString(
any(),
Mockito.eq(
io.opentelemetry.sdk.extension.aws.resource.EksResource.K8S_SVC_URL
+ io.opentelemetry.sdk.extension.aws.resource.EksResource.CW_CONFIGMAP_PATH),
any(),
any()))
.thenReturn("{\"data\":{\"cluster.name\":\"my-cluster\"}}");
when(mockDockerHelper.getContainerId()).thenReturn("0123456789A");
Resource eksResource =
EksResource.buildResource(
httpClient,
mockDockerHelper,
mockK8sTokenFile.getPath(),
mockK8sKeystoreFile.getPath());
Attributes attributes = eksResource.getAttributes();
assertThat(eksResource.getSchemaUrl()).isEqualTo(ResourceAttributes.SCHEMA_URL);
assertThat(attributes)
.containsOnly(
entry(ResourceAttributes.CLOUD_PROVIDER, "aws"),
entry(ResourceAttributes.CLOUD_PLATFORM, "aws_eks"),
entry(ResourceAttributes.K8S_CLUSTER_NAME, "my-cluster"),
entry(ResourceAttributes.CONTAINER_ID, "0123456789A"));
}
@Test
void testNotEks() {
Resource eksResource = EksResource.buildResource(httpClient, mockDockerHelper, "", "");
Attributes attributes = eksResource.getAttributes();
assertThat(attributes).isEmpty();
}
@Test
void inServiceLoader() {
// No practical way to test the attributes themselves so at least check the service loader picks
// it up.
assertThat(ServiceLoader.load(ResourceProvider.class))
.anyMatch(EksResourceProvider.class::isInstance);
}
}

View File

@ -1,71 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.sdk.extension.aws.resource;
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat;
import static java.util.Collections.emptyMap;
import static java.util.Collections.singletonMap;
import static org.assertj.core.api.Assertions.entry;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.semconv.resource.attributes.ResourceAttributes;
import java.util.HashMap;
import java.util.Map;
import java.util.ServiceLoader;
import org.junit.jupiter.api.Test;
@SuppressWarnings("deprecation") // Moved to contrib
class LambdaResourceTest {
@Test
void shouldNotCreateResourceForNotLambda() {
Attributes attributes = LambdaResource.buildResource(emptyMap()).getAttributes();
assertThat(attributes).isEmpty();
}
@Test
void shouldAddNonEmptyAttributes() {
Resource resource =
LambdaResource.buildResource(singletonMap("AWS_LAMBDA_FUNCTION_NAME", "my-function"));
Attributes attributes = resource.getAttributes();
assertThat(resource.getSchemaUrl()).isEqualTo(ResourceAttributes.SCHEMA_URL);
assertThat(attributes)
.containsOnly(
entry(ResourceAttributes.CLOUD_PROVIDER, "aws"),
entry(ResourceAttributes.CLOUD_PLATFORM, "aws_lambda"),
entry(ResourceAttributes.FAAS_NAME, "my-function"));
}
@Test
void shouldAddAllAttributes() {
Map<String, String> envVars = new HashMap<>();
envVars.put("AWS_REGION", "us-east-1");
envVars.put("AWS_LAMBDA_FUNCTION_NAME", "my-function");
envVars.put("AWS_LAMBDA_FUNCTION_VERSION", "1.2.3");
Resource resource = LambdaResource.buildResource(envVars);
Attributes attributes = resource.getAttributes();
assertThat(resource.getSchemaUrl()).isEqualTo(ResourceAttributes.SCHEMA_URL);
assertThat(attributes)
.containsOnly(
entry(ResourceAttributes.CLOUD_PROVIDER, "aws"),
entry(ResourceAttributes.CLOUD_PLATFORM, "aws_lambda"),
entry(ResourceAttributes.CLOUD_REGION, "us-east-1"),
entry(ResourceAttributes.FAAS_NAME, "my-function"),
entry(ResourceAttributes.FAAS_VERSION, "1.2.3"));
}
@Test
void inServiceLoader() {
// No practical way to test the attributes themselves so at least check the service loader picks
// it up.
assertThat(ServiceLoader.load(ResourceProvider.class))
.anyMatch(LambdaResourceProvider.class::isInstance);
}
}

View File

@ -1,115 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.sdk.extension.aws.resource;
import static org.assertj.core.api.Assertions.assertThat;
import com.google.common.collect.ImmutableMap;
import com.linecorp.armeria.common.AggregatedHttpRequest;
import com.linecorp.armeria.common.HttpResponse;
import com.linecorp.armeria.server.ServerBuilder;
import com.linecorp.armeria.testing.junit5.server.SelfSignedCertificateExtension;
import com.linecorp.armeria.testing.junit5.server.ServerExtension;
import com.linecorp.armeria.testing.junit5.server.mock.MockWebServerExtension;
import io.opentelemetry.internal.testing.slf4j.SuppressLogger;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collections;
import java.util.Map;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.junit.jupiter.api.io.TempDir;
class SimpleHttpClientTest {
@RegisterExtension public static MockWebServerExtension server = new MockWebServerExtension();
@Test
void testFetchString() {
server.enqueue(HttpResponse.of("expected result"));
Map<String, String> requestPropertyMap = ImmutableMap.of("key1", "value1", "key2", "value2");
String urlStr = String.format("http://localhost:%s%s", server.httpPort(), "/path");
SimpleHttpClient httpClient = new SimpleHttpClient();
String result = httpClient.fetchString("GET", urlStr, requestPropertyMap, null);
assertThat(result).isEqualTo("expected result");
AggregatedHttpRequest request1 = server.takeRequest().request();
assertThat(request1.path()).isEqualTo("/path");
assertThat(request1.headers().get("key1")).isEqualTo("value1");
assertThat(request1.headers().get("key2")).isEqualTo("value2");
}
@Test
void testFailedFetchString() {
Map<String, String> requestPropertyMap = ImmutableMap.of("key1", "value1", "key2", "value2");
String urlStr = String.format("http://localhost:%s%s", server.httpPort(), "/path");
SimpleHttpClient httpClient = new SimpleHttpClient();
String result = httpClient.fetchString("GET", urlStr, requestPropertyMap, null);
assertThat(result).isEmpty();
}
static class HttpsServerTest {
@RegisterExtension
@Order(1)
public static SelfSignedCertificateExtension certificate = new SelfSignedCertificateExtension();
@RegisterExtension
@Order(2)
public static ServerExtension server =
new ServerExtension() {
@Override
protected void configure(ServerBuilder sb) {
sb.tls(certificate.certificateFile(), certificate.privateKeyFile());
sb.service("/", (ctx, req) -> HttpResponse.of("Thanks for trusting me"));
}
};
@Test
void goodCert() {
SimpleHttpClient httpClient = new SimpleHttpClient();
String result =
httpClient.fetchString(
"GET",
"https://localhost:" + server.httpsPort() + "/",
Collections.emptyMap(),
certificate.certificateFile().getAbsolutePath());
assertThat(result).isEqualTo("Thanks for trusting me");
}
@Test
@SuppressLogger(SimpleHttpClient.class)
void missingCert() {
SimpleHttpClient httpClient = new SimpleHttpClient();
String result =
httpClient.fetchString(
"GET",
"https://localhost:" + server.httpsPort() + "/",
Collections.emptyMap(),
"/foo/bar/bad");
assertThat(result).isEmpty();
}
@Test
@SuppressLogger(SimpleHttpClient.class)
void badCert(@TempDir Path tempDir) throws Exception {
Path certFile = tempDir.resolve("test.crt");
Files.write(certFile, "bad cert".getBytes(StandardCharsets.UTF_8));
SimpleHttpClient httpClient = new SimpleHttpClient();
String result =
httpClient.fetchString(
"GET",
"https://localhost:" + server.httpsPort() + "/",
Collections.emptyMap(),
certFile.toString());
assertThat(result).isEmpty();
}
}
}

View File

@ -1,104 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.sdk.extension.aws.trace;
import static org.assertj.core.api.Assertions.assertThat;
import io.opentelemetry.api.trace.SpanId;
import io.opentelemetry.api.trace.TraceId;
import io.opentelemetry.sdk.trace.IdGenerator;
import java.util.Set;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import org.junit.jupiter.api.Test;
/** Unit tests for {@link AwsXrayIdGenerator}. */
@SuppressWarnings("deprecation") // Moved to contrib
class AwsXRayIdGeneratorTest {
@Test
void shouldGenerateValidIds() {
AwsXrayIdGenerator generator = AwsXrayIdGenerator.getInstance();
for (int i = 0; i < 1000; i++) {
String traceId = generator.generateTraceId();
assertThat(TraceId.isValid(traceId)).isTrue();
String spanId = generator.generateSpanId();
assertThat(SpanId.isValid(spanId)).isTrue();
}
}
@Test
void shouldGenerateTraceIdsWithTimestampsWithAllowedXrayTimeRange() {
AwsXrayIdGenerator generator = AwsXrayIdGenerator.getInstance();
for (int i = 0; i < 1000; i++) {
String traceId = generator.generateTraceId();
long unixSeconds = Long.valueOf(traceId.subSequence(0, 8).toString(), 16);
long ts = unixSeconds * 1000L;
long currentTs = System.currentTimeMillis();
assertThat(ts).isLessThanOrEqualTo(currentTs);
long month = 86400000L * 30L;
assertThat(ts).isGreaterThan(currentTs - month);
}
}
@Test
void shouldGenerateUniqueIdsInMultithreadedEnvironment()
throws BrokenBarrierException, InterruptedException {
AwsXrayIdGenerator generator = AwsXrayIdGenerator.getInstance();
Set<String> traceIds = new CopyOnWriteArraySet<>();
Set<String> spanIds = new CopyOnWriteArraySet<>();
int threads = 8;
int generations = 128;
CyclicBarrier barrier = new CyclicBarrier(threads + 1);
Executor executor = Executors.newFixedThreadPool(threads);
for (int i = 0; i < threads; i++) {
executor.execute(new GenerateRunner(generations, generator, barrier, traceIds, spanIds));
}
barrier.await();
barrier.await();
assertThat(traceIds).hasSize(threads * generations);
assertThat(spanIds).hasSize(threads * generations);
}
static class GenerateRunner implements Runnable {
private final int generations;
private final IdGenerator idsGenerator;
private final CyclicBarrier barrier;
private final Set<String> traceIds;
private final Set<String> spanIds;
GenerateRunner(
int generations,
IdGenerator idsGenerator,
CyclicBarrier barrier,
Set<String> traceIds,
Set<String> spanIds) {
this.generations = generations;
this.idsGenerator = idsGenerator;
this.barrier = barrier;
this.traceIds = traceIds;
this.spanIds = spanIds;
}
@Override
public void run() {
try {
barrier.await();
for (int i = 0; i < generations; i++) {
traceIds.add(idsGenerator.generateTraceId());
spanIds.add(idsGenerator.generateSpanId());
}
barrier.await();
} catch (InterruptedException | BrokenBarrierException cause) {
throw new IllegalStateException(cause);
}
}
}
}

View File

@ -1,31 +0,0 @@
{
"DockerId": "43481a6ce4842eec8fe72fc28500c6b52edcc0917f105b83379f88cac1ff3946",
"Name": "nginx-curl",
"DockerName": "ecs-nginx-5-nginx-curl-ccccb9f49db0dfe0d901",
"Image": "nrdlngr/nginx-curl",
"ImageID": "sha256:2e00ae64383cfc865ba0a2ba37f61b50a120d2d9378559dcd458dc0de47bc165",
"Labels": {
"com.amazonaws.ecs.cluster": "default",
"com.amazonaws.ecs.container-name": "nginx-curl",
"com.amazonaws.ecs.task-arn": "arn:aws:ecs:us-east-2:012345678910:task/9781c248-0edd-4cdb-9a93-f63cb662a5d3",
"com.amazonaws.ecs.task-definition-family": "nginx",
"com.amazonaws.ecs.task-definition-version": "5"
},
"DesiredStatus": "RUNNING",
"KnownStatus": "RUNNING",
"Limits": {
"CPU": 512,
"Memory": 512
},
"CreatedAt": "2018-02-01T20:55:10.554941919Z",
"StartedAt": "2018-02-01T20:55:11.064236631Z",
"Type": "NORMAL",
"Networks": [
{
"NetworkMode": "awsvpc",
"IPv4Addresses": [
"10.0.2.106"
]
}
]
}

View File

@ -1,44 +0,0 @@
{
"DockerId": "ea32192c8553fbff06c9340478a2ff089b2bb5646fb718b4ee206641c9086d66",
"Name": "curl",
"DockerName": "ecs-curltest-26-curl-cca48e8dcadd97805600",
"Image": "111122223333.dkr.ecr.us-west-2.amazonaws.com/curltest:latest",
"ImageID": "sha256:d691691e9652791a60114e67b365688d20d19940dde7c4736ea30e660d8d3553",
"Labels": {
"com.amazonaws.ecs.cluster": "default",
"com.amazonaws.ecs.container-name": "curl",
"com.amazonaws.ecs.task-arn": "arn:aws:ecs:us-west-2:111122223333:task/default/8f03e41243824aea923aca126495f665",
"com.amazonaws.ecs.task-definition-family": "curltest",
"com.amazonaws.ecs.task-definition-version": "26"
},
"DesiredStatus": "RUNNING",
"KnownStatus": "RUNNING",
"Limits": {
"CPU": 10,
"Memory": 128
},
"CreatedAt": "2020-10-02T00:15:07.620912337Z",
"StartedAt": "2020-10-02T00:15:08.062559351Z",
"Type": "NORMAL",
"LogDriver": "awslogs",
"LogOptions": {
"awslogs-create-group": "true",
"awslogs-group": "/ecs/metadata",
"awslogs-region": "us-west-2",
"awslogs-stream": "ecs/curl/8f03e41243824aea923aca126495f665"
},
"ContainerARN": "arn:aws:ecs:us-west-2:111122223333:container/0206b271-b33f-47ab-86c6-a0ba208a70a9",
"Networks": [
{
"NetworkMode": "awsvpc",
"IPv4Addresses": [
"10.0.2.100"
],
"AttachmentIndex": 0,
"MACAddress": "0e:9e:32:c7:48:85",
"IPv4SubnetCIDRBlock": "10.0.2.0/24",
"PrivateDNSName": "ip-10-0-2-100.us-west-2.compute.internal",
"SubnetGatewayIpv4Address": "10.0.2.1/24"
}
]
}

View File

@ -1,75 +0,0 @@
{
"Cluster": "default",
"TaskARN": "arn:aws:ecs:us-east-2:012345678910:task/9781c248-0edd-4cdb-9a93-f63cb662a5d3",
"Family": "nginx",
"Revision": "5",
"DesiredStatus": "RUNNING",
"KnownStatus": "RUNNING",
"Containers": [
{
"DockerId": "731a0d6a3b4210e2448339bc7015aaa79bfe4fa256384f4102db86ef94cbbc4c",
"Name": "~internal~ecs~pause",
"DockerName": "ecs-nginx-5-internalecspause-acc699c0cbf2d6d11700",
"Image": "amazon/amazon-ecs-pause:0.1.0",
"ImageID": "",
"Labels": {
"com.amazonaws.ecs.cluster": "default",
"com.amazonaws.ecs.container-name": "~internal~ecs~pause",
"com.amazonaws.ecs.task-arn": "arn:aws:ecs:us-east-2:012345678910:task/9781c248-0edd-4cdb-9a93-f63cb662a5d3",
"com.amazonaws.ecs.task-definition-family": "nginx",
"com.amazonaws.ecs.task-definition-version": "5"
},
"DesiredStatus": "RESOURCES_PROVISIONED",
"KnownStatus": "RESOURCES_PROVISIONED",
"Limits": {
"CPU": 0,
"Memory": 0
},
"CreatedAt": "2018-02-01T20:55:08.366329616Z",
"StartedAt": "2018-02-01T20:55:09.058354915Z",
"Type": "CNI_PAUSE",
"Networks": [
{
"NetworkMode": "awsvpc",
"IPv4Addresses": [
"10.0.2.106"
]
}
]
},
{
"DockerId": "43481a6ce4842eec8fe72fc28500c6b52edcc0917f105b83379f88cac1ff3946",
"Name": "nginx-curl",
"DockerName": "ecs-nginx-5-nginx-curl-ccccb9f49db0dfe0d901",
"Image": "nrdlngr/nginx-curl",
"ImageID": "sha256:2e00ae64383cfc865ba0a2ba37f61b50a120d2d9378559dcd458dc0de47bc165",
"Labels": {
"com.amazonaws.ecs.cluster": "default",
"com.amazonaws.ecs.container-name": "nginx-curl",
"com.amazonaws.ecs.task-arn": "arn:aws:ecs:us-east-2:012345678910:task/9781c248-0edd-4cdb-9a93-f63cb662a5d3",
"com.amazonaws.ecs.task-definition-family": "nginx",
"com.amazonaws.ecs.task-definition-version": "5"
},
"DesiredStatus": "RUNNING",
"KnownStatus": "RUNNING",
"Limits": {
"CPU": 512,
"Memory": 512
},
"CreatedAt": "2018-02-01T20:55:10.554941919Z",
"StartedAt": "2018-02-01T20:55:11.064236631Z",
"Type": "NORMAL",
"Networks": [
{
"NetworkMode": "awsvpc",
"IPv4Addresses": [
"10.0.2.106"
]
}
]
}
],
"PullStartedAt": "2018-02-01T20:55:09.372495529Z",
"PullStoppedAt": "2018-02-01T20:55:10.552018345Z",
"AvailabilityZone": "us-east-2b"
}

View File

@ -1,94 +0,0 @@
{
"Cluster": "default",
"TaskARN": "arn:aws:ecs:us-west-2:111122223333:task/default/158d1c8083dd49d6b527399fd6414f5c",
"Family": "curltest",
"Revision": "26",
"DesiredStatus": "RUNNING",
"KnownStatus": "RUNNING",
"PullStartedAt": "2020-10-02T00:43:06.202617438Z",
"PullStoppedAt": "2020-10-02T00:43:06.31288465Z",
"AvailabilityZone": "us-west-2d",
"LaunchType": "EC2",
"Containers": [
{
"DockerId": "598cba581fe3f939459eaba1e071d5c93bb2c49b7d1ba7db6bb19deeb70d8e38",
"Name": "~internal~ecs~pause",
"DockerName": "ecs-curltest-26-internalecspause-e292d586b6f9dade4a00",
"Image": "amazon/amazon-ecs-pause:0.1.0",
"ImageID": "",
"Labels": {
"com.amazonaws.ecs.cluster": "default",
"com.amazonaws.ecs.container-name": "~internal~ecs~pause",
"com.amazonaws.ecs.task-arn": "arn:aws:ecs:us-west-2:111122223333:task/default/158d1c8083dd49d6b527399fd6414f5c",
"com.amazonaws.ecs.task-definition-family": "curltest",
"com.amazonaws.ecs.task-definition-version": "26"
},
"DesiredStatus": "RESOURCES_PROVISIONED",
"KnownStatus": "RESOURCES_PROVISIONED",
"Limits": {
"CPU": 0,
"Memory": 0
},
"CreatedAt": "2020-10-02T00:43:05.602352471Z",
"StartedAt": "2020-10-02T00:43:06.076707576Z",
"Type": "CNI_PAUSE",
"Networks": [
{
"NetworkMode": "awsvpc",
"IPv4Addresses": [
"10.0.2.61"
],
"AttachmentIndex": 0,
"MACAddress": "0e:10:e2:01:bd:91",
"IPv4SubnetCIDRBlock": "10.0.2.0/24",
"PrivateDNSName": "ip-10-0-2-61.us-west-2.compute.internal",
"SubnetGatewayIpv4Address": "10.0.2.1/24"
}
]
},
{
"DockerId": "ee08638adaaf009d78c248913f629e38299471d45fe7dc944d1039077e3424ca",
"Name": "curl",
"DockerName": "ecs-curltest-26-curl-a0e7dba5aca6d8cb2e00",
"Image": "111122223333.dkr.ecr.us-west-2.amazonaws.com/curltest:latest",
"ImageID": "sha256:d691691e9652791a60114e67b365688d20d19940dde7c4736ea30e660d8d3553",
"Labels": {
"com.amazonaws.ecs.cluster": "default",
"com.amazonaws.ecs.container-name": "curl",
"com.amazonaws.ecs.task-arn": "arn:aws:ecs:us-west-2:111122223333:task/default/158d1c8083dd49d6b527399fd6414f5c",
"com.amazonaws.ecs.task-definition-family": "curltest",
"com.amazonaws.ecs.task-definition-version": "26"
},
"DesiredStatus": "RUNNING",
"KnownStatus": "RUNNING",
"Limits": {
"CPU": 10,
"Memory": 128
},
"CreatedAt": "2020-10-02T00:43:06.326590752Z",
"StartedAt": "2020-10-02T00:43:06.767535449Z",
"Type": "NORMAL",
"LogDriver": "awslogs",
"LogOptions": {
"awslogs-create-group": "true",
"awslogs-group": "/ecs/metadata",
"awslogs-region": "us-west-2",
"awslogs-stream": "ecs/curl/158d1c8083dd49d6b527399fd6414f5c"
},
"ContainerARN": "arn:aws:ecs:us-west-2:111122223333:container/abb51bdd-11b4-467f-8f6c-adcfe1fe059d",
"Networks": [
{
"NetworkMode": "awsvpc",
"IPv4Addresses": [
"10.0.2.61"
],
"AttachmentIndex": 0,
"MACAddress": "0e:10:e2:01:bd:91",
"IPv4SubnetCIDRBlock": "10.0.2.0/24",
"PrivateDNSName": "ip-10-0-2-61.us-west-2.compute.internal",
"SubnetGatewayIpv4Address": "10.0.2.1/24"
}
]
}
]
}

View File

@ -61,7 +61,6 @@ include(":sdk:trace")
include(":sdk:trace-shaded-deps")
include(":sdk-extensions:autoconfigure")
include(":sdk-extensions:autoconfigure-spi")
include(":sdk-extensions:aws")
include(":sdk-extensions:resources")
include(":sdk-extensions:incubator")
include(":sdk-extensions:jaeger-remote-sampler")