Skip to content

Commit 1263b5b

Browse files
authored
[dynamic control] Add SourceKind as sources are a known list (#2722)
1 parent 2554246 commit 1263b5b

File tree

2 files changed

+110
-0
lines changed

2 files changed

+110
-0
lines changed
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.contrib.dynamic.policy.source;
7+
8+
import java.util.Locale;
9+
import java.util.Objects;
10+
11+
/**
12+
* Identifies where policy configuration is loaded from for registry initialization (e.g. local
13+
* file, OpAMP, HTTP). Distinct from {@link SourceFormat}, which describes how individual policy
14+
* lines or payloads are encoded (key-value vs JSON).
15+
*/
16+
public enum SourceKind {
17+
/** Policies loaded from a local file (e.g. line-per-policy file). */
18+
FILE("file"),
19+
20+
/** Policies delivered via OpAMP (remote management). */
21+
OPAMP("opamp"),
22+
23+
/** Policies fetched from an HTTP/HTTPS endpoint. */
24+
HTTP("http"),
25+
26+
/** User-defined or extension provider. */
27+
CUSTOM("custom");
28+
29+
private final String configValue;
30+
31+
SourceKind(String configValue) {
32+
this.configValue = configValue;
33+
}
34+
35+
/**
36+
* Stable string used in registry JSON configuration (lowercase).
37+
*
38+
* @return the config value for this kind
39+
*/
40+
public String configValue() {
41+
return configValue;
42+
}
43+
44+
/**
45+
* Parses the value used in JSON configuration. Leading and trailing whitespace is removed, then
46+
* the remainder is matched case-insensitively against {@link #configValue()} for each kind.
47+
*
48+
* @param value the string from config (e.g. {@code "file"}, {@code "OPAMP"})
49+
* @return the matching kind
50+
* @throws NullPointerException if value is null
51+
* @throws IllegalArgumentException if no kind matches the trimmed value
52+
*/
53+
public static SourceKind fromConfigValue(String value) {
54+
Objects.requireNonNull(value, "value cannot be null");
55+
String normalized = value.trim().toLowerCase(Locale.ROOT);
56+
for (SourceKind kind : values()) {
57+
if (kind.configValue.equals(normalized)) {
58+
return kind;
59+
}
60+
}
61+
throw new IllegalArgumentException("Unknown source kind: " + value);
62+
}
63+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.contrib.dynamic.policy.source;
7+
8+
import static org.assertj.core.api.Assertions.assertThat;
9+
import static org.assertj.core.api.Assertions.assertThatThrownBy;
10+
11+
import org.junit.jupiter.api.Test;
12+
13+
class SourceKindTest {
14+
15+
@Test
16+
void configValuesAreStableLowercase() {
17+
assertThat(SourceKind.FILE.configValue()).isEqualTo("file");
18+
assertThat(SourceKind.OPAMP.configValue()).isEqualTo("opamp");
19+
assertThat(SourceKind.HTTP.configValue()).isEqualTo("http");
20+
assertThat(SourceKind.CUSTOM.configValue()).isEqualTo("custom");
21+
}
22+
23+
@Test
24+
void fromConfigValueParsesCaseInsensitive() {
25+
assertThat(SourceKind.fromConfigValue("FILE")).isEqualTo(SourceKind.FILE);
26+
assertThat(SourceKind.fromConfigValue("Opamp")).isEqualTo(SourceKind.OPAMP);
27+
}
28+
29+
@Test
30+
void fromConfigValueTrimsWhitespace() {
31+
assertThat(SourceKind.fromConfigValue(" http ")).isEqualTo(SourceKind.HTTP);
32+
}
33+
34+
@Test
35+
void fromConfigValueRejectsNullInput() {
36+
assertThatThrownBy(() -> SourceKind.fromConfigValue(null))
37+
.isInstanceOf(NullPointerException.class)
38+
.hasMessage("value cannot be null");
39+
}
40+
41+
@Test
42+
void fromConfigValueRejectsUnknownValue() {
43+
assertThatThrownBy(() -> SourceKind.fromConfigValue("unknown"))
44+
.isInstanceOf(IllegalArgumentException.class)
45+
.hasMessage("Unknown source kind: unknown");
46+
}
47+
}

0 commit comments

Comments
 (0)