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
pull/25943/head
Phillip Webb 4 years ago
parent e766c8b3a7
commit e4164d0143

@ -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.
@ -19,12 +19,12 @@ package org.springframework.boot.actuate.autoconfigure.cloudfoundry.reactive;
import reactor.core.publisher.Mono;
import org.springframework.boot.actuate.autoconfigure.cloudfoundry.EndpointCloudFoundryExtension;
import org.springframework.boot.actuate.endpoint.ApiVersion;
import org.springframework.boot.actuate.endpoint.SecurityContext;
import org.springframework.boot.actuate.endpoint.annotation.EndpointExtension;
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
import org.springframework.boot.actuate.endpoint.annotation.Selector;
import org.springframework.boot.actuate.endpoint.annotation.Selector.Match;
import org.springframework.boot.actuate.endpoint.http.ApiVersion;
import org.springframework.boot.actuate.endpoint.web.WebEndpointResponse;
import org.springframework.boot.actuate.health.HealthComponent;
import org.springframework.boot.actuate.health.HealthEndpoint;

@ -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.
@ -17,12 +17,12 @@
package org.springframework.boot.actuate.autoconfigure.cloudfoundry.servlet;
import org.springframework.boot.actuate.autoconfigure.cloudfoundry.EndpointCloudFoundryExtension;
import org.springframework.boot.actuate.endpoint.ApiVersion;
import org.springframework.boot.actuate.endpoint.SecurityContext;
import org.springframework.boot.actuate.endpoint.annotation.EndpointExtension;
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
import org.springframework.boot.actuate.endpoint.annotation.Selector;
import org.springframework.boot.actuate.endpoint.annotation.Selector.Match;
import org.springframework.boot.actuate.endpoint.http.ApiVersion;
import org.springframework.boot.actuate.endpoint.web.WebEndpointResponse;
import org.springframework.boot.actuate.health.HealthComponent;
import org.springframework.boot.actuate.health.HealthEndpoint;

@ -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 org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAu
import org.springframework.boot.actuate.autoconfigure.health.HealthContributorAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration;
import org.springframework.boot.actuate.endpoint.http.ApiVersion;
import org.springframework.boot.actuate.endpoint.ApiVersion;
import org.springframework.boot.actuate.health.CompositeHealth;
import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.HealthComponent;

@ -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.
@ -37,10 +37,10 @@ import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoC
import org.springframework.boot.actuate.autoconfigure.info.InfoContributorAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.info.InfoEndpointAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration;
import org.springframework.boot.actuate.endpoint.ApiVersion;
import org.springframework.boot.actuate.endpoint.EndpointId;
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
import org.springframework.boot.actuate.endpoint.http.ActuatorMediaType;
import org.springframework.boot.actuate.endpoint.web.EndpointMapping;
import org.springframework.boot.actuate.endpoint.web.ExposableWebEndpoint;
import org.springframework.boot.actuate.endpoint.web.WebOperation;
@ -80,6 +80,10 @@ import static org.mockito.Mockito.mock;
*/
class ReactiveCloudFoundryActuatorAutoConfigurationTests {
private static final String V2_JSON = ApiVersion.V2.getProducedMimeType().toString();
private static final String V3_JSON = ApiVersion.V3.getProducedMimeType().toString();
private final ReactiveWebApplicationContextRunner contextRunner = new ReactiveWebApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(ReactiveSecurityAutoConfiguration.class,
ReactiveUserDetailsServiceAutoConfiguration.class, WebFluxAutoConfiguration.class,
@ -120,7 +124,7 @@ class ReactiveCloudFoundryActuatorAutoConfigurationTests {
"vcap.application.cf_api:https://my-cloud-controller.com").run((context) -> {
WebTestClient webTestClient = WebTestClient.bindToApplicationContext(context).build();
webTestClient.get().uri("/cloudfoundryapplication").header("Content-Type",
ActuatorMediaType.V2_JSON + ";charset=UTF-8");
V2_JSON + ";charset=UTF-8");
});
}
@ -301,8 +305,7 @@ class ReactiveCloudFoundryActuatorAutoConfigurationTests {
private WebOperation findOperationWithRequestPath(ExposableWebEndpoint endpoint, String requestPath) {
for (WebOperation operation : endpoint.getOperations()) {
WebOperationRequestPredicate predicate = operation.getRequestPredicate();
if (predicate.getPath().equals(requestPath)
&& predicate.getProduces().contains(ActuatorMediaType.V3_JSON)) {
if (predicate.getPath().equals(requestPath) && predicate.getProduces().contains(V3_JSON)) {
return operation;
}
}

@ -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.
@ -27,10 +27,10 @@ import org.springframework.boot.actuate.autoconfigure.health.HealthContributorAu
import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.web.servlet.ServletManagementContextAutoConfiguration;
import org.springframework.boot.actuate.endpoint.ApiVersion;
import org.springframework.boot.actuate.endpoint.EndpointId;
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
import org.springframework.boot.actuate.endpoint.http.ActuatorMediaType;
import org.springframework.boot.actuate.endpoint.web.EndpointMapping;
import org.springframework.boot.actuate.endpoint.web.ExposableWebEndpoint;
import org.springframework.boot.actuate.endpoint.web.WebOperation;
@ -67,6 +67,8 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
*/
class CloudFoundryActuatorAutoConfigurationTests {
private static final String V3_JSON = ApiVersion.V3.getProducedMimeType().toString();
private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(SecurityAutoConfiguration.class, WebMvcAutoConfiguration.class,
JacksonAutoConfiguration.class, DispatcherServletAutoConfiguration.class,
@ -99,7 +101,7 @@ class CloudFoundryActuatorAutoConfigurationTests {
"vcap.application.cf_api:https://my-cloud-controller.com").run((context) -> {
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(context).build();
mockMvc.perform(get("/cloudfoundryapplication"))
.andExpect(header().string("Content-Type", ActuatorMediaType.V3_JSON));
.andExpect(header().string("Content-Type", V3_JSON));
});
}
@ -244,8 +246,7 @@ class CloudFoundryActuatorAutoConfigurationTests {
private WebOperation findOperationWithRequestPath(ExposableWebEndpoint endpoint, String requestPath) {
for (WebOperation operation : endpoint.getOperations()) {
WebOperationRequestPredicate predicate = operation.getRequestPredicate();
if (predicate.getPath().equals(requestPath)
&& predicate.getProduces().contains(ActuatorMediaType.V3_JSON)) {
if (predicate.getPath().equals(requestPath) && predicate.getProduces().contains(V3_JSON)) {
return operation;
}
}

@ -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.
@ -24,7 +24,7 @@ import org.springframework.boot.actuate.autoconfigure.health.HealthContributorAu
import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.web.servlet.ServletManagementContextAutoConfiguration;
import org.springframework.boot.actuate.endpoint.http.ApiVersion;
import org.springframework.boot.actuate.endpoint.ApiVersion;
import org.springframework.boot.actuate.health.CompositeHealth;
import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.HealthComponent;

@ -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,9 +25,9 @@ import org.junit.jupiter.api.Test;
import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.endpoint.expose.IncludeExcludeEndpointFilter;
import org.springframework.boot.actuate.endpoint.ApiVersion;
import org.springframework.boot.actuate.endpoint.EndpointId;
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.actuate.endpoint.http.ActuatorMediaType;
import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes;
import org.springframework.boot.actuate.endpoint.web.ExposableWebEndpoint;
import org.springframework.boot.actuate.endpoint.web.PathMappedEndpoint;
@ -51,6 +51,10 @@ import static org.assertj.core.api.Assertions.assertThat;
*/
class WebEndpointAutoConfigurationTests {
private static final String V2_JSON = ApiVersion.V2.getProducedMimeType().toString();
private static final String V3_JSON = ApiVersion.V3.getProducedMimeType().toString();
private static final AutoConfigurations CONFIGURATIONS = AutoConfigurations.of(EndpointAutoConfiguration.class,
WebEndpointAutoConfiguration.class);
@ -61,8 +65,7 @@ class WebEndpointAutoConfigurationTests {
void webApplicationConfiguresEndpointMediaTypes() {
this.contextRunner.run((context) -> {
EndpointMediaTypes endpointMediaTypes = context.getBean(EndpointMediaTypes.class);
assertThat(endpointMediaTypes.getConsumed()).containsExactly(ActuatorMediaType.V3_JSON,
ActuatorMediaType.V2_JSON, "application/json");
assertThat(endpointMediaTypes.getConsumed()).containsExactly(V3_JSON, V2_JSON, "application/json");
});
}

@ -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 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.SecurityContext;
import org.springframework.boot.actuate.endpoint.http.ApiVersion;
import org.springframework.boot.actuate.endpoint.web.WebEndpointResponse;
import org.springframework.boot.actuate.health.DefaultHealthContributorRegistry;
import org.springframework.boot.actuate.health.DefaultReactiveHealthContributorRegistry;

@ -0,0 +1,57 @@
/*
* 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.actuate.endpoint;
import org.springframework.util.MimeType;
import org.springframework.util.MimeTypeUtils;
/**
* API versions supported for the actuator API. This enum may be injected into actuator
* endpoints in order to return a response compatible with the requested version.
*
* @author Phillip Webb
* @since 2.4.0
*/
public enum ApiVersion implements Producible<ApiVersion> {
/**
* Version 2 (supported by Spring Boot 2.0+).
*/
V2("application/vnd.spring-boot.actuator.v2+json"),
/**
* Version 3 (supported by Spring Boot 2.2+).
*/
V3("application/vnd.spring-boot.actuator.v3+json");
/**
* The latest API version.
*/
public static final ApiVersion LATEST = ApiVersion.V3;
private final MimeType mimeType;
ApiVersion(String mimeType) {
this.mimeType = MimeTypeUtils.parseMimeType(mimeType);
}
@Override
public MimeType getProducedMimeType() {
return this.mimeType;
}
}

@ -22,7 +22,6 @@ import java.util.Arrays;
import java.util.List;
import java.util.Map;
import org.springframework.boot.actuate.endpoint.http.ApiVersion;
import org.springframework.boot.actuate.endpoint.invoke.OperationInvoker;
import org.springframework.util.Assert;
@ -60,8 +59,10 @@ public class InvocationContext {
* {@link #InvocationContext(SecurityContext, Map, OperationArgumentResolver[])}
*/
@Deprecated
public InvocationContext(ApiVersion apiVersion, SecurityContext securityContext, Map<String, Object> arguments) {
this(securityContext, arguments, OperationArgumentResolver.of(ApiVersion.class, () -> apiVersion));
public InvocationContext(org.springframework.boot.actuate.endpoint.http.ApiVersion apiVersion,
SecurityContext securityContext, Map<String, Object> arguments) {
this(securityContext, arguments, OperationArgumentResolver.of(ApiVersion.class,
() -> (apiVersion != null) ? ApiVersion.valueOf(apiVersion.name()) : null));
}
/**
@ -90,9 +91,16 @@ public class InvocationContext {
* Return the API version in use.
* @return the apiVersion the API version
* @since 2.2.0
* @deprecated since 2.5.0 for removal in 2.7.0 in favor of
* {@link #resolveArgument(Class)} using
* {@link org.springframework.boot.actuate.endpoint.ApiVersion}
*/
public ApiVersion getApiVersion() {
return resolveArgument(ApiVersion.class);
@Deprecated
public org.springframework.boot.actuate.endpoint.http.ApiVersion getApiVersion() {
ApiVersion version = resolveArgument(ApiVersion.class);
System.out.println(version);
return (version != null) ? org.springframework.boot.actuate.endpoint.http.ApiVersion.valueOf(version.name())
: org.springframework.boot.actuate.endpoint.http.ApiVersion.LATEST;
}
/**

@ -14,8 +14,11 @@
* limitations under the License.
*/
package org.springframework.boot.actuate.endpoint.annotation;
package org.springframework.boot.actuate.endpoint;
import org.springframework.boot.actuate.endpoint.annotation.DeleteOperation;
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
import org.springframework.boot.actuate.endpoint.annotation.WriteOperation;
import org.springframework.util.MimeType;
/**

@ -14,15 +14,13 @@
* 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.springframework.boot.actuate.endpoint.OperationArgumentResolver;
import org.springframework.boot.actuate.endpoint.annotation.Producible;
import org.springframework.util.CollectionUtils;
import org.springframework.util.MimeType;
import org.springframework.util.MimeTypeUtils;
@ -35,10 +33,14 @@ import org.springframework.util.MimeTypeUtils;
*/
public class ProducibleOperationArgumentResolver implements OperationArgumentResolver {
private final Map<String, List<String>> headers;
private final Supplier<List<String>> accepts;
public ProducibleOperationArgumentResolver(Map<String, List<String>> headers) {
this.headers = headers;
/**
* Create a new {@link ProducibleOperationArgumentResolver} instance.
* @param accepts supplier that returns accepted mime types
*/
public ProducibleOperationArgumentResolver(Supplier<List<String>> accepts) {
this.accepts = accepts;
}
@Override
@ -53,7 +55,7 @@ public class ProducibleOperationArgumentResolver implements OperationArgumentRes
}
private Enum<? extends Producible<?>> resolveProducible(Class<Enum<? extends Producible<?>>> type) {
List<String> accepts = this.headers.get("Accept");
List<String> accepts = this.accepts.get();
List<Enum<? extends Producible<?>>> values = Arrays.asList(type.getEnumConstants());
Collections.reverse(values);
if (CollectionUtils.isEmpty(accepts)) {

@ -22,6 +22,8 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.boot.actuate.endpoint.Producible;
/**
* Identifies a method on an {@link Endpoint @Endpoint} as being a delete operation.
*

@ -23,6 +23,7 @@ import java.util.Collections;
import java.util.List;
import org.springframework.boot.actuate.endpoint.OperationType;
import org.springframework.boot.actuate.endpoint.Producible;
import org.springframework.boot.actuate.endpoint.invoke.reflect.OperationMethod;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.util.Assert;

@ -22,6 +22,8 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.boot.actuate.endpoint.Producible;
/**
* Identifies a method on an {@link Endpoint @Endpoint} as being a read operation.
*

@ -22,6 +22,8 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.boot.actuate.endpoint.Producible;
/**
* Identifies a method on an {@link Endpoint @Endpoint} as being a write operation.
*

@ -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,7 +22,10 @@ package org.springframework.boot.actuate.endpoint.http;
* @author Andy Wilkinson
* @author Madhura Bhave
* @since 2.0.0
* @deprecated since 2.5.0 for removal in 2.7.0 in favor of
* {@link org.springframework.boot.actuate.endpoint.ApiVersion#getProducedMimeType()}
*/
@Deprecated
public final class ActuatorMediaType {
/**

@ -19,9 +19,8 @@ package org.springframework.boot.actuate.endpoint.http;
import java.util.List;
import java.util.Map;
import org.springframework.boot.actuate.endpoint.annotation.Producible;
import org.springframework.boot.actuate.endpoint.ProducibleOperationArgumentResolver;
import org.springframework.util.CollectionUtils;
import org.springframework.util.MimeType;
import org.springframework.util.MimeTypeUtils;
/**
@ -30,18 +29,21 @@ import org.springframework.util.MimeTypeUtils;
*
* @author Phillip Webb
* @since 2.2.0
* @deprecated since 2.5.0 for removal in 2.7.0 in favor of
* {@link org.springframework.boot.actuate.endpoint.ApiVersion}
*/
public enum ApiVersion implements Producible<ApiVersion> {
@Deprecated
public enum ApiVersion {
/**
* Version 2 (supported by Spring Boot 2.0+).
*/
V2(ActuatorMediaType.V2_JSON),
V2,
/**
* Version 3 (supported by Spring Boot 2.2+).
*/
V3(ActuatorMediaType.V3_JSON);
V3;
private static final String MEDIA_TYPE_PREFIX = "application/vnd.spring-boot.actuator.";
@ -50,17 +52,6 @@ public enum ApiVersion implements Producible<ApiVersion> {
*/
public static final ApiVersion LATEST = ApiVersion.V3;
private final MimeType mimeType;
ApiVersion(String mimeType) {
this.mimeType = MimeTypeUtils.parseMimeType(mimeType);
}
@Override
public MimeType getProducedMimeType() {
return this.mimeType;
}
/**
* Return the {@link ApiVersion} to use based on the HTTP request headers. The version
* will be deduced based on the {@code Accept} header.

@ -25,8 +25,8 @@ import java.util.concurrent.ConcurrentHashMap;
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.http.ApiVersion;
import org.springframework.boot.actuate.endpoint.invoke.OperationInvoker;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
@ -78,7 +78,7 @@ public class CachingOperationInvoker implements OperationInvoker {
return this.invoker.invoke(context);
}
long accessTime = System.currentTimeMillis();
ApiVersion contextApiVersion = context.getApiVersion();
ApiVersion contextApiVersion = context.resolveArgument(ApiVersion.class);
Principal principal = context.resolveArgument(Principal.class);
CacheKey cacheKey = new CacheKey(contextApiVersion, principal);
CachedResponse cached = this.cachedResponses.get(cacheKey);

@ -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.
@ -18,10 +18,10 @@ package org.springframework.boot.actuate.endpoint.invoker.cache;
import java.util.function.Function;
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.OperationInvokerAdvisor;
import org.springframework.boot.actuate.endpoint.invoke.OperationParameter;

@ -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.
@ -20,7 +20,7 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.springframework.boot.actuate.endpoint.http.ActuatorMediaType;
import org.springframework.boot.actuate.endpoint.ApiVersion;
import org.springframework.util.Assert;
/**
@ -31,13 +31,12 @@ import org.springframework.util.Assert;
*/
public class EndpointMediaTypes {
private static final String JSON_MEDIA_TYPE = "application/json";
/**
* Default {@link EndpointMediaTypes} for this version of Spring Boot.
*/
public static final EndpointMediaTypes DEFAULT = new EndpointMediaTypes(ActuatorMediaType.V3_JSON,
ActuatorMediaType.V2_JSON, JSON_MEDIA_TYPE);
public static final EndpointMediaTypes DEFAULT = new EndpointMediaTypes(
ApiVersion.V3.getProducedMimeType().toString(), ApiVersion.V2.getProducedMimeType().toString(),
"application/json");
private final List<String> produced;

@ -16,7 +16,7 @@
package org.springframework.boot.actuate.endpoint.web;
import org.springframework.boot.actuate.endpoint.annotation.Producible;
import org.springframework.boot.actuate.endpoint.Producible;
import org.springframework.boot.actuate.endpoint.web.annotation.EndpointWebExtension;
import org.springframework.util.MimeType;

@ -42,8 +42,8 @@ import reactor.core.publisher.Mono;
import org.springframework.boot.actuate.endpoint.InvalidEndpointRequestException;
import org.springframework.boot.actuate.endpoint.InvocationContext;
import org.springframework.boot.actuate.endpoint.ProducibleOperationArgumentResolver;
import org.springframework.boot.actuate.endpoint.SecurityContext;
import org.springframework.boot.actuate.endpoint.http.ProducibleOperationArgumentResolver;
import org.springframework.boot.actuate.endpoint.web.EndpointLinksResolver;
import org.springframework.boot.actuate.endpoint.web.EndpointMapping;
import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes;
@ -153,7 +153,7 @@ public class JerseyEndpointResourceFactory {
try {
JerseySecurityContext securityContext = new JerseySecurityContext(data.getSecurityContext());
InvocationContext invocationContext = new InvocationContext(securityContext, arguments,
new ProducibleOperationArgumentResolver(data.getHeaders()));
new ProducibleOperationArgumentResolver(() -> data.getHeaders().get("Accept")));
Object response = this.operation.invoke(invocationContext);
return convertToJaxRsResponse(response, data.getRequest().getMethod());
}

@ -32,8 +32,8 @@ import reactor.core.scheduler.Schedulers;
import org.springframework.boot.actuate.endpoint.InvalidEndpointRequestException;
import org.springframework.boot.actuate.endpoint.InvocationContext;
import org.springframework.boot.actuate.endpoint.OperationType;
import org.springframework.boot.actuate.endpoint.ProducibleOperationArgumentResolver;
import org.springframework.boot.actuate.endpoint.SecurityContext;
import org.springframework.boot.actuate.endpoint.http.ProducibleOperationArgumentResolver;
import org.springframework.boot.actuate.endpoint.invoke.OperationInvoker;
import org.springframework.boot.actuate.endpoint.web.EndpointMapping;
import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes;
@ -307,7 +307,8 @@ public abstract class AbstractWebFluxEndpointHandlerMapping extends RequestMappi
}
return this.securityContextSupplier.get()
.map((securityContext) -> new InvocationContext(securityContext, arguments,
new ProducibleOperationArgumentResolver(exchange.getRequest().getHeaders())))
new ProducibleOperationArgumentResolver(
() -> exchange.getRequest().getHeaders().get("Accept"))))
.flatMap((invocationContext) -> handleResult((Publisher<?>) this.invoker.invoke(invocationContext),
exchange.getRequest().getMethod()));
}

@ -32,8 +32,8 @@ import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.actuate.endpoint.InvalidEndpointRequestException;
import org.springframework.boot.actuate.endpoint.InvocationContext;
import org.springframework.boot.actuate.endpoint.ProducibleOperationArgumentResolver;
import org.springframework.boot.actuate.endpoint.SecurityContext;
import org.springframework.boot.actuate.endpoint.http.ProducibleOperationArgumentResolver;
import org.springframework.boot.actuate.endpoint.invoke.OperationInvoker;
import org.springframework.boot.actuate.endpoint.web.EndpointMapping;
import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes;
@ -287,7 +287,7 @@ public abstract class AbstractWebMvcEndpointHandlerMapping extends RequestMappin
try {
ServletSecurityContext securityContext = new ServletSecurityContext(request);
InvocationContext invocationContext = new InvocationContext(securityContext, arguments,
new ProducibleOperationArgumentResolver(headers));
new ProducibleOperationArgumentResolver(() -> headers.get("Accept")));
return handleResult(this.operation.invoke(invocationContext), HttpMethod.resolve(request.getMethod()));
}
catch (InvalidEndpointRequestException ex) {

@ -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 com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.springframework.boot.actuate.endpoint.http.ApiVersion;
import org.springframework.boot.actuate.endpoint.ApiVersion;
import org.springframework.util.Assert;
/**

@ -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.
@ -19,12 +19,12 @@ package org.springframework.boot.actuate.health;
import java.util.Map;
import java.util.Set;
import org.springframework.boot.actuate.endpoint.ApiVersion;
import org.springframework.boot.actuate.endpoint.SecurityContext;
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
import org.springframework.boot.actuate.endpoint.annotation.Selector;
import org.springframework.boot.actuate.endpoint.annotation.Selector.Match;
import org.springframework.boot.actuate.endpoint.http.ApiVersion;
/**
* {@link Endpoint @Endpoint} to expose application health information.

@ -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 java.util.Set;
import java.util.stream.Collectors;
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.util.Assert;
/**

@ -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.
@ -20,11 +20,11 @@ import java.util.Arrays;
import java.util.Map;
import java.util.Set;
import org.springframework.boot.actuate.endpoint.ApiVersion;
import org.springframework.boot.actuate.endpoint.SecurityContext;
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
import org.springframework.boot.actuate.endpoint.annotation.Selector;
import org.springframework.boot.actuate.endpoint.annotation.Selector.Match;
import org.springframework.boot.actuate.endpoint.http.ApiVersion;
import org.springframework.boot.actuate.endpoint.web.WebEndpointResponse;
import org.springframework.boot.actuate.endpoint.web.annotation.EndpointWebExtension;

@ -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,11 +23,11 @@ import java.util.Set;
import reactor.core.publisher.Flux;
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.annotation.ReadOperation;
import org.springframework.boot.actuate.endpoint.annotation.Selector;
import org.springframework.boot.actuate.endpoint.annotation.Selector.Match;
import org.springframework.boot.actuate.endpoint.http.ApiVersion;
import org.springframework.boot.actuate.endpoint.web.WebEndpointResponse;
import org.springframework.boot.actuate.endpoint.web.annotation.EndpointWebExtension;

@ -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.TreeSet;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import org.springframework.boot.actuate.endpoint.http.ApiVersion;
import org.springframework.boot.actuate.endpoint.ApiVersion;
/**
* A {@link HealthComponent} that represents the overall system health and the available

@ -23,7 +23,7 @@ import java.util.Enumeration;
import io.prometheus.client.Collector.MetricFamilySamples;
import io.prometheus.client.exporter.common.TextFormat;
import org.springframework.boot.actuate.endpoint.annotation.Producible;
import org.springframework.boot.actuate.endpoint.Producible;
import org.springframework.util.MimeType;
import org.springframework.util.MimeTypeUtils;

@ -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

@ -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);
}
}

@ -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;

@ -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;

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

@ -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;

@ -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;

@ -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;

@ -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

@ -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;

@ -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;

@ -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;

@ -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");
}

@ -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;

@ -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;

@ -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);
}

Loading…
Cancel
Save