Skip to content

Commit a707bea

Browse files
committed
drop comparable policies according to priority for an update
1 parent 93457ac commit a707bea

2 files changed

Lines changed: 69 additions & 5 deletions

File tree

dynamic-control/src/main/java/io/opentelemetry/contrib/dynamic/policy/PolicyStore.java

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ public final class PolicyStore {
2828
* Replaces the stored policies with a new accepted snapshot.
2929
*
3030
* <p>Input lists are normalized by policy identity, using policy type and policy id. Duplicate
31-
* policies with the same identity are dropped and only the first occurrence is kept in insertion
32-
* order. The store does not perform value-level no-op detection; providers can use source
33-
* hashes/versions to skip unchanged snapshots, and implementers must apply policies idempotently.
31+
* policies with the same identity are resolved by source kind priority. The store does not
32+
* perform value-level no-op detection; providers can use source hashes/versions to skip unchanged
33+
* snapshots, and implementers must apply policies idempotently.
3434
*
3535
* @return {@code true} after the snapshot is accepted
3636
*/
@@ -105,7 +105,9 @@ private static List<TelemetryPolicy> deletedPoliciesFrom(
105105
PolicyKey policyKey = policyKey(previousPolicy);
106106
TelemetryPolicyIdentity identity = previousPolicy.getIdentity();
107107
if (!activePolicyKeys.contains(policyKey)) {
108-
deletedPolicies.add(new DeletedTelemetryPolicy(identity, previousPolicy.getType()));
108+
deletedPolicies.add(
109+
new DeletedTelemetryPolicy(
110+
identity, previousPolicy.getType(), previousPolicy.getSourceKind()));
109111
}
110112
}
111113
return deletedPolicies;
@@ -117,16 +119,22 @@ private static Map<PolicyKey, TelemetryPolicy> normalizedPolicyMap(
117119
for (TelemetryPolicy policy : policies) {
118120
Objects.requireNonNull(policy, "newPolicies cannot contain null elements");
119121
PolicyKey key = policyKey(policy);
120-
if (!normalized.containsKey(key)) {
122+
TelemetryPolicy existing = normalized.get(key);
123+
if (existing == null || hasHigherPriority(policy, existing)) {
121124
normalized.put(key, policy);
122125
}
123126
}
124127
return normalized;
125128
}
126129

130+
private static boolean hasHigherPriority(TelemetryPolicy candidate, TelemetryPolicy existing) {
131+
return candidate.getSourceKind().hasHigherPriorityThan(existing.getSourceKind());
132+
}
133+
127134
private static PolicyKey policyKey(TelemetryPolicy policy) {
128135
TelemetryPolicyIdentity identity =
129136
Objects.requireNonNull(policy.getIdentity(), "policy identity cannot be null");
137+
Objects.requireNonNull(policy.getSourceKind(), "policy source kind cannot be null");
130138
return new PolicyKey(policy.getType(), identity.getId());
131139
}
132140

dynamic-control/src/test/java/io/opentelemetry/contrib/dynamic/policy/PolicyStoreTest.java

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import static org.mockito.Mockito.verify;
1515
import static org.mockito.Mockito.when;
1616

17+
import io.opentelemetry.contrib.dynamic.policy.source.SourceKind;
1718
import io.opentelemetry.contrib.dynamic.policy.tracesampling.TraceSamplingRatePolicy;
1819
import java.util.Arrays;
1920
import java.util.Collections;
@@ -79,6 +80,49 @@ void updatePoliciesIgnoresDuplicatePolicyIdentitiesInInput() {
7980
assertThat(store.getPolicies()).containsExactly(first);
8081
}
8182

83+
@Test
84+
void updatePoliciesResolvesDuplicatePolicyIdentitiesBySourcePriority() {
85+
PolicyStore store = new PolicyStore();
86+
TelemetryPolicy filePolicy =
87+
new TestTelemetryPolicy(
88+
new TelemetryPolicyIdentity("test-policy", "File policy"),
89+
"test-policy",
90+
SourceKind.FILE);
91+
TelemetryPolicy httpPolicy =
92+
new TestTelemetryPolicy(
93+
new TelemetryPolicyIdentity("test-policy", "HTTP policy"),
94+
"test-policy",
95+
SourceKind.HTTP);
96+
TelemetryPolicy opampPolicy =
97+
new TestTelemetryPolicy(
98+
new TelemetryPolicyIdentity("test-policy", "OpAMP policy"),
99+
"test-policy",
100+
SourceKind.OPAMP);
101+
102+
assertThat(store.updatePolicies(Arrays.asList(filePolicy, opampPolicy, httpPolicy))).isTrue();
103+
104+
assertThat(store.getPolicies()).containsExactly(opampPolicy);
105+
}
106+
107+
@Test
108+
void updatePoliciesUsesHttpWhenDuplicatePolicyHasNoOpampSource() {
109+
PolicyStore store = new PolicyStore();
110+
TelemetryPolicy filePolicy =
111+
new TestTelemetryPolicy(
112+
new TelemetryPolicyIdentity("test-policy", "File policy"),
113+
"test-policy",
114+
SourceKind.FILE);
115+
TelemetryPolicy httpPolicy =
116+
new TestTelemetryPolicy(
117+
new TelemetryPolicyIdentity("test-policy", "HTTP policy"),
118+
"test-policy",
119+
SourceKind.HTTP);
120+
121+
assertThat(store.updatePolicies(Arrays.asList(filePolicy, httpPolicy))).isTrue();
122+
123+
assertThat(store.getPolicies()).containsExactly(httpPolicy);
124+
}
125+
82126
@Test
83127
void getPoliciesReturnsEmptyWhenNeverUpdated() {
84128
assertThat(new PolicyStore().getPolicies()).isEqualTo(Collections.emptyList());
@@ -247,10 +291,17 @@ private static boolean containsTraceSamplingProbability(
247291
private static final class TestTelemetryPolicy implements TelemetryPolicy {
248292
private final TelemetryPolicyIdentity identity;
249293
private final String type;
294+
private final SourceKind sourceKind;
250295

251296
private TestTelemetryPolicy(TelemetryPolicyIdentity identity, String type) {
297+
this(identity, type, SourceKind.CUSTOM);
298+
}
299+
300+
private TestTelemetryPolicy(
301+
TelemetryPolicyIdentity identity, String type, SourceKind sourceKind) {
252302
this.identity = identity;
253303
this.type = type;
304+
this.sourceKind = sourceKind;
254305
}
255306

256307
@Override
@@ -262,5 +313,10 @@ public TelemetryPolicyIdentity getIdentity() {
262313
public String getType() {
263314
return type;
264315
}
316+
317+
@Override
318+
public SourceKind getSourceKind() {
319+
return sourceKind;
320+
}
265321
}
266322
}

0 commit comments

Comments
 (0)