From 035b854764fbe765bde57be92f6708aae712dc73 Mon Sep 17 00:00:00 2001 From: Jack Berg Date: Mon, 24 Apr 2023 10:39:27 -0500 Subject: [PATCH 01/11] Initialize file configuration --- .../kotlin/otel.java-conventions.gradle.kts | 1 + sdk-extensions/incubator/build.gradle.kts | 58 ++++++++++++++++++- .../fileconfig/ConfigurationReader.java | 28 +++++++++ .../fileconfig/ConfigurationReaderTest.java | 26 +++++++++ settings.gradle.kts | 2 + 5 files changed, 114 insertions(+), 1 deletion(-) create mode 100644 sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReader.java create mode 100644 sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReaderTest.java diff --git a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts index 3686cb954e6..012fd75672f 100644 --- a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts @@ -1,4 +1,5 @@ import io.opentelemetry.gradle.OtelJavaExtension +import org.gradle.api.plugins.quality.internal.CheckstyleAction import org.gradle.api.tasks.testing.logging.TestExceptionFormat plugins { diff --git a/sdk-extensions/incubator/build.gradle.kts b/sdk-extensions/incubator/build.gradle.kts index 55d282f005c..ca60f607f00 100644 --- a/sdk-extensions/incubator/build.gradle.kts +++ b/sdk-extensions/incubator/build.gradle.kts @@ -1,9 +1,14 @@ +import de.undercouch.gradle.tasks.download.Download + plugins { id("otel.java-conventions") id("otel.publish-conventions") id("otel.jmh-conventions") id("otel.animalsniffer-conventions") + + id("de.undercouch.download") + id("org.jsonschema2pojo") } // SDK modules that are still being developed. @@ -22,12 +27,63 @@ dependencies { implementation(project(":sdk-extensions:autoconfigure-spi")) implementation("org.snakeyaml:snakeyaml-engine") - // io.opentelemetry.sdk.extension.trace.zpages + // io.opentelemetry.sdk.extension.incubator.trace.zpages implementation(project(":semconv")) compileOnly("com.sun.net.httpserver:http") + // io.opentelemetry.sdk.extension.incubator.fileconfig + implementation("com.fasterxml.jackson.core:jackson-databind") + implementation("com.fasterxml.jackson.dataformat:jackson-dataformat-yaml") + testImplementation(project(":sdk:testing")) testImplementation(project(":sdk-extensions:autoconfigure")) testImplementation("com.google.guava:guava-testlib") } + +val configurationRef = "74607f261e1f9a2ef356b7f87e394b6e9dd90285" +val configurationRepoZip = "https://github.com/open-telemetry/opentelemetry-configuration/archive/$configurationRef.zip" + +val downloadConfigurationSchema by tasks.registering(Download::class) { + src(configurationRepoZip) + dest("$buildDir/configuration/opentelemetry-configuration.zip") + overwrite(false) +} + +val downloadAndUnzipConfigurationSchema by tasks.registering(Copy::class) { + dependsOn("downloadConfigurationSchema") + from(zipTree(downloadConfigurationSchema.get().dest)) + eachFile(closureOf { + // Remove the top level folder "/opentelemetry-configuration-$configurationRef" + val pathParts = path.split("/") + path = pathParts.subList(1, pathParts.size).joinToString("/") + }) + into("$buildDir/configuration/") +} + +jsonSchema2Pojo { + sourceFiles = setOf(file("$buildDir/configuration/schema")) + targetDirectory = file("$buildDir/generated/sources/js2p/java/main") + targetPackage = "io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model" + includeSetters = false + removeOldOutput = true +} + +tasks.getByName("generateJsonSchema2Pojo").dependsOn(downloadAndUnzipConfigurationSchema) +tasks.getByName("sourcesJar").dependsOn("generateJsonSchema2Pojo") + +// Exclude jsonschema2pojo generated sources from checkstyle +tasks.named("checkstyleMain") { + exclude("**/fileconfig/internal/model/**") +} + +tasks { + withType().configureEach { + environment( + mapOf( + // Expose the kitchen sink example file to tests + "CONFIG_EXAMPLE_FILE" to "$buildDir/configuration/kitchen-sink-example.yaml" + ) + ) + } +} diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReader.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReader.java new file mode 100644 index 00000000000..b7828972f75 --- /dev/null +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReader.java @@ -0,0 +1,28 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.extension.incubator.fileconfig; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpentelemetryConfiguration; +import java.io.IOException; +import java.io.InputStream; + +class ConfigurationReader { + + private static final ObjectMapper MAPPER = new ObjectMapper(new YAMLFactory()); + + private ConfigurationReader() {} + + /** + * Parse the {@code configuration} YAML and return the {@link OpentelemetryConfiguration}. + * + * @throws IOException if unable to parse + */ + static OpentelemetryConfiguration parse(InputStream configuration) throws IOException { + return MAPPER.readValue(configuration, OpentelemetryConfiguration.class); + } +} diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReaderTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReaderTest.java new file mode 100644 index 00000000000..b41219b8fb1 --- /dev/null +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReaderTest.java @@ -0,0 +1,26 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.extension.incubator.fileconfig; + +import static org.assertj.core.api.Assertions.assertThat; + +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpentelemetryConfiguration; +import java.io.FileInputStream; +import java.io.IOException; +import org.junit.jupiter.api.Test; + +class ConfigurationReaderTest { + + @Test + void read_ExampleFile() throws IOException { + try (FileInputStream configExampleFile = + new FileInputStream(System.getenv("CONFIG_EXAMPLE_FILE"))) { + OpentelemetryConfiguration configuration = ConfigurationReader.parse(configExampleFile); + + assertThat(configuration.getFileFormat()).isEqualTo("0.1"); + } + } +} diff --git a/settings.gradle.kts b/settings.gradle.kts index 852875f8ddc..38a6a7d4199 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -3,6 +3,8 @@ pluginManagement { id("com.github.ben-manes.versions") version "0.46.0" id("com.github.johnrengelman.shadow") version "8.1.1" id("com.gradle.enterprise") version "3.13" + id("de.undercouch.download") version "5.4.0" + id("org.jsonschema2pojo") version "1.2.1" id("io.github.gradle-nexus.publish-plugin") version "1.3.0" id("org.graalvm.buildtools.native") version "0.9.21" } From 5366a079b225079a63fa0824e7de3ab55a110297 Mon Sep 17 00:00:00 2001 From: Jack Berg Date: Mon, 24 Apr 2023 19:30:24 -0500 Subject: [PATCH 02/11] Include providers --- sdk-extensions/incubator/build.gradle.kts | 4 ++-- .../incubator/fileconfig/ConfigurationReaderTest.java | 11 ++++++++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/sdk-extensions/incubator/build.gradle.kts b/sdk-extensions/incubator/build.gradle.kts index ca60f607f00..579015f5eee 100644 --- a/sdk-extensions/incubator/build.gradle.kts +++ b/sdk-extensions/incubator/build.gradle.kts @@ -41,7 +41,7 @@ dependencies { testImplementation("com.google.guava:guava-testlib") } -val configurationRef = "74607f261e1f9a2ef356b7f87e394b6e9dd90285" +val configurationRef = "d018613a1bbac1ca5bbd6edbc7e6effeab3a71d0" val configurationRepoZip = "https://github.com/open-telemetry/opentelemetry-configuration/archive/$configurationRef.zip" val downloadConfigurationSchema by tasks.registering(Download::class) { @@ -65,7 +65,7 @@ jsonSchema2Pojo { sourceFiles = setOf(file("$buildDir/configuration/schema")) targetDirectory = file("$buildDir/generated/sources/js2p/java/main") targetPackage = "io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model" - includeSetters = false + includeSetters = true removeOldOutput = true } diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReaderTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReaderTest.java index b41219b8fb1..62f733026d3 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReaderTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReaderTest.java @@ -7,7 +7,10 @@ import static org.assertj.core.api.Assertions.assertThat; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LoggerProvider; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MeterProvider; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpentelemetryConfiguration; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.TracerProvider; import java.io.FileInputStream; import java.io.IOException; import org.junit.jupiter.api.Test; @@ -16,11 +19,17 @@ class ConfigurationReaderTest { @Test void read_ExampleFile() throws IOException { + OpentelemetryConfiguration expected = new OpentelemetryConfiguration(); + expected.setFileFormat("0.1"); + expected.setTracerProvider(new TracerProvider()); + expected.setMeterProvider(new MeterProvider()); + expected.setLoggerProvider(new LoggerProvider()); + try (FileInputStream configExampleFile = new FileInputStream(System.getenv("CONFIG_EXAMPLE_FILE"))) { OpentelemetryConfiguration configuration = ConfigurationReader.parse(configExampleFile); - assertThat(configuration.getFileFormat()).isEqualTo("0.1"); + assertThat(configuration).isEqualTo(expected); } } } From 908256b8120ce709d911e5e96ae174d4abd4aa16 Mon Sep 17 00:00:00 2001 From: Jack Berg Date: Wed, 26 Apr 2023 07:43:50 -0500 Subject: [PATCH 03/11] limits --- sdk-extensions/incubator/build.gradle.kts | 4 +-- .../fileconfig/ConfigurationReaderTest.java | 32 +++++++++++++++++-- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/sdk-extensions/incubator/build.gradle.kts b/sdk-extensions/incubator/build.gradle.kts index 579015f5eee..3b6b4b72f0e 100644 --- a/sdk-extensions/incubator/build.gradle.kts +++ b/sdk-extensions/incubator/build.gradle.kts @@ -41,8 +41,8 @@ dependencies { testImplementation("com.google.guava:guava-testlib") } -val configurationRef = "d018613a1bbac1ca5bbd6edbc7e6effeab3a71d0" -val configurationRepoZip = "https://github.com/open-telemetry/opentelemetry-configuration/archive/$configurationRef.zip" +val configurationRef = "565af0d91f5fd3c1f01d9842d3ac6bc6068a7c00" +val configurationRepoZip = "https://github.com/jack-berg/opentelemetry-configuration/archive/$configurationRef.zip" val downloadConfigurationSchema by tasks.registering(Download::class) { src(configurationRepoZip) diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReaderTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReaderTest.java index 62f733026d3..b6410c52b2f 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReaderTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReaderTest.java @@ -7,9 +7,12 @@ import static org.assertj.core.api.Assertions.assertThat; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributeLimits; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordLimits; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LoggerProvider; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MeterProvider; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpentelemetryConfiguration; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanLimits; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.TracerProvider; import java.io.FileInputStream; import java.io.IOException; @@ -20,10 +23,35 @@ class ConfigurationReaderTest { @Test void read_ExampleFile() throws IOException { OpentelemetryConfiguration expected = new OpentelemetryConfiguration(); + expected.setFileFormat("0.1"); - expected.setTracerProvider(new TracerProvider()); + + AttributeLimits attributeLimits = new AttributeLimits(); + expected.setAttributeLimits(attributeLimits); + attributeLimits.setAttributeValueLengthLimit(4096); + attributeLimits.setAttributeCountLimit(128); + + TracerProvider tracerProvider = new TracerProvider(); + expected.setTracerProvider(tracerProvider); + + SpanLimits spanLimits = new SpanLimits(); + tracerProvider.setSpanLimits(spanLimits); + spanLimits.setAttributeValueLengthLimit(4096); + spanLimits.setAttributeCountLimit(128); + spanLimits.setEventCountLimit(128); + spanLimits.setLinkCountLimit(128); + spanLimits.setEventAttributeCountLimit(128); + spanLimits.setLinkAttributeCountLimit(128); + expected.setMeterProvider(new MeterProvider()); - expected.setLoggerProvider(new LoggerProvider()); + + LoggerProvider loggerProvider = new LoggerProvider(); + expected.setLoggerProvider(loggerProvider); + + LogRecordLimits logRecordLimits = new LogRecordLimits(); + loggerProvider.setLogRecordLimits(logRecordLimits); + logRecordLimits.setAttributeValueLengthLimit(4096); + logRecordLimits.setAttributeCountLimit(128); try (FileInputStream configExampleFile = new FileInputStream(System.getenv("CONFIG_EXAMPLE_FILE"))) { From 7fa20aa603753a916649c39ee6fa380ada18663b Mon Sep 17 00:00:00 2001 From: Jack Berg Date: Tue, 2 May 2023 10:27:14 -0500 Subject: [PATCH 04/11] Add resource configuration --- sdk-extensions/incubator/build.gradle.kts | 2 +- .../fileconfig/ConfigurationReaderTest.java | 14 +++++++++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/sdk-extensions/incubator/build.gradle.kts b/sdk-extensions/incubator/build.gradle.kts index 3b6b4b72f0e..9d18966e596 100644 --- a/sdk-extensions/incubator/build.gradle.kts +++ b/sdk-extensions/incubator/build.gradle.kts @@ -41,7 +41,7 @@ dependencies { testImplementation("com.google.guava:guava-testlib") } -val configurationRef = "565af0d91f5fd3c1f01d9842d3ac6bc6068a7c00" +val configurationRef = "280d92434e27b5a3385e527c51f84f5d90280321" val configurationRepoZip = "https://github.com/jack-berg/opentelemetry-configuration/archive/$configurationRef.zip" val downloadConfigurationSchema by tasks.registering(Download::class) { diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReaderTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReaderTest.java index b6410c52b2f..1bbf631dae7 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReaderTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReaderTest.java @@ -8,10 +8,12 @@ import static org.assertj.core.api.Assertions.assertThat; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributeLimits; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordLimits; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Attributes; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LoggerProvider; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogrecordLimits; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MeterProvider; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpentelemetryConfiguration; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Resource; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanLimits; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.TracerProvider; import java.io.FileInputStream; @@ -26,6 +28,12 @@ void read_ExampleFile() throws IOException { expected.setFileFormat("0.1"); + Resource resource = new Resource(); + expected.setResource(resource); + Attributes attributes = new Attributes(); + resource.setAttributes(attributes); + attributes.setServiceName("unknown_service"); + AttributeLimits attributeLimits = new AttributeLimits(); expected.setAttributeLimits(attributeLimits); attributeLimits.setAttributeValueLengthLimit(4096); @@ -48,8 +56,8 @@ void read_ExampleFile() throws IOException { LoggerProvider loggerProvider = new LoggerProvider(); expected.setLoggerProvider(loggerProvider); - LogRecordLimits logRecordLimits = new LogRecordLimits(); - loggerProvider.setLogRecordLimits(logRecordLimits); + LogrecordLimits logRecordLimits = new LogrecordLimits(); + loggerProvider.setLogrecordLimits(logRecordLimits); logRecordLimits.setAttributeValueLengthLimit(4096); logRecordLimits.setAttributeCountLimit(128); From 7a2db44d89c6dbce2eedb1cd88cef60dfe637c68 Mon Sep 17 00:00:00 2001 From: Jack Berg Date: Tue, 27 Jun 2023 12:46:12 -0500 Subject: [PATCH 05/11] wip --- sdk-extensions/incubator/build.gradle.kts | 2 +- .../fileconfig/ConfigurationReaderTest.java | 28 ++++++++++++++++++- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/sdk-extensions/incubator/build.gradle.kts b/sdk-extensions/incubator/build.gradle.kts index 9d18966e596..5383ba9c6a9 100644 --- a/sdk-extensions/incubator/build.gradle.kts +++ b/sdk-extensions/incubator/build.gradle.kts @@ -41,7 +41,7 @@ dependencies { testImplementation("com.google.guava:guava-testlib") } -val configurationRef = "280d92434e27b5a3385e527c51f84f5d90280321" +val configurationRef = "657d205466c36d5d0265c1469ca254540d6d4b3e" val configurationRepoZip = "https://github.com/jack-berg/opentelemetry-configuration/archive/$configurationRef.zip" val downloadConfigurationSchema by tasks.registering(Download::class) { diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReaderTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReaderTest.java index 1bbf631dae7..6a3a7bc438e 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReaderTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReaderTest.java @@ -7,6 +7,7 @@ import static org.assertj.core.api.Assertions.assertThat; +import com.google.common.collect.ImmutableMap; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributeLimits; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Attributes; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LoggerProvider; @@ -14,6 +15,7 @@ import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MeterProvider; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpentelemetryConfiguration; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Resource; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Sampler; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanLimits; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.TracerProvider; import java.io.FileInputStream; @@ -51,6 +53,28 @@ void read_ExampleFile() throws IOException { spanLimits.setEventAttributeCountLimit(128); spanLimits.setLinkAttributeCountLimit(128); + Sampler sampler = new Sampler(); + tracerProvider.setSampler(sampler); + sampler.setId("parent_based"); + Sampler rootSampler = new Sampler(); + rootSampler.setId("trace_id_ratio_based"); + sampler.setAdditionalProperty("root", ImmutableMap.of( + "id", "trace_id_ratio_based", + "ratio", 0.0001 + )); + sampler.setAdditionalProperty("remote_parent_sampled", ImmutableMap.of( + "id", "always_on" + )); + sampler.setAdditionalProperty("remote_parent_not_sampled", ImmutableMap.of( + "id", "always_off" + )); + sampler.setAdditionalProperty("local_parent_sampled", ImmutableMap.of( + "id", "always_on" + )); + sampler.setAdditionalProperty("local_parent_not_sampled", ImmutableMap.of( + "id", "always_off" + )); + expected.setMeterProvider(new MeterProvider()); LoggerProvider loggerProvider = new LoggerProvider(); @@ -65,7 +89,9 @@ void read_ExampleFile() throws IOException { new FileInputStream(System.getenv("CONFIG_EXAMPLE_FILE"))) { OpentelemetryConfiguration configuration = ConfigurationReader.parse(configExampleFile); - assertThat(configuration).isEqualTo(expected); + assertThat(configuration.getTracerProvider().getSampler()).isEqualTo(sampler); + + // assertThat(configuration).isEqualTo(expected); } } } From a7e944cdd3dd06bddb668bae2be4a11c7dcd0b4f Mon Sep 17 00:00:00 2001 From: Jack Berg Date: Tue, 11 Jul 2023 15:48:15 -0500 Subject: [PATCH 06/11] Reflect latest config --- sdk-extensions/incubator/build.gradle.kts | 3 +- .../fileconfig/ConfigurationReader.java | 17 +- .../fileconfig/ConfigurationReaderTest.java | 223 +++++++++++++++--- 3 files changed, 203 insertions(+), 40 deletions(-) diff --git a/sdk-extensions/incubator/build.gradle.kts b/sdk-extensions/incubator/build.gradle.kts index 5383ba9c6a9..43063b97a4f 100644 --- a/sdk-extensions/incubator/build.gradle.kts +++ b/sdk-extensions/incubator/build.gradle.kts @@ -34,6 +34,7 @@ dependencies { // io.opentelemetry.sdk.extension.incubator.fileconfig implementation("com.fasterxml.jackson.core:jackson-databind") implementation("com.fasterxml.jackson.dataformat:jackson-dataformat-yaml") + implementation("org.yaml:snakeyaml:1.31") testImplementation(project(":sdk:testing")) testImplementation(project(":sdk-extensions:autoconfigure")) @@ -41,7 +42,7 @@ dependencies { testImplementation("com.google.guava:guava-testlib") } -val configurationRef = "657d205466c36d5d0265c1469ca254540d6d4b3e" +val configurationRef = "ed331cd958eb2f6ee16dba3a42e2548e7801ade5" val configurationRepoZip = "https://github.com/jack-berg/opentelemetry-configuration/archive/$configurationRef.zip" val downloadConfigurationSchema by tasks.registering(Download::class) { diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReader.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReader.java index b7828972f75..76af698938f 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReader.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReader.java @@ -6,23 +6,20 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig; import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpentelemetryConfiguration; -import java.io.IOException; import java.io.InputStream; +import org.yaml.snakeyaml.Yaml; class ConfigurationReader { - private static final ObjectMapper MAPPER = new ObjectMapper(new YAMLFactory()); + private static final ObjectMapper MAPPER = new ObjectMapper(); + private static final Yaml YAML = new Yaml(); private ConfigurationReader() {} - /** - * Parse the {@code configuration} YAML and return the {@link OpentelemetryConfiguration}. - * - * @throws IOException if unable to parse - */ - static OpentelemetryConfiguration parse(InputStream configuration) throws IOException { - return MAPPER.readValue(configuration, OpentelemetryConfiguration.class); + /** Parse the {@code configuration} YAML and return the {@link OpentelemetryConfiguration}. */ + static OpentelemetryConfiguration parse(InputStream configuration) { + Object yamlObj = YAML.load(configuration); + return MAPPER.convertValue(yamlObj, OpentelemetryConfiguration.class); } } diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReaderTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReaderTest.java index 6a3a7bc438e..06f89c4f2fd 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReaderTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReaderTest.java @@ -7,19 +7,46 @@ import static org.assertj.core.api.Assertions.assertThat; -import com.google.common.collect.ImmutableMap; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Aggregation; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AlwaysOff; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AlwaysOn; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributeLimits; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Attributes; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.BatchLogRecordProcessor; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.BatchSpanProcessor; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Console; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExplicitBucketHistogram; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Headers; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordExporter; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordLimits; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordProcessor; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LoggerProvider; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogrecordLimits; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MeterProvider; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MetricExporter; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MetricReader; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpentelemetryConfiguration; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Otlp; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpMetric; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ParentBased; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PeriodicMetricReader; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Prometheus; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PullMetricReader; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Resource; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Sampler; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Selector; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SimpleSpanProcessor; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanExporter; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanLimits; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanProcessor; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Stream; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.TraceIdRatioBased; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.TracerProvider; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.View; import java.io.FileInputStream; import java.io.IOException; +import java.util.Arrays; +import java.util.Collections; +import java.util.function.Consumer; import org.junit.jupiter.api.Test; class ConfigurationReaderTest { @@ -30,6 +57,7 @@ void read_ExampleFile() throws IOException { expected.setFileFormat("0.1"); + // General config Resource resource = new Resource(); expected.setResource(resource); Attributes attributes = new Attributes(); @@ -41,11 +69,12 @@ void read_ExampleFile() throws IOException { attributeLimits.setAttributeValueLengthLimit(4096); attributeLimits.setAttributeCountLimit(128); + // TracerProvider config TracerProvider tracerProvider = new TracerProvider(); expected.setTracerProvider(tracerProvider); SpanLimits spanLimits = new SpanLimits(); - tracerProvider.setSpanLimits(spanLimits); + tracerProvider.setLimits(spanLimits); spanLimits.setAttributeValueLengthLimit(4096); spanLimits.setAttributeCountLimit(128); spanLimits.setEventCountLimit(128); @@ -53,45 +82,181 @@ void read_ExampleFile() throws IOException { spanLimits.setEventAttributeCountLimit(128); spanLimits.setLinkAttributeCountLimit(128); - Sampler sampler = new Sampler(); + Sampler sampler = + createSampler( + it -> { + ParentBased parentBased = new ParentBased(); + it.setParentBased(parentBased); + parentBased.setRoot( + createSampler( + it1 -> { + TraceIdRatioBased traceIdRatioBased = new TraceIdRatioBased(); + it1.setTraceIdRatioBased(traceIdRatioBased); + traceIdRatioBased.setRatio(0.0001); + })); + parentBased.setRemoteParentSampled( + createSampler(it1 -> it1.setAlwaysOn(new AlwaysOn()))); + parentBased.setRemoteParentNotSampled( + createSampler(it1 -> it1.setAlwaysOff(new AlwaysOff()))); + parentBased.setLocalParentSampled( + createSampler(it1 -> it1.setAlwaysOn(new AlwaysOn()))); + parentBased.setLocalParentNotSampled( + createSampler(it1 -> it1.setAlwaysOff(new AlwaysOff()))); + }); tracerProvider.setSampler(sampler); - sampler.setId("parent_based"); - Sampler rootSampler = new Sampler(); - rootSampler.setId("trace_id_ratio_based"); - sampler.setAdditionalProperty("root", ImmutableMap.of( - "id", "trace_id_ratio_based", - "ratio", 0.0001 - )); - sampler.setAdditionalProperty("remote_parent_sampled", ImmutableMap.of( - "id", "always_on" - )); - sampler.setAdditionalProperty("remote_parent_not_sampled", ImmutableMap.of( - "id", "always_off" - )); - sampler.setAdditionalProperty("local_parent_sampled", ImmutableMap.of( - "id", "always_on" - )); - sampler.setAdditionalProperty("local_parent_not_sampled", ImmutableMap.of( - "id", "always_off" - )); - - expected.setMeterProvider(new MeterProvider()); + SpanProcessor spanProcessor1 = new SpanProcessor(); + BatchSpanProcessor batchSpanProcessor = new BatchSpanProcessor(); + spanProcessor1.setBatch(batchSpanProcessor); + batchSpanProcessor.setScheduleDelay(5000); + batchSpanProcessor.setExportTimeout(30_000); + batchSpanProcessor.setMaxQueueSize(2048); + batchSpanProcessor.setMaxExportBatchSize(512); + SpanExporter spanExporter1 = new SpanExporter(); + batchSpanProcessor.setExporter(spanExporter1); + Otlp otlpExporter = new Otlp(); + spanExporter1.setOtlp(otlpExporter); + otlpExporter.setProtocol("http/protobuf"); + otlpExporter.setEndpoint("http://localhost:4318"); + otlpExporter.setCertificate("/app/cert.pem"); + otlpExporter.setClientKey("/app/cert.pem"); + otlpExporter.setClientCertificate("/app/cert.pem"); + Headers headers = new Headers(); + otlpExporter.setHeaders(headers); + headers.setAdditionalProperty("api-key", 1234); + otlpExporter.setCompression("gzip"); + otlpExporter.setTimeout(10_000); + + SpanProcessor spanProcessor2 = new SpanProcessor(); + SimpleSpanProcessor simpleSpanProcessor = new SimpleSpanProcessor(); + spanProcessor2.setSimple(simpleSpanProcessor); + SpanExporter spanExporter2 = new SpanExporter(); + Console consoleExporter = new Console(); + spanExporter2.setConsole(consoleExporter); + simpleSpanProcessor.setExporter(spanExporter2); + + tracerProvider.setProcessors(Arrays.asList(spanProcessor1, spanProcessor2)); + + // LoggerProvider config LoggerProvider loggerProvider = new LoggerProvider(); expected.setLoggerProvider(loggerProvider); - LogrecordLimits logRecordLimits = new LogrecordLimits(); - loggerProvider.setLogrecordLimits(logRecordLimits); + LogRecordLimits logRecordLimits = new LogRecordLimits(); + loggerProvider.setLimits(logRecordLimits); logRecordLimits.setAttributeValueLengthLimit(4096); logRecordLimits.setAttributeCountLimit(128); + LogRecordProcessor logRecordProcessor = new LogRecordProcessor(); + BatchLogRecordProcessor batchLogRecordProcessor = new BatchLogRecordProcessor(); + logRecordProcessor.setBatch(batchLogRecordProcessor); + batchLogRecordProcessor.setScheduleDelay(5000); + batchLogRecordProcessor.setExportTimeout(30_000); + batchLogRecordProcessor.setMaxQueueSize(2048); + batchLogRecordProcessor.setMaxExportBatchSize(512); + LogRecordExporter logRecordExporter = new LogRecordExporter(); + batchLogRecordProcessor.setExporter(logRecordExporter); + logRecordExporter.setOtlp(otlpExporter); + + loggerProvider.setProcessors(Collections.singletonList(logRecordProcessor)); + + // MeterProvider config + MeterProvider meterProvider = new MeterProvider(); + expected.setMeterProvider(meterProvider); + + MetricReader metricReader1 = new MetricReader(); + PullMetricReader pullMetricReader = new PullMetricReader(); + metricReader1.setPull(pullMetricReader); + MetricExporter metricExporter1 = new MetricExporter(); + pullMetricReader.setExporter(metricExporter1); + Prometheus prometheus = new Prometheus(); + metricExporter1.setPrometheus(prometheus); + prometheus.setHost("localhost"); + prometheus.setPort(9464); + + MetricReader metricReader2 = new MetricReader(); + PeriodicMetricReader periodicMetricReader1 = new PeriodicMetricReader(); + metricReader2.setPeriodic(periodicMetricReader1); + periodicMetricReader1.setInterval(5000); + periodicMetricReader1.setTimeout(30_000); + MetricExporter metricExporter2 = new MetricExporter(); + periodicMetricReader1.setExporter(metricExporter2); + OtlpMetric otlpMetricExporter = new OtlpMetric(); + metricExporter2.setOtlp(otlpMetricExporter); + otlpMetricExporter.setProtocol("http/protobuf"); + otlpMetricExporter.setEndpoint("http://localhost:4318"); + otlpMetricExporter.setCertificate("/app/cert.pem"); + otlpMetricExporter.setClientKey("/app/cert.pem"); + otlpMetricExporter.setClientCertificate("/app/cert.pem"); + Headers headers1 = new Headers(); + otlpMetricExporter.setHeaders(headers1); + headers1.setAdditionalProperty("api-key", 1234); + otlpMetricExporter.setCompression("gzip"); + otlpMetricExporter.setTimeout(10_000); + otlpMetricExporter.setTemporalityPreference("delta"); + otlpMetricExporter.setDefaultHistogramAggregation("exponential_bucket_histogram"); + + MetricReader metricReader3 = new MetricReader(); + PeriodicMetricReader periodicMetricReader2 = new PeriodicMetricReader(); + metricReader3.setPeriodic(periodicMetricReader2); + MetricExporter metricExporter3 = new MetricExporter(); + periodicMetricReader2.setExporter(metricExporter3); + metricExporter3.setConsole(new Console()); + + meterProvider.setReaders(Arrays.asList(metricReader1, metricReader2, metricReader3)); + + View view = new View(); + Selector selector = new Selector(); + view.setSelector(selector); + selector.setInstrumentName("my-instrument"); + selector.setInstrumentType("histogram"); + selector.setMeterName("my-meter"); + selector.setMeterVersion("1.0.0"); + selector.setMeterSchemaUrl("https://opentelemetry.io/schemas/1.16.0"); + + Stream stream = new Stream(); + view.setStream(stream); + stream.setName("new_instrument_name"); + stream.setDescription("new_description"); + Aggregation aggregation = new Aggregation(); + stream.setAggregation(aggregation); + ExplicitBucketHistogram explicitBucketHistogram = new ExplicitBucketHistogram(); + aggregation.setExplicitBucketHistogram(explicitBucketHistogram); + explicitBucketHistogram.setBoundaries( + Arrays.asList( + 0.0, 5.0, 10.0, 25.0, 50.0, 75.0, 100.0, 250.0, 500.0, 750.0, 1000.0, 2500.0, 5000.0, + 7500.0, 10000.0)); + explicitBucketHistogram.setRecordMinMax(true); + stream.setAttributeKeys(Arrays.asList("key1", "key2")); + + meterProvider.setViews(Collections.singletonList(view)); + try (FileInputStream configExampleFile = new FileInputStream(System.getenv("CONFIG_EXAMPLE_FILE"))) { - OpentelemetryConfiguration configuration = ConfigurationReader.parse(configExampleFile); + OpentelemetryConfiguration config = ConfigurationReader.parse(configExampleFile); + + TracerProvider configTracerProvider = config.getTracerProvider(); + assertThat(configTracerProvider.getLimits()).isEqualTo(spanLimits); + assertThat(configTracerProvider.getSampler()).isEqualTo(sampler); + assertThat(configTracerProvider.getProcessors()) + .isEqualTo(Arrays.asList(spanProcessor1, spanProcessor2)); - assertThat(configuration.getTracerProvider().getSampler()).isEqualTo(sampler); + LoggerProvider configLoggerProvider = config.getLoggerProvider(); + assertThat(configLoggerProvider.getLimits()).isEqualTo(logRecordLimits); + assertThat(configLoggerProvider.getProcessors()) + .isEqualTo(Collections.singletonList(logRecordProcessor)); + + MeterProvider configMeterProvider = config.getMeterProvider(); + assertThat(configMeterProvider.getReaders()) + .isEqualTo(Arrays.asList(metricReader1, metricReader2, metricReader3)); + assertThat(configMeterProvider.getViews()).isEqualTo(Collections.singletonList(view)); // assertThat(configuration).isEqualTo(expected); } } + + private static Sampler createSampler(Consumer samplerConsumer) { + Sampler sampler = new Sampler(); + samplerConsumer.accept(sampler); + return sampler; + } } From 2b0e475dbd05b2ab6991fc72c94e0b635f5c3e8d Mon Sep 17 00:00:00 2001 From: Jack Berg Date: Tue, 1 Aug 2023 15:24:47 -0500 Subject: [PATCH 07/11] Update to latest opentelemetry-configuration --- sdk-extensions/incubator/build.gradle.kts | 6 ++-- .../fileconfig/ConfigurationReaderTest.java | 28 +++++++++++++++---- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/sdk-extensions/incubator/build.gradle.kts b/sdk-extensions/incubator/build.gradle.kts index 474ddd42ba7..8d7c570b2ed 100644 --- a/sdk-extensions/incubator/build.gradle.kts +++ b/sdk-extensions/incubator/build.gradle.kts @@ -35,8 +35,8 @@ dependencies { testImplementation("com.google.guava:guava-testlib") } -val configurationRef = "ed331cd958eb2f6ee16dba3a42e2548e7801ade5" -val configurationRepoZip = "https://github.com/jack-berg/opentelemetry-configuration/archive/$configurationRef.zip" +val configurationRef = "2107dbb6f2a6c99fe2f55d550796ee7e2286fd1d" +val configurationRepoZip = "https://github.com/open-telemetry/opentelemetry-configuration/archive/$configurationRef.zip" val downloadConfigurationSchema by tasks.registering(Download::class) { src(configurationRepoZip) @@ -76,7 +76,7 @@ tasks { environment( mapOf( // Expose the kitchen sink example file to tests - "CONFIG_EXAMPLE_FILE" to "$buildDir/configuration/kitchen-sink-example.yaml" + "CONFIG_EXAMPLE_DIR" to "$buildDir/configuration/examples/" ) ) } diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReaderTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReaderTest.java index 06f89c4f2fd..66bc212dc18 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReaderTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReaderTest.java @@ -46,13 +46,14 @@ import java.io.IOException; import java.util.Arrays; import java.util.Collections; +import java.util.List; import java.util.function.Consumer; import org.junit.jupiter.api.Test; class ConfigurationReaderTest { @Test - void read_ExampleFile() throws IOException { + void read_KitchenSinkExampleFile() throws IOException { OpentelemetryConfiguration expected = new OpentelemetryConfiguration(); expected.setFileFormat("0.1"); @@ -69,6 +70,10 @@ void read_ExampleFile() throws IOException { attributeLimits.setAttributeValueLengthLimit(4096); attributeLimits.setAttributeCountLimit(128); + List propagators = + Arrays.asList("tracecontext", "baggage", "b3", "b3multi", "jaeger", "xray", "ottrace"); + expected.setPropagators(propagators); + // TracerProvider config TracerProvider tracerProvider = new TracerProvider(); expected.setTracerProvider(tracerProvider); @@ -123,7 +128,7 @@ void read_ExampleFile() throws IOException { otlpExporter.setClientCertificate("/app/cert.pem"); Headers headers = new Headers(); otlpExporter.setHeaders(headers); - headers.setAdditionalProperty("api-key", 1234); + headers.setAdditionalProperty("api-key", "1234"); otlpExporter.setCompression("gzip"); otlpExporter.setTimeout(10_000); @@ -136,6 +141,7 @@ void read_ExampleFile() throws IOException { simpleSpanProcessor.setExporter(spanExporter2); tracerProvider.setProcessors(Arrays.asList(spanProcessor1, spanProcessor2)); + // end TracerProvider config // LoggerProvider config LoggerProvider loggerProvider = new LoggerProvider(); @@ -158,6 +164,7 @@ void read_ExampleFile() throws IOException { logRecordExporter.setOtlp(otlpExporter); loggerProvider.setProcessors(Collections.singletonList(logRecordProcessor)); + // end LoggerProvider config // MeterProvider config MeterProvider meterProvider = new MeterProvider(); @@ -189,7 +196,7 @@ void read_ExampleFile() throws IOException { otlpMetricExporter.setClientCertificate("/app/cert.pem"); Headers headers1 = new Headers(); otlpMetricExporter.setHeaders(headers1); - headers1.setAdditionalProperty("api-key", 1234); + headers1.setAdditionalProperty("api-key", "1234"); otlpMetricExporter.setCompression("gzip"); otlpMetricExporter.setTimeout(10_000); otlpMetricExporter.setTemporalityPreference("delta"); @@ -229,28 +236,39 @@ void read_ExampleFile() throws IOException { stream.setAttributeKeys(Arrays.asList("key1", "key2")); meterProvider.setViews(Collections.singletonList(view)); + // end MeterProvider config try (FileInputStream configExampleFile = - new FileInputStream(System.getenv("CONFIG_EXAMPLE_FILE"))) { + new FileInputStream(System.getenv("CONFIG_EXAMPLE_DIR") + "/kitchen-sink.yaml")) { OpentelemetryConfiguration config = ConfigurationReader.parse(configExampleFile); + // General config + assertThat(config.getFileFormat()).isEqualTo("0.1"); + assertThat(config.getResource()).isEqualTo(resource); + assertThat(config.getAttributeLimits()).isEqualTo(attributeLimits); + assertThat(config.getPropagators()).isEqualTo(propagators); + + // TracerProvider config TracerProvider configTracerProvider = config.getTracerProvider(); assertThat(configTracerProvider.getLimits()).isEqualTo(spanLimits); assertThat(configTracerProvider.getSampler()).isEqualTo(sampler); assertThat(configTracerProvider.getProcessors()) .isEqualTo(Arrays.asList(spanProcessor1, spanProcessor2)); + // LoggerProvider config LoggerProvider configLoggerProvider = config.getLoggerProvider(); assertThat(configLoggerProvider.getLimits()).isEqualTo(logRecordLimits); assertThat(configLoggerProvider.getProcessors()) .isEqualTo(Collections.singletonList(logRecordProcessor)); + // MeterProvider config MeterProvider configMeterProvider = config.getMeterProvider(); assertThat(configMeterProvider.getReaders()) .isEqualTo(Arrays.asList(metricReader1, metricReader2, metricReader3)); assertThat(configMeterProvider.getViews()).isEqualTo(Collections.singletonList(view)); - // assertThat(configuration).isEqualTo(expected); + // All configuration + assertThat(config).isEqualTo(expected); } } From d77b1c1c736a3ab3f30fd6260f5d361e3a9870e6 Mon Sep 17 00:00:00 2001 From: Jack Berg Date: Wed, 2 Aug 2023 12:40:54 -0500 Subject: [PATCH 08/11] Generate builders, ensure @Generated annotation is added --- .../kotlin/otel.java-conventions.gradle.kts | 1 + sdk-extensions/incubator/build.gradle.kts | 53 ++- .../fileconfig/ConfigurationReaderTest.java | 403 ++++++++++-------- 3 files changed, 279 insertions(+), 178 deletions(-) diff --git a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts index 012fd75672f..83a337e09f7 100644 --- a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts @@ -48,6 +48,7 @@ dependencyCheck { "annotationProcessor", "animalsniffer", "spotless-1972451482", // spotless-1972451482 is a weird configuration that's only added in jaeger-proto + "js2p", "jmhAnnotationProcessor", "jmhCompileClasspath", "jmhRuntimeClasspath", diff --git a/sdk-extensions/incubator/build.gradle.kts b/sdk-extensions/incubator/build.gradle.kts index 8d7c570b2ed..1ababb4e8a0 100644 --- a/sdk-extensions/incubator/build.gradle.kts +++ b/sdk-extensions/incubator/build.gradle.kts @@ -35,6 +35,16 @@ dependencies { testImplementation("com.google.guava:guava-testlib") } +// The following tasks download the JSON Schema files from open-telemetry/opentelemetry-configuration and generate classes from the type definitions which are used with jackson-databind to parse JSON / YAML to the configuration schema. +// The sequence of tasks is: +// 1. downloadConfigurationSchema - download configuration schema from open-telemetry/opentelemetry-configuration +// 2. unzipConfigurationSchema - unzip the configuration schema archive contents to $buildDir/configuration/ +// 3. generateJsonSchema2Pojo - generate java POJOs from the configuration schema +// 4. replaceGeneratedAnnotation - replace javax.annotation.processing.Generated with javax.annotation.Generated to address issue in org.jsonschema2pojo plugin preventing usage of java 8 @Generated annotation with our gradle build setup. Updated content are placed to tmp directory. +// 5. overwriteJs2p - overwrite original generated classes with versions containing updated @Generated annotation +// 6. deleteJs2pTmp - delete tmp directory +// ... proceed with normal sourcesJar, compileJava, etc + val configurationRef = "2107dbb6f2a6c99fe2f55d550796ee7e2286fd1d" val configurationRepoZip = "https://github.com/open-telemetry/opentelemetry-configuration/archive/$configurationRef.zip" @@ -44,7 +54,7 @@ val downloadConfigurationSchema by tasks.registering(Download::class) { overwrite(false) } -val downloadAndUnzipConfigurationSchema by tasks.registering(Copy::class) { +val unzipConfigurationSchema by tasks.registering(Copy::class) { dependsOn("downloadConfigurationSchema") from(zipTree(downloadConfigurationSchema.get().dest)) eachFile(closureOf { @@ -59,12 +69,47 @@ jsonSchema2Pojo { sourceFiles = setOf(file("$buildDir/configuration/schema")) targetDirectory = file("$buildDir/generated/sources/js2p/java/main") targetPackage = "io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model" - includeSetters = true + + // Clear old source files to avoid contaminated source dir when updating removeOldOutput = true + + // Prefer builders to setters + includeSetters = false + generateBuilders = true + useInnerClassBuilders = true + + // Force java 9+ @Generated annotation, since java 8 @Generated annotation isn't detected by + // jsonSchema2Pojo and annotation is skipped altogether + targetVersion = "1.9" +} + +val generateJsonSchema2Pojo = tasks.getByName("generateJsonSchema2Pojo") +generateJsonSchema2Pojo.dependsOn(unzipConfigurationSchema) + +val replaceGeneratedAnnotation by tasks.registering(Copy::class) { + from("$buildDir/generated/sources/js2p") + into("$buildDir/generated/sources/js2p-tmp") + filter { + it + // Replace java 9+ @Generated annotation with java 8 version + .replace("import javax.annotation.processing.Generated", "import javax.annotation.Generated") + // Add @SuppressWarnings("rawtypes") annotation to address raw types used in jsonschema2pojo builders + .replace("@Generated(\"jsonschema2pojo\")", "@Generated(\"jsonschema2pojo\")\n@SuppressWarnings(\"rawtypes\")") + } + dependsOn(generateJsonSchema2Pojo) +} +val overwriteJs2p by tasks.registering(Copy::class) { + from("$buildDir/generated/sources/js2p-tmp") + into("$buildDir/generated/sources/js2p") + dependsOn(replaceGeneratedAnnotation) +} +val deleteJs2pTmp by tasks.registering(Delete::class) { + delete("$buildDir/generated/sources/js2p-tmp/") + dependsOn(overwriteJs2p) } -tasks.getByName("generateJsonSchema2Pojo").dependsOn(downloadAndUnzipConfigurationSchema) -tasks.getByName("sourcesJar").dependsOn("generateJsonSchema2Pojo") +tasks.getByName("compileJava").dependsOn(deleteJs2pTmp) +tasks.getByName("sourcesJar").dependsOn(deleteJs2pTmp) // Exclude jsonschema2pojo generated sources from checkstyle tasks.named("checkstyleMain") { diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReaderTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReaderTest.java index 66bc212dc18..8f2592bd6da 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReaderTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReaderTest.java @@ -47,195 +47,256 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; -import java.util.function.Consumer; import org.junit.jupiter.api.Test; +@SuppressWarnings("unchecked") class ConfigurationReaderTest { @Test void read_KitchenSinkExampleFile() throws IOException { - OpentelemetryConfiguration expected = new OpentelemetryConfiguration(); + OpentelemetryConfiguration.OpentelemetryConfigurationBuilder expectedBuilder = + new OpentelemetryConfiguration.OpentelemetryConfigurationBuilder(); - expected.setFileFormat("0.1"); + expectedBuilder.withFileFormat("0.1"); // General config - Resource resource = new Resource(); - expected.setResource(resource); - Attributes attributes = new Attributes(); - resource.setAttributes(attributes); - attributes.setServiceName("unknown_service"); - - AttributeLimits attributeLimits = new AttributeLimits(); - expected.setAttributeLimits(attributeLimits); - attributeLimits.setAttributeValueLengthLimit(4096); - attributeLimits.setAttributeCountLimit(128); + Resource resource = + new Resource.ResourceBuilder() + .withAttributes( + new Attributes.AttributesBuilder().withServiceName("unknown_service").build()) + .build(); + expectedBuilder.withResource(resource); + + AttributeLimits attributeLimits = + new AttributeLimits.AttributeLimitsBuilder() + .withAttributeValueLengthLimit(4096) + .withAttributeCountLimit(128) + .build(); + expectedBuilder.withAttributeLimits(attributeLimits); List propagators = Arrays.asList("tracecontext", "baggage", "b3", "b3multi", "jaeger", "xray", "ottrace"); - expected.setPropagators(propagators); + expectedBuilder.withPropagators(propagators); // TracerProvider config - TracerProvider tracerProvider = new TracerProvider(); - expected.setTracerProvider(tracerProvider); - - SpanLimits spanLimits = new SpanLimits(); - tracerProvider.setLimits(spanLimits); - spanLimits.setAttributeValueLengthLimit(4096); - spanLimits.setAttributeCountLimit(128); - spanLimits.setEventCountLimit(128); - spanLimits.setLinkCountLimit(128); - spanLimits.setEventAttributeCountLimit(128); - spanLimits.setLinkAttributeCountLimit(128); + TracerProvider.TracerProviderBuilder tracerProviderBuilder = + new TracerProvider.TracerProviderBuilder(); + + SpanLimits spanLimits = + new SpanLimits.SpanLimitsBuilder() + .withAttributeValueLengthLimit(4096) + .withAttributeCountLimit(128) + .withEventCountLimit(128) + .withLinkCountLimit(128) + .withEventAttributeCountLimit(128) + .withLinkAttributeCountLimit(128) + .build(); + tracerProviderBuilder.withLimits(spanLimits); Sampler sampler = - createSampler( - it -> { - ParentBased parentBased = new ParentBased(); - it.setParentBased(parentBased); - parentBased.setRoot( - createSampler( - it1 -> { - TraceIdRatioBased traceIdRatioBased = new TraceIdRatioBased(); - it1.setTraceIdRatioBased(traceIdRatioBased); - traceIdRatioBased.setRatio(0.0001); - })); - parentBased.setRemoteParentSampled( - createSampler(it1 -> it1.setAlwaysOn(new AlwaysOn()))); - parentBased.setRemoteParentNotSampled( - createSampler(it1 -> it1.setAlwaysOff(new AlwaysOff()))); - parentBased.setLocalParentSampled( - createSampler(it1 -> it1.setAlwaysOn(new AlwaysOn()))); - parentBased.setLocalParentNotSampled( - createSampler(it1 -> it1.setAlwaysOff(new AlwaysOff()))); - }); - tracerProvider.setSampler(sampler); - - SpanProcessor spanProcessor1 = new SpanProcessor(); - BatchSpanProcessor batchSpanProcessor = new BatchSpanProcessor(); - spanProcessor1.setBatch(batchSpanProcessor); - batchSpanProcessor.setScheduleDelay(5000); - batchSpanProcessor.setExportTimeout(30_000); - batchSpanProcessor.setMaxQueueSize(2048); - batchSpanProcessor.setMaxExportBatchSize(512); - SpanExporter spanExporter1 = new SpanExporter(); - batchSpanProcessor.setExporter(spanExporter1); - Otlp otlpExporter = new Otlp(); - spanExporter1.setOtlp(otlpExporter); - otlpExporter.setProtocol("http/protobuf"); - otlpExporter.setEndpoint("http://localhost:4318"); - otlpExporter.setCertificate("/app/cert.pem"); - otlpExporter.setClientKey("/app/cert.pem"); - otlpExporter.setClientCertificate("/app/cert.pem"); - Headers headers = new Headers(); - otlpExporter.setHeaders(headers); - headers.setAdditionalProperty("api-key", "1234"); - otlpExporter.setCompression("gzip"); - otlpExporter.setTimeout(10_000); - - SpanProcessor spanProcessor2 = new SpanProcessor(); - SimpleSpanProcessor simpleSpanProcessor = new SimpleSpanProcessor(); - spanProcessor2.setSimple(simpleSpanProcessor); - SpanExporter spanExporter2 = new SpanExporter(); - Console consoleExporter = new Console(); - spanExporter2.setConsole(consoleExporter); - simpleSpanProcessor.setExporter(spanExporter2); - - tracerProvider.setProcessors(Arrays.asList(spanProcessor1, spanProcessor2)); + new Sampler.SamplerBuilder() + .withParentBased( + new ParentBased.ParentBasedBuilder() + .withRoot( + new Sampler.SamplerBuilder() + .withTraceIdRatioBased( + new TraceIdRatioBased.TraceIdRatioBasedBuilder() + .withRatio(0.0001) + .build()) + .build()) + .withRemoteParentSampled( + new Sampler.SamplerBuilder() + .withAlwaysOn(new AlwaysOn.AlwaysOnBuilder().build()) + .build()) + .withRemoteParentNotSampled( + new Sampler.SamplerBuilder() + .withAlwaysOff(new AlwaysOff.AlwaysOffBuilder().build()) + .build()) + .withLocalParentSampled( + new Sampler.SamplerBuilder() + .withAlwaysOn(new AlwaysOn.AlwaysOnBuilder().build()) + .build()) + .withLocalParentNotSampled( + new Sampler.SamplerBuilder() + .withAlwaysOff(new AlwaysOff.AlwaysOffBuilder().build()) + .build()) + .build()) + .build(); + tracerProviderBuilder.withSampler(sampler); + + SpanProcessor spanProcessor1 = + new SpanProcessor.SpanProcessorBuilder() + .withBatch( + new BatchSpanProcessor.BatchSpanProcessorBuilder() + .withScheduleDelay(5_000) + .withExportTimeout(30_000) + .withMaxQueueSize(2048) + .withMaxExportBatchSize(512) + .withExporter( + new SpanExporter.SpanExporterBuilder() + .withOtlp( + new Otlp.OtlpBuilder() + .withProtocol("http/protobuf") + .withEndpoint("http://localhost:4318") + .withCertificate("/app/cert.pem") + .withClientKey("/app/cert.pem") + .withClientCertificate("/app/cert.pem") + .withHeaders( + new Headers.HeadersBuilder() + .withAdditionalProperty("api-key", "1234") + .build()) + .withCompression("gzip") + .withTimeout(10_000) + .build()) + .build()) + .build()) + .build(); + SpanProcessor spanProcessor2 = + new SpanProcessor.SpanProcessorBuilder() + .withSimple( + new SimpleSpanProcessor.SimpleSpanProcessorBuilder() + .withExporter( + new SpanExporter.SpanExporterBuilder() + .withConsole(new Console.ConsoleBuilder().build()) + .build()) + .build()) + .build(); + tracerProviderBuilder.withProcessors(Arrays.asList(spanProcessor1, spanProcessor2)); + + expectedBuilder.withTracerProvider(tracerProviderBuilder.build()); // end TracerProvider config // LoggerProvider config - LoggerProvider loggerProvider = new LoggerProvider(); - expected.setLoggerProvider(loggerProvider); - - LogRecordLimits logRecordLimits = new LogRecordLimits(); - loggerProvider.setLimits(logRecordLimits); - logRecordLimits.setAttributeValueLengthLimit(4096); - logRecordLimits.setAttributeCountLimit(128); - - LogRecordProcessor logRecordProcessor = new LogRecordProcessor(); - BatchLogRecordProcessor batchLogRecordProcessor = new BatchLogRecordProcessor(); - logRecordProcessor.setBatch(batchLogRecordProcessor); - batchLogRecordProcessor.setScheduleDelay(5000); - batchLogRecordProcessor.setExportTimeout(30_000); - batchLogRecordProcessor.setMaxQueueSize(2048); - batchLogRecordProcessor.setMaxExportBatchSize(512); - LogRecordExporter logRecordExporter = new LogRecordExporter(); - batchLogRecordProcessor.setExporter(logRecordExporter); - logRecordExporter.setOtlp(otlpExporter); - - loggerProvider.setProcessors(Collections.singletonList(logRecordProcessor)); + LoggerProvider.LoggerProviderBuilderBase loggerProviderBuilder = + new LoggerProvider.LoggerProviderBuilder(); + + LogRecordLimits logRecordLimits = + new LogRecordLimits.LogRecordLimitsBuilder() + .withAttributeValueLengthLimit(4096) + .withAttributeCountLimit(128) + .build(); + loggerProviderBuilder.withLimits(logRecordLimits); + + LogRecordProcessor logRecordProcessor = + new LogRecordProcessor.LogRecordProcessorBuilder() + .withBatch( + new BatchLogRecordProcessor.BatchLogRecordProcessorBuilder() + .withScheduleDelay(5_000) + .withExportTimeout(30_000) + .withMaxQueueSize(2048) + .withMaxExportBatchSize(512) + .withExporter( + new LogRecordExporter.LogRecordExporterBuilder() + .withOtlp( + new Otlp.OtlpBuilder() + .withProtocol("http/protobuf") + .withEndpoint("http://localhost:4318") + .withCertificate("/app/cert.pem") + .withClientKey("/app/cert.pem") + .withClientCertificate("/app/cert.pem") + .withHeaders( + new Headers.HeadersBuilder() + .withAdditionalProperty("api-key", "1234") + .build()) + .withCompression("gzip") + .withTimeout(10_000) + .build()) + .build()) + .build()) + .build(); + loggerProviderBuilder.withProcessors(Collections.singletonList(logRecordProcessor)); + + expectedBuilder.withLoggerProvider(loggerProviderBuilder.build()); // end LoggerProvider config // MeterProvider config - MeterProvider meterProvider = new MeterProvider(); - expected.setMeterProvider(meterProvider); - - MetricReader metricReader1 = new MetricReader(); - PullMetricReader pullMetricReader = new PullMetricReader(); - metricReader1.setPull(pullMetricReader); - MetricExporter metricExporter1 = new MetricExporter(); - pullMetricReader.setExporter(metricExporter1); - Prometheus prometheus = new Prometheus(); - metricExporter1.setPrometheus(prometheus); - prometheus.setHost("localhost"); - prometheus.setPort(9464); - - MetricReader metricReader2 = new MetricReader(); - PeriodicMetricReader periodicMetricReader1 = new PeriodicMetricReader(); - metricReader2.setPeriodic(periodicMetricReader1); - periodicMetricReader1.setInterval(5000); - periodicMetricReader1.setTimeout(30_000); - MetricExporter metricExporter2 = new MetricExporter(); - periodicMetricReader1.setExporter(metricExporter2); - OtlpMetric otlpMetricExporter = new OtlpMetric(); - metricExporter2.setOtlp(otlpMetricExporter); - otlpMetricExporter.setProtocol("http/protobuf"); - otlpMetricExporter.setEndpoint("http://localhost:4318"); - otlpMetricExporter.setCertificate("/app/cert.pem"); - otlpMetricExporter.setClientKey("/app/cert.pem"); - otlpMetricExporter.setClientCertificate("/app/cert.pem"); - Headers headers1 = new Headers(); - otlpMetricExporter.setHeaders(headers1); - headers1.setAdditionalProperty("api-key", "1234"); - otlpMetricExporter.setCompression("gzip"); - otlpMetricExporter.setTimeout(10_000); - otlpMetricExporter.setTemporalityPreference("delta"); - otlpMetricExporter.setDefaultHistogramAggregation("exponential_bucket_histogram"); - - MetricReader metricReader3 = new MetricReader(); - PeriodicMetricReader periodicMetricReader2 = new PeriodicMetricReader(); - metricReader3.setPeriodic(periodicMetricReader2); - MetricExporter metricExporter3 = new MetricExporter(); - periodicMetricReader2.setExporter(metricExporter3); - metricExporter3.setConsole(new Console()); - - meterProvider.setReaders(Arrays.asList(metricReader1, metricReader2, metricReader3)); - - View view = new View(); - Selector selector = new Selector(); - view.setSelector(selector); - selector.setInstrumentName("my-instrument"); - selector.setInstrumentType("histogram"); - selector.setMeterName("my-meter"); - selector.setMeterVersion("1.0.0"); - selector.setMeterSchemaUrl("https://opentelemetry.io/schemas/1.16.0"); - - Stream stream = new Stream(); - view.setStream(stream); - stream.setName("new_instrument_name"); - stream.setDescription("new_description"); - Aggregation aggregation = new Aggregation(); - stream.setAggregation(aggregation); - ExplicitBucketHistogram explicitBucketHistogram = new ExplicitBucketHistogram(); - aggregation.setExplicitBucketHistogram(explicitBucketHistogram); - explicitBucketHistogram.setBoundaries( - Arrays.asList( - 0.0, 5.0, 10.0, 25.0, 50.0, 75.0, 100.0, 250.0, 500.0, 750.0, 1000.0, 2500.0, 5000.0, - 7500.0, 10000.0)); - explicitBucketHistogram.setRecordMinMax(true); - stream.setAttributeKeys(Arrays.asList("key1", "key2")); - - meterProvider.setViews(Collections.singletonList(view)); + MeterProvider.MeterProviderBuilderBase meterProviderBuilder = + new MeterProvider.MeterProviderBuilder(); + + MetricReader metricReader1 = + new MetricReader.MetricReaderBuilder() + .withPull( + new PullMetricReader.PullMetricReaderBuilder() + .withExporter( + new MetricExporter.MetricExporterBuilder() + .withPrometheus( + new Prometheus.PrometheusBuilder() + .withHost("localhost") + .withPort(9464) + .build()) + .build()) + .build()) + .build(); + MetricReader metricReader2 = + new MetricReader.MetricReaderBuilder() + .withPeriodic( + new PeriodicMetricReader.PeriodicMetricReaderBuilder() + .withInterval(5_000) + .withTimeout(30_000) + .withExporter( + new MetricExporter.MetricExporterBuilder() + .withOtlp( + new OtlpMetric.OtlpMetricBuilder() + .withProtocol("http/protobuf") + .withEndpoint("http://localhost:4318") + .withCertificate("/app/cert.pem") + .withClientKey("/app/cert.pem") + .withClientCertificate("/app/cert.pem") + .withHeaders( + new Headers.HeadersBuilder() + .withAdditionalProperty("api-key", "1234") + .build()) + .withCompression("gzip") + .withTimeout(10_000) + .withTemporalityPreference("delta") + .withDefaultHistogramAggregation("exponential_bucket_histogram") + .build()) + .build()) + .build()) + .build(); + MetricReader metricReader3 = + new MetricReader.MetricReaderBuilder() + .withPeriodic( + new PeriodicMetricReader.PeriodicMetricReaderBuilder() + .withExporter( + new MetricExporter.MetricExporterBuilder() + .withConsole(new Console.ConsoleBuilder().build()) + .build()) + .build()) + .build(); + meterProviderBuilder.withReaders(Arrays.asList(metricReader1, metricReader2, metricReader3)); + + View view = + new View.ViewBuilder() + .withSelector( + new Selector.SelectorBuilder() + .withInstrumentName("my-instrument") + .withInstrumentType("histogram") + .withMeterName("my-meter") + .withMeterVersion("1.0.0") + .withMeterSchemaUrl("https://opentelemetry.io/schemas/1.16.0") + .build()) + .withStream( + new Stream.StreamBuilder() + .withName("new_instrument_name") + .withDescription("new_description") + .withAggregation( + new Aggregation.AggregationBuilder() + .withExplicitBucketHistogram( + new ExplicitBucketHistogram.ExplicitBucketHistogramBuilder() + .withBoundaries( + Arrays.asList( + 0.0, 5.0, 10.0, 25.0, 50.0, 75.0, 100.0, 250.0, 500.0, + 750.0, 1000.0, 2500.0, 5000.0, 7500.0, 10000.0)) + .withRecordMinMax(true) + .build()) + .build()) + .withAttributeKeys(Arrays.asList("key1", "key2")) + .build()) + .build(); + meterProviderBuilder.withViews(Collections.singletonList(view)); + + expectedBuilder.withMeterProvider(meterProviderBuilder.build()); // end MeterProvider config try (FileInputStream configExampleFile = @@ -268,13 +329,7 @@ void read_KitchenSinkExampleFile() throws IOException { assertThat(configMeterProvider.getViews()).isEqualTo(Collections.singletonList(view)); // All configuration - assertThat(config).isEqualTo(expected); + assertThat(config).isEqualTo(expectedBuilder.build()); } } - - private static Sampler createSampler(Consumer samplerConsumer) { - Sampler sampler = new Sampler(); - samplerConsumer.accept(sampler); - return sampler; - } } From 55f3829be851686290b7fe7799b941e51d4b5e1f Mon Sep 17 00:00:00 2001 From: Jack Berg Date: Wed, 2 Aug 2023 12:50:28 -0500 Subject: [PATCH 09/11] PR feedback --- sdk-extensions/incubator/build.gradle.kts | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/sdk-extensions/incubator/build.gradle.kts b/sdk-extensions/incubator/build.gradle.kts index 1ababb4e8a0..29418ee7eb1 100644 --- a/sdk-extensions/incubator/build.gradle.kts +++ b/sdk-extensions/incubator/build.gradle.kts @@ -45,6 +45,7 @@ dependencies { // 6. deleteJs2pTmp - delete tmp directory // ... proceed with normal sourcesJar, compileJava, etc +// TODO(jack-berg): update ref to be released version when available val configurationRef = "2107dbb6f2a6c99fe2f55d550796ee7e2286fd1d" val configurationRepoZip = "https://github.com/open-telemetry/opentelemetry-configuration/archive/$configurationRef.zip" @@ -55,7 +56,8 @@ val downloadConfigurationSchema by tasks.registering(Download::class) { } val unzipConfigurationSchema by tasks.registering(Copy::class) { - dependsOn("downloadConfigurationSchema") + dependsOn(downloadConfigurationSchema) + from(zipTree(downloadConfigurationSchema.get().dest)) eachFile(closureOf { // Remove the top level folder "/opentelemetry-configuration-$configurationRef" @@ -87,6 +89,8 @@ val generateJsonSchema2Pojo = tasks.getByName("generateJsonSchema2Pojo") generateJsonSchema2Pojo.dependsOn(unzipConfigurationSchema) val replaceGeneratedAnnotation by tasks.registering(Copy::class) { + dependsOn(generateJsonSchema2Pojo) + from("$buildDir/generated/sources/js2p") into("$buildDir/generated/sources/js2p-tmp") filter { @@ -96,16 +100,17 @@ val replaceGeneratedAnnotation by tasks.registering(Copy::class) { // Add @SuppressWarnings("rawtypes") annotation to address raw types used in jsonschema2pojo builders .replace("@Generated(\"jsonschema2pojo\")", "@Generated(\"jsonschema2pojo\")\n@SuppressWarnings(\"rawtypes\")") } - dependsOn(generateJsonSchema2Pojo) } val overwriteJs2p by tasks.registering(Copy::class) { + dependsOn(replaceGeneratedAnnotation) + from("$buildDir/generated/sources/js2p-tmp") into("$buildDir/generated/sources/js2p") - dependsOn(replaceGeneratedAnnotation) } val deleteJs2pTmp by tasks.registering(Delete::class) { - delete("$buildDir/generated/sources/js2p-tmp/") dependsOn(overwriteJs2p) + + delete("$buildDir/generated/sources/js2p-tmp/") } tasks.getByName("compileJava").dependsOn(deleteJs2pTmp) From 4e87de103d8fef655d9f31ba78ff7eb3296fee91 Mon Sep 17 00:00:00 2001 From: Jack Berg Date: Wed, 2 Aug 2023 13:57:41 -0500 Subject: [PATCH 10/11] Rename replaceGeneratedAnnotation to jsonSchema2PojoPostProcessing --- sdk-extensions/incubator/build.gradle.kts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sdk-extensions/incubator/build.gradle.kts b/sdk-extensions/incubator/build.gradle.kts index 29418ee7eb1..bbb33e80fcc 100644 --- a/sdk-extensions/incubator/build.gradle.kts +++ b/sdk-extensions/incubator/build.gradle.kts @@ -40,7 +40,7 @@ dependencies { // 1. downloadConfigurationSchema - download configuration schema from open-telemetry/opentelemetry-configuration // 2. unzipConfigurationSchema - unzip the configuration schema archive contents to $buildDir/configuration/ // 3. generateJsonSchema2Pojo - generate java POJOs from the configuration schema -// 4. replaceGeneratedAnnotation - replace javax.annotation.processing.Generated with javax.annotation.Generated to address issue in org.jsonschema2pojo plugin preventing usage of java 8 @Generated annotation with our gradle build setup. Updated content are placed to tmp directory. +// 4. jsonSchema2PojoPostProcessing - perform various post processing on the generated POJOs, e.g. replace javax.annotation.processing.Generated with javax.annotation.Generated, add @SuppressWarning("rawtypes") annotation // 5. overwriteJs2p - overwrite original generated classes with versions containing updated @Generated annotation // 6. deleteJs2pTmp - delete tmp directory // ... proceed with normal sourcesJar, compileJava, etc @@ -88,7 +88,7 @@ jsonSchema2Pojo { val generateJsonSchema2Pojo = tasks.getByName("generateJsonSchema2Pojo") generateJsonSchema2Pojo.dependsOn(unzipConfigurationSchema) -val replaceGeneratedAnnotation by tasks.registering(Copy::class) { +val jsonSchema2PojoPostProcessing by tasks.registering(Copy::class) { dependsOn(generateJsonSchema2Pojo) from("$buildDir/generated/sources/js2p") @@ -102,7 +102,7 @@ val replaceGeneratedAnnotation by tasks.registering(Copy::class) { } } val overwriteJs2p by tasks.registering(Copy::class) { - dependsOn(replaceGeneratedAnnotation) + dependsOn(jsonSchema2PojoPostProcessing) from("$buildDir/generated/sources/js2p-tmp") into("$buildDir/generated/sources/js2p") From d9b0350abcd1693bd34edb4a8ef85527656f4ad2 Mon Sep 17 00:00:00 2001 From: Jack Berg Date: Wed, 2 Aug 2023 18:07:24 -0500 Subject: [PATCH 11/11] PR feedback --- .../kotlin/otel.java-conventions.gradle.kts | 1 - sdk-extensions/incubator/build.gradle.kts | 4 +- .../fileconfig/ConfigurationReader.java | 8 +- .../fileconfig/ConfigurationReaderTest.java | 213 ++++++------------ 4 files changed, 78 insertions(+), 148 deletions(-) diff --git a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts index 83a337e09f7..124fb7ca387 100644 --- a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts @@ -1,5 +1,4 @@ import io.opentelemetry.gradle.OtelJavaExtension -import org.gradle.api.plugins.quality.internal.CheckstyleAction import org.gradle.api.tasks.testing.logging.TestExceptionFormat plugins { diff --git a/sdk-extensions/incubator/build.gradle.kts b/sdk-extensions/incubator/build.gradle.kts index bbb33e80fcc..b0594594095 100644 --- a/sdk-extensions/incubator/build.gradle.kts +++ b/sdk-extensions/incubator/build.gradle.kts @@ -78,7 +78,9 @@ jsonSchema2Pojo { // Prefer builders to setters includeSetters = false generateBuilders = true - useInnerClassBuilders = true + + // Use title field to generate class name, instead of default which is based on filename / propertynames + useTitleAsClassname = true // Force java 9+ @Generated annotation, since java 8 @Generated annotation isn't detected by // jsonSchema2Pojo and annotation is skipped altogether diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReader.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReader.java index 76af698938f..670b7c9843f 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReader.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReader.java @@ -6,7 +6,7 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig; import com.fasterxml.jackson.databind.ObjectMapper; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpentelemetryConfiguration; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfiguration; import java.io.InputStream; import org.yaml.snakeyaml.Yaml; @@ -17,9 +17,9 @@ class ConfigurationReader { private ConfigurationReader() {} - /** Parse the {@code configuration} YAML and return the {@link OpentelemetryConfiguration}. */ - static OpentelemetryConfiguration parse(InputStream configuration) { + /** Parse the {@code configuration} YAML and return the {@link OpenTelemetryConfiguration}. */ + static OpenTelemetryConfiguration parse(InputStream configuration) { Object yamlObj = YAML.load(configuration); - return MAPPER.convertValue(yamlObj, OpentelemetryConfiguration.class); + return MAPPER.convertValue(yamlObj, OpenTelemetryConfiguration.class); } } diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReaderTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReaderTest.java index 8f2592bd6da..9328721912a 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReaderTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReaderTest.java @@ -24,7 +24,7 @@ import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MeterProvider; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MetricExporter; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MetricReader; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpentelemetryConfiguration; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfiguration; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Otlp; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpMetric; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ParentBased; @@ -49,259 +49,188 @@ import java.util.List; import org.junit.jupiter.api.Test; -@SuppressWarnings("unchecked") class ConfigurationReaderTest { @Test void read_KitchenSinkExampleFile() throws IOException { - OpentelemetryConfiguration.OpentelemetryConfigurationBuilder expectedBuilder = - new OpentelemetryConfiguration.OpentelemetryConfigurationBuilder(); + OpenTelemetryConfiguration expected = new OpenTelemetryConfiguration(); - expectedBuilder.withFileFormat("0.1"); + expected.withFileFormat("0.1"); // General config Resource resource = - new Resource.ResourceBuilder() - .withAttributes( - new Attributes.AttributesBuilder().withServiceName("unknown_service").build()) - .build(); - expectedBuilder.withResource(resource); + new Resource().withAttributes(new Attributes().withServiceName("unknown_service")); + expected.withResource(resource); AttributeLimits attributeLimits = - new AttributeLimits.AttributeLimitsBuilder() - .withAttributeValueLengthLimit(4096) - .withAttributeCountLimit(128) - .build(); - expectedBuilder.withAttributeLimits(attributeLimits); + new AttributeLimits().withAttributeValueLengthLimit(4096).withAttributeCountLimit(128); + expected.withAttributeLimits(attributeLimits); List propagators = Arrays.asList("tracecontext", "baggage", "b3", "b3multi", "jaeger", "xray", "ottrace"); - expectedBuilder.withPropagators(propagators); + expected.withPropagators(propagators); // TracerProvider config - TracerProvider.TracerProviderBuilder tracerProviderBuilder = - new TracerProvider.TracerProviderBuilder(); + TracerProvider tracerProvider = new TracerProvider(); SpanLimits spanLimits = - new SpanLimits.SpanLimitsBuilder() + new SpanLimits() .withAttributeValueLengthLimit(4096) .withAttributeCountLimit(128) .withEventCountLimit(128) .withLinkCountLimit(128) .withEventAttributeCountLimit(128) - .withLinkAttributeCountLimit(128) - .build(); - tracerProviderBuilder.withLimits(spanLimits); + .withLinkAttributeCountLimit(128); + tracerProvider.withLimits(spanLimits); Sampler sampler = - new Sampler.SamplerBuilder() + new Sampler() .withParentBased( - new ParentBased.ParentBasedBuilder() + new ParentBased() .withRoot( - new Sampler.SamplerBuilder() - .withTraceIdRatioBased( - new TraceIdRatioBased.TraceIdRatioBasedBuilder() - .withRatio(0.0001) - .build()) - .build()) - .withRemoteParentSampled( - new Sampler.SamplerBuilder() - .withAlwaysOn(new AlwaysOn.AlwaysOnBuilder().build()) - .build()) - .withRemoteParentNotSampled( - new Sampler.SamplerBuilder() - .withAlwaysOff(new AlwaysOff.AlwaysOffBuilder().build()) - .build()) - .withLocalParentSampled( - new Sampler.SamplerBuilder() - .withAlwaysOn(new AlwaysOn.AlwaysOnBuilder().build()) - .build()) - .withLocalParentNotSampled( - new Sampler.SamplerBuilder() - .withAlwaysOff(new AlwaysOff.AlwaysOffBuilder().build()) - .build()) - .build()) - .build(); - tracerProviderBuilder.withSampler(sampler); + new Sampler() + .withTraceIdRatioBased(new TraceIdRatioBased().withRatio(0.0001))) + .withRemoteParentSampled(new Sampler().withAlwaysOn(new AlwaysOn())) + .withRemoteParentNotSampled(new Sampler().withAlwaysOff(new AlwaysOff())) + .withLocalParentSampled(new Sampler().withAlwaysOn(new AlwaysOn())) + .withLocalParentNotSampled(new Sampler().withAlwaysOff(new AlwaysOff()))); + tracerProvider.withSampler(sampler); SpanProcessor spanProcessor1 = - new SpanProcessor.SpanProcessorBuilder() + new SpanProcessor() .withBatch( - new BatchSpanProcessor.BatchSpanProcessorBuilder() + new BatchSpanProcessor() .withScheduleDelay(5_000) .withExportTimeout(30_000) .withMaxQueueSize(2048) .withMaxExportBatchSize(512) .withExporter( - new SpanExporter.SpanExporterBuilder() + new SpanExporter() .withOtlp( - new Otlp.OtlpBuilder() + new Otlp() .withProtocol("http/protobuf") .withEndpoint("http://localhost:4318") .withCertificate("/app/cert.pem") .withClientKey("/app/cert.pem") .withClientCertificate("/app/cert.pem") .withHeaders( - new Headers.HeadersBuilder() - .withAdditionalProperty("api-key", "1234") - .build()) + new Headers().withAdditionalProperty("api-key", "1234")) .withCompression("gzip") - .withTimeout(10_000) - .build()) - .build()) - .build()) - .build(); + .withTimeout(10_000)))); SpanProcessor spanProcessor2 = - new SpanProcessor.SpanProcessorBuilder() + new SpanProcessor() .withSimple( - new SimpleSpanProcessor.SimpleSpanProcessorBuilder() - .withExporter( - new SpanExporter.SpanExporterBuilder() - .withConsole(new Console.ConsoleBuilder().build()) - .build()) - .build()) - .build(); - tracerProviderBuilder.withProcessors(Arrays.asList(spanProcessor1, spanProcessor2)); + new SimpleSpanProcessor() + .withExporter(new SpanExporter().withConsole(new Console()))); + tracerProvider.withProcessors(Arrays.asList(spanProcessor1, spanProcessor2)); - expectedBuilder.withTracerProvider(tracerProviderBuilder.build()); + expected.withTracerProvider(tracerProvider); // end TracerProvider config // LoggerProvider config - LoggerProvider.LoggerProviderBuilderBase loggerProviderBuilder = - new LoggerProvider.LoggerProviderBuilder(); + LoggerProvider loggerProvider = new LoggerProvider(); LogRecordLimits logRecordLimits = - new LogRecordLimits.LogRecordLimitsBuilder() - .withAttributeValueLengthLimit(4096) - .withAttributeCountLimit(128) - .build(); - loggerProviderBuilder.withLimits(logRecordLimits); + new LogRecordLimits().withAttributeValueLengthLimit(4096).withAttributeCountLimit(128); + loggerProvider.withLimits(logRecordLimits); LogRecordProcessor logRecordProcessor = - new LogRecordProcessor.LogRecordProcessorBuilder() + new LogRecordProcessor() .withBatch( - new BatchLogRecordProcessor.BatchLogRecordProcessorBuilder() + new BatchLogRecordProcessor() .withScheduleDelay(5_000) .withExportTimeout(30_000) .withMaxQueueSize(2048) .withMaxExportBatchSize(512) .withExporter( - new LogRecordExporter.LogRecordExporterBuilder() + new LogRecordExporter() .withOtlp( - new Otlp.OtlpBuilder() + new Otlp() .withProtocol("http/protobuf") .withEndpoint("http://localhost:4318") .withCertificate("/app/cert.pem") .withClientKey("/app/cert.pem") .withClientCertificate("/app/cert.pem") .withHeaders( - new Headers.HeadersBuilder() - .withAdditionalProperty("api-key", "1234") - .build()) + new Headers().withAdditionalProperty("api-key", "1234")) .withCompression("gzip") - .withTimeout(10_000) - .build()) - .build()) - .build()) - .build(); - loggerProviderBuilder.withProcessors(Collections.singletonList(logRecordProcessor)); + .withTimeout(10_000)))); + loggerProvider.withProcessors(Collections.singletonList(logRecordProcessor)); - expectedBuilder.withLoggerProvider(loggerProviderBuilder.build()); + expected.withLoggerProvider(loggerProvider); // end LoggerProvider config // MeterProvider config - MeterProvider.MeterProviderBuilderBase meterProviderBuilder = - new MeterProvider.MeterProviderBuilder(); + MeterProvider meterProvider = new MeterProvider(); MetricReader metricReader1 = - new MetricReader.MetricReaderBuilder() + new MetricReader() .withPull( - new PullMetricReader.PullMetricReaderBuilder() + new PullMetricReader() .withExporter( - new MetricExporter.MetricExporterBuilder() + new MetricExporter() .withPrometheus( - new Prometheus.PrometheusBuilder() - .withHost("localhost") - .withPort(9464) - .build()) - .build()) - .build()) - .build(); + new Prometheus().withHost("localhost").withPort(9464)))); MetricReader metricReader2 = - new MetricReader.MetricReaderBuilder() + new MetricReader() .withPeriodic( - new PeriodicMetricReader.PeriodicMetricReaderBuilder() + new PeriodicMetricReader() .withInterval(5_000) .withTimeout(30_000) .withExporter( - new MetricExporter.MetricExporterBuilder() + new MetricExporter() .withOtlp( - new OtlpMetric.OtlpMetricBuilder() + new OtlpMetric() .withProtocol("http/protobuf") .withEndpoint("http://localhost:4318") .withCertificate("/app/cert.pem") .withClientKey("/app/cert.pem") .withClientCertificate("/app/cert.pem") .withHeaders( - new Headers.HeadersBuilder() - .withAdditionalProperty("api-key", "1234") - .build()) + new Headers().withAdditionalProperty("api-key", "1234")) .withCompression("gzip") .withTimeout(10_000) .withTemporalityPreference("delta") - .withDefaultHistogramAggregation("exponential_bucket_histogram") - .build()) - .build()) - .build()) - .build(); + .withDefaultHistogramAggregation( + "exponential_bucket_histogram")))); MetricReader metricReader3 = - new MetricReader.MetricReaderBuilder() + new MetricReader() .withPeriodic( - new PeriodicMetricReader.PeriodicMetricReaderBuilder() - .withExporter( - new MetricExporter.MetricExporterBuilder() - .withConsole(new Console.ConsoleBuilder().build()) - .build()) - .build()) - .build(); - meterProviderBuilder.withReaders(Arrays.asList(metricReader1, metricReader2, metricReader3)); + new PeriodicMetricReader() + .withExporter(new MetricExporter().withConsole(new Console()))); + meterProvider.withReaders(Arrays.asList(metricReader1, metricReader2, metricReader3)); View view = - new View.ViewBuilder() + new View() .withSelector( - new Selector.SelectorBuilder() + new Selector() .withInstrumentName("my-instrument") .withInstrumentType("histogram") .withMeterName("my-meter") .withMeterVersion("1.0.0") - .withMeterSchemaUrl("https://opentelemetry.io/schemas/1.16.0") - .build()) + .withMeterSchemaUrl("https://opentelemetry.io/schemas/1.16.0")) .withStream( - new Stream.StreamBuilder() + new Stream() .withName("new_instrument_name") .withDescription("new_description") .withAggregation( - new Aggregation.AggregationBuilder() + new Aggregation() .withExplicitBucketHistogram( - new ExplicitBucketHistogram.ExplicitBucketHistogramBuilder() + new ExplicitBucketHistogram() .withBoundaries( Arrays.asList( 0.0, 5.0, 10.0, 25.0, 50.0, 75.0, 100.0, 250.0, 500.0, 750.0, 1000.0, 2500.0, 5000.0, 7500.0, 10000.0)) - .withRecordMinMax(true) - .build()) - .build()) - .withAttributeKeys(Arrays.asList("key1", "key2")) - .build()) - .build(); - meterProviderBuilder.withViews(Collections.singletonList(view)); + .withRecordMinMax(true))) + .withAttributeKeys(Arrays.asList("key1", "key2"))); + meterProvider.withViews(Collections.singletonList(view)); - expectedBuilder.withMeterProvider(meterProviderBuilder.build()); + expected.withMeterProvider(meterProvider); // end MeterProvider config try (FileInputStream configExampleFile = new FileInputStream(System.getenv("CONFIG_EXAMPLE_DIR") + "/kitchen-sink.yaml")) { - OpentelemetryConfiguration config = ConfigurationReader.parse(configExampleFile); + OpenTelemetryConfiguration config = ConfigurationReader.parse(configExampleFile); // General config assertThat(config.getFileFormat()).isEqualTo("0.1"); @@ -329,7 +258,7 @@ void read_KitchenSinkExampleFile() throws IOException { assertThat(configMeterProvider.getViews()).isEqualTo(Collections.singletonList(view)); // All configuration - assertThat(config).isEqualTo(expectedBuilder.build()); + assertThat(config).isEqualTo(expected); } } }