Skip to content

Commit 6498aca

Browse files
committed
be strict about validation scheme validation
Signed-off-by: Gregor Zeitlinger <[email protected]>
1 parent be6bd43 commit 6498aca

File tree

9 files changed

+85
-40
lines changed

9 files changed

+85
-40
lines changed

prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/NamingProperties.java

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,42 @@
11
package io.prometheus.metrics.config;
22

33
import java.util.Map;
4+
import javax.annotation.Nullable;
45

56
public class NamingProperties {
67

78
private static final String PREFIX = "io.prometheus.naming";
89
private static final String VALIDATION_SCHEME = "validationScheme";
9-
private final String validationScheme;
10+
private final ValidationScheme validationScheme;
1011

11-
private NamingProperties(String validation) {
12+
private NamingProperties(ValidationScheme validation) {
1213
this.validationScheme = validation;
1314
}
1415

15-
public String getValidationScheme() {
16+
public ValidationScheme getValidationScheme() {
1617
return validationScheme;
1718
}
1819

1920
static NamingProperties load(Map<Object, Object> properties)
2021
throws PrometheusPropertiesException {
2122
String validationScheme = Util.loadString(PREFIX + "." + VALIDATION_SCHEME, properties);
22-
return new NamingProperties(validationScheme);
23+
return new NamingProperties(parseValidationScheme(validationScheme));
24+
}
25+
26+
static ValidationScheme parseValidationScheme(@Nullable String scheme) {
27+
if (scheme == null || scheme.isEmpty()) {
28+
return ValidationScheme.LEGACY_VALIDATION;
29+
}
30+
31+
switch (scheme) {
32+
case "utf-8":
33+
return ValidationScheme.UTF_8_VALIDATION;
34+
case "legacy":
35+
return ValidationScheme.LEGACY_VALIDATION;
36+
default:
37+
throw new PrometheusPropertiesException(
38+
"Unknown validation scheme: " + scheme + ". Valid values are: utf-8, legacy.");
39+
}
2340
}
2441

2542
public static Builder builder() {
@@ -28,11 +45,11 @@ public static Builder builder() {
2845

2946
public static class Builder {
3047

31-
private String validationScheme;
48+
private ValidationScheme validationScheme;
3249

3350
private Builder() {}
3451

35-
public Builder validation(String validationScheme) {
52+
public Builder validation(ValidationScheme validationScheme) {
3653
this.validationScheme = validationScheme;
3754
return this;
3855
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package io.prometheus.metrics.config;
2+
3+
/**
4+
* ValidationScheme is an enum for determining how metric and label names will be validated by this
5+
* library.
6+
*/
7+
public enum ValidationScheme {
8+
/**
9+
* LEGACY_VALIDATION is a setting that requires that metric and label names conform to the
10+
* original character requirements.
11+
*/
12+
LEGACY_VALIDATION,
13+
14+
/** UTF_8_VALIDATION only requires that metric and label names be valid UTF-8 strings. */
15+
UTF_8_VALIDATION
16+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package io.prometheus.metrics.config;
2+
3+
import static org.assertj.core.api.Assertions.assertThat;
4+
import static org.assertj.core.api.Assertions.assertThatCode;
5+
6+
import org.junit.jupiter.api.Test;
7+
8+
class NamingPropertiesTest {
9+
@Test
10+
void testBuilder() {
11+
NamingProperties properties =
12+
NamingProperties.builder().validation(ValidationScheme.UTF_8_VALIDATION).build();
13+
assertThat(properties.getValidationScheme()).isEqualTo(ValidationScheme.UTF_8_VALIDATION);
14+
}
15+
16+
@Test
17+
void parseValidationScheme() {
18+
assertThat(NamingProperties.parseValidationScheme("utf-8"))
19+
.isEqualTo(ValidationScheme.UTF_8_VALIDATION);
20+
assertThat(NamingProperties.parseValidationScheme("legacy"))
21+
.isEqualTo(ValidationScheme.LEGACY_VALIDATION);
22+
assertThat(NamingProperties.parseValidationScheme(null))
23+
.isEqualTo(ValidationScheme.LEGACY_VALIDATION);
24+
assertThatCode(() -> NamingProperties.parseValidationScheme("unknown"))
25+
.isInstanceOf(PrometheusPropertiesException.class)
26+
.hasMessageContaining(
27+
"Unknown validation scheme: unknown. Valid values are: utf-8, legacy.");
28+
}
29+
}

prometheus-metrics-exposition-textformats/src/main/java/io/prometheus/metrics/expositionformats/TextFormatUtil.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
package io.prometheus.metrics.expositionformats;
22

3+
import io.prometheus.metrics.config.ValidationScheme;
34
import io.prometheus.metrics.model.snapshots.Labels;
45
import io.prometheus.metrics.model.snapshots.PrometheusNaming;
5-
import io.prometheus.metrics.model.snapshots.ValidationScheme;
66
import java.io.IOException;
77
import java.io.Writer;
88

prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Labels.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import static io.prometheus.metrics.model.snapshots.PrometheusNaming.isValidLabelName;
44
import static io.prometheus.metrics.model.snapshots.PrometheusNaming.prometheusName;
55

6+
import io.prometheus.metrics.config.ValidationScheme;
67
import java.util.ArrayList;
78
import java.util.Arrays;
89
import java.util.Collections;

prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/MetricMetadata.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package io.prometheus.metrics.model.snapshots;
22

3+
import io.prometheus.metrics.config.ValidationScheme;
4+
35
/** Immutable container for metric metadata: name, help, unit. */
46
public final class MetricMetadata {
57

prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/PrometheusNaming.java

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
import io.prometheus.metrics.config.PrometheusProperties;
88
import io.prometheus.metrics.config.PrometheusPropertiesLoader;
9+
import io.prometheus.metrics.config.ValidationScheme;
910
import java.nio.charset.StandardCharsets;
1011
import java.util.ArrayList;
1112
import java.util.List;
@@ -28,7 +29,7 @@ public class PrometheusNaming {
2829
* is intended to be set by UTF-8-aware binaries as part of their startup via a properties file.
2930
*/
3031
public static ValidationScheme nameValidationScheme =
31-
initValidationScheme(PrometheusProperties.get());
32+
PrometheusProperties.get().getNamingProperties().getValidationScheme();
3233

3334
/** Default escaping scheme for names when not specified. */
3435
public static final EscapingScheme DEFAULT_ESCAPING_SCHEME =
@@ -77,17 +78,10 @@ public class PrometheusNaming {
7778
".total", ".created", ".bucket", ".info"
7879
};
7980

80-
static ValidationScheme initValidationScheme(PrometheusProperties properties) {
81-
if ("utf-8".equals(properties.getNamingProperties().getValidationScheme())) {
82-
return ValidationScheme.UTF_8_VALIDATION;
83-
}
84-
85-
return ValidationScheme.LEGACY_VALIDATION;
86-
}
87-
8881
// VisibleForTesting
8982
public static void resetForTest() {
90-
nameValidationScheme = initValidationScheme(PrometheusPropertiesLoader.load());
83+
nameValidationScheme =
84+
PrometheusPropertiesLoader.load().getNamingProperties().getValidationScheme();
9185
}
9286

9387
/**

prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/ValidationScheme.java

Lines changed: 0 additions & 13 deletions
This file was deleted.

prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/PrometheusNamingTest.java

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,5 @@
11
package io.prometheus.metrics.model.snapshots;
22

3-
import org.junit.jupiter.api.AfterEach;
4-
import org.junit.jupiter.api.Test;
5-
import org.junit.jupiter.params.ParameterizedTest;
6-
import org.junit.jupiter.params.provider.Arguments;
7-
import org.junit.jupiter.params.provider.CsvSource;
8-
import org.junit.jupiter.params.provider.MethodSource;
9-
import org.junitpioneer.jupiter.SetSystemProperty;
10-
11-
import java.util.stream.Stream;
12-
133
import static io.prometheus.metrics.model.snapshots.PrometheusNaming.escapeMetricSnapshot;
144
import static io.prometheus.metrics.model.snapshots.PrometheusNaming.escapeName;
155
import static io.prometheus.metrics.model.snapshots.PrometheusNaming.isValidLabelName;
@@ -23,6 +13,15 @@
2313
import static org.assertj.core.api.Assertions.assertThat;
2414
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
2515

16+
import java.util.stream.Stream;
17+
import org.junit.jupiter.api.AfterEach;
18+
import org.junit.jupiter.api.Test;
19+
import org.junit.jupiter.params.ParameterizedTest;
20+
import org.junit.jupiter.params.provider.Arguments;
21+
import org.junit.jupiter.params.provider.CsvSource;
22+
import org.junit.jupiter.params.provider.MethodSource;
23+
import org.junitpioneer.jupiter.SetSystemProperty;
24+
2625
class PrometheusNamingTest {
2726

2827
@AfterEach

0 commit comments

Comments
 (0)