From 5ab685e4de1f81a2ba6663f0edf2eb143b981662 Mon Sep 17 00:00:00 2001 From: cleverchuk Date: Fri, 30 Jan 2026 11:36:29 -0500 Subject: [PATCH] bump upstream to 2.24.0 and update required code and tests --- README.md | 2 +- build.gradle.kts | 2 +- .../extensions/config/DeclarativeLoader.java | 45 +++---- .../CustomConfigCustomizerProvider.java | 10 +- .../config/DeclarativeLoaderTest.java | 71 +++++++++++ .../LogRecordExporterCustomizerTest.java | 21 +++- .../config/SpanExporterCustomizerTest.java | 20 ++- dependencyManagement/build.gradle.kts | 8 +- .../SolarwindsIgnoredTypesConfigurer.java | 3 +- .../SharedConfigCustomizerProvider.java | 65 ++++++---- .../MetricExporterCustomizerTest.java | 20 ++- .../SharedConfigCustomizerProviderTest.java | 118 ++++++++---------- 12 files changed, 250 insertions(+), 135 deletions(-) create mode 100644 custom/src/test/java/com/solarwinds/opentelemetry/extensions/config/DeclarativeLoaderTest.java diff --git a/README.md b/README.md index 6e30ea9e..11df24e0 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ [![Status](https://img.shields.io/badge/status-stable-informational?style=for-the-badge)](https://github.com/solarwinds/apm-java) -[![OTEL](https://img.shields.io/badge/otel-2.3.0-blueviolet?style=for-the-badge)](https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/tag/v2.3.0) +[![OTEL](https://img.shields.io/badge/otel-2.24.0-blueviolet?style=for-the-badge)](https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/tag/v2.24.0) [![SWO](https://img.shields.io/github/v/release/solarwinds/apm-java?include_prereleases&style=for-the-badge)](https://github.com/solarwinds/apm-java/releases) [![SWO SDK](https://img.shields.io/maven-central/v/io.github.appoptics/solarwinds-otel-sdk?style=for-the-badge)](https://maven-badges.herokuapp.com/maven-central/io.github.appoptics/solarwinds-otel-sdk) [![License](https://img.shields.io/badge/License-Apache_2.0-red.svg?style=for-the-badge)](https://github.com/solarwinds/apm-java/blob/main/LICENSE) diff --git a/build.gradle.kts b/build.gradle.kts index c6d44856..c013d6a5 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -18,7 +18,7 @@ plugins{ id("io.github.gradle-nexus.publish-plugin") version "2.0.0" } -val swoAgentVersion = "3.1.2" +val swoAgentVersion = "3.1.3" extra["swoAgentVersion"] = swoAgentVersion group = "com.solarwinds" version = if (System.getenv("SNAPSHOT_BUILD").toBoolean()) "$swoAgentVersion-SNAPSHOT" else swoAgentVersion diff --git a/custom/src/main/java/com/solarwinds/opentelemetry/extensions/config/DeclarativeLoader.java b/custom/src/main/java/com/solarwinds/opentelemetry/extensions/config/DeclarativeLoader.java index 0b522e66..fdfced47 100644 --- a/custom/src/main/java/com/solarwinds/opentelemetry/extensions/config/DeclarativeLoader.java +++ b/custom/src/main/java/com/solarwinds/opentelemetry/extensions/config/DeclarativeLoader.java @@ -25,11 +25,11 @@ import com.solarwinds.joboe.logging.LoggerFactory; import com.solarwinds.opentelemetry.extensions.LoggingConfigProvider; import com.solarwinds.opentelemetry.extensions.config.parser.yaml.DeclarativeConfigParser; -import io.opentelemetry.api.incubator.config.ConfigProvider; +import io.opentelemetry.api.incubator.ExtendedOpenTelemetry; import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.javaagent.tooling.BeforeAgentListener; +import io.opentelemetry.sdk.OpenTelemetrySdk; import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk; -import io.opentelemetry.sdk.autoconfigure.internal.AutoConfigureUtil; @AutoService(BeforeAgentListener.class) public class DeclarativeLoader implements BeforeAgentListener { @@ -37,30 +37,33 @@ public class DeclarativeLoader implements BeforeAgentListener { @Override public void beforeAgent(AutoConfiguredOpenTelemetrySdk autoConfiguredOpenTelemetrySdk) { - ConfigProvider configProvider = - AutoConfigureUtil.getConfigProvider(autoConfiguredOpenTelemetrySdk); + OpenTelemetrySdk openTelemetrySdk = autoConfiguredOpenTelemetrySdk.getOpenTelemetrySdk(); + if (!(openTelemetrySdk instanceof ExtendedOpenTelemetry)) { + // Shouldn't happen in practice, but just in case + logger.warn( + "OpenTelemetrySdk is not an instance of ExtendedOpenTelemetry. Declarative configuration will not be applied."); + return; + } - if (configProvider != null) { - DeclarativeConfigProperties instrumentationConfig = configProvider.getInstrumentationConfig(); + ExtendedOpenTelemetry extendedOpenTelemetry = (ExtendedOpenTelemetry) openTelemetrySdk; + DeclarativeConfigProperties solarwinds = + extendedOpenTelemetry.getInstrumentationConfig("solarwinds"); - if (instrumentationConfig != null) { - DeclarativeConfigProperties solarwinds = - instrumentationConfig - .getStructured("java", DeclarativeConfigProperties.empty()) - .getStructured("solarwinds", DeclarativeConfigProperties.empty()); + if (solarwinds != null && !solarwinds.getPropertyKeys().isEmpty()) { + try { + ConfigContainer configContainer = new ConfigContainer(); + DeclarativeConfigParser declarativeConfigParser = + new DeclarativeConfigParser(configContainer); - try { - ConfigContainer configContainer = new ConfigContainer(); - new DeclarativeConfigParser(configContainer).parse(solarwinds); - ConfigurationLoader.processConfigs(configContainer); + declarativeConfigParser.parse(solarwinds); + ConfigurationLoader.processConfigs(configContainer); - ConfigContainer agentConfig = configContainer.subset(ConfigGroup.AGENT); - LoggerFactory.init(LoggingConfigProvider.getLoggerConfiguration(agentConfig)); - logger.info("Loaded via declarative config"); + ConfigContainer agentConfig = configContainer.subset(ConfigGroup.AGENT); + LoggerFactory.init(LoggingConfigProvider.getLoggerConfiguration(agentConfig)); + logger.info("Loaded via declarative config"); - } catch (InvalidConfigException e) { - throw new RuntimeException(e); - } + } catch (InvalidConfigException e) { + throw new RuntimeException(e); } if (!JavaRuntimeVersionChecker.isJdkVersionSupported()) { diff --git a/custom/src/main/java/com/solarwinds/opentelemetry/extensions/config/provider/CustomConfigCustomizerProvider.java b/custom/src/main/java/com/solarwinds/opentelemetry/extensions/config/provider/CustomConfigCustomizerProvider.java index 02f84a50..f56a1054 100644 --- a/custom/src/main/java/com/solarwinds/opentelemetry/extensions/config/provider/CustomConfigCustomizerProvider.java +++ b/custom/src/main/java/com/solarwinds/opentelemetry/extensions/config/provider/CustomConfigCustomizerProvider.java @@ -22,8 +22,10 @@ import io.opentelemetry.sdk.extension.incubator.fileconfig.DeclarativeConfigurationCustomizerProvider; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalResourceDetectionModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalResourceDetectorModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalResourceDetectorPropertyModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ResourceModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanProcessorModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanProcessorPropertyModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.TracerProviderModel; import java.util.ArrayList; import java.util.Collections; @@ -71,12 +73,14 @@ private void addResourceDetector(ResourceModel resourceModel) { newDetectors.add( new ExperimentalResourceDetectorModel() .withAdditionalProperty( - ResourceComponentProvider.COMPONENT_NAME, Collections.emptyMap())); + ResourceComponentProvider.COMPONENT_NAME, + new ExperimentalResourceDetectorPropertyModel())); newDetectors.add( new ExperimentalResourceDetectorModel() .withAdditionalProperty( - HostIdResourceComponentProvider.COMPONENT_NAME, Collections.emptyMap())); + HostIdResourceComponentProvider.COMPONENT_NAME, + new ExperimentalResourceDetectorPropertyModel())); detectionDevelopment.withDetectors(newDetectors); } @@ -87,7 +91,7 @@ private void addProcessors(TracerProviderModel model) { new SpanProcessorModel() .withAdditionalProperty( ProfilingSpanProcessorComponentProvider.COMPONENT_NAME, - Collections.emptyMap())); + new SpanProcessorPropertyModel())); ArrayList allProcessors = new ArrayList<>(model.getProcessors()); allProcessors.addAll(processors); diff --git a/custom/src/test/java/com/solarwinds/opentelemetry/extensions/config/DeclarativeLoaderTest.java b/custom/src/test/java/com/solarwinds/opentelemetry/extensions/config/DeclarativeLoaderTest.java new file mode 100644 index 00000000..672d9552 --- /dev/null +++ b/custom/src/test/java/com/solarwinds/opentelemetry/extensions/config/DeclarativeLoaderTest.java @@ -0,0 +1,71 @@ +/* + * © SolarWinds Worldwide, LLC. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.solarwinds.opentelemetry.extensions.config; + +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.when; + +import com.solarwinds.joboe.config.ConfigManager; +import com.solarwinds.joboe.config.ConfigProperty; +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; +import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk; +import io.opentelemetry.sdk.extension.incubator.ExtendedOpenTelemetrySdk; +import io.opentelemetry.sdk.extension.incubator.fileconfig.DeclarativeConfiguration; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalLanguageSpecificInstrumentationPropertyModel; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +class DeclarativeLoaderTest { + + @InjectMocks private DeclarativeLoader tested; + + @Mock private AutoConfiguredOpenTelemetrySdk autoConfiguredOpenTelemetrySdkMock; + + @Mock private ExtendedOpenTelemetrySdk extendedOpenTelemetrySdkMock; + + private final ExperimentalLanguageSpecificInstrumentationPropertyModel solarwinds = + new ExperimentalLanguageSpecificInstrumentationPropertyModel() + .withAdditionalProperty( + ConfigProperty.AGENT_SERVICE_KEY.getConfigFileKey(), "token:service") + .withAdditionalProperty( + ConfigProperty.AGENT_COLLECTOR.getConfigFileKey(), "apm.collector.com"); + + @AfterAll + public static void clearConfig() { + ConfigManager.reset(); + } + + @Test + public void testBeforeAgent() { + DeclarativeConfigProperties configProperties = + DeclarativeConfiguration.toConfigProperties(solarwinds); + when(autoConfiguredOpenTelemetrySdkMock.getOpenTelemetrySdk()) + .thenReturn(extendedOpenTelemetrySdkMock); + when(extendedOpenTelemetrySdkMock.getInstrumentationConfig(eq("solarwinds"))) + .thenReturn(configProperties); + tested.beforeAgent(autoConfiguredOpenTelemetrySdkMock); + + assertNotNull(ConfigManager.getConfig(ConfigProperty.AGENT_COLLECTOR)); + assertNotNull(ConfigManager.getConfig(ConfigProperty.AGENT_SERVICE_KEY)); + } +} diff --git a/custom/src/test/java/com/solarwinds/opentelemetry/extensions/config/LogRecordExporterCustomizerTest.java b/custom/src/test/java/com/solarwinds/opentelemetry/extensions/config/LogRecordExporterCustomizerTest.java index d794c737..86770ed5 100644 --- a/custom/src/test/java/com/solarwinds/opentelemetry/extensions/config/LogRecordExporterCustomizerTest.java +++ b/custom/src/test/java/com/solarwinds/opentelemetry/extensions/config/LogRecordExporterCustomizerTest.java @@ -18,12 +18,16 @@ import static com.solarwinds.opentelemetry.extensions.SharedNames.SW_OTEL_PROXY_HOST_KEY; import static com.solarwinds.opentelemetry.extensions.SharedNames.SW_OTEL_PROXY_PORT_KEY; -import static org.junit.jupiter.api.Assertions.assertNotSame; import static org.junit.jupiter.api.Assertions.assertSame; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporter; +import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; +import io.opentelemetry.sdk.common.export.ProxyOptions; import io.opentelemetry.sdk.logs.export.LogRecordExporter; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -46,12 +50,19 @@ void shouldReturnSameExporterWhenProxyNotConfigured() { } @Test - void shouldReturnNewExporterWhenProxyConfigured() { + void shouldCallSetProxyWhenProxyConfigured() { when(configProperties.getString(SW_OTEL_PROXY_HOST_KEY)).thenReturn("localhost"); when(configProperties.getInt(SW_OTEL_PROXY_PORT_KEY)).thenReturn(8080); - OtlpHttpLogRecordExporter originalExporter = OtlpHttpLogRecordExporter.builder().build(); - LogRecordExporter result = tested.apply(originalExporter, configProperties); - assertNotSame(originalExporter, result); + OtlpHttpLogRecordExporter originalExporter = mock(OtlpHttpLogRecordExporter.class); + OtlpHttpLogRecordExporterBuilder builder = mock(OtlpHttpLogRecordExporterBuilder.class); + + when(originalExporter.toBuilder()).thenReturn(builder); + when(builder.setProxyOptions(any(ProxyOptions.class))).thenReturn(builder); + when(builder.build()).thenReturn(mock(OtlpHttpLogRecordExporter.class)); + + tested.apply(originalExporter, configProperties); + + verify(builder).setProxyOptions(any(ProxyOptions.class)); } } diff --git a/custom/src/test/java/com/solarwinds/opentelemetry/extensions/config/SpanExporterCustomizerTest.java b/custom/src/test/java/com/solarwinds/opentelemetry/extensions/config/SpanExporterCustomizerTest.java index 5f3b155c..37ae4a3f 100644 --- a/custom/src/test/java/com/solarwinds/opentelemetry/extensions/config/SpanExporterCustomizerTest.java +++ b/custom/src/test/java/com/solarwinds/opentelemetry/extensions/config/SpanExporterCustomizerTest.java @@ -18,12 +18,16 @@ import static com.solarwinds.opentelemetry.extensions.SharedNames.SW_OTEL_PROXY_HOST_KEY; import static com.solarwinds.opentelemetry.extensions.SharedNames.SW_OTEL_PROXY_PORT_KEY; -import static org.junit.jupiter.api.Assertions.assertNotSame; import static org.junit.jupiter.api.Assertions.assertSame; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporter; +import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; +import io.opentelemetry.sdk.common.export.ProxyOptions; import io.opentelemetry.sdk.trace.export.SpanExporter; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -46,12 +50,18 @@ void shouldReturnSameExporterWhenProxyNotConfigured() { } @Test - void shouldReturnNewExporterWhenProxyConfigured() { + void shouldCallSetProxyWhenProxyConfigured() { when(configProperties.getString(SW_OTEL_PROXY_HOST_KEY)).thenReturn("localhost"); when(configProperties.getInt(SW_OTEL_PROXY_PORT_KEY)).thenReturn(8080); - OtlpHttpSpanExporter originalExporter = OtlpHttpSpanExporter.builder().build(); - SpanExporter result = tested.apply(originalExporter, configProperties); - assertNotSame(originalExporter, result); + OtlpHttpSpanExporter originalExporter = mock(OtlpHttpSpanExporter.class); + OtlpHttpSpanExporterBuilder builder = mock(OtlpHttpSpanExporterBuilder.class); + + when(originalExporter.toBuilder()).thenReturn(builder); + when(builder.setProxy(any(ProxyOptions.class))).thenReturn(builder); + when(builder.build()).thenReturn(mock(OtlpHttpSpanExporter.class)); + + tested.apply(originalExporter, configProperties); + verify(builder).setProxy(any(ProxyOptions.class)); } } diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 08674247..d6aaa067 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -2,11 +2,11 @@ plugins { `java-platform` } -val otelAgentVersion = "2.23.0" -val otelSdkVersion = "1.57.0" +val otelAgentVersion = "2.24.0" +val otelSdkVersion = "1.58.0" val mockitoVersion = "4.11.0" -val byteBuddyVersion = "1.15.10" +val byteBuddyVersion = "1.18.4" val joboeVersion = "10.0.27" val opentelemetryJavaagentAlpha = "$otelAgentVersion-alpha" @@ -15,7 +15,7 @@ val opentelemetrySemconv = "1.37.0" val opentelemetrySemconvAlpha = "$opentelemetrySemconv-alpha" val autoservice = "1.1.1" -val otelJavaContribVersion = "1.52.0-alpha" +val otelJavaContribVersion = "1.53.0-alpha" val junit5 = "5.9.2" rootProject.extra["otelAgentVersion"] = otelAgentVersion diff --git a/libs/shared/src/main/java/com/solarwinds/opentelemetry/extensions/SolarwindsIgnoredTypesConfigurer.java b/libs/shared/src/main/java/com/solarwinds/opentelemetry/extensions/SolarwindsIgnoredTypesConfigurer.java index eddd5065..d727f853 100644 --- a/libs/shared/src/main/java/com/solarwinds/opentelemetry/extensions/SolarwindsIgnoredTypesConfigurer.java +++ b/libs/shared/src/main/java/com/solarwinds/opentelemetry/extensions/SolarwindsIgnoredTypesConfigurer.java @@ -19,12 +19,11 @@ import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.ignore.IgnoredTypesBuilder; import io.opentelemetry.javaagent.extension.ignore.IgnoredTypesConfigurer; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; @AutoService(IgnoredTypesConfigurer.class) public class SolarwindsIgnoredTypesConfigurer implements IgnoredTypesConfigurer { @Override - public void configure(IgnoredTypesBuilder builder, ConfigProperties config) { + public void configure(IgnoredTypesBuilder builder) { builder.ignoreClass("com.solarwinds.ext."); builder.ignoreClass("com.solarwinds.joboe."); } diff --git a/libs/shared/src/main/java/com/solarwinds/opentelemetry/extensions/config/provider/SharedConfigCustomizerProvider.java b/libs/shared/src/main/java/com/solarwinds/opentelemetry/extensions/config/provider/SharedConfigCustomizerProvider.java index ef5e6eb9..a0a15d02 100644 --- a/libs/shared/src/main/java/com/solarwinds/opentelemetry/extensions/config/provider/SharedConfigCustomizerProvider.java +++ b/libs/shared/src/main/java/com/solarwinds/opentelemetry/extensions/config/provider/SharedConfigCustomizerProvider.java @@ -38,13 +38,15 @@ import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PeriodicMetricReaderModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PropagatorModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PushMetricExporterModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PushMetricExporterPropertyModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SamplerModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SamplerPropertyModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanExporterModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanProcessorModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanProcessorPropertyModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.TracerProviderModel; import java.util.ArrayList; import java.util.Collections; -import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; @@ -101,7 +103,8 @@ private void addProcessors(TracerProviderModel model) { allProcessors.add( new SpanProcessorModel() .withAdditionalProperty( - InboundMeasurementMetricsComponentProvider.COMPONENT_NAME, Collections.emptyMap())); + InboundMeasurementMetricsComponentProvider.COMPONENT_NAME, + new SpanProcessorPropertyModel())); String experimentalStacktrace = "stacktrace/development"; Optional modelOptional = @@ -112,21 +115,24 @@ private void addProcessors(TracerProviderModel model) { .findFirst(); if (!modelOptional.isPresent()) { - Map properties = new HashMap<>(); - properties.put("filter", SPAN_STACKTRACE_FILTER_CLASS); allProcessors.add( - new SpanProcessorModel().withAdditionalProperty(experimentalStacktrace, properties)); + new SpanProcessorModel() + .withAdditionalProperty( + experimentalStacktrace, + new SpanProcessorPropertyModel() + .withAdditionalProperty("filter", SPAN_STACKTRACE_FILTER_CLASS))); } else { SpanProcessorModel spanProcessorModel = modelOptional.get(); - @SuppressWarnings("unchecked") - Map additionalProperties = - (Map) - spanProcessorModel.getAdditionalProperties().get(experimentalStacktrace); + SpanProcessorPropertyModel spanProcessorPropertyModel = + spanProcessorModel.getAdditionalProperties().get(experimentalStacktrace); + Map additionalProperties = + spanProcessorPropertyModel.getAdditionalProperties(); if (!additionalProperties.containsKey("filter")) { - Map newProperties = new HashMap<>(additionalProperties); - newProperties.put("filter", SPAN_STACKTRACE_FILTER_CLASS); - spanProcessorModel.setAdditionalProperty(experimentalStacktrace, newProperties); + spanProcessorModel.setAdditionalProperty( + experimentalStacktrace, + spanProcessorPropertyModel.withAdditionalProperty( + "filter", SPAN_STACKTRACE_FILTER_CLASS)); } } @@ -137,7 +143,7 @@ private void addSampler(TracerProviderModel model) { model.withSampler( new SamplerModel() .withAdditionalProperty( - SamplerComponentProvider.COMPONENT_NAME, Collections.emptyMap())); + SamplerComponentProvider.COMPONENT_NAME, new SamplerPropertyModel())); } private void addContextPropagators(PropagatorModel model) { @@ -180,16 +186,6 @@ private void addMetricExporter(OpenTelemetryConfigurationModel model) { return; } - Map configs = new HashMap<>(); - configs.put("timeout", 10000); - configs.put("protocol", "grpc"); - - configs.put("compression", "gzip"); - configs.put("endpoint", serviceKeyAndEndpoint[1]); - configs.put("temporality_preference", "cumulative"); - - configs.put("default_histogram_aggregation", "explicit_bucket_histogram"); - configs.put("headers_list", String.format("authorization=Bearer %s", serviceKeyAndEndpoint[0])); model.withMeterProvider( new MeterProviderModel() .withReaders( @@ -203,7 +199,22 @@ private void addMetricExporter(OpenTelemetryConfigurationModel model) { new PushMetricExporterModel() .withAdditionalProperty( MetricExporterComponentProvider.COMPONENT_NAME, - configs)))))); + new PushMetricExporterPropertyModel() + .withAdditionalProperty("timeout", 10000) + .withAdditionalProperty("protocol", "grpc") + .withAdditionalProperty("compression", "gzip") + .withAdditionalProperty( + "endpoint", serviceKeyAndEndpoint[1]) + .withAdditionalProperty( + "temporality_preference", "delta") + .withAdditionalProperty( + "default_histogram_aggregation", + "base2_exponential_bucket_histogram") + .withAdditionalProperty( + "headers_list", + String.format( + "authorization=Bearer %s", + serviceKeyAndEndpoint[0])))))))); } private void addLogExporter(OpenTelemetryConfigurationModel model) { @@ -214,7 +225,10 @@ private void addLogExporter(OpenTelemetryConfigurationModel model) { processors.stream() .anyMatch(logRecordProcessorModel -> logRecordProcessorModel.getBatch() != null); - if (hasExporter) return; + if (hasExporter) { + return; + } + LogRecordProcessorModel logRecordProcessorModel = new LogRecordProcessorModel() .withBatch( @@ -233,6 +247,7 @@ private void addLogExporter(OpenTelemetryConfigurationModel model) { private void setServiceKeyAndEndpoint(OpenTelemetryConfigurationModel model) { DeclarativeConfigProperties configProperties = DeclarativeConfiguration.toConfigProperties(model); + DeclarativeConfigProperties solarwinds = configProperties .getStructured("instrumentation/development", DeclarativeConfigProperties.empty()) diff --git a/libs/shared/src/test/java/com/solarwinds/opentelemetry/extensions/MetricExporterCustomizerTest.java b/libs/shared/src/test/java/com/solarwinds/opentelemetry/extensions/MetricExporterCustomizerTest.java index 681e1c2c..07ab7f84 100644 --- a/libs/shared/src/test/java/com/solarwinds/opentelemetry/extensions/MetricExporterCustomizerTest.java +++ b/libs/shared/src/test/java/com/solarwinds/opentelemetry/extensions/MetricExporterCustomizerTest.java @@ -19,12 +19,16 @@ import static com.solarwinds.opentelemetry.extensions.SharedNames.SW_OTEL_PROXY_HOST_KEY; import static com.solarwinds.opentelemetry.extensions.SharedNames.SW_OTEL_PROXY_PORT_KEY; import static org.junit.jupiter.api.Assertions.assertInstanceOf; -import static org.junit.jupiter.api.Assertions.assertNotSame; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporter; +import io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; +import io.opentelemetry.sdk.common.export.ProxyOptions; import io.opentelemetry.sdk.metrics.export.MetricExporter; import java.util.Collections; import org.junit.jupiter.api.Test; @@ -56,13 +60,19 @@ void shouldReturnDelegatingExporterWhenProxyNotConfigured() { } @Test - void shouldReturnNewExporterWhenProxyConfigured() { + void shouldCallSetProxyOptionsWhenProxyConfigured() { when(configProperties.getString(SW_OTEL_PROXY_HOST_KEY)).thenReturn("localhost"); when(configProperties.getInt(SW_OTEL_PROXY_PORT_KEY)).thenReturn(8080); - OtlpHttpMetricExporter originalExporter = OtlpHttpMetricExporter.builder().build(); - MetricExporter result = tested.apply(originalExporter, configProperties); + OtlpHttpMetricExporter originalExporter = mock(OtlpHttpMetricExporter.class); + OtlpHttpMetricExporterBuilder builder = mock(OtlpHttpMetricExporterBuilder.class); + + when(originalExporter.toBuilder()).thenReturn(builder); + when(builder.setProxyOptions(any(ProxyOptions.class))).thenReturn(builder); + when(builder.build()).thenReturn(mock(OtlpHttpMetricExporter.class)); - assertNotSame(originalExporter, result); + MetricExporter result = tested.apply(originalExporter, configProperties); + verify(builder).setProxyOptions(any(ProxyOptions.class)); + assertInstanceOf(DelegatingMetricExporter.class, result); } } diff --git a/libs/shared/src/test/java/com/solarwinds/opentelemetry/extensions/config/provider/SharedConfigCustomizerProviderTest.java b/libs/shared/src/test/java/com/solarwinds/opentelemetry/extensions/config/provider/SharedConfigCustomizerProviderTest.java index c1830c30..76786844 100644 --- a/libs/shared/src/test/java/com/solarwinds/opentelemetry/extensions/config/provider/SharedConfigCustomizerProviderTest.java +++ b/libs/shared/src/test/java/com/solarwinds/opentelemetry/extensions/config/provider/SharedConfigCustomizerProviderTest.java @@ -25,8 +25,9 @@ import io.opentelemetry.sdk.extension.incubator.fileconfig.DeclarativeConfigurationCustomizer; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributeLimitsModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.BatchLogRecordProcessorModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalInstrumentationModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalLanguageSpecificInstrumentationModel; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.InstrumentationModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalLanguageSpecificInstrumentationPropertyModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordExporterModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordProcessorModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LoggerProviderModel; @@ -35,9 +36,9 @@ import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PeriodicMetricReaderModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SamplerModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanProcessorModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanProcessorPropertyModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.TracerProviderModel; import java.util.Collections; -import java.util.HashMap; import java.util.Map; import java.util.Optional; import java.util.function.Function; @@ -65,21 +66,18 @@ void testCustomize() { OpenTelemetryConfigurationModel openTelemetryConfigurationModel = new OpenTelemetryConfigurationModel() .withInstrumentationDevelopment( - new InstrumentationModel() + new ExperimentalInstrumentationModel() .withJava( new ExperimentalLanguageSpecificInstrumentationModel() .withAdditionalProperty( "solarwinds", - new HashMap() { - { - put( + new ExperimentalLanguageSpecificInstrumentationPropertyModel() + .withAdditionalProperty( ConfigProperty.AGENT_SERVICE_KEY.getConfigFileKey(), - "token:service"); - put( + "token:service") + .withAdditionalProperty( ConfigProperty.AGENT_COLLECTOR.getConfigFileKey(), - "apm.collector.com"); - } - }))); + "apm.collector.com")))); doNothing() .when(declarativeConfigurationCustomizerMock) @@ -133,21 +131,18 @@ void testCustomize1() { OpenTelemetryConfigurationModel openTelemetryConfigurationModel = new OpenTelemetryConfigurationModel() .withInstrumentationDevelopment( - new InstrumentationModel() + new ExperimentalInstrumentationModel() .withJava( new ExperimentalLanguageSpecificInstrumentationModel() .withAdditionalProperty( "solarwinds", - new HashMap() { - { - put( + new ExperimentalLanguageSpecificInstrumentationPropertyModel() + .withAdditionalProperty( ConfigProperty.AGENT_SERVICE_KEY.getConfigFileKey(), - "token:service"); - put( + "token:service") + .withAdditionalProperty( ConfigProperty.AGENT_COLLECTOR.getConfigFileKey(), - "apm.collector.com"); - } - }))); + "apm.collector.com")))); doNothing() .when(declarativeConfigurationCustomizerMock) @@ -174,22 +169,22 @@ void testCustomize1() { PeriodicMetricReaderModel periodic = openTelemetryConfigurationModel.getMeterProvider().getReaders().get(0).getPeriodic(); - @SuppressWarnings("unchecked") Map configs = - (Map) - periodic - .getExporter() - .getAdditionalProperties() - .get(MetricExporterComponentProvider.COMPONENT_NAME); - assertNotNull(configs); + periodic + .getExporter() + .getAdditionalProperties() + .get(MetricExporterComponentProvider.COMPONENT_NAME) + .getAdditionalProperties(); + assertNotNull(configs); assertEquals(10000, configs.get("timeout")); assertEquals("grpc", configs.get("protocol")); assertEquals("gzip", configs.get("compression")); assertEquals("https://otel.collector.com", configs.get("endpoint")); - assertEquals("cumulative", configs.get("temporality_preference")); - assertEquals("explicit_bucket_histogram", configs.get("default_histogram_aggregation")); + assertEquals("delta", configs.get("temporality_preference")); + assertEquals( + "base2_exponential_bucket_histogram", configs.get("default_histogram_aggregation")); assertEquals("authorization=Bearer token", configs.get("headers_list")); } @@ -199,10 +194,12 @@ void testCustomizeSetsExperimentalStacktraceWhenNotSet() { OpenTelemetryConfigurationModel openTelemetryConfigurationModel = new OpenTelemetryConfigurationModel() .withInstrumentationDevelopment( - new InstrumentationModel() + new ExperimentalInstrumentationModel() .withJava( new ExperimentalLanguageSpecificInstrumentationModel() - .withAdditionalProperty("solarwinds", Collections.emptyMap()))); + .withAdditionalProperty( + "solarwinds", + new ExperimentalLanguageSpecificInstrumentationPropertyModel()))); doNothing() .when(declarativeConfigurationCustomizerMock) @@ -233,12 +230,14 @@ void testCustomizeSetExperimentalStacktraceFilterWhenNotSet() { Collections.singletonList( new SpanProcessorModel() .withAdditionalProperty( - "stacktrace/development", Collections.emptyMap())))) + "stacktrace/development", new SpanProcessorPropertyModel())))) .withInstrumentationDevelopment( - new InstrumentationModel() + new ExperimentalInstrumentationModel() .withJava( new ExperimentalLanguageSpecificInstrumentationModel() - .withAdditionalProperty("solarwinds", Collections.emptyMap()))); + .withAdditionalProperty( + "solarwinds", + new ExperimentalLanguageSpecificInstrumentationPropertyModel()))); doNothing() .when(declarativeConfigurationCustomizerMock) @@ -256,8 +255,10 @@ void testCustomizeSetExperimentalStacktraceFilterWhenNotSet() { processorModel.getAdditionalProperties().containsKey("stacktrace/development")) .map( processorModel -> - (Map) - processorModel.getAdditionalProperties().get("stacktrace/development")) + processorModel + .getAdditionalProperties() + .get("stacktrace/development") + .getAdditionalProperties()) .findFirst(); assertTrue(map.isPresent()); @@ -269,21 +270,18 @@ void testCustomize2() { OpenTelemetryConfigurationModel openTelemetryConfigurationModel = new OpenTelemetryConfigurationModel() .withInstrumentationDevelopment( - new InstrumentationModel() + new ExperimentalInstrumentationModel() .withJava( new ExperimentalLanguageSpecificInstrumentationModel() .withAdditionalProperty( "solarwinds", - new HashMap() { - { - put( + new ExperimentalLanguageSpecificInstrumentationPropertyModel() + .withAdditionalProperty( ConfigProperty.AGENT_SERVICE_KEY.getConfigFileKey(), - "token:service"); - put( + "token:service") + .withAdditionalProperty( ConfigProperty.AGENT_COLLECTOR.getConfigFileKey(), - "http://apm.collector.com"); - } - }))); + "http://apm.collector.com")))); doNothing() .when(declarativeConfigurationCustomizerMock) @@ -310,21 +308,18 @@ void UrlShouldNotChangeWhenNotApm() { OpenTelemetryConfigurationModel openTelemetryConfigurationModel = new OpenTelemetryConfigurationModel() .withInstrumentationDevelopment( - new InstrumentationModel() + new ExperimentalInstrumentationModel() .withJava( new ExperimentalLanguageSpecificInstrumentationModel() .withAdditionalProperty( "solarwinds", - new HashMap() { - { - put( + new ExperimentalLanguageSpecificInstrumentationPropertyModel() + .withAdditionalProperty( ConfigProperty.AGENT_SERVICE_KEY.getConfigFileKey(), - "token:service"); - put( + "token:service") + .withAdditionalProperty( ConfigProperty.AGENT_COLLECTOR.getConfigFileKey(), - "http://example.com"); - } - }))); + "http://example.com")))); doNothing() .when(declarativeConfigurationCustomizerMock) @@ -351,21 +346,18 @@ void UrlShouldNotChangeWhenNotApm2() { OpenTelemetryConfigurationModel openTelemetryConfigurationModel = new OpenTelemetryConfigurationModel() .withInstrumentationDevelopment( - new InstrumentationModel() + new ExperimentalInstrumentationModel() .withJava( new ExperimentalLanguageSpecificInstrumentationModel() .withAdditionalProperty( "solarwinds", - new HashMap() { - { - put( + new ExperimentalLanguageSpecificInstrumentationPropertyModel() + .withAdditionalProperty( ConfigProperty.AGENT_SERVICE_KEY.getConfigFileKey(), - "token:service"); - put( + "token:service") + .withAdditionalProperty( ConfigProperty.AGENT_COLLECTOR.getConfigFileKey(), - "http://localhost:4317"); - } - }))); + "http://localhost:4317")))); doNothing() .when(declarativeConfigurationCustomizerMock)