alerting(core): drop unused perExchangeLingerSeconds from ExchangeMatchCondition
Dead field — was enforced by compact ctor as required for PER_EXCHANGE, but never read anywhere in the codebase. Removal tightens the API surface and is precondition for the Task 3.3 cross-field validator. Pre-prod; no shim / migration.
This commit is contained in:
@@ -145,7 +145,7 @@ class AlertRuleControllerIT extends AbstractPostgresIT {
|
|||||||
{"name":"sqli-test","severity":"WARNING","conditionKind":"EXCHANGE_MATCH",
|
{"name":"sqli-test","severity":"WARNING","conditionKind":"EXCHANGE_MATCH",
|
||||||
"condition":{"kind":"EXCHANGE_MATCH","scope":{},
|
"condition":{"kind":"EXCHANGE_MATCH","scope":{},
|
||||||
"filter":{"status":"FAILED","attributes":{"foo'; DROP TABLE executions; --":"x"}},
|
"filter":{"status":"FAILED","attributes":{"foo'; DROP TABLE executions; --":"x"}},
|
||||||
"fireMode":"PER_EXCHANGE","perExchangeLingerSeconds":60}}
|
"fireMode":"PER_EXCHANGE"}}
|
||||||
""";
|
""";
|
||||||
|
|
||||||
ResponseEntity<String> resp = restTemplate.exchange(
|
ResponseEntity<String> resp = restTemplate.exchange(
|
||||||
@@ -164,7 +164,7 @@ class AlertRuleControllerIT extends AbstractPostgresIT {
|
|||||||
{"name":"valid-attr","severity":"WARNING","conditionKind":"EXCHANGE_MATCH",
|
{"name":"valid-attr","severity":"WARNING","conditionKind":"EXCHANGE_MATCH",
|
||||||
"condition":{"kind":"EXCHANGE_MATCH","scope":{},
|
"condition":{"kind":"EXCHANGE_MATCH","scope":{},
|
||||||
"filter":{"status":"FAILED","attributes":{"order.type":"x"}},
|
"filter":{"status":"FAILED","attributes":{"order.type":"x"}},
|
||||||
"fireMode":"PER_EXCHANGE","perExchangeLingerSeconds":60}}
|
"fireMode":"PER_EXCHANGE"}}
|
||||||
""";
|
""";
|
||||||
|
|
||||||
ResponseEntity<String> resp = restTemplate.exchange(
|
ResponseEntity<String> resp = restTemplate.exchange(
|
||||||
|
|||||||
@@ -158,7 +158,7 @@ class AlertEvaluatorJobIT extends AbstractPostgresIT {
|
|||||||
var condition = new ExchangeMatchCondition(
|
var condition = new ExchangeMatchCondition(
|
||||||
new AlertScope(APP_SLUG, null, null),
|
new AlertScope(APP_SLUG, null, null),
|
||||||
new ExchangeMatchCondition.ExchangeFilter("FAILED", Map.of()),
|
new ExchangeMatchCondition.ExchangeFilter("FAILED", Map.of()),
|
||||||
FireMode.PER_EXCHANGE, null, null, 60);
|
FireMode.PER_EXCHANGE, null, null);
|
||||||
var webhook = new WebhookBinding(UUID.randomUUID(), null, null, Map.of());
|
var webhook = new WebhookBinding(UUID.randomUUID(), null, null, Map.of());
|
||||||
var rule = new AlertRule(
|
var rule = new AlertRule(
|
||||||
ruleId2, envId, "per-exchange-rule-" + ruleId2, null,
|
ruleId2, envId, "per-exchange-rule-" + ruleId2, null,
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ class ExchangeMatchEvaluatorTest {
|
|||||||
return new ExchangeMatchCondition(
|
return new ExchangeMatchCondition(
|
||||||
new AlertScope("orders", null, null),
|
new AlertScope("orders", null, null),
|
||||||
new ExchangeMatchCondition.ExchangeFilter("FAILED", Map.of()),
|
new ExchangeMatchCondition.ExchangeFilter("FAILED", Map.of()),
|
||||||
FireMode.PER_EXCHANGE, null, null, 60);
|
FireMode.PER_EXCHANGE, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ExecutionSummary summary(String id, Instant startTime, String status) {
|
private ExecutionSummary summary(String id, Instant startTime, String status) {
|
||||||
@@ -77,7 +77,7 @@ class ExchangeMatchEvaluatorTest {
|
|||||||
var condition = new ExchangeMatchCondition(
|
var condition = new ExchangeMatchCondition(
|
||||||
new AlertScope("orders", null, null),
|
new AlertScope("orders", null, null),
|
||||||
new ExchangeMatchCondition.ExchangeFilter("FAILED", Map.of()),
|
new ExchangeMatchCondition.ExchangeFilter("FAILED", Map.of()),
|
||||||
FireMode.COUNT_IN_WINDOW, 5, 300, null);
|
FireMode.COUNT_IN_WINDOW, 5, 300);
|
||||||
|
|
||||||
when(searchIndex.countExecutionsForAlerting(any())).thenReturn(7L);
|
when(searchIndex.countExecutionsForAlerting(any())).thenReturn(7L);
|
||||||
|
|
||||||
@@ -92,7 +92,7 @@ class ExchangeMatchEvaluatorTest {
|
|||||||
var condition = new ExchangeMatchCondition(
|
var condition = new ExchangeMatchCondition(
|
||||||
new AlertScope("orders", null, null),
|
new AlertScope("orders", null, null),
|
||||||
new ExchangeMatchCondition.ExchangeFilter("FAILED", Map.of()),
|
new ExchangeMatchCondition.ExchangeFilter("FAILED", Map.of()),
|
||||||
FireMode.COUNT_IN_WINDOW, 5, 300, null);
|
FireMode.COUNT_IN_WINDOW, 5, 300);
|
||||||
|
|
||||||
when(searchIndex.countExecutionsForAlerting(any())).thenReturn(3L);
|
when(searchIndex.countExecutionsForAlerting(any())).thenReturn(3L);
|
||||||
|
|
||||||
@@ -105,7 +105,7 @@ class ExchangeMatchEvaluatorTest {
|
|||||||
var condition = new ExchangeMatchCondition(
|
var condition = new ExchangeMatchCondition(
|
||||||
new AlertScope("orders", "direct:pay", null),
|
new AlertScope("orders", "direct:pay", null),
|
||||||
new ExchangeMatchCondition.ExchangeFilter("FAILED", Map.of("orderId", "123")),
|
new ExchangeMatchCondition.ExchangeFilter("FAILED", Map.of("orderId", "123")),
|
||||||
FireMode.COUNT_IN_WINDOW, 1, 120, null);
|
FireMode.COUNT_IN_WINDOW, 1, 120);
|
||||||
|
|
||||||
when(searchIndex.countExecutionsForAlerting(any())).thenReturn(2L);
|
when(searchIndex.countExecutionsForAlerting(any())).thenReturn(2L);
|
||||||
|
|
||||||
@@ -132,7 +132,7 @@ class ExchangeMatchEvaluatorTest {
|
|||||||
var condition = new ExchangeMatchCondition(
|
var condition = new ExchangeMatchCondition(
|
||||||
new AlertScope("orders", null, null),
|
new AlertScope("orders", null, null),
|
||||||
new ExchangeMatchCondition.ExchangeFilter("FAILED", Map.of()),
|
new ExchangeMatchCondition.ExchangeFilter("FAILED", Map.of()),
|
||||||
FireMode.PER_EXCHANGE, null, null, 60);
|
FireMode.PER_EXCHANGE, null, null);
|
||||||
|
|
||||||
when(searchIndex.search(any())).thenReturn(SearchResult.empty(0, 50));
|
when(searchIndex.search(any())).thenReturn(SearchResult.empty(0, 50));
|
||||||
|
|
||||||
@@ -146,7 +146,7 @@ class ExchangeMatchEvaluatorTest {
|
|||||||
var condition = new ExchangeMatchCondition(
|
var condition = new ExchangeMatchCondition(
|
||||||
new AlertScope("orders", null, null),
|
new AlertScope("orders", null, null),
|
||||||
new ExchangeMatchCondition.ExchangeFilter("FAILED", Map.of()),
|
new ExchangeMatchCondition.ExchangeFilter("FAILED", Map.of()),
|
||||||
FireMode.PER_EXCHANGE, null, null, 60);
|
FireMode.PER_EXCHANGE, null, null);
|
||||||
|
|
||||||
Instant t1 = NOW.minusSeconds(50);
|
Instant t1 = NOW.minusSeconds(50);
|
||||||
Instant t2 = NOW.minusSeconds(30);
|
Instant t2 = NOW.minusSeconds(30);
|
||||||
@@ -170,7 +170,7 @@ class ExchangeMatchEvaluatorTest {
|
|||||||
var condition = new ExchangeMatchCondition(
|
var condition = new ExchangeMatchCondition(
|
||||||
new AlertScope("orders", null, null),
|
new AlertScope("orders", null, null),
|
||||||
new ExchangeMatchCondition.ExchangeFilter("FAILED", Map.of()),
|
new ExchangeMatchCondition.ExchangeFilter("FAILED", Map.of()),
|
||||||
FireMode.PER_EXCHANGE, null, null, 60);
|
FireMode.PER_EXCHANGE, null, null);
|
||||||
|
|
||||||
Instant t1 = NOW.minusSeconds(50);
|
Instant t1 = NOW.minusSeconds(50);
|
||||||
Instant t2 = NOW.minusSeconds(10); // latest
|
Instant t2 = NOW.minusSeconds(10); // latest
|
||||||
@@ -193,7 +193,7 @@ class ExchangeMatchEvaluatorTest {
|
|||||||
var condition = new ExchangeMatchCondition(
|
var condition = new ExchangeMatchCondition(
|
||||||
new AlertScope("orders", null, null),
|
new AlertScope("orders", null, null),
|
||||||
new ExchangeMatchCondition.ExchangeFilter("FAILED", Map.of()),
|
new ExchangeMatchCondition.ExchangeFilter("FAILED", Map.of()),
|
||||||
FireMode.PER_EXCHANGE, null, null, 60);
|
FireMode.PER_EXCHANGE, null, null);
|
||||||
|
|
||||||
Instant cursor = NOW.minusSeconds(120);
|
Instant cursor = NOW.minusSeconds(120);
|
||||||
var rule = ruleWith(condition, Map.of("lastExchangeCursor", cursor.toString() + "|ex-prev"));
|
var rule = ruleWith(condition, Map.of("lastExchangeCursor", cursor.toString() + "|ex-prev"));
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ class NotificationContextBuilderTest {
|
|||||||
case EXCHANGE_MATCH -> new ExchangeMatchCondition(
|
case EXCHANGE_MATCH -> new ExchangeMatchCondition(
|
||||||
new AlertScope("my-app", "route-1", null),
|
new AlertScope("my-app", "route-1", null),
|
||||||
new ExchangeMatchCondition.ExchangeFilter("FAILED", Map.of()),
|
new ExchangeMatchCondition.ExchangeFilter("FAILED", Map.of()),
|
||||||
FireMode.PER_EXCHANGE, null, null, 30);
|
FireMode.PER_EXCHANGE, null, null);
|
||||||
case AGENT_STATE -> new AgentStateCondition(
|
case AGENT_STATE -> new AgentStateCondition(
|
||||||
new AlertScope(null, null, null),
|
new AlertScope(null, null, null),
|
||||||
"DEAD", 0);
|
"DEAD", 0);
|
||||||
|
|||||||
@@ -9,8 +9,7 @@ public record ExchangeMatchCondition(
|
|||||||
ExchangeFilter filter,
|
ExchangeFilter filter,
|
||||||
FireMode fireMode,
|
FireMode fireMode,
|
||||||
Integer threshold, // required when COUNT_IN_WINDOW; null for PER_EXCHANGE
|
Integer threshold, // required when COUNT_IN_WINDOW; null for PER_EXCHANGE
|
||||||
Integer windowSeconds, // required when COUNT_IN_WINDOW
|
Integer windowSeconds // required when COUNT_IN_WINDOW
|
||||||
Integer perExchangeLingerSeconds // required when PER_EXCHANGE
|
|
||||||
) implements AlertCondition {
|
) implements AlertCondition {
|
||||||
|
|
||||||
public ExchangeMatchCondition {
|
public ExchangeMatchCondition {
|
||||||
@@ -18,8 +17,6 @@ public record ExchangeMatchCondition(
|
|||||||
throw new IllegalArgumentException("fireMode is required (PER_EXCHANGE or COUNT_IN_WINDOW)");
|
throw new IllegalArgumentException("fireMode is required (PER_EXCHANGE or COUNT_IN_WINDOW)");
|
||||||
if (fireMode == FireMode.COUNT_IN_WINDOW && (threshold == null || windowSeconds == null))
|
if (fireMode == FireMode.COUNT_IN_WINDOW && (threshold == null || windowSeconds == null))
|
||||||
throw new IllegalArgumentException("COUNT_IN_WINDOW requires threshold + windowSeconds");
|
throw new IllegalArgumentException("COUNT_IN_WINDOW requires threshold + windowSeconds");
|
||||||
if (fireMode == FireMode.PER_EXCHANGE && perExchangeLingerSeconds == null)
|
|
||||||
throw new IllegalArgumentException("PER_EXCHANGE requires perExchangeLingerSeconds");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ class AlertConditionJsonTest {
|
|||||||
var c = new ExchangeMatchCondition(
|
var c = new ExchangeMatchCondition(
|
||||||
new AlertScope("orders", null, null),
|
new AlertScope("orders", null, null),
|
||||||
new ExchangeMatchCondition.ExchangeFilter("FAILED", Map.of("type","payment")),
|
new ExchangeMatchCondition.ExchangeFilter("FAILED", Map.of("type","payment")),
|
||||||
FireMode.PER_EXCHANGE, null, null, 300);
|
FireMode.PER_EXCHANGE, null, null);
|
||||||
String json = om.writeValueAsString((AlertCondition) c);
|
String json = om.writeValueAsString((AlertCondition) c);
|
||||||
AlertCondition parsed = om.readValue(json, AlertCondition.class);
|
AlertCondition parsed = om.readValue(json, AlertCondition.class);
|
||||||
assertThat(parsed).isInstanceOf(ExchangeMatchCondition.class);
|
assertThat(parsed).isInstanceOf(ExchangeMatchCondition.class);
|
||||||
@@ -39,7 +39,7 @@ class AlertConditionJsonTest {
|
|||||||
var c = new ExchangeMatchCondition(
|
var c = new ExchangeMatchCondition(
|
||||||
new AlertScope("orders", null, null),
|
new AlertScope("orders", null, null),
|
||||||
new ExchangeMatchCondition.ExchangeFilter("FAILED", Map.of()),
|
new ExchangeMatchCondition.ExchangeFilter("FAILED", Map.of()),
|
||||||
FireMode.COUNT_IN_WINDOW, 5, 900, null);
|
FireMode.COUNT_IN_WINDOW, 5, 900);
|
||||||
AlertCondition parsed = om.readValue(om.writeValueAsString((AlertCondition) c), AlertCondition.class);
|
AlertCondition parsed = om.readValue(om.writeValueAsString((AlertCondition) c), AlertCondition.class);
|
||||||
assertThat(((ExchangeMatchCondition) parsed).threshold()).isEqualTo(5);
|
assertThat(((ExchangeMatchCondition) parsed).threshold()).isEqualTo(5);
|
||||||
}
|
}
|
||||||
@@ -49,7 +49,7 @@ class AlertConditionJsonTest {
|
|||||||
assertThatThrownBy(() -> new ExchangeMatchCondition(
|
assertThatThrownBy(() -> new ExchangeMatchCondition(
|
||||||
new AlertScope(null, null, null),
|
new AlertScope(null, null, null),
|
||||||
new ExchangeMatchCondition.ExchangeFilter("FAILED", Map.of()),
|
new ExchangeMatchCondition.ExchangeFilter("FAILED", Map.of()),
|
||||||
null, null, null, null))
|
null, null, null))
|
||||||
.isInstanceOf(IllegalArgumentException.class)
|
.isInstanceOf(IllegalArgumentException.class)
|
||||||
.hasMessageContaining("fireMode");
|
.hasMessageContaining("fireMode");
|
||||||
}
|
}
|
||||||
@@ -63,8 +63,7 @@ class AlertConditionJsonTest {
|
|||||||
"filter": {"status": "FAILED", "attributes": {}},
|
"filter": {"status": "FAILED", "attributes": {}},
|
||||||
"fireMode": null,
|
"fireMode": null,
|
||||||
"threshold": null,
|
"threshold": null,
|
||||||
"windowSeconds": null,
|
"windowSeconds": null
|
||||||
"perExchangeLingerSeconds": null
|
|
||||||
}
|
}
|
||||||
""";
|
""";
|
||||||
assertThatThrownBy(() -> om.readValue(json, AlertCondition.class))
|
assertThatThrownBy(() -> om.readValue(json, AlertCondition.class))
|
||||||
|
|||||||
Reference in New Issue
Block a user