diff --git a/dynamic-control/src/main/java/io/opentelemetry/contrib/dynamic/policy/source/SourceKind.java b/dynamic-control/src/main/java/io/opentelemetry/contrib/dynamic/policy/source/SourceKind.java new file mode 100644 index 000000000..6a8b4a2a6 --- /dev/null +++ b/dynamic-control/src/main/java/io/opentelemetry/contrib/dynamic/policy/source/SourceKind.java @@ -0,0 +1,63 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.contrib.dynamic.policy.source; + +import java.util.Locale; +import java.util.Objects; + +/** + * Identifies where policy configuration is loaded from for registry initialization (e.g. local + * file, OpAMP, HTTP). Distinct from {@link SourceFormat}, which describes how individual policy + * lines or payloads are encoded (key-value vs JSON). + */ +public enum SourceKind { + /** Policies loaded from a local file (e.g. line-per-policy file). */ + FILE("file"), + + /** Policies delivered via OpAMP (remote management). */ + OPAMP("opamp"), + + /** Policies fetched from an HTTP/HTTPS endpoint. */ + HTTP("http"), + + /** User-defined or extension provider. */ + CUSTOM("custom"); + + private final String configValue; + + SourceKind(String configValue) { + this.configValue = configValue; + } + + /** + * Stable string used in registry JSON configuration (lowercase). + * + * @return the config value for this kind + */ + public String configValue() { + return configValue; + } + + /** + * Parses the value used in JSON configuration. Leading and trailing whitespace is removed, then + * the remainder is matched case-insensitively against {@link #configValue()} for each kind. + * + * @param value the string from config (e.g. {@code "file"}, {@code "OPAMP"}) + * @return the matching kind + * @throws NullPointerException if value is null + * @throws IllegalArgumentException if no kind matches the trimmed value + */ + public static SourceKind fromConfigValue(String value) { + Objects.requireNonNull(value, "value cannot be null"); + String normalized = value.trim().toLowerCase(Locale.ROOT); + for (SourceKind kind : values()) { + if (kind.configValue.equals(normalized)) { + return kind; + } + } + throw new IllegalArgumentException("Unknown source kind: " + value); + } +} diff --git a/dynamic-control/src/test/java/io/opentelemetry/contrib/dynamic/policy/source/SourceKindTest.java b/dynamic-control/src/test/java/io/opentelemetry/contrib/dynamic/policy/source/SourceKindTest.java new file mode 100644 index 000000000..34576a54a --- /dev/null +++ b/dynamic-control/src/test/java/io/opentelemetry/contrib/dynamic/policy/source/SourceKindTest.java @@ -0,0 +1,47 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.contrib.dynamic.policy.source; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import org.junit.jupiter.api.Test; + +class SourceKindTest { + + @Test + void configValuesAreStableLowercase() { + assertThat(SourceKind.FILE.configValue()).isEqualTo("file"); + assertThat(SourceKind.OPAMP.configValue()).isEqualTo("opamp"); + assertThat(SourceKind.HTTP.configValue()).isEqualTo("http"); + assertThat(SourceKind.CUSTOM.configValue()).isEqualTo("custom"); + } + + @Test + void fromConfigValueParsesCaseInsensitive() { + assertThat(SourceKind.fromConfigValue("FILE")).isEqualTo(SourceKind.FILE); + assertThat(SourceKind.fromConfigValue("Opamp")).isEqualTo(SourceKind.OPAMP); + } + + @Test + void fromConfigValueTrimsWhitespace() { + assertThat(SourceKind.fromConfigValue(" http ")).isEqualTo(SourceKind.HTTP); + } + + @Test + void fromConfigValueRejectsNullInput() { + assertThatThrownBy(() -> SourceKind.fromConfigValue(null)) + .isInstanceOf(NullPointerException.class) + .hasMessage("value cannot be null"); + } + + @Test + void fromConfigValueRejectsUnknownValue() { + assertThatThrownBy(() -> SourceKind.fromConfigValue("unknown")) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("Unknown source kind: unknown"); + } +}