Fix package tangle in endpoint package

Fix package tangle in the actuator endpoint package by relocating a
few classes.

The `Producible` and `ProducibleOperationArgumentResolver` classes have
been moved from `endpoint.annotation` to `endpoint` since they aren't
directly tied to annotations.

The `ApiVersion` class has been moved from `endpoint.http` to
`endpoint` since it needs to implement `Producible` and isn't really
tied to HTTP.

Closes gh-25914
This commit is contained in:
Phillip Webb
2021-04-07 11:54:42 -07:00
parent e766c8b3a7
commit e4164d0143
48 changed files with 234 additions and 151 deletions

View File

@@ -21,8 +21,6 @@ import java.util.Map;
import org.junit.jupiter.api.Test;
import org.springframework.boot.actuate.endpoint.http.ApiVersion;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
import static org.mockito.Mockito.mock;
@@ -42,13 +40,14 @@ class InvocationContextTests {
@SuppressWarnings("deprecation")
void createWhenApiVersionIsNullUsesLatestVersion() {
InvocationContext context = new InvocationContext(null, this.securityContext, this.arguments);
assertThat(context.getApiVersion()).isEqualTo(ApiVersion.LATEST);
assertThat(context.getApiVersion()).isEqualTo(org.springframework.boot.actuate.endpoint.http.ApiVersion.LATEST);
}
@Test
@Deprecated
void whenCreatedWithoutApiVersionThenGetApiVersionReturnsLatestVersion() {
InvocationContext context = new InvocationContext(this.securityContext, this.arguments);
assertThat(context.getApiVersion()).isEqualTo(ApiVersion.LATEST);
assertThat(context.getApiVersion()).isEqualTo(org.springframework.boot.actuate.endpoint.http.ApiVersion.LATEST);
}
@Test
@@ -72,8 +71,9 @@ class InvocationContextTests {
@Test
@SuppressWarnings("deprecation")
void getApiVersionReturnsApiVersion() {
InvocationContext context = new InvocationContext(ApiVersion.V2, this.securityContext, this.arguments);
assertThat(context.getApiVersion()).isEqualTo(ApiVersion.V2);
InvocationContext context = new InvocationContext(org.springframework.boot.actuate.endpoint.http.ApiVersion.V2,
this.securityContext, this.arguments);
assertThat(context.getApiVersion()).isEqualTo(org.springframework.boot.actuate.endpoint.http.ApiVersion.V2);
}
@Test

View File

@@ -14,12 +14,11 @@
* limitations under the License.
*/
package org.springframework.boot.actuate.endpoint.http;
package org.springframework.boot.actuate.endpoint;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;
import org.junit.jupiter.api.Test;
@@ -32,6 +31,10 @@ import static org.assertj.core.api.Assertions.assertThat;
*/
class ProducibleOperationArgumentResolverTests {
private static final String V2_JSON = ApiVersion.V2.getProducedMimeType().toString();
private static final String V3_JSON = ApiVersion.V3.getProducedMimeType().toString();
@Test
void whenAcceptHeaderIsEmptyThenHighestOrdinalIsReturned() {
assertThat(resolve(acceptHeader())).isEqualTo(ApiVersion.V3);
@@ -49,31 +52,29 @@ class ProducibleOperationArgumentResolverTests {
@Test
void whenSingleValueIsAcceptableThenMatchingEnumValueIsReturned() {
assertThat(new ProducibleOperationArgumentResolver(acceptHeader(ActuatorMediaType.V2_JSON))
.resolve(ApiVersion.class)).isEqualTo(ApiVersion.V2);
assertThat(new ProducibleOperationArgumentResolver(acceptHeader(ActuatorMediaType.V3_JSON))
.resolve(ApiVersion.class)).isEqualTo(ApiVersion.V3);
assertThat(new ProducibleOperationArgumentResolver(acceptHeader(V2_JSON)).resolve(ApiVersion.class))
.isEqualTo(ApiVersion.V2);
assertThat(new ProducibleOperationArgumentResolver(acceptHeader(V3_JSON)).resolve(ApiVersion.class))
.isEqualTo(ApiVersion.V3);
}
@Test
void whenMultipleValuesAreAcceptableThenHighestOrdinalIsReturned() {
assertThat(resolve(acceptHeader(ActuatorMediaType.V2_JSON, ActuatorMediaType.V3_JSON)))
.isEqualTo(ApiVersion.V3);
assertThat(resolve(acceptHeader(V2_JSON, V3_JSON))).isEqualTo(ApiVersion.V3);
}
@Test
void whenMultipleValuesAreAcceptableAsSingleHeaderThenHighestOrdinalIsReturned() {
assertThat(resolve(acceptHeader(ActuatorMediaType.V2_JSON + "," + ActuatorMediaType.V3_JSON)))
.isEqualTo(ApiVersion.V3);
assertThat(resolve(acceptHeader(V2_JSON + "," + V3_JSON))).isEqualTo(ApiVersion.V3);
}
private Map<String, List<String>> acceptHeader(String... types) {
private Supplier<List<String>> acceptHeader(String... types) {
List<String> value = Arrays.asList(types);
return value.isEmpty() ? Collections.emptyMap() : Collections.singletonMap("Accept", value);
return () -> (value.isEmpty() ? null : value);
}
private ApiVersion resolve(Map<String, List<String>> httpHeaders) {
return new ProducibleOperationArgumentResolver(httpHeaders).resolve(ApiVersion.class);
private ApiVersion resolve(Supplier<List<String>> accepts) {
return new ProducibleOperationArgumentResolver(accepts).resolve(ApiVersion.class);
}
}

View File

@@ -21,6 +21,7 @@ import java.lang.reflect.Method;
import org.junit.jupiter.api.Test;
import org.springframework.boot.actuate.endpoint.OperationType;
import org.springframework.boot.actuate.endpoint.Producible;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.util.MimeType;
import org.springframework.util.ReflectionUtils;

View File

@@ -28,6 +28,7 @@ import org.junit.jupiter.api.Test;
import org.springframework.boot.actuate.endpoint.EndpointId;
import org.springframework.boot.actuate.endpoint.InvocationContext;
import org.springframework.boot.actuate.endpoint.OperationType;
import org.springframework.boot.actuate.endpoint.Producible;
import org.springframework.boot.actuate.endpoint.SecurityContext;
import org.springframework.boot.actuate.endpoint.invoke.OperationInvoker;
import org.springframework.boot.actuate.endpoint.invoke.OperationInvokerAdvisor;

View File

@@ -30,6 +30,7 @@ import static org.assertj.core.api.Assertions.assertThat;
*
* @author Phillip Webb
*/
@Deprecated
class ApiVersionTests {
@Test

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,10 +21,10 @@ import java.util.Collections;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.boot.actuate.endpoint.ApiVersion;
import org.springframework.boot.actuate.endpoint.InvocationContext;
import org.springframework.boot.actuate.endpoint.OperationType;
import org.springframework.boot.actuate.endpoint.SecurityContext;
import org.springframework.boot.actuate.endpoint.http.ApiVersion;
import org.springframework.boot.actuate.endpoint.invoke.MissingParametersException;
import org.springframework.boot.actuate.endpoint.invoke.ParameterValueMapper;
import org.springframework.lang.Nullable;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2020 the original author or authors.
* Copyright 2012-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,10 +25,10 @@ import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.boot.actuate.endpoint.ApiVersion;
import org.springframework.boot.actuate.endpoint.EndpointId;
import org.springframework.boot.actuate.endpoint.OperationType;
import org.springframework.boot.actuate.endpoint.SecurityContext;
import org.springframework.boot.actuate.endpoint.http.ApiVersion;
import org.springframework.boot.actuate.endpoint.invoke.OperationInvoker;
import org.springframework.boot.actuate.endpoint.invoke.OperationParameters;
import org.springframework.boot.actuate.endpoint.invoke.reflect.OperationMethod;

View File

@@ -27,10 +27,10 @@ import org.junit.jupiter.api.Test;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import org.springframework.boot.actuate.endpoint.ApiVersion;
import org.springframework.boot.actuate.endpoint.InvocationContext;
import org.springframework.boot.actuate.endpoint.OperationArgumentResolver;
import org.springframework.boot.actuate.endpoint.SecurityContext;
import org.springframework.boot.actuate.endpoint.http.ApiVersion;
import org.springframework.boot.actuate.endpoint.invoke.MissingParametersException;
import org.springframework.boot.actuate.endpoint.invoke.OperationInvoker;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,7 +22,7 @@ import java.util.List;
import org.junit.jupiter.api.Test;
import org.springframework.boot.actuate.endpoint.http.ActuatorMediaType;
import org.springframework.boot.actuate.endpoint.ApiVersion;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
@@ -34,12 +34,14 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException
*/
class EndpointMediaTypesTests {
private static final String V2_JSON = ApiVersion.V2.getProducedMimeType().toString();
private static final String V3_JSON = ApiVersion.V3.getProducedMimeType().toString();
@Test
void defaultReturnsExpectedProducedAndConsumedTypes() {
assertThat(EndpointMediaTypes.DEFAULT.getProduced()).containsExactly(ActuatorMediaType.V3_JSON,
ActuatorMediaType.V2_JSON, "application/json");
assertThat(EndpointMediaTypes.DEFAULT.getConsumed()).containsExactly(ActuatorMediaType.V3_JSON,
ActuatorMediaType.V2_JSON, "application/json");
assertThat(EndpointMediaTypes.DEFAULT.getProduced()).containsExactly(V3_JSON, V2_JSON, "application/json");
assertThat(EndpointMediaTypes.DEFAULT.getConsumed()).containsExactly(V3_JSON, V2_JSON, "application/json");
}
@Test

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2020 the original author or authors.
* Copyright 2012-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,7 +23,7 @@ import java.util.Map;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.Test;
import org.springframework.boot.actuate.endpoint.http.ApiVersion;
import org.springframework.boot.actuate.endpoint.ApiVersion;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2020 the original author or authors.
* Copyright 2012-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,8 +22,8 @@ import java.util.Map;
import org.junit.jupiter.api.Test;
import org.springframework.boot.actuate.endpoint.ApiVersion;
import org.springframework.boot.actuate.endpoint.SecurityContext;
import org.springframework.boot.actuate.endpoint.http.ApiVersion;
import org.springframework.boot.actuate.health.HealthEndpointSupport.HealthResult;
import static org.assertj.core.api.Assertions.assertThat;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2020 the original author or authors.
* Copyright 2012-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,8 +21,8 @@ import java.util.Map;
import org.junit.jupiter.api.Test;
import org.springframework.boot.actuate.endpoint.ApiVersion;
import org.springframework.boot.actuate.endpoint.SecurityContext;
import org.springframework.boot.actuate.endpoint.http.ApiVersion;
import org.springframework.boot.actuate.endpoint.web.WebEndpointResponse;
import org.springframework.boot.actuate.health.HealthEndpointSupport.HealthResult;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,7 +23,7 @@ import java.util.Map;
import org.assertj.core.api.ThrowableAssert.ThrowingCallable;
import reactor.core.publisher.Mono;
import org.springframework.boot.actuate.endpoint.http.ActuatorMediaType;
import org.springframework.boot.actuate.endpoint.ApiVersion;
import org.springframework.boot.actuate.endpoint.web.test.WebEndpointTest;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
@@ -45,6 +45,10 @@ import org.springframework.util.ReflectionUtils;
*/
class HealthEndpointWebIntegrationTests {
private static final String V2_JSON = ApiVersion.V2.getProducedMimeType().toString();
private static final String V3_JSON = ApiVersion.V3.getProducedMimeType().toString();
@WebEndpointTest
void whenHealthIsUp200ResponseIsReturned(WebTestClient client) {
client.get().uri("/actuator/health").accept(MediaType.APPLICATION_JSON).exchange().expectStatus().isOk()
@@ -54,8 +58,7 @@ class HealthEndpointWebIntegrationTests {
@WebEndpointTest
void whenHealthIsUpAndAcceptsV3Request200ResponseIsReturned(WebTestClient client) {
client.get().uri("/actuator/health")
.headers((headers) -> headers.set(HttpHeaders.ACCEPT, ActuatorMediaType.V3_JSON)).exchange()
client.get().uri("/actuator/health").headers((headers) -> headers.set(HttpHeaders.ACCEPT, V3_JSON)).exchange()
.expectStatus().isOk().expectBody().jsonPath("status").isEqualTo("UP")
.jsonPath("components.alpha.status").isEqualTo("UP").jsonPath("components.bravo.status")
.isEqualTo("UP");
@@ -71,8 +74,7 @@ class HealthEndpointWebIntegrationTests {
@WebEndpointTest
void whenHealthIsUpAndV2Request200ResponseIsReturnedInV2Format(WebTestClient client) {
client.get().uri("/actuator/health")
.headers((headers) -> headers.set(HttpHeaders.ACCEPT, ActuatorMediaType.V2_JSON)).exchange()
client.get().uri("/actuator/health").headers((headers) -> headers.set(HttpHeaders.ACCEPT, V2_JSON)).exchange()
.expectStatus().isOk().expectBody().jsonPath("status").isEqualTo("UP").jsonPath("details.alpha.status")
.isEqualTo("UP").jsonPath("details.bravo.status").isEqualTo("UP");
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2020 the original author or authors.
* Copyright 2012-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,8 +22,8 @@ import java.util.Map;
import org.junit.jupiter.api.Test;
import reactor.core.publisher.Mono;
import org.springframework.boot.actuate.endpoint.ApiVersion;
import org.springframework.boot.actuate.endpoint.SecurityContext;
import org.springframework.boot.actuate.endpoint.http.ApiVersion;
import org.springframework.boot.actuate.endpoint.web.WebEndpointResponse;
import org.springframework.boot.actuate.health.HealthEndpointSupport.HealthResult;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2020 the original author or authors.
* Copyright 2012-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,7 +25,7 @@ import java.util.Set;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.Test;
import org.springframework.boot.actuate.endpoint.http.ApiVersion;
import org.springframework.boot.actuate.endpoint.ApiVersion;
import static org.assertj.core.api.Assertions.assertThat;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -30,7 +30,7 @@ import org.junit.jupiter.api.BeforeEach;
import org.mockito.Mockito;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.actuate.endpoint.http.ActuatorMediaType;
import org.springframework.boot.actuate.endpoint.ApiVersion;
import org.springframework.boot.actuate.endpoint.web.test.WebEndpointTest;
import org.springframework.boot.logging.LogLevel;
import org.springframework.boot.logging.LoggerConfiguration;
@@ -61,6 +61,10 @@ import static org.mockito.Mockito.verifyNoInteractions;
*/
class LoggersEndpointWebIntegrationTests {
private static final String V2_JSON = ApiVersion.V2.getProducedMimeType().toString();
private static final String V3_JSON = ApiVersion.V3.getProducedMimeType().toString();
private WebTestClient client;
private LoggingSystem loggingSystem;
@@ -125,8 +129,7 @@ class LoggersEndpointWebIntegrationTests {
@WebEndpointTest
void setLoggerUsingActuatorV2JsonShouldSetLogLevel() {
this.client.post().uri("/actuator/loggers/ROOT")
.contentType(MediaType.parseMediaType(ActuatorMediaType.V2_JSON))
this.client.post().uri("/actuator/loggers/ROOT").contentType(MediaType.parseMediaType(V2_JSON))
.bodyValue(Collections.singletonMap("configuredLevel", "debug")).exchange().expectStatus()
.isNoContent();
verify(this.loggingSystem).setLogLevel("ROOT", LogLevel.DEBUG);
@@ -134,8 +137,7 @@ class LoggersEndpointWebIntegrationTests {
@WebEndpointTest
void setLoggerUsingActuatorV3JsonShouldSetLogLevel() {
this.client.post().uri("/actuator/loggers/ROOT")
.contentType(MediaType.parseMediaType(ActuatorMediaType.V3_JSON))
this.client.post().uri("/actuator/loggers/ROOT").contentType(MediaType.parseMediaType(V3_JSON))
.bodyValue(Collections.singletonMap("configuredLevel", "debug")).exchange().expectStatus()
.isNoContent();
verify(this.loggingSystem).setLogLevel("ROOT", LogLevel.DEBUG);
@@ -143,8 +145,7 @@ class LoggersEndpointWebIntegrationTests {
@WebEndpointTest
void setLoggerGroupUsingActuatorV2JsonShouldSetLogLevel() {
this.client.post().uri("/actuator/loggers/test")
.contentType(MediaType.parseMediaType(ActuatorMediaType.V2_JSON))
this.client.post().uri("/actuator/loggers/test").contentType(MediaType.parseMediaType(V2_JSON))
.bodyValue(Collections.singletonMap("configuredLevel", "debug")).exchange().expectStatus()
.isNoContent();
verify(this.loggingSystem).setLogLevel("test.member1", LogLevel.DEBUG);
@@ -170,24 +171,21 @@ class LoggersEndpointWebIntegrationTests {
@WebEndpointTest
void setLoggerWithNullLogLevel() {
this.client.post().uri("/actuator/loggers/ROOT")
.contentType(MediaType.parseMediaType(ActuatorMediaType.V3_JSON))
this.client.post().uri("/actuator/loggers/ROOT").contentType(MediaType.parseMediaType(V3_JSON))
.bodyValue(Collections.singletonMap("configuredLevel", null)).exchange().expectStatus().isNoContent();
verify(this.loggingSystem).setLogLevel("ROOT", null);
}
@WebEndpointTest
void setLoggerWithNoLogLevel() {
this.client.post().uri("/actuator/loggers/ROOT")
.contentType(MediaType.parseMediaType(ActuatorMediaType.V3_JSON)).bodyValue(Collections.emptyMap())
.exchange().expectStatus().isNoContent();
this.client.post().uri("/actuator/loggers/ROOT").contentType(MediaType.parseMediaType(V3_JSON))
.bodyValue(Collections.emptyMap()).exchange().expectStatus().isNoContent();
verify(this.loggingSystem).setLogLevel("ROOT", null);
}
@WebEndpointTest
void setLoggerGroupWithNullLogLevel() {
this.client.post().uri("/actuator/loggers/test")
.contentType(MediaType.parseMediaType(ActuatorMediaType.V3_JSON))
this.client.post().uri("/actuator/loggers/test").contentType(MediaType.parseMediaType(V3_JSON))
.bodyValue(Collections.singletonMap("configuredLevel", null)).exchange().expectStatus().isNoContent();
verify(this.loggingSystem).setLogLevel("test.member1", null);
verify(this.loggingSystem).setLogLevel("test.member2", null);
@@ -195,9 +193,8 @@ class LoggersEndpointWebIntegrationTests {
@WebEndpointTest
void setLoggerGroupWithNoLogLevel() {
this.client.post().uri("/actuator/loggers/test")
.contentType(MediaType.parseMediaType(ActuatorMediaType.V3_JSON)).bodyValue(Collections.emptyMap())
.exchange().expectStatus().isNoContent();
this.client.post().uri("/actuator/loggers/test").contentType(MediaType.parseMediaType(V3_JSON))
.bodyValue(Collections.emptyMap()).exchange().expectStatus().isNoContent();
verify(this.loggingSystem).setLogLevel("test.member1", null);
verify(this.loggingSystem).setLogLevel("test.member2", null);
}