Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 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
3 changes: 3 additions & 0 deletions api/incubator/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ dependencies {

annotationProcessor("com.google.auto.value:auto-value")

// To use parsed config file as input for InstrumentationConfigUtilTest
testImplementation(project(":sdk-extensions:incubator"))

testImplementation(project(":sdk:testing"))
testImplementation(project(":api:testing-internal"))

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

package io.opentelemetry.api.incubator.config;

import javax.annotation.Nullable;
import javax.annotation.concurrent.ThreadSafe;

/**
* A registry for accessing declarative configuration.
*
* <p>The name <i>Provider</i> is for consistency with other languages and it is <b>NOT</b> loaded
* using reflection.
*
* <p>See {@link InstrumentationConfigUtil} for convenience methods for extracting config from
* {@link ConfigProvider}.
*/
@ThreadSafe
public interface ConfigProvider {

/**
* Returns the {@link DeclarativeConfigProperties} corresponding to <a
* href="https://github.com/open-telemetry/opentelemetry-configuration/blob/main/schema/instrumentation.json">instrumentation
* config</a>, or {@code null} if unavailable.
*
* @return the instrumentation {@link DeclarativeConfigProperties}
*/
@Nullable
DeclarativeConfigProperties getInstrumentationConfig();

/** Returns a no-op {@link ConfigProvider}. */
static ConfigProvider noop() {
return () -> null;
}
}
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;

/** An exception that is thrown when errors occur with declarative configuration. */
public final class DeclarativeConfigException extends RuntimeException {

private static final long serialVersionUID = 3036584181551130522L;

/** Create a new configuration exception with specified {@code message} and without a cause. */
public DeclarativeConfigException(String message) {
super(message);
}

/** Create a new configuration exception with specified {@code message} and {@code cause}. */
public DeclarativeConfigException(String message, Throwable cause) {
super(message, cause);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,43 +3,41 @@
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.sdk.autoconfigure.spi.internal;
package io.opentelemetry.api.incubator.config;

import static io.opentelemetry.api.internal.ConfigUtil.defaultIfNull;

import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException;
import java.util.List;
import java.util.Set;
import javax.annotation.Nullable;

/**
* An interface for accessing structured configuration data.
* An interface for accessing declarative configuration data.
*
* <p>An instance of {@link StructuredConfigProperties} is equivalent to a <a
* <p>An instance of {@link DeclarativeConfigProperties} is equivalent to a <a
* href="https://yaml.org/spec/1.2.2/#3211-nodes">YAML mapping node</a>. It has accessors for
* reading scalar properties, {@link #getStructured(String)} for reading children which are
* themselves mappings, and {@link #getStructuredList(String)} for reading children which are
* sequences of mappings.
*/
public interface StructuredConfigProperties {
public interface DeclarativeConfigProperties {

/**
* Return an empty {@link StructuredConfigProperties} instance.
* Return an empty {@link DeclarativeConfigProperties} instance.
*
* <p>Useful for walking the tree without checking for null. For example, to access a string key
* nested at .foo.bar.baz, call: {@code config.getStructured("foo", empty()).getStructured("bar",
* empty()).getString("baz")}.
*/
static StructuredConfigProperties empty() {
return EmptyStructuredConfigProperties.getInstance();
static DeclarativeConfigProperties empty() {
return EmptyDeclarativeConfigProperties.getInstance();
}

/**
* Returns a {@link String} configuration property.
*
* @return null if the property has not been configured
* @throws ConfigurationException if the property is not a valid scalar string
* @throws DeclarativeConfigException if the property is not a valid scalar string
*/
@Nullable
String getString(String name);
Expand All @@ -49,7 +47,7 @@ static StructuredConfigProperties empty() {
*
* @return a {@link String} configuration property or {@code defaultValue} if a property with
* {@code name} has not been configured
* @throws ConfigurationException if the property is not a valid scalar string
* @throws DeclarativeConfigException if the property is not a valid scalar string
*/
default String getString(String name, String defaultValue) {
return defaultIfNull(getString(name), defaultValue);
Expand All @@ -60,7 +58,7 @@ default String getString(String name, String defaultValue) {
* {@link Boolean#parseBoolean(String)} for handling the values.
*
* @return null if the property has not been configured
* @throws ConfigurationException if the property is not a valid scalar boolean
* @throws DeclarativeConfigException if the property is not a valid scalar boolean
*/
@Nullable
Boolean getBoolean(String name);
Expand All @@ -70,7 +68,7 @@ default String getString(String name, String defaultValue) {
*
* @return a {@link Boolean} configuration property or {@code defaultValue} if a property with
* {@code name} has not been configured
* @throws ConfigurationException if the property is not a valid scalar boolean
* @throws DeclarativeConfigException if the property is not a valid scalar boolean
*/
default boolean getBoolean(String name, boolean defaultValue) {
return defaultIfNull(getBoolean(name), defaultValue);
Expand All @@ -83,7 +81,7 @@ default boolean getBoolean(String name, boolean defaultValue) {
* {@link Long#intValue()} which may result in loss of precision.
*
* @return null if the property has not been configured
* @throws ConfigurationException if the property is not a valid scalar integer
* @throws DeclarativeConfigException if the property is not a valid scalar integer
*/
@Nullable
Integer getInt(String name);
Expand All @@ -96,7 +94,7 @@ default boolean getBoolean(String name, boolean defaultValue) {
*
* @return a {@link Integer} configuration property or {@code defaultValue} if a property with
* {@code name} has not been configured
* @throws ConfigurationException if the property is not a valid scalar integer
* @throws DeclarativeConfigException if the property is not a valid scalar integer
*/
default int getInt(String name, int defaultValue) {
return defaultIfNull(getInt(name), defaultValue);
Expand All @@ -106,7 +104,7 @@ default int getInt(String name, int defaultValue) {
* Returns a {@link Long} configuration property.
*
* @return null if the property has not been configured
* @throws ConfigurationException if the property is not a valid scalar long
* @throws DeclarativeConfigException if the property is not a valid scalar long
*/
@Nullable
Long getLong(String name);
Expand All @@ -116,7 +114,7 @@ default int getInt(String name, int defaultValue) {
*
* @return a {@link Long} configuration property or {@code defaultValue} if a property with {@code
* name} has not been configured
* @throws ConfigurationException if the property is not a valid scalar long
* @throws DeclarativeConfigException if the property is not a valid scalar long
*/
default long getLong(String name, long defaultValue) {
return defaultIfNull(getLong(name), defaultValue);
Expand All @@ -126,7 +124,7 @@ default long getLong(String name, long defaultValue) {
* Returns a {@link Double} configuration property.
*
* @return null if the property has not been configured
* @throws ConfigurationException if the property is not a valid scalar double
* @throws DeclarativeConfigException if the property is not a valid scalar double
*/
@Nullable
Double getDouble(String name);
Expand All @@ -136,7 +134,7 @@ default long getLong(String name, long defaultValue) {
*
* @return a {@link Double} configuration property or {@code defaultValue} if a property with
* {@code name} has not been configured
* @throws ConfigurationException if the property is not a valid scalar double
* @throws DeclarativeConfigException if the property is not a valid scalar double
*/
default double getDouble(String name, double defaultValue) {
return defaultIfNull(getDouble(name), defaultValue);
Expand All @@ -150,8 +148,8 @@ default double getDouble(String name, double defaultValue) {
* @param scalarType the scalar type, one of {@link String}, {@link Boolean}, {@link Long} or
* {@link Double}
* @return a {@link List} configuration property, or null if the property has not been configured
* @throws ConfigurationException if the property is not a valid sequence of scalars, or if {@code
* scalarType} is not supported
* @throws DeclarativeConfigException if the property is not a valid sequence of scalars, or if
* {@code scalarType} is not supported
*/
@Nullable
<T> List<T> getScalarList(String name, Class<T> scalarType);
Expand All @@ -160,56 +158,58 @@ default double getDouble(String name, double defaultValue) {
* Returns a {@link List} configuration property. Entries which are not strings are converted to
* their string representation.
*
* @see ConfigProperties#getList(String name)
* @param name the property name
* @param scalarType the scalar type, one of {@link String}, {@link Boolean}, {@link Long} or
* {@link Double}
* @return a {@link List} configuration property or {@code defaultValue} if a property with {@code
* name} has not been configured
* @throws ConfigurationException if the property is not a valid sequence of scalars
* @throws DeclarativeConfigException if the property is not a valid sequence of scalars
*/
default <T> List<T> getScalarList(String name, Class<T> scalarType, List<T> defaultValue) {
return defaultIfNull(getScalarList(name, scalarType), defaultValue);
}

/**
* Returns a {@link StructuredConfigProperties} configuration property.
* Returns a {@link DeclarativeConfigProperties} configuration property.
*
* @return a map-valued configuration property, or {@code null} if {@code name} has not been
* configured
* @throws ConfigurationException if the property is not a mapping
* @throws DeclarativeConfigException if the property is not a mapping
*/
@Nullable
StructuredConfigProperties getStructured(String name);
DeclarativeConfigProperties getStructured(String name);

/**
* Returns a {@link StructuredConfigProperties} configuration property.
* Returns a list of {@link DeclarativeConfigProperties} configuration property.
*
* @return a map-valued configuration property, or {@code defaultValue} if {@code name} has not
* been configured
* @throws ConfigurationException if the property is not a mapping
* @throws DeclarativeConfigException if the property is not a mapping
*/
default StructuredConfigProperties getStructured(
String name, StructuredConfigProperties defaultValue) {
default DeclarativeConfigProperties getStructured(
String name, DeclarativeConfigProperties defaultValue) {
return defaultIfNull(getStructured(name), defaultValue);
}

/**
* Returns a list of {@link StructuredConfigProperties} configuration property.
* Returns a list of {@link DeclarativeConfigProperties} configuration property.
*
* @return a list of map-valued configuration property, or {@code null} if {@code name} has not
* been configured
* @throws ConfigurationException if the property is not a sequence of mappings
* @throws DeclarativeConfigException if the property is not a sequence of mappings
*/
@Nullable
List<StructuredConfigProperties> getStructuredList(String name);
List<DeclarativeConfigProperties> getStructuredList(String name);

/**
* Returns a list of {@link StructuredConfigProperties} configuration property.
* Returns a list of {@link DeclarativeConfigProperties} configuration property.
*
* @return a list of map-valued configuration property, or {@code defaultValue} if {@code name}
* has not been configured
* @throws ConfigurationException if the property is not a sequence of mappings
* @throws DeclarativeConfigException if the property is not a sequence of mappings
*/
default List<StructuredConfigProperties> getStructuredList(
String name, List<StructuredConfigProperties> defaultValue) {
default List<DeclarativeConfigProperties> getStructuredList(
String name, List<DeclarativeConfigProperties> defaultValue) {
return defaultIfNull(getStructuredList(name), defaultValue);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,22 @@
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.sdk.autoconfigure.spi.internal;
package io.opentelemetry.api.incubator.config;

import java.util.Collections;
import java.util.List;
import java.util.Set;
import javax.annotation.Nullable;

/** Empty instance of {@link StructuredConfigProperties}. */
final class EmptyStructuredConfigProperties implements StructuredConfigProperties {
/** Empty instance of {@link DeclarativeConfigProperties}. */
final class EmptyDeclarativeConfigProperties implements DeclarativeConfigProperties {

private static final EmptyStructuredConfigProperties INSTANCE =
new EmptyStructuredConfigProperties();
private static final EmptyDeclarativeConfigProperties INSTANCE =
new EmptyDeclarativeConfigProperties();

private EmptyStructuredConfigProperties() {}
private EmptyDeclarativeConfigProperties() {}

static EmptyStructuredConfigProperties getInstance() {
static EmptyDeclarativeConfigProperties getInstance() {
return INSTANCE;
}

Expand Down Expand Up @@ -60,13 +60,13 @@ public <T> List<T> getScalarList(String name, Class<T> scalarType) {

@Nullable
@Override
public StructuredConfigProperties getStructured(String name) {
public DeclarativeConfigProperties getStructured(String name) {
return null;
}

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

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

package io.opentelemetry.api.incubator.config;

import io.opentelemetry.api.GlobalOpenTelemetry;
import java.util.concurrent.atomic.AtomicReference;
import javax.annotation.Nullable;

/**
* This class provides a temporary global accessor for {@link ConfigProvider} until the
* instrumentation config API is marked stable. It will eventually be merged into {@link
* GlobalOpenTelemetry}.
*/
// We intentionally assign to be used for error reporting.
@SuppressWarnings("StaticAssignmentOfThrowable")
public final class GlobalConfigProvider {

private static final AtomicReference<ConfigProvider> instance =
new AtomicReference<>(ConfigProvider.noop());

@SuppressWarnings("NonFinalStaticField")
@Nullable
private static volatile Throwable setInstanceCaller;

private GlobalConfigProvider() {}

/** Returns the globally registered {@link ConfigProvider}. */
// instance cannot be set to null
@SuppressWarnings("NullAway")
public static ConfigProvider get() {
return instance.get();
}

/**
* Sets the global {@link ConfigProvider}. Future calls to {@link #get()} will return the provided
* {@link ConfigProvider} instance. This should be called once as early as possible in your
* application initialization logic.
*
* @throws IllegalStateException when called more than once
*/
public static void set(ConfigProvider configProvider) {
boolean changed = instance.compareAndSet(ConfigProvider.noop(), configProvider);
if (!changed && (configProvider != ConfigProvider.noop())) {
throw new IllegalStateException(
"GlobalConfigProvider.set has already been called. GlobalConfigProvider.set "
+ "must be called only once before any calls to GlobalConfigProvider.get. "
+ "Previous invocation set to cause of this exception.",
setInstanceCaller);
}
setInstanceCaller = new Throwable();
}

/**
* Unsets the global {@link ConfigProvider}. This is only meant to be used from tests which need
* to reconfigure {@link ConfigProvider}.
*/
public static void resetForTest() {
instance.set(ConfigProvider.noop());
}
}
Loading