Skip to content

Commit 96175a8

Browse files
committed
Use OperationParameter consistently
Closes gh-31240
1 parent a2f9e30 commit 96175a8

File tree

7 files changed

+77
-29
lines changed

7 files changed

+77
-29
lines changed

spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/EndpointAutoConfigurationTests.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2019 the original author or authors.
2+
* Copyright 2012-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@
1616

1717
package org.springframework.boot.actuate.autoconfigure.endpoint;
1818

19+
import java.lang.annotation.Annotation;
1920
import java.util.Collections;
2021
import java.util.Set;
2122

@@ -200,6 +201,11 @@ public boolean isMandatory() {
200201
return false;
201202
}
202203

204+
@Override
205+
public <T extends Annotation> T getAnnotation(Class<T> annotation) {
206+
return null;
207+
}
208+
203209
}
204210

205211
}

spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/invoke/OperationParameter.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2019 the original author or authors.
2+
* Copyright 2012-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,10 +16,13 @@
1616

1717
package org.springframework.boot.actuate.endpoint.invoke;
1818

19+
import java.lang.annotation.Annotation;
20+
1921
/**
2022
* A single operation parameter.
2123
*
2224
* @author Phillip Webb
25+
* @author Moritz Halbritter
2326
* @since 2.0.0
2427
*/
2528
public interface OperationParameter {
@@ -42,4 +45,13 @@ public interface OperationParameter {
4245
*/
4346
boolean isMandatory();
4447

48+
/**
49+
* Returns this element's annotation for the specified type if such an annotation is
50+
* present, else null.
51+
* @param annotation class of the annotation
52+
* @return annotation value
53+
* @param <T> type of the annotation
54+
*/
55+
<T extends Annotation> T getAnnotation(Class<T> annotation);
56+
4557
}

spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/invoke/reflect/OperationMethodParameter.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2021 the original author or authors.
2+
* Copyright 2012-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@
1616

1717
package org.springframework.boot.actuate.endpoint.invoke.reflect;
1818

19+
import java.lang.annotation.Annotation;
1920
import java.lang.reflect.Parameter;
2021

2122
import javax.annotation.Nonnull;
@@ -32,6 +33,7 @@
3233
* {@link OperationParameter} created from an {@link OperationMethod}.
3334
*
3435
* @author Phillip Webb
36+
* @author Moritz Halbritter
3537
*/
3638
class OperationMethodParameter implements OperationParameter {
3739

@@ -69,6 +71,11 @@ public boolean isMandatory() {
6971
return (jsr305Present) ? new Jsr305().isMandatory(this.parameter) : true;
7072
}
7173

74+
@Override
75+
public <T extends Annotation> T getAnnotation(Class<T> annotation) {
76+
return this.parameter.getAnnotation(annotation);
77+
}
78+
7279
@Override
7380
public String toString() {
7481
return this.name + " of type " + this.parameter.getType().getName();

spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/annotation/DiscoveredWebOperation.java

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2019 the original author or authors.
2+
* Copyright 2012-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,10 +16,7 @@
1616

1717
package org.springframework.boot.actuate.endpoint.web.annotation;
1818

19-
import java.lang.reflect.Method;
20-
import java.lang.reflect.Parameter;
2119
import java.util.stream.Collectors;
22-
import java.util.stream.Stream;
2320

2421
import org.reactivestreams.Publisher;
2522

@@ -28,6 +25,8 @@
2825
import org.springframework.boot.actuate.endpoint.annotation.DiscoveredOperationMethod;
2926
import org.springframework.boot.actuate.endpoint.annotation.Selector;
3027
import org.springframework.boot.actuate.endpoint.invoke.OperationInvoker;
28+
import org.springframework.boot.actuate.endpoint.invoke.OperationParameter;
29+
import org.springframework.boot.actuate.endpoint.invoke.reflect.OperationMethod;
3130
import org.springframework.boot.actuate.endpoint.web.WebOperation;
3231
import org.springframework.boot.actuate.endpoint.web.WebOperationRequestPredicate;
3332
import org.springframework.core.style.ToStringCreator;
@@ -39,6 +38,7 @@
3938
* @author Andy Wilkinson
4039
* @author Stephane Nicoll
4140
* @author Phillip Webb
41+
* @author Moritz Halbritter
4242
*/
4343
class DiscoveredWebOperation extends AbstractDiscoveredOperation implements WebOperation {
4444

@@ -54,27 +54,26 @@ class DiscoveredWebOperation extends AbstractDiscoveredOperation implements WebO
5454
DiscoveredWebOperation(EndpointId endpointId, DiscoveredOperationMethod operationMethod, OperationInvoker invoker,
5555
WebOperationRequestPredicate requestPredicate) {
5656
super(operationMethod, invoker);
57-
Method method = operationMethod.getMethod();
58-
this.id = getId(endpointId, method);
59-
this.blocking = getBlocking(method);
57+
this.id = getId(endpointId, operationMethod);
58+
this.blocking = getBlocking(operationMethod);
6059
this.requestPredicate = requestPredicate;
6160
}
6261

63-
private String getId(EndpointId endpointId, Method method) {
64-
return endpointId + Stream.of(method.getParameters()).filter(this::hasSelector).map(this::dashName)
62+
private String getId(EndpointId endpointId, OperationMethod method) {
63+
return endpointId + method.getParameters().stream().filter(this::hasSelector).map(this::dashName)
6564
.collect(Collectors.joining());
6665
}
6766

68-
private boolean hasSelector(Parameter parameter) {
67+
private boolean hasSelector(OperationParameter parameter) {
6968
return parameter.getAnnotation(Selector.class) != null;
7069
}
7170

72-
private String dashName(Parameter parameter) {
71+
private String dashName(OperationParameter parameter) {
7372
return "-" + parameter.getName();
7473
}
7574

76-
private boolean getBlocking(Method method) {
77-
return !REACTIVE_STREAMS_PRESENT || !Publisher.class.isAssignableFrom(method.getReturnType());
75+
private boolean getBlocking(OperationMethod method) {
76+
return !REACTIVE_STREAMS_PRESENT || !Publisher.class.isAssignableFrom(method.getMethod().getReturnType());
7877
}
7978

8079
@Override

spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/annotation/RequestPredicateFactory.java

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2019 the original author or authors.
2+
* Copyright 2012-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -17,8 +17,6 @@
1717
package org.springframework.boot.actuate.endpoint.web.annotation;
1818

1919
import java.lang.reflect.Method;
20-
import java.lang.reflect.Parameter;
21-
import java.util.Arrays;
2220
import java.util.Collection;
2321
import java.util.Collections;
2422
import java.util.stream.Stream;
@@ -27,6 +25,7 @@
2725
import org.springframework.boot.actuate.endpoint.annotation.DiscoveredOperationMethod;
2826
import org.springframework.boot.actuate.endpoint.annotation.Selector;
2927
import org.springframework.boot.actuate.endpoint.annotation.Selector.Match;
28+
import org.springframework.boot.actuate.endpoint.invoke.OperationParameter;
3029
import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes;
3130
import org.springframework.boot.actuate.endpoint.web.WebEndpointHttpMethod;
3231
import org.springframework.boot.actuate.endpoint.web.WebEndpointResponse;
@@ -41,6 +40,7 @@
4140
* @author Andy Wilkinson
4241
* @author Stephane Nicoll
4342
* @author Phillip Webb
43+
* @author Moritz Halbritter
4444
*/
4545
class RequestPredicateFactory {
4646

@@ -53,19 +53,19 @@ class RequestPredicateFactory {
5353

5454
WebOperationRequestPredicate getRequestPredicate(String rootPath, DiscoveredOperationMethod operationMethod) {
5555
Method method = operationMethod.getMethod();
56-
Parameter[] selectorParameters = Arrays.stream(method.getParameters()).filter(this::hasSelector)
57-
.toArray(Parameter[]::new);
58-
Parameter allRemainingPathSegmentsParameter = getAllRemainingPathSegmentsParameter(selectorParameters);
56+
OperationParameter[] selectorParameters = operationMethod.getParameters().stream().filter(this::hasSelector)
57+
.toArray(OperationParameter[]::new);
58+
OperationParameter allRemainingPathSegmentsParameter = getAllRemainingPathSegmentsParameter(selectorParameters);
5959
String path = getPath(rootPath, selectorParameters, allRemainingPathSegmentsParameter != null);
6060
WebEndpointHttpMethod httpMethod = determineHttpMethod(operationMethod.getOperationType());
6161
Collection<String> consumes = getConsumes(httpMethod, method);
6262
Collection<String> produces = getProduces(operationMethod, method);
6363
return new WebOperationRequestPredicate(path, httpMethod, consumes, produces);
6464
}
6565

66-
private Parameter getAllRemainingPathSegmentsParameter(Parameter[] selectorParameters) {
67-
Parameter trailingPathsParameter = null;
68-
for (Parameter selectorParameter : selectorParameters) {
66+
private OperationParameter getAllRemainingPathSegmentsParameter(OperationParameter[] selectorParameters) {
67+
OperationParameter trailingPathsParameter = null;
68+
for (OperationParameter selectorParameter : selectorParameters) {
6969
Selector selector = selectorParameter.getAnnotation(Selector.class);
7070
if (selector.match() == Match.ALL_REMAINING) {
7171
Assert.state(trailingPathsParameter == null,
@@ -80,7 +80,8 @@ private Parameter getAllRemainingPathSegmentsParameter(Parameter[] selectorParam
8080
return trailingPathsParameter;
8181
}
8282

83-
private String getPath(String rootPath, Parameter[] selectorParameters, boolean matchRemainingPathSegments) {
83+
private String getPath(String rootPath, OperationParameter[] selectorParameters,
84+
boolean matchRemainingPathSegments) {
8485
StringBuilder path = new StringBuilder(rootPath);
8586
for (int i = 0; i < selectorParameters.length; i++) {
8687
path.append("/{");
@@ -93,7 +94,7 @@ private String getPath(String rootPath, Parameter[] selectorParameters, boolean
9394
return path.toString();
9495
}
9596

96-
private boolean hasSelector(Parameter parameter) {
97+
private boolean hasSelector(OperationParameter parameter) {
9798
return parameter.getAnnotation(Selector.class) != null;
9899
}
99100

spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/invoke/convert/ConversionServiceParameterValueMapperTests.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2022 the original author or authors.
2+
* Copyright 2012-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@
1616

1717
package org.springframework.boot.actuate.endpoint.invoke.convert;
1818

19+
import java.lang.annotation.Annotation;
1920
import java.time.OffsetDateTime;
2021

2122
import org.junit.jupiter.api.Test;
@@ -104,6 +105,11 @@ public boolean isMandatory() {
104105
return false;
105106
}
106107

108+
@Override
109+
public <T extends Annotation> T getAnnotation(Class<T> annotation) {
110+
return null;
111+
}
112+
107113
}
108114

109115
}

spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/invoke/reflect/OperationMethodParameterTests.java

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2021 the original author or authors.
2+
* Copyright 2012-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -26,6 +26,8 @@
2626

2727
import org.junit.jupiter.api.Test;
2828

29+
import org.springframework.boot.actuate.endpoint.annotation.Selector;
30+
import org.springframework.boot.actuate.endpoint.annotation.Selector.Match;
2931
import org.springframework.lang.Nullable;
3032
import org.springframework.util.ReflectionUtils;
3133

@@ -35,6 +37,7 @@
3537
* Tests for {@link OperationMethodParameter}.
3638
*
3739
* @author Phillip Webb
40+
* @author Moritz Halbritter
3841
*/
3942
class OperationMethodParameterTests {
4043

@@ -48,6 +51,8 @@ class OperationMethodParameterTests {
4851
private Method exampleJsr305NonNull = ReflectionUtils.findMethod(getClass(), "exampleJsr305NonNull", String.class,
4952
String.class);
5053

54+
private Method exampleAnnotation = ReflectionUtils.findMethod(getClass(), "exampleAnnotation", String.class);
55+
5156
@Test
5257
void getNameShouldReturnName() {
5358
OperationMethodParameter parameter = new OperationMethodParameter("name", this.example.getParameters()[0]);
@@ -93,6 +98,15 @@ void isMandatoryWhenJsrNonnullAnnotationShouldReturnTrue() {
9398
assertThat(parameter.isMandatory()).isTrue();
9499
}
95100

101+
@Test
102+
void getAnnotationShouldReturnAnnotation() {
103+
OperationMethodParameter parameter = new OperationMethodParameter("name",
104+
this.exampleAnnotation.getParameters()[0]);
105+
Selector annotation = parameter.getAnnotation(Selector.class);
106+
assertThat(annotation).isNotNull();
107+
assertThat(annotation.match()).isEqualTo(Match.ALL_REMAINING);
108+
}
109+
96110
void example(String one, @Nullable String two) {
97111
}
98112

@@ -105,6 +119,9 @@ void exampleMetaJsr305(String one, @MetaNullable String two) {
105119
void exampleJsr305NonNull(String one, @javax.annotation.Nonnull String two) {
106120
}
107121

122+
void exampleAnnotation(@Selector(match = Match.ALL_REMAINING) String allRemaining) {
123+
}
124+
108125
@TypeQualifier
109126
@Retention(RetentionPolicy.RUNTIME)
110127
@Nonnull(when = When.MAYBE)

0 commit comments

Comments
 (0)