Skip to content

Commit 4909447

Browse files
committed
Add nullability annotations to module/spring-boot-metrics
See gh-46587
1 parent b705817 commit 4909447

File tree

75 files changed

+495
-288
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

75 files changed

+495
-288
lines changed

module/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/actuate/endpoint/MetricsEndpoint.java

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import io.micrometer.core.instrument.Statistic;
3333
import io.micrometer.core.instrument.Tag;
3434
import io.micrometer.core.instrument.composite.CompositeMeterRegistry;
35+
import org.jspecify.annotations.Nullable;
3536

3637
import org.springframework.boot.actuate.endpoint.InvalidEndpointRequestException;
3738
import org.springframework.boot.actuate.endpoint.OperationResponseBody;
@@ -77,7 +78,7 @@ private String getName(Meter meter) {
7778
}
7879

7980
@ReadOperation
80-
public MetricDescriptor metric(@Selector String requiredMetricName, @OptionalParameter List<String> tag) {
81+
public @Nullable MetricDescriptor metric(@Selector String requiredMetricName, @OptionalParameter List<String> tag) {
8182
List<Tag> tags = parseTags(tag);
8283
Collection<Meter> meters = findFirstMatchingMeters(this.registry, requiredMetricName, tags);
8384
if (meters.isEmpty()) {
@@ -91,7 +92,7 @@ public MetricDescriptor metric(@Selector String requiredMetricName, @OptionalPar
9192
asList(samples, Sample::new), asList(availableTags, AvailableTag::new));
9293
}
9394

94-
private List<Tag> parseTags(List<String> tags) {
95+
private List<Tag> parseTags(@Nullable List<String> tags) {
9596
return (tags != null) ? tags.stream().map(this::parseTag).toList() : Collections.emptyList();
9697
}
9798

@@ -186,16 +187,16 @@ public static final class MetricDescriptor implements OperationResponseBody {
186187

187188
private final String name;
188189

189-
private final String description;
190+
private final @Nullable String description;
190191

191-
private final String baseUnit;
192+
private final @Nullable String baseUnit;
192193

193194
private final List<Sample> measurements;
194195

195196
private final List<AvailableTag> availableTags;
196197

197-
MetricDescriptor(String name, String description, String baseUnit, List<Sample> measurements,
198-
List<AvailableTag> availableTags) {
198+
MetricDescriptor(String name, @Nullable String description, @Nullable String baseUnit,
199+
List<Sample> measurements, List<AvailableTag> availableTags) {
199200
this.name = name;
200201
this.description = description;
201202
this.baseUnit = baseUnit;
@@ -207,11 +208,11 @@ public String getName() {
207208
return this.name;
208209
}
209210

210-
public String getDescription() {
211+
public @Nullable String getDescription() {
211212
return this.description;
212213
}
213214

214-
public String getBaseUnit() {
215+
public @Nullable String getBaseUnit() {
215216
return this.baseUnit;
216217
}
217218

module/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/actuate/endpoint/package-info.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,7 @@
1717
/**
1818
* Actuator endpoint for metrics.
1919
*/
20+
@NullMarked
2021
package org.springframework.boot.metrics.actuate.endpoint;
22+
23+
import org.jspecify.annotations.NullMarked;

module/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/MeterValue.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import java.util.concurrent.TimeUnit;
2121

2222
import io.micrometer.core.instrument.Meter.Type;
23+
import org.jspecify.annotations.Nullable;
2324

2425
import org.springframework.boot.convert.DurationStyle;
2526

@@ -49,7 +50,7 @@ public final class MeterValue {
4950
* @param meterType the meter type
5051
* @return the value or {@code null} if the value cannot be applied
5152
*/
52-
public Double getValue(Type meterType) {
53+
public @Nullable Double getValue(Type meterType) {
5354
if (meterType == Type.DISTRIBUTION_SUMMARY) {
5455
return getDistributionSummaryValue();
5556
}
@@ -62,14 +63,14 @@ public Double getValue(Type meterType) {
6263
return null;
6364
}
6465

65-
private Double getDistributionSummaryValue() {
66+
private @Nullable Double getDistributionSummaryValue() {
6667
if (this.value instanceof Double doubleValue) {
6768
return doubleValue;
6869
}
6970
return null;
7071
}
7172

72-
private Long getTimerValue() {
73+
private @Nullable Long getTimerValue() {
7374
if (this.value instanceof Double doubleValue) {
7475
return TimeUnit.MILLISECONDS.toNanos(doubleValue.longValue());
7576
}
@@ -102,7 +103,7 @@ public static MeterValue valueOf(double value) {
102103
return new MeterValue(value);
103104
}
104105

105-
private static Duration safeParseDuration(String value) {
106+
private static @Nullable Duration safeParseDuration(String value) {
106107
try {
107108
return DurationStyle.detectAndParse(value);
108109
}

module/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/PropertiesMeterFilter.java

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,10 @@
2929
import io.micrometer.core.instrument.config.MeterFilter;
3030
import io.micrometer.core.instrument.config.MeterFilterReply;
3131
import io.micrometer.core.instrument.distribution.DistributionStatisticConfig;
32+
import org.jspecify.annotations.Nullable;
3233

3334
import org.springframework.boot.metrics.autoconfigure.MetricsProperties.Distribution;
35+
import org.springframework.lang.Contract;
3436
import org.springframework.util.Assert;
3537
import org.springframework.util.StringUtils;
3638

@@ -98,7 +100,8 @@ public DistributionStatisticConfig configure(Meter.Id id, DistributionStatisticC
98100
.merge(config);
99101
}
100102

101-
private double[] convertServiceLevelObjectives(Meter.Type meterType, ServiceLevelObjectiveBoundary[] slo) {
103+
private double @Nullable [] convertServiceLevelObjectives(Meter.Type meterType,
104+
ServiceLevelObjectiveBoundary @Nullable [] slo) {
102105
if (slo == null) {
103106
return null;
104107
}
@@ -110,25 +113,28 @@ private double[] convertServiceLevelObjectives(Meter.Type meterType, ServiceLeve
110113
return (converted.length != 0) ? converted : null;
111114
}
112115

113-
private Double convertMeterValue(Meter.Type meterType, String value) {
116+
private @Nullable Double convertMeterValue(Meter.Type meterType, @Nullable String value) {
114117
return (value != null) ? MeterValue.valueOf(value).getValue(meterType) : null;
115118
}
116119

117-
private <T> T lookup(Map<String, T> values, Id id, T defaultValue) {
120+
@SuppressWarnings("NullAway") // Lambda isn't detected with the correct nullability
121+
private <T> @Nullable T lookup(Map<String, T> values, Id id, @Nullable T defaultValue) {
118122
if (values.isEmpty()) {
119123
return defaultValue;
120124
}
121125
return doLookup(values, id, () -> defaultValue);
122126
}
123127

124-
private <T> T lookupWithFallbackToAll(Map<String, T> values, Id id, T defaultValue) {
128+
@Contract("_, _, !null -> !null")
129+
@SuppressWarnings("NullAway") // Lambda isn't detected with the correct nullability
130+
private <T> @Nullable T lookupWithFallbackToAll(Map<String, T> values, Id id, @Nullable T defaultValue) {
125131
if (values.isEmpty()) {
126132
return defaultValue;
127133
}
128134
return doLookup(values, id, () -> values.getOrDefault("all", defaultValue));
129135
}
130136

131-
private <T> T doLookup(Map<String, T> values, Id id, Supplier<T> defaultValue) {
137+
private <T> @Nullable T doLookup(Map<String, T> values, Id id, Supplier<@Nullable T> defaultValue) {
132138
String name = id.getName();
133139
while (StringUtils.hasLength(name)) {
134140
T result = values.get(name);

module/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/ServiceLevelObjectiveBoundary.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import java.time.Duration;
2020

2121
import io.micrometer.core.instrument.Meter;
22+
import org.jspecify.annotations.Nullable;
2223

2324
import org.springframework.aot.hint.MemberCategory;
2425
import org.springframework.aot.hint.RuntimeHints;
@@ -47,7 +48,7 @@ public final class ServiceLevelObjectiveBoundary {
4748
* @param meterType the meter type
4849
* @return the value or {@code null} if the value cannot be applied
4950
*/
50-
public Double getValue(Meter.Type meterType) {
51+
public @Nullable Double getValue(Meter.Type meterType) {
5152
return this.value.getValue(meterType);
5253
}
5354

@@ -74,7 +75,7 @@ public static ServiceLevelObjectiveBoundary valueOf(String value) {
7475
static class ServiceLevelObjectiveBoundaryHints implements RuntimeHintsRegistrar {
7576

7677
@Override
77-
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
78+
public void registerHints(RuntimeHints hints, @Nullable ClassLoader classLoader) {
7879
hints.reflection().registerType(ServiceLevelObjectiveBoundary.class, MemberCategory.INVOKE_PUBLIC_METHODS);
7980
}
8081

module/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/OnMetricsExportEnabledCondition.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
package org.springframework.boot.metrics.autoconfigure.export;
1818

19+
import org.jspecify.annotations.Nullable;
20+
1921
import org.springframework.boot.autoconfigure.condition.ConditionMessage;
2022
import org.springframework.boot.autoconfigure.condition.ConditionOutcome;
2123
import org.springframework.boot.autoconfigure.condition.SpringBootCondition;
@@ -24,6 +26,7 @@
2426
import org.springframework.core.annotation.AnnotationAttributes;
2527
import org.springframework.core.env.Environment;
2628
import org.springframework.core.type.AnnotatedTypeMetadata;
29+
import org.springframework.util.Assert;
2730

2831
/**
2932
* {@link Condition} that checks if a metrics exporter is enabled.
@@ -41,6 +44,7 @@ class OnMetricsExportEnabledCondition extends SpringBootCondition {
4144
public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {
4245
AnnotationAttributes annotationAttributes = AnnotationAttributes
4346
.fromMap(metadata.getAnnotationAttributes(ConditionalOnEnabledMetricsExport.class.getName()));
47+
Assert.state(annotationAttributes != null, "'annotationAttributes' must not be null");
4448
String endpointName = annotationAttributes.getString("value");
4549
ConditionOutcome outcome = getProductOutcome(context, endpointName);
4650
if (outcome != null) {
@@ -49,7 +53,7 @@ public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeM
4953
return getDefaultOutcome(context);
5054
}
5155

52-
private ConditionOutcome getProductOutcome(ConditionContext context, String productName) {
56+
private @Nullable ConditionOutcome getProductOutcome(ConditionContext context, String productName) {
5357
Environment environment = context.getEnvironment();
5458
String enabledProperty = PROPERTY_TEMPLATE.formatted(productName);
5559
if (environment.containsProperty(enabledProperty)) {

module/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/appoptics/AppOpticsProperties.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818

1919
import java.time.Duration;
2020

21+
import org.jspecify.annotations.Nullable;
22+
2123
import org.springframework.boot.context.properties.ConfigurationProperties;
2224
import org.springframework.boot.metrics.autoconfigure.export.properties.StepRegistryProperties;
2325

@@ -39,7 +41,7 @@ public class AppOpticsProperties extends StepRegistryProperties {
3941
/**
4042
* AppOptics API token.
4143
*/
42-
private String apiToken;
44+
private @Nullable String apiToken;
4345

4446
/**
4547
* Tag that will be mapped to "@host" when shipping metrics to AppOptics.
@@ -71,11 +73,11 @@ public void setUri(String uri) {
7173
this.uri = uri;
7274
}
7375

74-
public String getApiToken() {
76+
public @Nullable String getApiToken() {
7577
return this.apiToken;
7678
}
7779

78-
public void setApiToken(String apiToken) {
80+
public void setApiToken(@Nullable String apiToken) {
7981
this.apiToken = apiToken;
8082
}
8183

module/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/appoptics/AppOpticsPropertiesConfigAdapter.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package org.springframework.boot.metrics.autoconfigure.export.appoptics;
1818

1919
import io.micrometer.appoptics.AppOpticsConfig;
20+
import org.jspecify.annotations.Nullable;
2021

2122
import org.springframework.boot.metrics.autoconfigure.export.properties.StepRegistryPropertiesConfigAdapter;
2223

@@ -39,22 +40,23 @@ public String prefix() {
3940

4041
@Override
4142
public String uri() {
42-
return get(AppOpticsProperties::getUri, AppOpticsConfig.super::uri);
43+
return getRequired(AppOpticsProperties::getUri, AppOpticsConfig.super::uri);
4344
}
4445

4546
@Override
4647
public String apiToken() {
47-
return get(AppOpticsProperties::getApiToken, AppOpticsConfig.super::apiToken);
48+
return getRequired(AppOpticsProperties::getApiToken, AppOpticsConfig.super::apiToken);
4849
}
4950

5051
@Override
51-
public String hostTag() {
52+
@SuppressWarnings("NullAway") // Lambda isn't detected with the correct nullability
53+
public @Nullable String hostTag() {
5254
return get(AppOpticsProperties::getHostTag, AppOpticsConfig.super::hostTag);
5355
}
5456

5557
@Override
5658
public boolean floorTimes() {
57-
return get(AppOpticsProperties::isFloorTimes, AppOpticsConfig.super::floorTimes);
59+
return getRequired(AppOpticsProperties::isFloorTimes, AppOpticsConfig.super::floorTimes);
5860
}
5961

6062
}

module/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/appoptics/package-info.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,7 @@
1717
/**
1818
* Support for exporting actuator metrics to AppOptics.
1919
*/
20+
@NullMarked
2021
package org.springframework.boot.metrics.autoconfigure.export.appoptics;
22+
23+
import org.jspecify.annotations.NullMarked;

0 commit comments

Comments
 (0)