Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.api.incubator.authenticator;

import java.util.Map;

public interface ExporterAuthenticator {
Map<String, String> getAuthenticationHeaders();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.api.incubator.config;

/**
* This class is internal and is hence not for public use. Its APIs are unstable and can change at
* any time.
*/
public interface ComponentProviderLoader {
<T> T loadComponent(Class<T> type, String name, DeclarativeConfigProperties properties);
}
Original file line number Diff line number Diff line change
Expand Up @@ -232,4 +232,8 @@ default List<DeclarativeConfigProperties> getStructuredList(

/** Return a {@link ComponentLoader} that should be used to load SPIs. */
ComponentLoader getComponentLoader();

default ComponentProviderLoader getComponentProviderLoader() {
return EmptyComponentProviderLoader.getInstance();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.api.incubator.config;

final class EmptyComponentProviderLoader implements ComponentProviderLoader {

private static final EmptyComponentProviderLoader INSTANCE = new EmptyComponentProviderLoader();

EmptyComponentProviderLoader() {}

static ComponentProviderLoader getInstance() {
return INSTANCE;
}

@Override
public <T> T loadComponent(Class<T> type, String name, DeclarativeConfigProperties properties) {
throw new UnsupportedOperationException("Empty ComponentProviderLoader is not implemented");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.readFileBytes;
import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.validateEndpoint;

import io.opentelemetry.api.incubator.authenticator.ExporterAuthenticator;
import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties;
import io.opentelemetry.common.ComponentLoader;
import io.opentelemetry.exporter.internal.IncubatingExporterBuilderUtil;
Expand All @@ -22,8 +23,11 @@
import java.time.Duration;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Supplier;

/**
* This class is internal and is hence not for public use. Its APIs are unstable and can change at
Expand Down Expand Up @@ -51,6 +55,7 @@ public static void configureOtlpExporterBuilder(
Consumer<ComponentLoader> setComponentLoader,
Consumer<String> setEndpoint,
BiConsumer<String, String> addHeader,
Consumer<Supplier<Map<String, String>>> setHeaders,
Consumer<String> setCompression,
Consumer<Duration> setTimeout,
Consumer<byte[]> setTrustedCertificates,
Expand All @@ -65,6 +70,27 @@ public static void configureOtlpExporterBuilder(
setEndpoint.accept(endpoint.toString());
}

DeclarativeConfigProperties authenticator = config.getStructured("authenticator");
if (authenticator != null) {
Set<String> propertyKeys = authenticator.getPropertyKeys();
int size = propertyKeys.size();
if (size != 1) {
throw new ConfigurationException(
"authenticator must be a single structured property, but found "
+ size
+ " properties: "
+ propertyKeys);
}

String authenticatorName = propertyKeys.iterator().next();
ExporterAuthenticator exporterAuthenticator =
config
.getComponentProviderLoader()
.loadComponent(ExporterAuthenticator.class, authenticatorName, authenticator);

setHeaders.accept(exporterAuthenticator::getAuthenticationHeaders);
}

String headerList = config.getString("headers_list");
if (headerList != null) {
ConfigProperties headersListConfig =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ public LogRecordExporter create(DeclarativeConfigProperties config) {
builder::setComponentLoader,
builder::setEndpoint,
builder::addHeader,
builder::setHeaders,
builder::setCompression,
builder::setTimeout,
builder::setTrustedCertificates,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ public MetricExporter create(DeclarativeConfigProperties config) {
builder::setComponentLoader,
builder::setEndpoint,
builder::addHeader,
builder::setHeaders,
builder::setCompression,
builder::setTimeout,
builder::setTrustedCertificates,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ public SpanExporter create(DeclarativeConfigProperties config) {
builder::setComponentLoader,
builder::setEndpoint,
builder::addHeader,
builder::setHeaders,
builder::setCompression,
builder::setTimeout,
builder::setTrustedCertificates,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ public LogRecordExporter create(DeclarativeConfigProperties config) {
builder::setComponentLoader,
builder::setEndpoint,
builder::addHeader,
builder::setHeaders,
builder::setCompression,
builder::setTimeout,
builder::setTrustedCertificates,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ public MetricExporter create(DeclarativeConfigProperties config) {
builder::setComponentLoader,
builder::setEndpoint,
builder::addHeader,
builder::setHeaders,
builder::setCompression,
builder::setTimeout,
builder::setTrustedCertificates,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ public SpanExporter create(DeclarativeConfigProperties config) {
builder::setComponentLoader,
builder::setEndpoint,
builder::addHeader,
builder::setHeaders,
builder::setCompression,
builder::setTimeout,
builder::setTrustedCertificates,
Expand Down
5 changes: 3 additions & 2 deletions sdk-extensions/incubator/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,9 @@ dependencies {
// ... proceed with normal sourcesJar, compileJava, etc

val configurationTag = "1.0.0-rc.1"
val configurationRef = "refs/tags/v$configurationTag" // Replace with commit SHA to point to experiment with a specific commit
val configurationRepoZip = "https://github.com/open-telemetry/opentelemetry-configuration/archive/$configurationRef.zip"
// todo revert this when config PR is merged: https://github.com/open-telemetry/opentelemetry-configuration/pull/275
val configurationRef = "refs/heads/authenticator" // Replace with commit SHA to point to experiment with a specific commit
val configurationRepoZip = "https://github.com/zeitlinger/opentelemetry-configuration/archive/$configurationRef.zip"
val buildDirectory = layout.buildDirectory.asFile.get()

val downloadConfigurationSchema by tasks.registering(Download::class) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,12 @@ List<Closeable> getCloseables() {
@SuppressWarnings({"unchecked", "rawtypes"})
<T> T loadComponent(Class<T> type, String name, Object model) {
DeclarativeConfigProperties config =
DeclarativeConfiguration.toConfigProperties(model, spiHelper.getComponentLoader());
new DeclarativeConfigPropertiesWithComponentProviderLoader(
model instanceof DeclarativeConfigProperties
? (DeclarativeConfigProperties) model
: DeclarativeConfiguration.toConfigProperties(
model, spiHelper.getComponentLoader()),
this::loadComponent);

// TODO(jack-berg): cache loaded component providers
List<ComponentProvider> componentProviders = spiHelper.load(ComponentProvider.class);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.sdk.extension.incubator.fileconfig;

import io.opentelemetry.api.incubator.config.ComponentProviderLoader;
import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties;
import io.opentelemetry.common.ComponentLoader;
import java.util.List;
import java.util.Set;
import javax.annotation.Nullable;

class DeclarativeConfigPropertiesWithComponentProviderLoader
implements DeclarativeConfigProperties {
private final DeclarativeConfigProperties properties;
private final ComponentProviderLoader componentProviderLoader;

DeclarativeConfigPropertiesWithComponentProviderLoader(
DeclarativeConfigProperties properties, ComponentProviderLoader componentProviderLoader) {
this.properties = properties;
this.componentProviderLoader = componentProviderLoader;
}

@Nullable
@Override
public String getString(String name) {
return properties.getString(name);
}

@Nullable
@Override
public Boolean getBoolean(String name) {
return properties.getBoolean(name);
}

@Nullable
@Override
public Integer getInt(String name) {
return properties.getInt(name);
}

@Nullable
@Override
public Long getLong(String name) {
return properties.getLong(name);
}

@Nullable
@Override
public Double getDouble(String name) {
return properties.getDouble(name);
}

@Nullable
@Override
public <T> List<T> getScalarList(String name, Class<T> scalarType) {
return properties.getScalarList(name, scalarType);
}

@Nullable
@Override
public DeclarativeConfigProperties getStructured(String name) {
return properties.getStructured(name);
}

@Nullable
@Override
public List<DeclarativeConfigProperties> getStructuredList(String name) {
return properties.getStructuredList(name);
}

@Override
public Set<String> getPropertyKeys() {
return properties.getPropertyKeys();
}

@Override
public ComponentLoader getComponentLoader() {
return properties.getComponentLoader();
}

@Override
public ComponentProviderLoader getComponentProviderLoader() {
return componentProviderLoader;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ public static YamlDeclarativeConfigProperties create(
+ "\" has unrecognized object type "
+ value.getClass().getName());
}

return new YamlDeclarativeConfigProperties(
simpleEntries, listEntries, mapEntries, componentLoader);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.sdk.extension.incubator.fileconfig;

import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;

import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper;
import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import org.junit.jupiter.api.extension.BeforeEachCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.mockito.Mockito;

public class ComponentProviderExtension implements BeforeEachCallback {

private final SpiHelper spiHelper =
spy(SpiHelper.create(SpanExporterFactoryTest.class.getClassLoader()));
private final DeclarativeConfigContext context = new DeclarativeConfigContext(spiHelper);

private List<ComponentProvider<?>> loadedComponentProviders = Collections.emptyList();

@SuppressWarnings("unchecked")
@Override
public void beforeEach(ExtensionContext context) throws Exception {
when(spiHelper.load(ComponentProvider.class))
.thenAnswer(
invocation -> {
List<ComponentProvider<?>> result =
(List<ComponentProvider<?>>) invocation.callRealMethod();

// only capture first invocation for exporter, not second for authenticator
if (loadedComponentProviders.isEmpty()) {
loadedComponentProviders =
result.stream().map(Mockito::spy).collect(Collectors.toList());
return loadedComponentProviders;
}
return result;
});
}

DeclarativeConfigContext getContext() {
return context;
}

ComponentProvider<?> getComponentProvider(String name, Class<?> type) {
return loadedComponentProviders.stream()
.filter(
componentProvider ->
componentProvider.getName().equals(name)
&& componentProvider.getType().equals(type))
.findFirst()
.orElseThrow(IllegalStateException::new);
}
}
Loading
Loading