commit
3b49bdecb3
|
@ -40,19 +40,19 @@ public enum AccessLevel {
|
||||||
|
|
||||||
public static final String REQUEST_ATTRIBUTE = "cloudFoundryAccessLevel";
|
public static final String REQUEST_ATTRIBUTE = "cloudFoundryAccessLevel";
|
||||||
|
|
||||||
private final List<String> endpointIds;
|
private final List<String> ids;
|
||||||
|
|
||||||
AccessLevel(String... endpointIds) {
|
AccessLevel(String... ids) {
|
||||||
this.endpointIds = Arrays.asList(endpointIds);
|
this.ids = Arrays.asList(ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns if the access level should allow access to the specified endpoint path.
|
* Returns if the access level should allow access to the specified ID.
|
||||||
* @param endpointId the endpoint ID to check
|
* @param id the ID to check
|
||||||
* @return {@code true} if access is allowed
|
* @return {@code true} if access is allowed
|
||||||
*/
|
*/
|
||||||
public boolean isAccessAllowed(String endpointId) {
|
public boolean isAccessAllowed(String id) {
|
||||||
return this.endpointIds.isEmpty() || this.endpointIds.contains(endpointId);
|
return this.ids.isEmpty() || this.ids.contains(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,7 +59,7 @@ class CloudFoundrySecurityInterceptor {
|
||||||
this.applicationId = applicationId;
|
this.applicationId = applicationId;
|
||||||
}
|
}
|
||||||
|
|
||||||
Mono<SecurityResponse> preHandle(ServerWebExchange exchange, String endpointId) {
|
Mono<SecurityResponse> preHandle(ServerWebExchange exchange, String id) {
|
||||||
ServerHttpRequest request = exchange.getRequest();
|
ServerHttpRequest request = exchange.getRequest();
|
||||||
if (CorsUtils.isPreFlightRequest(request)) {
|
if (CorsUtils.isPreFlightRequest(request)) {
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
|
@ -72,7 +72,7 @@ class CloudFoundrySecurityInterceptor {
|
||||||
return Mono.error(new CloudFoundryAuthorizationException(
|
return Mono.error(new CloudFoundryAuthorizationException(
|
||||||
Reason.SERVICE_UNAVAILABLE, "Cloud controller URL is not available"));
|
Reason.SERVICE_UNAVAILABLE, "Cloud controller URL is not available"));
|
||||||
}
|
}
|
||||||
return check(exchange, endpointId).then(SUCCESS).doOnError(this::logError)
|
return check(exchange, id).then(SUCCESS).doOnError(this::logError)
|
||||||
.onErrorResume(this::getErrorResponse);
|
.onErrorResume(this::getErrorResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,13 +80,13 @@ class CloudFoundrySecurityInterceptor {
|
||||||
logger.error(ex.getMessage(), ex);
|
logger.error(ex.getMessage(), ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Mono<Void> check(ServerWebExchange exchange, String path) {
|
private Mono<Void> check(ServerWebExchange exchange, String id) {
|
||||||
try {
|
try {
|
||||||
Token token = getToken(exchange.getRequest());
|
Token token = getToken(exchange.getRequest());
|
||||||
return this.tokenValidator.validate(token)
|
return this.tokenValidator.validate(token)
|
||||||
.then(this.cloudFoundrySecurityService
|
.then(this.cloudFoundrySecurityService
|
||||||
.getAccessLevel(token.toString(), this.applicationId))
|
.getAccessLevel(token.toString(), this.applicationId))
|
||||||
.filter((accessLevel) -> accessLevel.isAccessAllowed(path))
|
.filter((accessLevel) -> accessLevel.isAccessAllowed(id))
|
||||||
.switchIfEmpty(Mono.error(new CloudFoundryAuthorizationException(
|
.switchIfEmpty(Mono.error(new CloudFoundryAuthorizationException(
|
||||||
Reason.ACCESS_DENIED, "Access denied")))
|
Reason.ACCESS_DENIED, "Access denied")))
|
||||||
.doOnSuccess((accessLevel) -> exchange.getAttributes()
|
.doOnSuccess((accessLevel) -> exchange.getAttributes()
|
||||||
|
|
|
@ -27,6 +27,7 @@ import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
import org.springframework.boot.actuate.autoconfigure.cloudfoundry.AccessLevel;
|
import org.springframework.boot.actuate.autoconfigure.cloudfoundry.AccessLevel;
|
||||||
import org.springframework.boot.actuate.autoconfigure.cloudfoundry.SecurityResponse;
|
import org.springframework.boot.actuate.autoconfigure.cloudfoundry.SecurityResponse;
|
||||||
|
import org.springframework.boot.actuate.endpoint.EndpointId;
|
||||||
import org.springframework.boot.actuate.endpoint.web.EndpointLinksResolver;
|
import org.springframework.boot.actuate.endpoint.web.EndpointLinksResolver;
|
||||||
import org.springframework.boot.actuate.endpoint.web.EndpointMapping;
|
import org.springframework.boot.actuate.endpoint.web.EndpointMapping;
|
||||||
import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes;
|
import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes;
|
||||||
|
@ -70,7 +71,7 @@ class CloudFoundryWebFluxEndpointHandlerMapping
|
||||||
protected ReactiveWebOperation wrapReactiveWebOperation(ExposableWebEndpoint endpoint,
|
protected ReactiveWebOperation wrapReactiveWebOperation(ExposableWebEndpoint endpoint,
|
||||||
WebOperation operation, ReactiveWebOperation reactiveWebOperation) {
|
WebOperation operation, ReactiveWebOperation reactiveWebOperation) {
|
||||||
return new SecureReactiveWebOperation(reactiveWebOperation,
|
return new SecureReactiveWebOperation(reactiveWebOperation,
|
||||||
this.securityInterceptor, endpoint.getId());
|
this.securityInterceptor, endpoint.getEndpointId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -113,10 +114,11 @@ class CloudFoundryWebFluxEndpointHandlerMapping
|
||||||
|
|
||||||
private final CloudFoundrySecurityInterceptor securityInterceptor;
|
private final CloudFoundrySecurityInterceptor securityInterceptor;
|
||||||
|
|
||||||
private final String endpointId;
|
private final EndpointId endpointId;
|
||||||
|
|
||||||
SecureReactiveWebOperation(ReactiveWebOperation delegate,
|
SecureReactiveWebOperation(ReactiveWebOperation delegate,
|
||||||
CloudFoundrySecurityInterceptor securityInterceptor, String endpointId) {
|
CloudFoundrySecurityInterceptor securityInterceptor,
|
||||||
|
EndpointId endpointId) {
|
||||||
this.delegate = delegate;
|
this.delegate = delegate;
|
||||||
this.securityInterceptor = securityInterceptor;
|
this.securityInterceptor = securityInterceptor;
|
||||||
this.endpointId = endpointId;
|
this.endpointId = endpointId;
|
||||||
|
@ -125,7 +127,8 @@ class CloudFoundryWebFluxEndpointHandlerMapping
|
||||||
@Override
|
@Override
|
||||||
public Mono<ResponseEntity<Object>> handle(ServerWebExchange exchange,
|
public Mono<ResponseEntity<Object>> handle(ServerWebExchange exchange,
|
||||||
Map<String, String> body) {
|
Map<String, String> body) {
|
||||||
return this.securityInterceptor.preHandle(exchange, this.endpointId)
|
return this.securityInterceptor
|
||||||
|
.preHandle(exchange, this.endpointId.toLowerCaseString())
|
||||||
.flatMap((securityResponse) -> flatMapResponse(exchange, body,
|
.flatMap((securityResponse) -> flatMapResponse(exchange, body,
|
||||||
securityResponse));
|
securityResponse));
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ import org.springframework.boot.actuate.autoconfigure.cloudfoundry.CloudFoundryA
|
||||||
import org.springframework.boot.actuate.autoconfigure.cloudfoundry.CloudFoundryAuthorizationException.Reason;
|
import org.springframework.boot.actuate.autoconfigure.cloudfoundry.CloudFoundryAuthorizationException.Reason;
|
||||||
import org.springframework.boot.actuate.autoconfigure.cloudfoundry.SecurityResponse;
|
import org.springframework.boot.actuate.autoconfigure.cloudfoundry.SecurityResponse;
|
||||||
import org.springframework.boot.actuate.autoconfigure.cloudfoundry.Token;
|
import org.springframework.boot.actuate.autoconfigure.cloudfoundry.Token;
|
||||||
|
import org.springframework.boot.actuate.endpoint.EndpointId;
|
||||||
import org.springframework.http.HttpMethod;
|
import org.springframework.http.HttpMethod;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
@ -59,7 +60,7 @@ class CloudFoundrySecurityInterceptor {
|
||||||
this.applicationId = applicationId;
|
this.applicationId = applicationId;
|
||||||
}
|
}
|
||||||
|
|
||||||
SecurityResponse preHandle(HttpServletRequest request, String endpointId) {
|
SecurityResponse preHandle(HttpServletRequest request, EndpointId endpointId) {
|
||||||
if (CorsUtils.isPreFlightRequest(request)) {
|
if (CorsUtils.isPreFlightRequest(request)) {
|
||||||
return SecurityResponse.success();
|
return SecurityResponse.success();
|
||||||
}
|
}
|
||||||
|
@ -90,12 +91,14 @@ class CloudFoundrySecurityInterceptor {
|
||||||
return SecurityResponse.success();
|
return SecurityResponse.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void check(HttpServletRequest request, String endpointId) throws Exception {
|
private void check(HttpServletRequest request, EndpointId endpointId)
|
||||||
|
throws Exception {
|
||||||
Token token = getToken(request);
|
Token token = getToken(request);
|
||||||
this.tokenValidator.validate(token);
|
this.tokenValidator.validate(token);
|
||||||
AccessLevel accessLevel = this.cloudFoundrySecurityService
|
AccessLevel accessLevel = this.cloudFoundrySecurityService
|
||||||
.getAccessLevel(token.toString(), this.applicationId);
|
.getAccessLevel(token.toString(), this.applicationId);
|
||||||
if (!accessLevel.isAccessAllowed(endpointId)) {
|
if (!accessLevel.isAccessAllowed(
|
||||||
|
(endpointId != null) ? endpointId.toLowerCaseString() : "")) {
|
||||||
throw new CloudFoundryAuthorizationException(Reason.ACCESS_DENIED,
|
throw new CloudFoundryAuthorizationException(Reason.ACCESS_DENIED,
|
||||||
"Access denied");
|
"Access denied");
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@ import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import org.springframework.boot.actuate.autoconfigure.cloudfoundry.AccessLevel;
|
import org.springframework.boot.actuate.autoconfigure.cloudfoundry.AccessLevel;
|
||||||
import org.springframework.boot.actuate.autoconfigure.cloudfoundry.SecurityResponse;
|
import org.springframework.boot.actuate.autoconfigure.cloudfoundry.SecurityResponse;
|
||||||
|
import org.springframework.boot.actuate.endpoint.EndpointId;
|
||||||
import org.springframework.boot.actuate.endpoint.web.EndpointLinksResolver;
|
import org.springframework.boot.actuate.endpoint.web.EndpointLinksResolver;
|
||||||
import org.springframework.boot.actuate.endpoint.web.EndpointMapping;
|
import org.springframework.boot.actuate.endpoint.web.EndpointMapping;
|
||||||
import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes;
|
import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes;
|
||||||
|
@ -68,7 +69,7 @@ class CloudFoundryWebEndpointServletHandlerMapping
|
||||||
protected ServletWebOperation wrapServletWebOperation(ExposableWebEndpoint endpoint,
|
protected ServletWebOperation wrapServletWebOperation(ExposableWebEndpoint endpoint,
|
||||||
WebOperation operation, ServletWebOperation servletWebOperation) {
|
WebOperation operation, ServletWebOperation servletWebOperation) {
|
||||||
return new SecureServletWebOperation(servletWebOperation,
|
return new SecureServletWebOperation(servletWebOperation,
|
||||||
this.securityInterceptor, endpoint.getId());
|
this.securityInterceptor, endpoint.getEndpointId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -76,7 +77,7 @@ class CloudFoundryWebEndpointServletHandlerMapping
|
||||||
protected Map<String, Map<String, Link>> links(HttpServletRequest request,
|
protected Map<String, Map<String, Link>> links(HttpServletRequest request,
|
||||||
HttpServletResponse response) {
|
HttpServletResponse response) {
|
||||||
SecurityResponse securityResponse = this.securityInterceptor.preHandle(request,
|
SecurityResponse securityResponse = this.securityInterceptor.preHandle(request,
|
||||||
"");
|
null);
|
||||||
if (!securityResponse.getStatus().equals(HttpStatus.OK)) {
|
if (!securityResponse.getStatus().equals(HttpStatus.OK)) {
|
||||||
sendFailureResponse(response, securityResponse);
|
sendFailureResponse(response, securityResponse);
|
||||||
}
|
}
|
||||||
|
@ -115,10 +116,11 @@ class CloudFoundryWebEndpointServletHandlerMapping
|
||||||
|
|
||||||
private final CloudFoundrySecurityInterceptor securityInterceptor;
|
private final CloudFoundrySecurityInterceptor securityInterceptor;
|
||||||
|
|
||||||
private final String endpointId;
|
private final EndpointId endpointId;
|
||||||
|
|
||||||
SecureServletWebOperation(ServletWebOperation delegate,
|
SecureServletWebOperation(ServletWebOperation delegate,
|
||||||
CloudFoundrySecurityInterceptor securityInterceptor, String endpointId) {
|
CloudFoundrySecurityInterceptor securityInterceptor,
|
||||||
|
EndpointId endpointId) {
|
||||||
this.delegate = delegate;
|
this.delegate = delegate;
|
||||||
this.securityInterceptor = securityInterceptor;
|
this.securityInterceptor = securityInterceptor;
|
||||||
this.endpointId = endpointId;
|
this.endpointId = endpointId;
|
||||||
|
|
|
@ -19,6 +19,7 @@ package org.springframework.boot.actuate.autoconfigure.endpoint;
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import org.springframework.boot.actuate.endpoint.EndpointId;
|
||||||
import org.springframework.boot.actuate.endpoint.invoker.cache.CachingOperationInvokerAdvisor;
|
import org.springframework.boot.actuate.endpoint.invoker.cache.CachingOperationInvokerAdvisor;
|
||||||
import org.springframework.boot.context.properties.bind.BindResult;
|
import org.springframework.boot.context.properties.bind.BindResult;
|
||||||
import org.springframework.boot.context.properties.bind.Bindable;
|
import org.springframework.boot.context.properties.bind.Bindable;
|
||||||
|
@ -33,7 +34,7 @@ import org.springframework.core.env.PropertyResolver;
|
||||||
* @author Stephane Nicoll
|
* @author Stephane Nicoll
|
||||||
* @author Phillip Webb
|
* @author Phillip Webb
|
||||||
*/
|
*/
|
||||||
class EndpointIdTimeToLivePropertyFunction implements Function<String, Long> {
|
class EndpointIdTimeToLivePropertyFunction implements Function<EndpointId, Long> {
|
||||||
|
|
||||||
private static final Bindable<Duration> DURATION = Bindable.of(Duration.class);
|
private static final Bindable<Duration> DURATION = Bindable.of(Duration.class);
|
||||||
|
|
||||||
|
@ -48,9 +49,9 @@ class EndpointIdTimeToLivePropertyFunction implements Function<String, Long> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Long apply(String endpointId) {
|
public Long apply(EndpointId endpointId) {
|
||||||
String name = String.format("management.endpoint.%s.cache.time-to-live",
|
String name = String.format("management.endpoint.%s.cache.time-to-live",
|
||||||
endpointId);
|
endpointId.toLowerCaseString());
|
||||||
BindResult<Duration> duration = Binder.get(this.environment).bind(name, DURATION);
|
BindResult<Duration> duration = Binder.get(this.environment).bind(name, DURATION);
|
||||||
return duration.map(Duration::toMillis).orElse(null);
|
return duration.map(Duration::toMillis).orElse(null);
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,11 +21,13 @@ import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.springframework.boot.actuate.endpoint.EndpointFilter;
|
import org.springframework.boot.actuate.endpoint.EndpointFilter;
|
||||||
|
import org.springframework.boot.actuate.endpoint.EndpointId;
|
||||||
import org.springframework.boot.actuate.endpoint.ExposableEndpoint;
|
import org.springframework.boot.actuate.endpoint.ExposableEndpoint;
|
||||||
import org.springframework.boot.context.properties.bind.Bindable;
|
import org.springframework.boot.context.properties.bind.Bindable;
|
||||||
import org.springframework.boot.context.properties.bind.Binder;
|
import org.springframework.boot.context.properties.bind.Binder;
|
||||||
|
@ -74,10 +76,19 @@ public class ExposeExcludePropertyEndpointFilter<E extends ExposableEndpoint<?>>
|
||||||
}
|
}
|
||||||
|
|
||||||
private Set<String> bind(Binder binder, String name) {
|
private Set<String> bind(Binder binder, String name) {
|
||||||
return asSet(binder.bind(name, Bindable.listOf(String.class))
|
return asSet(binder.bind(name, Bindable.listOf(String.class)).map(this::cleanup)
|
||||||
.orElseGet(ArrayList::new));
|
.orElseGet(ArrayList::new));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<String> cleanup(List<String> values) {
|
||||||
|
return values.stream().map(this::cleanup).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
private String cleanup(String value) {
|
||||||
|
return "*".equals(value) ? "*"
|
||||||
|
: EndpointId.fromPropertyValue(value).toLowerCaseString();
|
||||||
|
}
|
||||||
|
|
||||||
private Set<String> asSet(Collection<String> items) {
|
private Set<String> asSet(Collection<String> items) {
|
||||||
if (items == null) {
|
if (items == null) {
|
||||||
return Collections.emptySet();
|
return Collections.emptySet();
|
||||||
|
@ -110,7 +121,7 @@ public class ExposeExcludePropertyEndpointFilter<E extends ExposableEndpoint<?>>
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean contains(Set<String> items, ExposableEndpoint<?> endpoint) {
|
private boolean contains(Set<String> items, ExposableEndpoint<?> endpoint) {
|
||||||
return items.contains(endpoint.getId().toLowerCase(Locale.ENGLISH));
|
return items.contains(endpoint.getEndpointId().toLowerCaseString());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ package org.springframework.boot.actuate.autoconfigure.endpoint.condition;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import org.springframework.boot.actuate.endpoint.EndpointId;
|
||||||
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
|
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
|
||||||
import org.springframework.boot.actuate.endpoint.annotation.EndpointExtension;
|
import org.springframework.boot.actuate.endpoint.annotation.EndpointExtension;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionMessage;
|
import org.springframework.boot.autoconfigure.condition.ConditionMessage;
|
||||||
|
@ -54,8 +55,8 @@ class OnEnabledEndpointCondition extends SpringBootCondition {
|
||||||
AnnotatedTypeMetadata metadata) {
|
AnnotatedTypeMetadata metadata) {
|
||||||
Environment environment = context.getEnvironment();
|
Environment environment = context.getEnvironment();
|
||||||
AnnotationAttributes attributes = getEndpointAttributes(context, metadata);
|
AnnotationAttributes attributes = getEndpointAttributes(context, metadata);
|
||||||
String id = attributes.getString("id");
|
EndpointId id = EndpointId.of(attributes.getString("id"));
|
||||||
String key = "management.endpoint." + id + ".enabled";
|
String key = "management.endpoint." + id.toLowerCaseString() + ".enabled";
|
||||||
Boolean userDefinedEnabled = environment.getProperty(key, Boolean.class);
|
Boolean userDefinedEnabled = environment.getProperty(key, Boolean.class);
|
||||||
if (userDefinedEnabled != null) {
|
if (userDefinedEnabled != null) {
|
||||||
return new ConditionOutcome(userDefinedEnabled,
|
return new ConditionOutcome(userDefinedEnabled,
|
||||||
|
|
|
@ -52,7 +52,8 @@ class DefaultEndpointObjectNameFactory implements EndpointObjectNameFactory {
|
||||||
throws MalformedObjectNameException {
|
throws MalformedObjectNameException {
|
||||||
StringBuilder builder = new StringBuilder(this.properties.getDomain());
|
StringBuilder builder = new StringBuilder(this.properties.getDomain());
|
||||||
builder.append(":type=Endpoint");
|
builder.append(":type=Endpoint");
|
||||||
builder.append(",name=" + StringUtils.capitalize(endpoint.getId()));
|
builder.append(
|
||||||
|
",name=" + StringUtils.capitalize(endpoint.getEndpointId().toString()));
|
||||||
String baseName = builder.toString();
|
String baseName = builder.toString();
|
||||||
if (this.mBeanServer != null && hasMBean(baseName)) {
|
if (this.mBeanServer != null && hasMBean(baseName)) {
|
||||||
builder.append(",context=" + this.contextId);
|
builder.append(",context=" + this.contextId);
|
||||||
|
|
|
@ -16,8 +16,10 @@
|
||||||
|
|
||||||
package org.springframework.boot.actuate.autoconfigure.endpoint.web;
|
package org.springframework.boot.actuate.autoconfigure.endpoint.web;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.springframework.boot.actuate.endpoint.EndpointId;
|
||||||
import org.springframework.boot.actuate.endpoint.web.PathMapper;
|
import org.springframework.boot.actuate.endpoint.web.PathMapper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -28,15 +30,23 @@ import org.springframework.boot.actuate.endpoint.web.PathMapper;
|
||||||
*/
|
*/
|
||||||
class MappingWebEndpointPathMapper implements PathMapper {
|
class MappingWebEndpointPathMapper implements PathMapper {
|
||||||
|
|
||||||
private final Map<String, String> pathMapping;
|
private final Map<EndpointId, String> pathMapping;
|
||||||
|
|
||||||
MappingWebEndpointPathMapper(Map<String, String> pathMapping) {
|
MappingWebEndpointPathMapper(Map<String, String> pathMapping) {
|
||||||
this.pathMapping = pathMapping;
|
this.pathMapping = new HashMap<>();
|
||||||
|
pathMapping.forEach((id, path) -> this.pathMapping
|
||||||
|
.put(EndpointId.fromPropertyValue(id), path));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Deprecated
|
||||||
public String getRootPath(String endpointId) {
|
public String getRootPath(String endpointId) {
|
||||||
return this.pathMapping.getOrDefault(endpointId, endpointId);
|
return getRootPath(EndpointId.of(endpointId));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getRootPath(EndpointId endpointId) {
|
||||||
|
return this.pathMapping.getOrDefault(endpointId, endpointId.toLowerCaseString());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link MeterFilter} to log only once a warning message and deny {@link Meter.Id}.
|
* {@link MeterFilter} to log only once a warning message and deny {@code Meter.Id}.
|
||||||
*
|
*
|
||||||
* @author Jon Schneider
|
* @author Jon Schneider
|
||||||
* @author Dmytro Nosan
|
* @author Dmytro Nosan
|
||||||
|
|
|
@ -31,6 +31,7 @@ import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||||
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties;
|
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties;
|
||||||
|
import org.springframework.boot.actuate.endpoint.EndpointId;
|
||||||
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
|
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
|
||||||
import org.springframework.boot.actuate.endpoint.web.PathMappedEndpoints;
|
import org.springframework.boot.actuate.endpoint.web.PathMappedEndpoints;
|
||||||
import org.springframework.boot.security.reactive.ApplicationContextServerWebExchangeMatcher;
|
import org.springframework.boot.security.reactive.ApplicationContextServerWebExchangeMatcher;
|
||||||
|
@ -208,9 +209,12 @@ public final class EndpointRequest {
|
||||||
.map(pathMappedEndpoints::getPath);
|
.map(pathMappedEndpoints::getPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getEndpointId(Object source) {
|
private EndpointId getEndpointId(Object source) {
|
||||||
|
if (source instanceof EndpointId) {
|
||||||
|
return (EndpointId) source;
|
||||||
|
}
|
||||||
if (source instanceof String) {
|
if (source instanceof String) {
|
||||||
return (String) source;
|
return (EndpointId.of((String) source));
|
||||||
}
|
}
|
||||||
if (source instanceof Class) {
|
if (source instanceof Class) {
|
||||||
return getEndpointId((Class<?>) source);
|
return getEndpointId((Class<?>) source);
|
||||||
|
@ -218,12 +222,12 @@ public final class EndpointRequest {
|
||||||
throw new IllegalStateException("Unsupported source " + source);
|
throw new IllegalStateException("Unsupported source " + source);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getEndpointId(Class<?> source) {
|
private EndpointId getEndpointId(Class<?> source) {
|
||||||
Endpoint annotation = AnnotatedElementUtils.getMergedAnnotation(source,
|
Endpoint annotation = AnnotatedElementUtils.getMergedAnnotation(source,
|
||||||
Endpoint.class);
|
Endpoint.class);
|
||||||
Assert.state(annotation != null,
|
Assert.state(annotation != null,
|
||||||
() -> "Class " + source + " is not annotated with @Endpoint");
|
() -> "Class " + source + " is not annotated with @Endpoint");
|
||||||
return annotation.id();
|
return EndpointId.of(annotation.id());
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<ServerWebExchangeMatcher> getDelegateMatchers(Set<String> paths) {
|
private List<ServerWebExchangeMatcher> getDelegateMatchers(Set<String> paths) {
|
||||||
|
|
|
@ -31,6 +31,7 @@ import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||||
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties;
|
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties;
|
||||||
|
import org.springframework.boot.actuate.endpoint.EndpointId;
|
||||||
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
|
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
|
||||||
import org.springframework.boot.actuate.endpoint.web.PathMappedEndpoints;
|
import org.springframework.boot.actuate.endpoint.web.PathMappedEndpoints;
|
||||||
import org.springframework.boot.autoconfigure.security.servlet.RequestMatcherProvider;
|
import org.springframework.boot.autoconfigure.security.servlet.RequestMatcherProvider;
|
||||||
|
@ -256,9 +257,12 @@ public final class EndpointRequest {
|
||||||
.map(pathMappedEndpoints::getPath);
|
.map(pathMappedEndpoints::getPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getEndpointId(Object source) {
|
private EndpointId getEndpointId(Object source) {
|
||||||
|
if (source instanceof EndpointId) {
|
||||||
|
return (EndpointId) source;
|
||||||
|
}
|
||||||
if (source instanceof String) {
|
if (source instanceof String) {
|
||||||
return (String) source;
|
return (EndpointId.of((String) source));
|
||||||
}
|
}
|
||||||
if (source instanceof Class) {
|
if (source instanceof Class) {
|
||||||
return getEndpointId((Class<?>) source);
|
return getEndpointId((Class<?>) source);
|
||||||
|
@ -266,12 +270,12 @@ public final class EndpointRequest {
|
||||||
throw new IllegalStateException("Unsupported source " + source);
|
throw new IllegalStateException("Unsupported source " + source);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getEndpointId(Class<?> source) {
|
private EndpointId getEndpointId(Class<?> source) {
|
||||||
Endpoint annotation = AnnotatedElementUtils.getMergedAnnotation(source,
|
Endpoint annotation = AnnotatedElementUtils.getMergedAnnotation(source,
|
||||||
Endpoint.class);
|
Endpoint.class);
|
||||||
Assert.state(annotation != null,
|
Assert.state(annotation != null,
|
||||||
() -> "Class " + source + " is not annotated with @Endpoint");
|
() -> "Class " + source + " is not annotated with @Endpoint");
|
||||||
return annotation.id();
|
return EndpointId.of(annotation.id());
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<RequestMatcher> getDelegateMatchers(
|
private List<RequestMatcher> getDelegateMatchers(
|
||||||
|
|
|
@ -23,6 +23,7 @@ import java.util.function.Function;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.springframework.boot.actuate.endpoint.EndpointId;
|
||||||
import org.springframework.boot.actuate.endpoint.InvocationContext;
|
import org.springframework.boot.actuate.endpoint.InvocationContext;
|
||||||
import org.springframework.boot.actuate.endpoint.SecurityContext;
|
import org.springframework.boot.actuate.endpoint.SecurityContext;
|
||||||
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
|
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
|
||||||
|
@ -57,7 +58,7 @@ public class CloudFoundryWebEndpointDiscovererTests {
|
||||||
Collection<ExposableWebEndpoint> endpoints = discoverer.getEndpoints();
|
Collection<ExposableWebEndpoint> endpoints = discoverer.getEndpoints();
|
||||||
assertThat(endpoints.size()).isEqualTo(2);
|
assertThat(endpoints.size()).isEqualTo(2);
|
||||||
for (ExposableWebEndpoint endpoint : endpoints) {
|
for (ExposableWebEndpoint endpoint : endpoints) {
|
||||||
if (endpoint.getId().equals("health")) {
|
if (endpoint.getEndpointId().equals(EndpointId.of("health"))) {
|
||||||
WebOperation operation = endpoint.getOperations().iterator().next();
|
WebOperation operation = endpoint.getOperations().iterator().next();
|
||||||
assertThat(operation.invoke(new InvocationContext(
|
assertThat(operation.invoke(new InvocationContext(
|
||||||
mock(SecurityContext.class), Collections.emptyMap())))
|
mock(SecurityContext.class), Collections.emptyMap())))
|
||||||
|
@ -72,8 +73,8 @@ public class CloudFoundryWebEndpointDiscovererTests {
|
||||||
this.load((id) -> null, (id) -> id, configuration, consumer);
|
this.load((id) -> null, (id) -> id, configuration, consumer);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void load(Function<String, Long> timeToLive, PathMapper endpointPathMapper,
|
private void load(Function<EndpointId, Long> timeToLive,
|
||||||
Class<?> configuration,
|
PathMapper endpointPathMapper, Class<?> configuration,
|
||||||
Consumer<CloudFoundryWebEndpointDiscoverer> consumer) {
|
Consumer<CloudFoundryWebEndpointDiscoverer> consumer) {
|
||||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
|
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
|
||||||
configuration);
|
configuration);
|
||||||
|
|
|
@ -167,13 +167,6 @@ public class CloudFoundryWebFluxEndpointIntegrationTests {
|
||||||
.jsonPath("_links.test-part").doesNotExist()));
|
.jsonPath("_links.test-part").doesNotExist()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private AnnotationConfigReactiveWebServerApplicationContext createApplicationContext(
|
|
||||||
Class<?>... config) {
|
|
||||||
AnnotationConfigReactiveWebServerApplicationContext context = new AnnotationConfigReactiveWebServerApplicationContext();
|
|
||||||
context.register(config);
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ContextConsumer<AssertableReactiveWebApplicationContext> withWebTestClient(
|
private ContextConsumer<AssertableReactiveWebApplicationContext> withWebTestClient(
|
||||||
Consumer<WebTestClient> clientConsumer) {
|
Consumer<WebTestClient> clientConsumer) {
|
||||||
return (context) -> {
|
return (context) -> {
|
||||||
|
|
|
@ -33,6 +33,7 @@ import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfi
|
||||||
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration;
|
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration;
|
||||||
import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoConfiguration;
|
import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoConfiguration;
|
||||||
import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration;
|
import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration;
|
||||||
|
import org.springframework.boot.actuate.endpoint.EndpointId;
|
||||||
import org.springframework.boot.actuate.endpoint.ExposableEndpoint;
|
import org.springframework.boot.actuate.endpoint.ExposableEndpoint;
|
||||||
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
|
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
|
||||||
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
|
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
|
||||||
|
@ -243,9 +244,10 @@ public class ReactiveCloudFoundryActuatorAutoConfigurationTests {
|
||||||
context);
|
context);
|
||||||
Collection<ExposableWebEndpoint> endpoints = handlerMapping
|
Collection<ExposableWebEndpoint> endpoints = handlerMapping
|
||||||
.getEndpoints();
|
.getEndpoints();
|
||||||
List<String> endpointIds = endpoints.stream()
|
List<EndpointId> endpointIds = endpoints.stream()
|
||||||
.map(ExposableEndpoint::getId).collect(Collectors.toList());
|
.map(ExposableEndpoint::getEndpointId)
|
||||||
assertThat(endpointIds).contains("test");
|
.collect(Collectors.toList());
|
||||||
|
assertThat(endpointIds).contains(EndpointId.of("test"));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -261,7 +263,8 @@ public class ReactiveCloudFoundryActuatorAutoConfigurationTests {
|
||||||
Collection<ExposableWebEndpoint> endpoints = handlerMapping
|
Collection<ExposableWebEndpoint> endpoints = handlerMapping
|
||||||
.getEndpoints();
|
.getEndpoints();
|
||||||
ExposableWebEndpoint endpoint = endpoints.stream()
|
ExposableWebEndpoint endpoint = endpoints.stream()
|
||||||
.filter((candidate) -> "test".equals(candidate.getId()))
|
.filter((candidate) -> EndpointId.of("test")
|
||||||
|
.equals(candidate.getEndpointId()))
|
||||||
.findFirst().get();
|
.findFirst().get();
|
||||||
assertThat(endpoint.getOperations()).hasSize(1);
|
assertThat(endpoint.getOperations()).hasSize(1);
|
||||||
WebOperation operation = endpoint.getOperations().iterator().next();
|
WebOperation operation = endpoint.getOperations().iterator().next();
|
||||||
|
|
|
@ -26,6 +26,7 @@ import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAu
|
||||||
import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoConfiguration;
|
import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoConfiguration;
|
||||||
import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration;
|
import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration;
|
||||||
import org.springframework.boot.actuate.autoconfigure.web.servlet.ServletManagementContextAutoConfiguration;
|
import org.springframework.boot.actuate.autoconfigure.web.servlet.ServletManagementContextAutoConfiguration;
|
||||||
|
import org.springframework.boot.actuate.endpoint.EndpointId;
|
||||||
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
|
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
|
||||||
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
|
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
|
||||||
import org.springframework.boot.actuate.endpoint.http.ActuatorMediaType;
|
import org.springframework.boot.actuate.endpoint.http.ActuatorMediaType;
|
||||||
|
@ -235,7 +236,8 @@ public class CloudFoundryActuatorAutoConfigurationTests {
|
||||||
Collection<ExposableWebEndpoint> endpoints = handlerMapping
|
Collection<ExposableWebEndpoint> endpoints = handlerMapping
|
||||||
.getEndpoints();
|
.getEndpoints();
|
||||||
assertThat(endpoints.stream()
|
assertThat(endpoints.stream()
|
||||||
.filter((candidate) -> "test".equals(candidate.getId()))
|
.filter((candidate) -> EndpointId.of("test")
|
||||||
|
.equals(candidate.getEndpointId()))
|
||||||
.findFirst()).isNotEmpty();
|
.findFirst()).isNotEmpty();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -253,7 +255,8 @@ public class CloudFoundryActuatorAutoConfigurationTests {
|
||||||
Collection<ExposableWebEndpoint> endpoints = handlerMapping
|
Collection<ExposableWebEndpoint> endpoints = handlerMapping
|
||||||
.getEndpoints();
|
.getEndpoints();
|
||||||
ExposableWebEndpoint endpoint = endpoints.stream()
|
ExposableWebEndpoint endpoint = endpoints.stream()
|
||||||
.filter((candidate) -> "test".equals(candidate.getId()))
|
.filter((candidate) -> EndpointId.of("test")
|
||||||
|
.equals(candidate.getEndpointId()))
|
||||||
.findFirst().get();
|
.findFirst().get();
|
||||||
Collection<WebOperation> operations = endpoint.getOperations();
|
Collection<WebOperation> operations = endpoint.getOperations();
|
||||||
assertThat(operations).hasSize(1);
|
assertThat(operations).hasSize(1);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2012-2017 the original author or authors.
|
* Copyright 2012-2018 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -26,6 +26,7 @@ import org.springframework.boot.actuate.autoconfigure.cloudfoundry.AccessLevel;
|
||||||
import org.springframework.boot.actuate.autoconfigure.cloudfoundry.CloudFoundryAuthorizationException.Reason;
|
import org.springframework.boot.actuate.autoconfigure.cloudfoundry.CloudFoundryAuthorizationException.Reason;
|
||||||
import org.springframework.boot.actuate.autoconfigure.cloudfoundry.SecurityResponse;
|
import org.springframework.boot.actuate.autoconfigure.cloudfoundry.SecurityResponse;
|
||||||
import org.springframework.boot.actuate.autoconfigure.cloudfoundry.Token;
|
import org.springframework.boot.actuate.autoconfigure.cloudfoundry.Token;
|
||||||
|
import org.springframework.boot.actuate.endpoint.EndpointId;
|
||||||
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.mock.web.MockHttpServletRequest;
|
import org.springframework.mock.web.MockHttpServletRequest;
|
||||||
|
@ -65,13 +66,15 @@ public class CloudFoundrySecurityInterceptorTests {
|
||||||
this.request.setMethod("OPTIONS");
|
this.request.setMethod("OPTIONS");
|
||||||
this.request.addHeader(HttpHeaders.ORIGIN, "http://example.com");
|
this.request.addHeader(HttpHeaders.ORIGIN, "http://example.com");
|
||||||
this.request.addHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "GET");
|
this.request.addHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "GET");
|
||||||
SecurityResponse response = this.interceptor.preHandle(this.request, "/a");
|
SecurityResponse response = this.interceptor.preHandle(this.request,
|
||||||
|
EndpointId.of("test"));
|
||||||
assertThat(response.getStatus()).isEqualTo(HttpStatus.OK);
|
assertThat(response.getStatus()).isEqualTo(HttpStatus.OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void preHandleWhenTokenIsMissingShouldReturnFalse() {
|
public void preHandleWhenTokenIsMissingShouldReturnFalse() {
|
||||||
SecurityResponse response = this.interceptor.preHandle(this.request, "/a");
|
SecurityResponse response = this.interceptor.preHandle(this.request,
|
||||||
|
EndpointId.of("test"));
|
||||||
assertThat(response.getStatus())
|
assertThat(response.getStatus())
|
||||||
.isEqualTo(Reason.MISSING_AUTHORIZATION.getStatus());
|
.isEqualTo(Reason.MISSING_AUTHORIZATION.getStatus());
|
||||||
}
|
}
|
||||||
|
@ -79,7 +82,8 @@ public class CloudFoundrySecurityInterceptorTests {
|
||||||
@Test
|
@Test
|
||||||
public void preHandleWhenTokenIsNotBearerShouldReturnFalse() {
|
public void preHandleWhenTokenIsNotBearerShouldReturnFalse() {
|
||||||
this.request.addHeader("Authorization", mockAccessToken());
|
this.request.addHeader("Authorization", mockAccessToken());
|
||||||
SecurityResponse response = this.interceptor.preHandle(this.request, "/a");
|
SecurityResponse response = this.interceptor.preHandle(this.request,
|
||||||
|
EndpointId.of("test"));
|
||||||
assertThat(response.getStatus())
|
assertThat(response.getStatus())
|
||||||
.isEqualTo(Reason.MISSING_AUTHORIZATION.getStatus());
|
.isEqualTo(Reason.MISSING_AUTHORIZATION.getStatus());
|
||||||
}
|
}
|
||||||
|
@ -89,7 +93,8 @@ public class CloudFoundrySecurityInterceptorTests {
|
||||||
this.interceptor = new CloudFoundrySecurityInterceptor(this.tokenValidator,
|
this.interceptor = new CloudFoundrySecurityInterceptor(this.tokenValidator,
|
||||||
this.securityService, null);
|
this.securityService, null);
|
||||||
this.request.addHeader("Authorization", "bearer " + mockAccessToken());
|
this.request.addHeader("Authorization", "bearer " + mockAccessToken());
|
||||||
SecurityResponse response = this.interceptor.preHandle(this.request, "/a");
|
SecurityResponse response = this.interceptor.preHandle(this.request,
|
||||||
|
EndpointId.of("test"));
|
||||||
assertThat(response.getStatus())
|
assertThat(response.getStatus())
|
||||||
.isEqualTo(Reason.SERVICE_UNAVAILABLE.getStatus());
|
.isEqualTo(Reason.SERVICE_UNAVAILABLE.getStatus());
|
||||||
}
|
}
|
||||||
|
@ -99,7 +104,8 @@ public class CloudFoundrySecurityInterceptorTests {
|
||||||
this.interceptor = new CloudFoundrySecurityInterceptor(this.tokenValidator, null,
|
this.interceptor = new CloudFoundrySecurityInterceptor(this.tokenValidator, null,
|
||||||
"my-app-id");
|
"my-app-id");
|
||||||
this.request.addHeader("Authorization", "bearer " + mockAccessToken());
|
this.request.addHeader("Authorization", "bearer " + mockAccessToken());
|
||||||
SecurityResponse response = this.interceptor.preHandle(this.request, "/a");
|
SecurityResponse response = this.interceptor.preHandle(this.request,
|
||||||
|
EndpointId.of("test"));
|
||||||
assertThat(response.getStatus())
|
assertThat(response.getStatus())
|
||||||
.isEqualTo(Reason.SERVICE_UNAVAILABLE.getStatus());
|
.isEqualTo(Reason.SERVICE_UNAVAILABLE.getStatus());
|
||||||
}
|
}
|
||||||
|
@ -110,7 +116,8 @@ public class CloudFoundrySecurityInterceptorTests {
|
||||||
this.request.addHeader("Authorization", "bearer " + accessToken);
|
this.request.addHeader("Authorization", "bearer " + accessToken);
|
||||||
given(this.securityService.getAccessLevel(accessToken, "my-app-id"))
|
given(this.securityService.getAccessLevel(accessToken, "my-app-id"))
|
||||||
.willReturn(AccessLevel.RESTRICTED);
|
.willReturn(AccessLevel.RESTRICTED);
|
||||||
SecurityResponse response = this.interceptor.preHandle(this.request, "/a");
|
SecurityResponse response = this.interceptor.preHandle(this.request,
|
||||||
|
EndpointId.of("test"));
|
||||||
assertThat(response.getStatus()).isEqualTo(Reason.ACCESS_DENIED.getStatus());
|
assertThat(response.getStatus()).isEqualTo(Reason.ACCESS_DENIED.getStatus());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,7 +127,8 @@ public class CloudFoundrySecurityInterceptorTests {
|
||||||
this.request.addHeader("Authorization", "Bearer " + accessToken);
|
this.request.addHeader("Authorization", "Bearer " + accessToken);
|
||||||
given(this.securityService.getAccessLevel(accessToken, "my-app-id"))
|
given(this.securityService.getAccessLevel(accessToken, "my-app-id"))
|
||||||
.willReturn(AccessLevel.FULL);
|
.willReturn(AccessLevel.FULL);
|
||||||
SecurityResponse response = this.interceptor.preHandle(this.request, "/a");
|
SecurityResponse response = this.interceptor.preHandle(this.request,
|
||||||
|
EndpointId.of("test"));
|
||||||
ArgumentCaptor<Token> tokenArgumentCaptor = ArgumentCaptor.forClass(Token.class);
|
ArgumentCaptor<Token> tokenArgumentCaptor = ArgumentCaptor.forClass(Token.class);
|
||||||
verify(this.tokenValidator).validate(tokenArgumentCaptor.capture());
|
verify(this.tokenValidator).validate(tokenArgumentCaptor.capture());
|
||||||
Token token = tokenArgumentCaptor.getValue();
|
Token token = tokenArgumentCaptor.getValue();
|
||||||
|
@ -136,7 +144,8 @@ public class CloudFoundrySecurityInterceptorTests {
|
||||||
this.request.addHeader("Authorization", "Bearer " + accessToken);
|
this.request.addHeader("Authorization", "Bearer " + accessToken);
|
||||||
given(this.securityService.getAccessLevel(accessToken, "my-app-id"))
|
given(this.securityService.getAccessLevel(accessToken, "my-app-id"))
|
||||||
.willReturn(AccessLevel.RESTRICTED);
|
.willReturn(AccessLevel.RESTRICTED);
|
||||||
SecurityResponse response = this.interceptor.preHandle(this.request, "info");
|
SecurityResponse response = this.interceptor.preHandle(this.request,
|
||||||
|
EndpointId.of("info"));
|
||||||
ArgumentCaptor<Token> tokenArgumentCaptor = ArgumentCaptor.forClass(Token.class);
|
ArgumentCaptor<Token> tokenArgumentCaptor = ArgumentCaptor.forClass(Token.class);
|
||||||
verify(this.tokenValidator).validate(tokenArgumentCaptor.capture());
|
verify(this.tokenValidator).validate(tokenArgumentCaptor.capture());
|
||||||
Token token = tokenArgumentCaptor.getValue();
|
Token token = tokenArgumentCaptor.getValue();
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2012-2017 the original author or authors.
|
* Copyright 2012-2018 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -20,6 +20,7 @@ import java.util.function.Function;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.springframework.boot.actuate.endpoint.EndpointId;
|
||||||
import org.springframework.mock.env.MockEnvironment;
|
import org.springframework.mock.env.MockEnvironment;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
@ -34,21 +35,26 @@ public class EndpointIdTimeToLivePropertyFunctionTests {
|
||||||
|
|
||||||
private final MockEnvironment environment = new MockEnvironment();
|
private final MockEnvironment environment = new MockEnvironment();
|
||||||
|
|
||||||
private final Function<String, Long> timeToLive = new EndpointIdTimeToLivePropertyFunction(
|
private final Function<EndpointId, Long> timeToLive = new EndpointIdTimeToLivePropertyFunction(
|
||||||
this.environment);
|
this.environment);
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void defaultConfiguration() {
|
public void defaultConfiguration() {
|
||||||
Long result = this.timeToLive.apply("test");
|
Long result = this.timeToLive.apply(EndpointId.of("test"));
|
||||||
assertThat(result).isNull();
|
assertThat(result).isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void userConfiguration() {
|
public void userConfiguration() {
|
||||||
this.environment.setProperty("management.endpoint.test.cache.time-to-live",
|
this.environment.setProperty(
|
||||||
"500");
|
"management.endpoint.another-test.cache.time-to-live", "500");
|
||||||
Long result = this.timeToLive.apply("test");
|
Long result = this.timeToLive.apply(EndpointId.of("anotherTest"));
|
||||||
assertThat(result).isEqualTo(500L);
|
assertThat(result).isEqualTo(500L);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void mixedCaseUserConfiguration() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ import org.junit.rules.ExpectedException;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
|
|
||||||
import org.springframework.boot.actuate.endpoint.EndpointFilter;
|
import org.springframework.boot.actuate.endpoint.EndpointFilter;
|
||||||
|
import org.springframework.boot.actuate.endpoint.EndpointId;
|
||||||
import org.springframework.boot.actuate.endpoint.ExposableEndpoint;
|
import org.springframework.boot.actuate.endpoint.ExposableEndpoint;
|
||||||
import org.springframework.boot.actuate.endpoint.web.ExposableWebEndpoint;
|
import org.springframework.boot.actuate.endpoint.web.ExposableWebEndpoint;
|
||||||
import org.springframework.mock.env.MockEnvironment;
|
import org.springframework.mock.env.MockEnvironment;
|
||||||
|
@ -81,43 +82,43 @@ public class ExposeExcludePropertyEndpointFilterTests {
|
||||||
@Test
|
@Test
|
||||||
public void matchWhenExposeIsEmptyAndExcludeIsEmptyAndInDefaultShouldMatch() {
|
public void matchWhenExposeIsEmptyAndExcludeIsEmptyAndInDefaultShouldMatch() {
|
||||||
setupFilter("", "");
|
setupFilter("", "");
|
||||||
assertThat(match("def")).isTrue();
|
assertThat(match(EndpointId.of("def"))).isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void matchWhenExposeIsEmptyAndExcludeIsEmptyAndNotInDefaultShouldNotMatch() {
|
public void matchWhenExposeIsEmptyAndExcludeIsEmptyAndNotInDefaultShouldNotMatch() {
|
||||||
setupFilter("", "");
|
setupFilter("", "");
|
||||||
assertThat(match("bar")).isFalse();
|
assertThat(match(EndpointId.of("bar"))).isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void matchWhenExposeMatchesAndExcludeIsEmptyShouldMatch() {
|
public void matchWhenExposeMatchesAndExcludeIsEmptyShouldMatch() {
|
||||||
setupFilter("bar", "");
|
setupFilter("bar", "");
|
||||||
assertThat(match("bar")).isTrue();
|
assertThat(match(EndpointId.of("bar"))).isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void matchWhenExposeDoesNotMatchAndExcludeIsEmptyShouldNotMatch() {
|
public void matchWhenExposeDoesNotMatchAndExcludeIsEmptyShouldNotMatch() {
|
||||||
setupFilter("bar", "");
|
setupFilter("bar", "");
|
||||||
assertThat(match("baz")).isFalse();
|
assertThat(match(EndpointId.of("baz"))).isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void matchWhenExposeMatchesAndExcludeMatchesShouldNotMatch() {
|
public void matchWhenExposeMatchesAndExcludeMatchesShouldNotMatch() {
|
||||||
setupFilter("bar,baz", "baz");
|
setupFilter("bar,baz", "baz");
|
||||||
assertThat(match("baz")).isFalse();
|
assertThat(match(EndpointId.of("baz"))).isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void matchWhenExposeMatchesAndExcludeDoesNotMatchShouldMatch() {
|
public void matchWhenExposeMatchesAndExcludeDoesNotMatchShouldMatch() {
|
||||||
setupFilter("bar,baz", "buz");
|
setupFilter("bar,baz", "buz");
|
||||||
assertThat(match("baz")).isTrue();
|
assertThat(match(EndpointId.of("baz"))).isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void matchWhenExposeMatchesWithDifferentCaseShouldMatch() {
|
public void matchWhenExposeMatchesWithDifferentCaseShouldMatch() {
|
||||||
setupFilter("bar", "");
|
setupFilter("bar", "");
|
||||||
assertThat(match("bAr")).isTrue();
|
assertThat(match(EndpointId.of("bAr"))).isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -127,23 +128,29 @@ public class ExposeExcludePropertyEndpointFilterTests {
|
||||||
environment.setProperty("foo.exclude", "");
|
environment.setProperty("foo.exclude", "");
|
||||||
this.filter = new ExposeExcludePropertyEndpointFilter<>(
|
this.filter = new ExposeExcludePropertyEndpointFilter<>(
|
||||||
DifferentTestExposableWebEndpoint.class, environment, "foo");
|
DifferentTestExposableWebEndpoint.class, environment, "foo");
|
||||||
assertThat(match("baz")).isTrue();
|
assertThat(match(EndpointId.of("baz"))).isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void matchWhenIncludeIsAsteriskShouldMatchAll() {
|
public void matchWhenIncludeIsAsteriskShouldMatchAll() {
|
||||||
setupFilter("*", "buz");
|
setupFilter("*", "buz");
|
||||||
assertThat(match("bar")).isTrue();
|
assertThat(match(EndpointId.of("bar"))).isTrue();
|
||||||
assertThat(match("baz")).isTrue();
|
assertThat(match(EndpointId.of("baz"))).isTrue();
|
||||||
assertThat(match("buz")).isFalse();
|
assertThat(match(EndpointId.of("buz"))).isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void matchWhenExcludeIsAsteriskShouldMatchNone() {
|
public void matchWhenExcludeIsAsteriskShouldMatchNone() {
|
||||||
setupFilter("bar,baz,buz", "*");
|
setupFilter("bar,baz,buz", "*");
|
||||||
assertThat(match("bar")).isFalse();
|
assertThat(match(EndpointId.of("bar"))).isFalse();
|
||||||
assertThat(match("baz")).isFalse();
|
assertThat(match(EndpointId.of("baz"))).isFalse();
|
||||||
assertThat(match("buz")).isFalse();
|
assertThat(match(EndpointId.of("buz"))).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void matchWhenMixedCaseShouldMatch() {
|
||||||
|
setupFilter("foo-bar", "");
|
||||||
|
assertThat(match(EndpointId.of("fooBar"))).isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupFilter(String include, String exclude) {
|
private void setupFilter(String include, String exclude) {
|
||||||
|
@ -155,9 +162,9 @@ public class ExposeExcludePropertyEndpointFilterTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||||
private boolean match(String id) {
|
private boolean match(EndpointId id) {
|
||||||
ExposableEndpoint<?> endpoint = mock(TestExposableWebEndpoint.class);
|
ExposableEndpoint<?> endpoint = mock(TestExposableWebEndpoint.class);
|
||||||
given(endpoint.getId()).willReturn(id);
|
given(endpoint.getEndpointId()).willReturn(id);
|
||||||
return ((EndpointFilter) this.filter).match(endpoint);
|
return ((EndpointFilter) this.filter).match(endpoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -140,6 +140,14 @@ public class ConditionalOnEnabledEndpointTests {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void outcomeWhenEndpointEnabledPropertyIsTrueAndMixedCaseShouldMatch() {
|
||||||
|
this.contextRunner.withPropertyValues("management.endpoint.foo-bar.enabled=true")
|
||||||
|
.withUserConfiguration(
|
||||||
|
FooBarEndpointEnabledByDefaultFalseConfiguration.class)
|
||||||
|
.run((context) -> assertThat(context).hasBean("fooBar"));
|
||||||
|
}
|
||||||
|
|
||||||
@Endpoint(id = "foo", enableByDefault = true)
|
@Endpoint(id = "foo", enableByDefault = true)
|
||||||
static class FooEndpointEnabledByDefaultTrue {
|
static class FooEndpointEnabledByDefaultTrue {
|
||||||
|
|
||||||
|
@ -150,6 +158,11 @@ public class ConditionalOnEnabledEndpointTests {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Endpoint(id = "fooBar", enableByDefault = false)
|
||||||
|
static class FooBarEndpointEnabledByDefaultFalse {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@EndpointExtension(endpoint = FooEndpointEnabledByDefaultTrue.class, filter = TestFilter.class)
|
@EndpointExtension(endpoint = FooEndpointEnabledByDefaultTrue.class, filter = TestFilter.class)
|
||||||
static class FooEndpointExtensionEnabledByDefaultTrue {
|
static class FooEndpointExtensionEnabledByDefaultTrue {
|
||||||
|
|
||||||
|
@ -191,6 +204,17 @@ public class ConditionalOnEnabledEndpointTests {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
static class FooBarEndpointEnabledByDefaultFalseConfiguration {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnEnabledEndpoint
|
||||||
|
public FooBarEndpointEnabledByDefaultFalse fooBar() {
|
||||||
|
return new FooBarEndpointEnabledByDefaultFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
static class FooEndpointAndExtensionEnabledByDefaultTrueConfiguration {
|
static class FooEndpointAndExtensionEnabledByDefaultTrueConfiguration {
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@ import javax.management.ObjectName;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.springframework.boot.actuate.endpoint.EndpointId;
|
||||||
import org.springframework.boot.actuate.endpoint.jmx.ExposableJmxEndpoint;
|
import org.springframework.boot.actuate.endpoint.jmx.ExposableJmxEndpoint;
|
||||||
import org.springframework.mock.env.MockEnvironment;
|
import org.springframework.mock.env.MockEnvironment;
|
||||||
import org.springframework.util.ObjectUtils;
|
import org.springframework.util.ObjectUtils;
|
||||||
|
@ -50,22 +51,23 @@ public class DefaultEndpointObjectNameFactoryTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void generateObjectName() {
|
public void generateObjectName() {
|
||||||
ObjectName objectName = generateObjectName(endpoint("Test"));
|
ObjectName objectName = generateObjectName(endpoint(EndpointId.of("test")));
|
||||||
assertThat(objectName.toString())
|
assertThat(objectName.toString())
|
||||||
.isEqualTo("org.springframework.boot:type=Endpoint,name=Test");
|
.isEqualTo("org.springframework.boot:type=Endpoint,name=Test");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void generateObjectNameWithCapitalizedId() {
|
public void generateObjectNameWithCapitalizedId() {
|
||||||
ObjectName objectName = generateObjectName(endpoint("test"));
|
ObjectName objectName = generateObjectName(
|
||||||
|
endpoint(EndpointId.of("testEndpoint")));
|
||||||
assertThat(objectName.toString())
|
assertThat(objectName.toString())
|
||||||
.isEqualTo("org.springframework.boot:type=Endpoint,name=Test");
|
.isEqualTo("org.springframework.boot:type=Endpoint,name=TestEndpoint");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void generateObjectNameWithCustomDomain() {
|
public void generateObjectNameWithCustomDomain() {
|
||||||
this.properties.setDomain("com.example.acme");
|
this.properties.setDomain("com.example.acme");
|
||||||
ObjectName objectName = generateObjectName(endpoint("test"));
|
ObjectName objectName = generateObjectName(endpoint(EndpointId.of("test")));
|
||||||
assertThat(objectName.toString())
|
assertThat(objectName.toString())
|
||||||
.isEqualTo("com.example.acme:type=Endpoint,name=Test");
|
.isEqualTo("com.example.acme:type=Endpoint,name=Test");
|
||||||
}
|
}
|
||||||
|
@ -73,7 +75,7 @@ public class DefaultEndpointObjectNameFactoryTests {
|
||||||
@Test
|
@Test
|
||||||
public void generateObjectNameWithUniqueNames() {
|
public void generateObjectNameWithUniqueNames() {
|
||||||
this.properties.setUniqueNames(true);
|
this.properties.setUniqueNames(true);
|
||||||
ExposableJmxEndpoint endpoint = endpoint("test");
|
ExposableJmxEndpoint endpoint = endpoint(EndpointId.of("test"));
|
||||||
String id = ObjectUtils.getIdentityHexString(endpoint);
|
String id = ObjectUtils.getIdentityHexString(endpoint);
|
||||||
ObjectName objectName = generateObjectName(endpoint);
|
ObjectName objectName = generateObjectName(endpoint);
|
||||||
assertThat(objectName.toString()).isEqualTo(
|
assertThat(objectName.toString()).isEqualTo(
|
||||||
|
@ -84,7 +86,7 @@ public class DefaultEndpointObjectNameFactoryTests {
|
||||||
public void generateObjectNameWithStaticNames() {
|
public void generateObjectNameWithStaticNames() {
|
||||||
this.properties.getStaticNames().setProperty("counter", "42");
|
this.properties.getStaticNames().setProperty("counter", "42");
|
||||||
this.properties.getStaticNames().setProperty("foo", "bar");
|
this.properties.getStaticNames().setProperty("foo", "bar");
|
||||||
ObjectName objectName = generateObjectName(endpoint("test"));
|
ObjectName objectName = generateObjectName(endpoint(EndpointId.of("test")));
|
||||||
assertThat(objectName.getKeyProperty("counter")).isEqualTo("42");
|
assertThat(objectName.getKeyProperty("counter")).isEqualTo("42");
|
||||||
assertThat(objectName.getKeyProperty("foo")).isEqualTo("bar");
|
assertThat(objectName.getKeyProperty("foo")).isEqualTo("bar");
|
||||||
assertThat(objectName.toString())
|
assertThat(objectName.toString())
|
||||||
|
@ -99,7 +101,7 @@ public class DefaultEndpointObjectNameFactoryTests {
|
||||||
null)).willReturn(
|
null)).willReturn(
|
||||||
Collections.singleton(new ObjectName(
|
Collections.singleton(new ObjectName(
|
||||||
"org.springframework.boot:type=Endpoint,name=Test")));
|
"org.springframework.boot:type=Endpoint,name=Test")));
|
||||||
ObjectName objectName = generateObjectName(endpoint("test"));
|
ObjectName objectName = generateObjectName(endpoint(EndpointId.of("test")));
|
||||||
assertThat(objectName.toString()).isEqualTo(
|
assertThat(objectName.toString()).isEqualTo(
|
||||||
"org.springframework.boot:type=Endpoint,name=Test,context=testContext");
|
"org.springframework.boot:type=Endpoint,name=Test,context=testContext");
|
||||||
|
|
||||||
|
@ -115,9 +117,9 @@ public class DefaultEndpointObjectNameFactoryTests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private ExposableJmxEndpoint endpoint(String id) {
|
private ExposableJmxEndpoint endpoint(EndpointId id) {
|
||||||
ExposableJmxEndpoint endpoint = mock(ExposableJmxEndpoint.class);
|
ExposableJmxEndpoint endpoint = mock(ExposableJmxEndpoint.class);
|
||||||
given(endpoint.getId()).willReturn(id);
|
given(endpoint.getEndpointId()).willReturn(id);
|
||||||
return endpoint;
|
return endpoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,8 @@ import java.util.Collections;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.springframework.boot.actuate.endpoint.EndpointId;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -33,14 +35,29 @@ public class MappingWebEndpointPathMapperTests {
|
||||||
public void defaultConfiguration() {
|
public void defaultConfiguration() {
|
||||||
MappingWebEndpointPathMapper mapper = new MappingWebEndpointPathMapper(
|
MappingWebEndpointPathMapper mapper = new MappingWebEndpointPathMapper(
|
||||||
Collections.emptyMap());
|
Collections.emptyMap());
|
||||||
assertThat(mapper.getRootPath("test")).isEqualTo("test");
|
assertThat(mapper.getRootPath(EndpointId.of("test"))).isEqualTo("test");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void userConfiguration() {
|
public void userConfiguration() {
|
||||||
MappingWebEndpointPathMapper mapper = new MappingWebEndpointPathMapper(
|
MappingWebEndpointPathMapper mapper = new MappingWebEndpointPathMapper(
|
||||||
Collections.singletonMap("test", "custom"));
|
Collections.singletonMap("test", "custom"));
|
||||||
assertThat(mapper.getRootPath("test")).isEqualTo("custom");
|
assertThat(mapper.getRootPath(EndpointId.of("test"))).isEqualTo("custom");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void mixedCaseDefaultConfiguration() {
|
||||||
|
MappingWebEndpointPathMapper mapper = new MappingWebEndpointPathMapper(
|
||||||
|
Collections.emptyMap());
|
||||||
|
assertThat(mapper.getRootPath(EndpointId.of("testEndpoint")))
|
||||||
|
.isEqualTo("testendpoint");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void mixedCaseUserConfiguration() {
|
||||||
|
MappingWebEndpointPathMapper mapper = new MappingWebEndpointPathMapper(
|
||||||
|
Collections.singletonMap("test-endpoint", "custom"));
|
||||||
|
assertThat(mapper.getRootPath(EndpointId.of("testEndpoint"))).isEqualTo("custom");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ import org.junit.Test;
|
||||||
|
|
||||||
import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration;
|
import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration;
|
||||||
import org.springframework.boot.actuate.autoconfigure.endpoint.ExposeExcludePropertyEndpointFilter;
|
import org.springframework.boot.actuate.autoconfigure.endpoint.ExposeExcludePropertyEndpointFilter;
|
||||||
|
import org.springframework.boot.actuate.endpoint.EndpointId;
|
||||||
import org.springframework.boot.actuate.endpoint.http.ActuatorMediaType;
|
import org.springframework.boot.actuate.endpoint.http.ActuatorMediaType;
|
||||||
import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes;
|
import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes;
|
||||||
import org.springframework.boot.actuate.endpoint.web.PathMapper;
|
import org.springframework.boot.actuate.endpoint.web.PathMapper;
|
||||||
|
@ -65,7 +66,7 @@ public class WebEndpointAutoConfigurationTests {
|
||||||
.run((context) -> {
|
.run((context) -> {
|
||||||
assertThat(context).hasSingleBean(PathMapper.class);
|
assertThat(context).hasSingleBean(PathMapper.class);
|
||||||
String pathMapping = context.getBean(PathMapper.class)
|
String pathMapping = context.getBean(PathMapper.class)
|
||||||
.getRootPath("health");
|
.getRootPath(EndpointId.of("health"));
|
||||||
assertThat(pathMapping).isEqualTo("healthcheck");
|
assertThat(pathMapping).isEqualTo("healthcheck");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ import org.assertj.core.api.AssertDelegateTarget;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties;
|
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties;
|
||||||
|
import org.springframework.boot.actuate.endpoint.EndpointId;
|
||||||
import org.springframework.boot.actuate.endpoint.ExposableEndpoint;
|
import org.springframework.boot.actuate.endpoint.ExposableEndpoint;
|
||||||
import org.springframework.boot.actuate.endpoint.Operation;
|
import org.springframework.boot.actuate.endpoint.Operation;
|
||||||
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
|
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
|
||||||
|
@ -129,9 +130,9 @@ public class EndpointRequestTests {
|
||||||
ServerWebExchangeMatcher matcher = EndpointRequest.toAnyEndpoint()
|
ServerWebExchangeMatcher matcher = EndpointRequest.toAnyEndpoint()
|
||||||
.excluding(FooEndpoint.class, BazServletEndpoint.class);
|
.excluding(FooEndpoint.class, BazServletEndpoint.class);
|
||||||
List<ExposableEndpoint<?>> endpoints = new ArrayList<>();
|
List<ExposableEndpoint<?>> endpoints = new ArrayList<>();
|
||||||
endpoints.add(mockEndpoint("foo", "foo"));
|
endpoints.add(mockEndpoint(EndpointId.of("foo"), "foo"));
|
||||||
endpoints.add(mockEndpoint("bar", "bar"));
|
endpoints.add(mockEndpoint(EndpointId.of("bar"), "bar"));
|
||||||
endpoints.add(mockEndpoint("baz", "baz"));
|
endpoints.add(mockEndpoint(EndpointId.of("baz"), "baz"));
|
||||||
PathMappedEndpoints pathMappedEndpoints = new PathMappedEndpoints("/actuator",
|
PathMappedEndpoints pathMappedEndpoints = new PathMappedEndpoints("/actuator",
|
||||||
() -> endpoints);
|
() -> endpoints);
|
||||||
assertMatcher(matcher, pathMappedEndpoints).doesNotMatch("/actuator/foo");
|
assertMatcher(matcher, pathMappedEndpoints).doesNotMatch("/actuator/foo");
|
||||||
|
@ -202,14 +203,14 @@ public class EndpointRequestTests {
|
||||||
|
|
||||||
private PathMappedEndpoints mockPathMappedEndpoints(String basePath) {
|
private PathMappedEndpoints mockPathMappedEndpoints(String basePath) {
|
||||||
List<ExposableEndpoint<?>> endpoints = new ArrayList<>();
|
List<ExposableEndpoint<?>> endpoints = new ArrayList<>();
|
||||||
endpoints.add(mockEndpoint("foo", "foo"));
|
endpoints.add(mockEndpoint(EndpointId.of("foo"), "foo"));
|
||||||
endpoints.add(mockEndpoint("bar", "bar"));
|
endpoints.add(mockEndpoint(EndpointId.of("bar"), "bar"));
|
||||||
return new PathMappedEndpoints(basePath, () -> endpoints);
|
return new PathMappedEndpoints(basePath, () -> endpoints);
|
||||||
}
|
}
|
||||||
|
|
||||||
private TestEndpoint mockEndpoint(String id, String rootPath) {
|
private TestEndpoint mockEndpoint(EndpointId id, String rootPath) {
|
||||||
TestEndpoint endpoint = mock(TestEndpoint.class);
|
TestEndpoint endpoint = mock(TestEndpoint.class);
|
||||||
given(endpoint.getId()).willReturn(id);
|
given(endpoint.getEndpointId()).willReturn(id);
|
||||||
given(endpoint.getRootPath()).willReturn(rootPath);
|
given(endpoint.getRootPath()).willReturn(rootPath);
|
||||||
return endpoint;
|
return endpoint;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ import org.assertj.core.api.AssertDelegateTarget;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties;
|
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties;
|
||||||
|
import org.springframework.boot.actuate.endpoint.EndpointId;
|
||||||
import org.springframework.boot.actuate.endpoint.ExposableEndpoint;
|
import org.springframework.boot.actuate.endpoint.ExposableEndpoint;
|
||||||
import org.springframework.boot.actuate.endpoint.Operation;
|
import org.springframework.boot.actuate.endpoint.Operation;
|
||||||
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
|
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
|
||||||
|
@ -163,9 +164,9 @@ public class EndpointRequestTests {
|
||||||
RequestMatcher matcher = EndpointRequest.toAnyEndpoint()
|
RequestMatcher matcher = EndpointRequest.toAnyEndpoint()
|
||||||
.excluding(FooEndpoint.class, BazServletEndpoint.class);
|
.excluding(FooEndpoint.class, BazServletEndpoint.class);
|
||||||
List<ExposableEndpoint<?>> endpoints = new ArrayList<>();
|
List<ExposableEndpoint<?>> endpoints = new ArrayList<>();
|
||||||
endpoints.add(mockEndpoint("foo", "foo"));
|
endpoints.add(mockEndpoint(EndpointId.of("foo"), "foo"));
|
||||||
endpoints.add(mockEndpoint("bar", "bar"));
|
endpoints.add(mockEndpoint(EndpointId.of("bar"), "bar"));
|
||||||
endpoints.add(mockEndpoint("baz", "baz"));
|
endpoints.add(mockEndpoint(EndpointId.of("baz"), "baz"));
|
||||||
PathMappedEndpoints pathMappedEndpoints = new PathMappedEndpoints("/actuator",
|
PathMappedEndpoints pathMappedEndpoints = new PathMappedEndpoints("/actuator",
|
||||||
() -> endpoints);
|
() -> endpoints);
|
||||||
assertMatcher(matcher, pathMappedEndpoints).doesNotMatch("/actuator/foo");
|
assertMatcher(matcher, pathMappedEndpoints).doesNotMatch("/actuator/foo");
|
||||||
|
@ -258,14 +259,14 @@ public class EndpointRequestTests {
|
||||||
|
|
||||||
private PathMappedEndpoints mockPathMappedEndpoints(String basePath) {
|
private PathMappedEndpoints mockPathMappedEndpoints(String basePath) {
|
||||||
List<ExposableEndpoint<?>> endpoints = new ArrayList<>();
|
List<ExposableEndpoint<?>> endpoints = new ArrayList<>();
|
||||||
endpoints.add(mockEndpoint("foo", "foo"));
|
endpoints.add(mockEndpoint(EndpointId.of("foo"), "foo"));
|
||||||
endpoints.add(mockEndpoint("bar", "bar"));
|
endpoints.add(mockEndpoint(EndpointId.of("bar"), "bar"));
|
||||||
return new PathMappedEndpoints(basePath, () -> endpoints);
|
return new PathMappedEndpoints(basePath, () -> endpoints);
|
||||||
}
|
}
|
||||||
|
|
||||||
private TestEndpoint mockEndpoint(String id, String rootPath) {
|
private TestEndpoint mockEndpoint(EndpointId id, String rootPath) {
|
||||||
TestEndpoint endpoint = mock(TestEndpoint.class);
|
TestEndpoint endpoint = mock(TestEndpoint.class);
|
||||||
given(endpoint.getId()).willReturn(id);
|
given(endpoint.getEndpointId()).willReturn(id);
|
||||||
given(endpoint.getRootPath()).willReturn(rootPath);
|
given(endpoint.getRootPath()).willReturn(rootPath);
|
||||||
return endpoint;
|
return endpoint;
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@ import org.springframework.util.Assert;
|
||||||
public abstract class AbstractExposableEndpoint<O extends Operation>
|
public abstract class AbstractExposableEndpoint<O extends Operation>
|
||||||
implements ExposableEndpoint<O> {
|
implements ExposableEndpoint<O> {
|
||||||
|
|
||||||
private final String id;
|
private final EndpointId id;
|
||||||
|
|
||||||
private boolean enabledByDefault;
|
private boolean enabledByDefault;
|
||||||
|
|
||||||
|
@ -44,9 +44,24 @@ public abstract class AbstractExposableEndpoint<O extends Operation>
|
||||||
* @param id the endpoint id
|
* @param id the endpoint id
|
||||||
* @param enabledByDefault if the endpoint is enabled by default
|
* @param enabledByDefault if the endpoint is enabled by default
|
||||||
* @param operations the endpoint operations
|
* @param operations the endpoint operations
|
||||||
|
* @deprecated since 2.0.6 in favor of
|
||||||
|
* {@link #AbstractExposableEndpoint(EndpointId, boolean, Collection)}
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public AbstractExposableEndpoint(String id, boolean enabledByDefault,
|
public AbstractExposableEndpoint(String id, boolean enabledByDefault,
|
||||||
Collection<? extends O> operations) {
|
Collection<? extends O> operations) {
|
||||||
|
this(EndpointId.of(id), enabledByDefault, operations);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@link AbstractExposableEndpoint} instance.
|
||||||
|
* @param id the endpoint id
|
||||||
|
* @param enabledByDefault if the endpoint is enabled by default
|
||||||
|
* @param operations the endpoint operations
|
||||||
|
* @since 2.0.6
|
||||||
|
*/
|
||||||
|
public AbstractExposableEndpoint(EndpointId id, boolean enabledByDefault,
|
||||||
|
Collection<? extends O> operations) {
|
||||||
Assert.notNull(id, "ID must not be null");
|
Assert.notNull(id, "ID must not be null");
|
||||||
Assert.notNull(operations, "Operations must not be null");
|
Assert.notNull(operations, "Operations must not be null");
|
||||||
this.id = id;
|
this.id = id;
|
||||||
|
@ -56,7 +71,7 @@ public abstract class AbstractExposableEndpoint<O extends Operation>
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getId() {
|
public String getId() {
|
||||||
return this.id;
|
return this.id.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -0,0 +1,100 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2012-2018 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
|
||||||
|
*
|
||||||
|
* http://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 java.util.Locale;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An identifier for an actuator endpoint. Endpoint IDs may contain only letters and
|
||||||
|
* numbers and must begin with a lower-case letter. Case is ignored when comparing
|
||||||
|
* endpoint IDs.
|
||||||
|
*
|
||||||
|
* @author Phillip Webb
|
||||||
|
* @since 2.0.6
|
||||||
|
*/
|
||||||
|
public final class EndpointId {
|
||||||
|
|
||||||
|
private static final Pattern ALPHA_NUMERIC = Pattern.compile("[a-zA-Z0-9]+");
|
||||||
|
|
||||||
|
private final String value;
|
||||||
|
|
||||||
|
private final String lowerCaseValue;
|
||||||
|
|
||||||
|
private EndpointId(String value) {
|
||||||
|
Assert.hasText(value, "Value must not be empty");
|
||||||
|
Assert.isTrue(ALPHA_NUMERIC.matcher(value).matches(),
|
||||||
|
"Value must be alpha-numeric");
|
||||||
|
Assert.isTrue(!Character.isDigit(value.charAt(0)),
|
||||||
|
"Value must not start with a number");
|
||||||
|
Assert.isTrue(!Character.isUpperCase(value.charAt(0)),
|
||||||
|
"Value must not start with an uppercase letter");
|
||||||
|
this.value = value;
|
||||||
|
this.lowerCaseValue = value.toLowerCase(Locale.ENGLISH);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (obj == null || getClass() != obj.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return toLowerCaseString().equals(((EndpointId) obj).toLowerCaseString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return toLowerCaseString().hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a lower-case version of the endpoint ID.
|
||||||
|
* @return the lower-case endpoint ID
|
||||||
|
*/
|
||||||
|
public String toLowerCaseString() {
|
||||||
|
return this.lowerCaseValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return this.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Factory method to create a new {@link EndpointId} of the specified value.
|
||||||
|
* @param value the endpoint ID value
|
||||||
|
* @return an {@link EndpointId} instance
|
||||||
|
*/
|
||||||
|
public static EndpointId of(String value) {
|
||||||
|
return new EndpointId(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Factory method to create a new {@link EndpointId} from a property value. Is more
|
||||||
|
* lenient that {@link #of(String)} to allow for common "relaxed" property variants.
|
||||||
|
* @param value the property value to convert
|
||||||
|
* @return an {@link EndpointId} instance
|
||||||
|
*/
|
||||||
|
public static EndpointId fromPropertyValue(String value) {
|
||||||
|
return new EndpointId(value.replace("-", ""));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -31,9 +31,20 @@ public interface ExposableEndpoint<O extends Operation> {
|
||||||
/**
|
/**
|
||||||
* Returns the id of the endpoint.
|
* Returns the id of the endpoint.
|
||||||
* @return the id
|
* @return the id
|
||||||
|
* @deprecated since 2.0.6 in favor of {@link #getEndpointId()}
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
String getId();
|
String getId();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the endpoint ID.
|
||||||
|
* @return the endpoint ID
|
||||||
|
* @since 2.0.6
|
||||||
|
*/
|
||||||
|
default EndpointId getEndpointId() {
|
||||||
|
return EndpointId.of(getId());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns if the endpoint is enabled by default.
|
* Returns if the endpoint is enabled by default.
|
||||||
* @return if the endpoint is enabled by default
|
* @return if the endpoint is enabled by default
|
||||||
|
|
|
@ -19,6 +19,7 @@ package org.springframework.boot.actuate.endpoint.annotation;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
import org.springframework.boot.actuate.endpoint.AbstractExposableEndpoint;
|
import org.springframework.boot.actuate.endpoint.AbstractExposableEndpoint;
|
||||||
|
import org.springframework.boot.actuate.endpoint.EndpointId;
|
||||||
import org.springframework.boot.actuate.endpoint.ExposableEndpoint;
|
import org.springframework.boot.actuate.endpoint.ExposableEndpoint;
|
||||||
import org.springframework.boot.actuate.endpoint.Operation;
|
import org.springframework.boot.actuate.endpoint.Operation;
|
||||||
import org.springframework.core.style.ToStringCreator;
|
import org.springframework.core.style.ToStringCreator;
|
||||||
|
@ -46,10 +47,28 @@ public abstract class AbstractDiscoveredEndpoint<O extends Operation>
|
||||||
* @param id the ID of the endpoint
|
* @param id the ID of the endpoint
|
||||||
* @param enabledByDefault if the endpoint is enabled by default
|
* @param enabledByDefault if the endpoint is enabled by default
|
||||||
* @param operations the endpoint operations
|
* @param operations the endpoint operations
|
||||||
|
* @deprecated since 2.0.6 in favor of
|
||||||
|
* {@link #AbstractDiscoveredEndpoint(EndpointDiscoverer, Object, EndpointId, boolean, Collection)}
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public AbstractDiscoveredEndpoint(EndpointDiscoverer<?, ?> discoverer,
|
public AbstractDiscoveredEndpoint(EndpointDiscoverer<?, ?> discoverer,
|
||||||
Object endpointBean, String id, boolean enabledByDefault,
|
Object endpointBean, String id, boolean enabledByDefault,
|
||||||
Collection<? extends O> operations) {
|
Collection<? extends O> operations) {
|
||||||
|
this(discoverer, endpointBean, EndpointId.of(id), enabledByDefault, operations);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@link AbstractDiscoveredEndpoint} instance.
|
||||||
|
* @param discoverer the discoverer that discovered the endpoint
|
||||||
|
* @param endpointBean the primary source bean
|
||||||
|
* @param id the ID of the endpoint
|
||||||
|
* @param enabledByDefault if the endpoint is enabled by default
|
||||||
|
* @param operations the endpoint operations
|
||||||
|
* @since 2.0.6
|
||||||
|
*/
|
||||||
|
public AbstractDiscoveredEndpoint(EndpointDiscoverer<?, ?> discoverer,
|
||||||
|
Object endpointBean, EndpointId id, boolean enabledByDefault,
|
||||||
|
Collection<? extends O> operations) {
|
||||||
super(id, enabledByDefault, operations);
|
super(id, enabledByDefault, operations);
|
||||||
Assert.notNull(discoverer, "Discoverer must not be null");
|
Assert.notNull(discoverer, "Discoverer must not be null");
|
||||||
Assert.notNull(endpointBean, "EndpointBean must not be null");
|
Assert.notNull(endpointBean, "EndpointBean must not be null");
|
||||||
|
|
|
@ -24,6 +24,7 @@ import java.util.EnumMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import org.springframework.boot.actuate.endpoint.EndpointId;
|
||||||
import org.springframework.boot.actuate.endpoint.Operation;
|
import org.springframework.boot.actuate.endpoint.Operation;
|
||||||
import org.springframework.boot.actuate.endpoint.OperationType;
|
import org.springframework.boot.actuate.endpoint.OperationType;
|
||||||
import org.springframework.boot.actuate.endpoint.invoke.OperationInvoker;
|
import org.springframework.boot.actuate.endpoint.invoke.OperationInvoker;
|
||||||
|
@ -68,20 +69,20 @@ abstract class DiscoveredOperationsFactory<O extends Operation> {
|
||||||
this.invokerAdvisors = invokerAdvisors;
|
this.invokerAdvisors = invokerAdvisors;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<O> createOperations(String id, Object target) {
|
public Collection<O> createOperations(EndpointId id, Object target) {
|
||||||
return MethodIntrospector.selectMethods(target.getClass(),
|
return MethodIntrospector.selectMethods(target.getClass(),
|
||||||
(MetadataLookup<O>) (method) -> createOperation(id, target, method))
|
(MetadataLookup<O>) (method) -> createOperation(id, target, method))
|
||||||
.values();
|
.values();
|
||||||
}
|
}
|
||||||
|
|
||||||
private O createOperation(String endpointId, Object target, Method method) {
|
private O createOperation(EndpointId endpointId, Object target, Method method) {
|
||||||
return OPERATION_TYPES.entrySet().stream()
|
return OPERATION_TYPES.entrySet().stream()
|
||||||
.map((entry) -> createOperation(endpointId, target, method,
|
.map((entry) -> createOperation(endpointId, target, method,
|
||||||
entry.getKey(), entry.getValue()))
|
entry.getKey(), entry.getValue()))
|
||||||
.filter(Objects::nonNull).findFirst().orElse(null);
|
.filter(Objects::nonNull).findFirst().orElse(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private O createOperation(String endpointId, Object target, Method method,
|
private O createOperation(EndpointId endpointId, Object target, Method method,
|
||||||
OperationType operationType, Class<? extends Annotation> annotationType) {
|
OperationType operationType, Class<? extends Annotation> annotationType) {
|
||||||
AnnotationAttributes annotationAttributes = AnnotatedElementUtils
|
AnnotationAttributes annotationAttributes = AnnotatedElementUtils
|
||||||
.getMergedAnnotationAttributes(method, annotationType);
|
.getMergedAnnotationAttributes(method, annotationType);
|
||||||
|
@ -96,7 +97,7 @@ abstract class DiscoveredOperationsFactory<O extends Operation> {
|
||||||
return createOperation(endpointId, operationMethod, invoker);
|
return createOperation(endpointId, operationMethod, invoker);
|
||||||
}
|
}
|
||||||
|
|
||||||
private OperationInvoker applyAdvisors(String endpointId,
|
private OperationInvoker applyAdvisors(EndpointId endpointId,
|
||||||
OperationMethod operationMethod, OperationInvoker invoker) {
|
OperationMethod operationMethod, OperationInvoker invoker) {
|
||||||
if (this.invokerAdvisors != null) {
|
if (this.invokerAdvisors != null) {
|
||||||
for (OperationInvokerAdvisor advisor : this.invokerAdvisors) {
|
for (OperationInvokerAdvisor advisor : this.invokerAdvisors) {
|
||||||
|
@ -107,7 +108,7 @@ abstract class DiscoveredOperationsFactory<O extends Operation> {
|
||||||
return invoker;
|
return invoker;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract O createOperation(String endpointId,
|
protected abstract O createOperation(EndpointId endpointId,
|
||||||
DiscoveredOperationMethod operationMethod, OperationInvoker invoker);
|
DiscoveredOperationMethod operationMethod, OperationInvoker invoker);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,8 @@ import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
import java.lang.annotation.Target;
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
import org.springframework.boot.actuate.endpoint.EndpointId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Identifies a type as being an actuator endpoint that provides information about the
|
* Identifies a type as being an actuator endpoint that provides information about the
|
||||||
* running application. Endpoints can be exposed over a variety of technologies including
|
* running application. Endpoints can be exposed over a variety of technologies including
|
||||||
|
@ -52,8 +54,9 @@ import java.lang.annotation.Target;
|
||||||
public @interface Endpoint {
|
public @interface Endpoint {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The id of the endpoint.
|
* The id of the endpoint (must follow {@link EndpointId} rules).
|
||||||
* @return the id
|
* @return the id
|
||||||
|
* @see EndpointId
|
||||||
*/
|
*/
|
||||||
String id() default "";
|
String id() default "";
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,7 @@ import java.util.stream.Collectors;
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.beans.factory.BeanFactoryUtils;
|
import org.springframework.beans.factory.BeanFactoryUtils;
|
||||||
import org.springframework.boot.actuate.endpoint.EndpointFilter;
|
import org.springframework.boot.actuate.endpoint.EndpointFilter;
|
||||||
|
import org.springframework.boot.actuate.endpoint.EndpointId;
|
||||||
import org.springframework.boot.actuate.endpoint.EndpointsSupplier;
|
import org.springframework.boot.actuate.endpoint.EndpointsSupplier;
|
||||||
import org.springframework.boot.actuate.endpoint.ExposableEndpoint;
|
import org.springframework.boot.actuate.endpoint.ExposableEndpoint;
|
||||||
import org.springframework.boot.actuate.endpoint.Operation;
|
import org.springframework.boot.actuate.endpoint.Operation;
|
||||||
|
@ -101,7 +102,7 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten
|
||||||
return new DiscoveredOperationsFactory<O>(parameterValueMapper, invokerAdvisors) {
|
return new DiscoveredOperationsFactory<O>(parameterValueMapper, invokerAdvisors) {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected O createOperation(String endpointId,
|
protected O createOperation(EndpointId endpointId,
|
||||||
DiscoveredOperationMethod operationMethod, OperationInvoker invoker) {
|
DiscoveredOperationMethod operationMethod, OperationInvoker invoker) {
|
||||||
return EndpointDiscoverer.this.createOperation(endpointId,
|
return EndpointDiscoverer.this.createOperation(endpointId,
|
||||||
operationMethod, invoker);
|
operationMethod, invoker);
|
||||||
|
@ -125,7 +126,7 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten
|
||||||
}
|
}
|
||||||
|
|
||||||
private Collection<EndpointBean> createEndpointBeans() {
|
private Collection<EndpointBean> createEndpointBeans() {
|
||||||
Map<String, EndpointBean> byId = new LinkedHashMap<>();
|
Map<EndpointId, EndpointBean> byId = new LinkedHashMap<>();
|
||||||
String[] beanNames = BeanFactoryUtils.beanNamesForAnnotationIncludingAncestors(
|
String[] beanNames = BeanFactoryUtils.beanNamesForAnnotationIncludingAncestors(
|
||||||
this.applicationContext, Endpoint.class);
|
this.applicationContext, Endpoint.class);
|
||||||
for (String beanName : beanNames) {
|
for (String beanName : beanNames) {
|
||||||
|
@ -145,7 +146,7 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addExtensionBeans(Collection<EndpointBean> endpointBeans) {
|
private void addExtensionBeans(Collection<EndpointBean> endpointBeans) {
|
||||||
Map<String, EndpointBean> byId = endpointBeans.stream()
|
Map<EndpointId, EndpointBean> byId = endpointBeans.stream()
|
||||||
.collect(Collectors.toMap(EndpointBean::getId, (bean) -> bean));
|
.collect(Collectors.toMap(EndpointBean::getId, (bean) -> bean));
|
||||||
String[] beanNames = BeanFactoryUtils.beanNamesForAnnotationIncludingAncestors(
|
String[] beanNames = BeanFactoryUtils.beanNamesForAnnotationIncludingAncestors(
|
||||||
this.applicationContext, EndpointExtension.class);
|
this.applicationContext, EndpointExtension.class);
|
||||||
|
@ -189,7 +190,7 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten
|
||||||
|
|
||||||
private E convertToEndpoint(EndpointBean endpointBean) {
|
private E convertToEndpoint(EndpointBean endpointBean) {
|
||||||
MultiValueMap<OperationKey, O> indexed = new LinkedMultiValueMap<>();
|
MultiValueMap<OperationKey, O> indexed = new LinkedMultiValueMap<>();
|
||||||
String id = endpointBean.getId();
|
EndpointId id = endpointBean.getId();
|
||||||
addOperations(indexed, id, endpointBean.getBean(), false);
|
addOperations(indexed, id, endpointBean.getBean(), false);
|
||||||
if (endpointBean.getExtensions().size() > 1) {
|
if (endpointBean.getExtensions().size() > 1) {
|
||||||
String extensionBeans = endpointBean.getExtensions().stream()
|
String extensionBeans = endpointBean.getExtensions().stream()
|
||||||
|
@ -209,7 +210,7 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten
|
||||||
endpointBean.isEnabledByDefault(), operations);
|
endpointBean.isEnabledByDefault(), operations);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addOperations(MultiValueMap<OperationKey, O> indexed, String id,
|
private void addOperations(MultiValueMap<OperationKey, O> indexed, EndpointId id,
|
||||||
Object target, boolean replaceLast) {
|
Object target, boolean replaceLast) {
|
||||||
Set<OperationKey> replacedLast = new HashSet<>();
|
Set<OperationKey> replacedLast = new HashSet<>();
|
||||||
Collection<O> operations = this.operationsFactory.createOperations(id, target);
|
Collection<O> operations = this.operationsFactory.createOperations(id, target);
|
||||||
|
@ -339,7 +340,25 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten
|
||||||
* @param enabledByDefault if the endpoint is enabled by default
|
* @param enabledByDefault if the endpoint is enabled by default
|
||||||
* @param operations the endpoint operations
|
* @param operations the endpoint operations
|
||||||
* @return a created endpoint (a {@link DiscoveredEndpoint} is recommended)
|
* @return a created endpoint (a {@link DiscoveredEndpoint} is recommended)
|
||||||
|
* @since 2.0.6
|
||||||
*/
|
*/
|
||||||
|
protected E createEndpoint(Object endpointBean, EndpointId id,
|
||||||
|
boolean enabledByDefault, Collection<O> operations) {
|
||||||
|
return createEndpoint(endpointBean, (id != null) ? id.toString() : null,
|
||||||
|
enabledByDefault, operations);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Factory method called to create the {@link ExposableEndpoint endpoint}.
|
||||||
|
* @param endpointBean the source endpoint bean
|
||||||
|
* @param id the ID of the endpoint
|
||||||
|
* @param enabledByDefault if the endpoint is enabled by default
|
||||||
|
* @param operations the endpoint operations
|
||||||
|
* @return a created endpoint (a {@link DiscoveredEndpoint} is recommended)
|
||||||
|
* @deprecated Since 2.0.6 in favor of
|
||||||
|
* {@link #createEndpoint(Object, EndpointId, boolean, Collection)}
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
protected abstract E createEndpoint(Object endpointBean, String id,
|
protected abstract E createEndpoint(Object endpointBean, String id,
|
||||||
boolean enabledByDefault, Collection<O> operations);
|
boolean enabledByDefault, Collection<O> operations);
|
||||||
|
|
||||||
|
@ -349,7 +368,24 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten
|
||||||
* @param operationMethod the operation method
|
* @param operationMethod the operation method
|
||||||
* @param invoker the invoker to use
|
* @param invoker the invoker to use
|
||||||
* @return a created operation
|
* @return a created operation
|
||||||
|
* @since 2.0.6
|
||||||
*/
|
*/
|
||||||
|
protected O createOperation(EndpointId endpointId,
|
||||||
|
DiscoveredOperationMethod operationMethod, OperationInvoker invoker) {
|
||||||
|
return createOperation((endpointId != null) ? endpointId.toString() : null,
|
||||||
|
operationMethod, invoker);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Factory method to create an {@link Operation endpoint operation}.
|
||||||
|
* @param endpointId the endpoint id
|
||||||
|
* @param operationMethod the operation method
|
||||||
|
* @param invoker the invoker to use
|
||||||
|
* @return a created operation
|
||||||
|
* @deprecated since 2.0.6 in favor of
|
||||||
|
* {@link #createOperation(EndpointId, DiscoveredOperationMethod, OperationInvoker)}
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
protected abstract O createOperation(String endpointId,
|
protected abstract O createOperation(String endpointId,
|
||||||
DiscoveredOperationMethod operationMethod, OperationInvoker invoker);
|
DiscoveredOperationMethod operationMethod, OperationInvoker invoker);
|
||||||
|
|
||||||
|
@ -414,7 +450,7 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten
|
||||||
|
|
||||||
private final Object bean;
|
private final Object bean;
|
||||||
|
|
||||||
private final String id;
|
private final EndpointId id;
|
||||||
|
|
||||||
private boolean enabledByDefault;
|
private boolean enabledByDefault;
|
||||||
|
|
||||||
|
@ -426,14 +462,15 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten
|
||||||
AnnotationAttributes attributes = AnnotatedElementUtils
|
AnnotationAttributes attributes = AnnotatedElementUtils
|
||||||
.findMergedAnnotationAttributes(bean.getClass(), Endpoint.class, true,
|
.findMergedAnnotationAttributes(bean.getClass(), Endpoint.class, true,
|
||||||
true);
|
true);
|
||||||
this.beanName = beanName;
|
String id = attributes.getString("id");
|
||||||
this.bean = bean;
|
Assert.state(StringUtils.hasText(id),
|
||||||
this.id = attributes.getString("id");
|
|
||||||
this.enabledByDefault = (Boolean) attributes.get("enableByDefault");
|
|
||||||
this.filter = getFilter(this.bean.getClass());
|
|
||||||
Assert.state(StringUtils.hasText(this.id),
|
|
||||||
() -> "No @Endpoint id attribute specified for "
|
() -> "No @Endpoint id attribute specified for "
|
||||||
+ bean.getClass().getName());
|
+ bean.getClass().getName());
|
||||||
|
this.beanName = beanName;
|
||||||
|
this.bean = bean;
|
||||||
|
this.id = EndpointId.of(id);
|
||||||
|
this.enabledByDefault = (Boolean) attributes.get("enableByDefault");
|
||||||
|
this.filter = getFilter(this.bean.getClass());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addExtension(ExtensionBean extensionBean) {
|
public void addExtension(ExtensionBean extensionBean) {
|
||||||
|
@ -461,7 +498,7 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten
|
||||||
return this.bean;
|
return this.bean;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getId() {
|
public EndpointId getId() {
|
||||||
return this.id;
|
return this.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -484,7 +521,7 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten
|
||||||
|
|
||||||
private final Object bean;
|
private final Object bean;
|
||||||
|
|
||||||
private final String endpointId;
|
private final EndpointId endpointId;
|
||||||
|
|
||||||
private final Class<?> filter;
|
private final Class<?> filter;
|
||||||
|
|
||||||
|
@ -500,7 +537,7 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten
|
||||||
true);
|
true);
|
||||||
Assert.state(endpointAttributes != null, () -> "Extension "
|
Assert.state(endpointAttributes != null, () -> "Extension "
|
||||||
+ endpointType.getName() + " does not specify an endpoint");
|
+ endpointType.getName() + " does not specify an endpoint");
|
||||||
this.endpointId = endpointAttributes.getString("id");
|
this.endpointId = EndpointId.of(endpointAttributes.getString("id"));
|
||||||
this.filter = attributes.getClass("filter");
|
this.filter = attributes.getClass("filter");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -512,7 +549,7 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten
|
||||||
return this.bean;
|
return this.bean;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getEndpointId() {
|
public EndpointId getEndpointId() {
|
||||||
return this.endpointId;
|
return this.endpointId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
package org.springframework.boot.actuate.endpoint.invoke;
|
package org.springframework.boot.actuate.endpoint.invoke;
|
||||||
|
|
||||||
|
import org.springframework.boot.actuate.endpoint.EndpointId;
|
||||||
import org.springframework.boot.actuate.endpoint.OperationType;
|
import org.springframework.boot.actuate.endpoint.OperationType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -34,7 +35,25 @@ public interface OperationInvokerAdvisor {
|
||||||
* @param parameters the operation parameters
|
* @param parameters the operation parameters
|
||||||
* @param invoker the invoker to advise
|
* @param invoker the invoker to advise
|
||||||
* @return an potentially new operation invoker with support for additional features
|
* @return an potentially new operation invoker with support for additional features
|
||||||
|
* @since 2.0.6
|
||||||
*/
|
*/
|
||||||
|
default OperationInvoker apply(EndpointId endpointId, OperationType operationType,
|
||||||
|
OperationParameters parameters, OperationInvoker invoker) {
|
||||||
|
return apply((endpointId != null) ? endpointId.toString() : null, operationType,
|
||||||
|
parameters, invoker);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply additional functionality to the given invoker.
|
||||||
|
* @param endpointId the endpoint ID
|
||||||
|
* @param operationType the operation type
|
||||||
|
* @param parameters the operation parameters
|
||||||
|
* @param invoker the invoker to advise
|
||||||
|
* @return an potentially new operation invoker with support for additional features
|
||||||
|
* @deprecated since 2.0.6 in favor of
|
||||||
|
* {@link #apply(EndpointId, OperationType, OperationParameters, OperationInvoker)}
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
OperationInvoker apply(String endpointId, OperationType operationType,
|
OperationInvoker apply(String endpointId, OperationType operationType,
|
||||||
OperationParameters parameters, OperationInvoker invoker);
|
OperationParameters parameters, OperationInvoker invoker);
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@ package org.springframework.boot.actuate.endpoint.invoker.cache;
|
||||||
|
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import org.springframework.boot.actuate.endpoint.EndpointId;
|
||||||
import org.springframework.boot.actuate.endpoint.OperationType;
|
import org.springframework.boot.actuate.endpoint.OperationType;
|
||||||
import org.springframework.boot.actuate.endpoint.SecurityContext;
|
import org.springframework.boot.actuate.endpoint.SecurityContext;
|
||||||
import org.springframework.boot.actuate.endpoint.invoke.OperationInvoker;
|
import org.springframework.boot.actuate.endpoint.invoke.OperationInvoker;
|
||||||
|
@ -33,15 +34,23 @@ import org.springframework.boot.actuate.endpoint.invoke.OperationParameters;
|
||||||
*/
|
*/
|
||||||
public class CachingOperationInvokerAdvisor implements OperationInvokerAdvisor {
|
public class CachingOperationInvokerAdvisor implements OperationInvokerAdvisor {
|
||||||
|
|
||||||
private final Function<String, Long> endpointIdTimeToLive;
|
private final Function<EndpointId, Long> endpointIdTimeToLive;
|
||||||
|
|
||||||
public CachingOperationInvokerAdvisor(Function<String, Long> endpointIdTimeToLive) {
|
public CachingOperationInvokerAdvisor(
|
||||||
|
Function<EndpointId, Long> endpointIdTimeToLive) {
|
||||||
this.endpointIdTimeToLive = endpointIdTimeToLive;
|
this.endpointIdTimeToLive = endpointIdTimeToLive;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Deprecated
|
||||||
public OperationInvoker apply(String endpointId, OperationType operationType,
|
public OperationInvoker apply(String endpointId, OperationType operationType,
|
||||||
OperationParameters parameters, OperationInvoker invoker) {
|
OperationParameters parameters, OperationInvoker invoker) {
|
||||||
|
return apply(EndpointId.of(endpointId), operationType, parameters, invoker);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public OperationInvoker apply(EndpointId endpointId, OperationType operationType,
|
||||||
|
OperationParameters parameters, OperationInvoker invoker) {
|
||||||
if (operationType == OperationType.READ && !hasMandatoryParameter(parameters)) {
|
if (operationType == OperationType.READ && !hasMandatoryParameter(parameters)) {
|
||||||
Long timeToLive = this.endpointIdTimeToLive.apply(endpointId);
|
Long timeToLive = this.endpointIdTimeToLive.apply(endpointId);
|
||||||
if (timeToLive != null && timeToLive > 0) {
|
if (timeToLive != null && timeToLive > 0) {
|
||||||
|
|
|
@ -89,7 +89,7 @@ public class EndpointMBean implements DynamicMBean {
|
||||||
throws MBeanException, ReflectionException {
|
throws MBeanException, ReflectionException {
|
||||||
JmxOperation operation = this.operations.get(actionName);
|
JmxOperation operation = this.operations.get(actionName);
|
||||||
if (operation == null) {
|
if (operation == null) {
|
||||||
String message = "Endpoint with id '" + this.endpoint.getId()
|
String message = "Endpoint with id '" + this.endpoint.getEndpointId()
|
||||||
+ "' has no operation named " + actionName;
|
+ "' has no operation named " + actionName;
|
||||||
throw new ReflectionException(new IllegalArgumentException(message), message);
|
throw new ReflectionException(new IllegalArgumentException(message), message);
|
||||||
}
|
}
|
||||||
|
|
|
@ -136,7 +136,7 @@ public class JmxEndpointExporter
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getEndpointDescription(ExposableJmxEndpoint endpoint) {
|
private String getEndpointDescription(ExposableJmxEndpoint endpoint) {
|
||||||
return "endpoint '" + endpoint.getId() + "'";
|
return "endpoint '" + endpoint.getEndpointId() + "'";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,7 +58,7 @@ class MBeanInfoFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getDescription(ExposableJmxEndpoint endpoint) {
|
private String getDescription(ExposableJmxEndpoint endpoint) {
|
||||||
return "MBean operations for endpoint " + endpoint.getId();
|
return "MBean operations for endpoint " + endpoint.getEndpointId();
|
||||||
}
|
}
|
||||||
|
|
||||||
private ModelMBeanOperationInfo[] getMBeanOperations(ExposableJmxEndpoint endpoint) {
|
private ModelMBeanOperationInfo[] getMBeanOperations(ExposableJmxEndpoint endpoint) {
|
||||||
|
|
|
@ -18,6 +18,7 @@ package org.springframework.boot.actuate.endpoint.jmx.annotation;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import org.springframework.boot.actuate.endpoint.EndpointId;
|
||||||
import org.springframework.boot.actuate.endpoint.annotation.AbstractDiscoveredEndpoint;
|
import org.springframework.boot.actuate.endpoint.annotation.AbstractDiscoveredEndpoint;
|
||||||
import org.springframework.boot.actuate.endpoint.annotation.EndpointDiscoverer;
|
import org.springframework.boot.actuate.endpoint.annotation.EndpointDiscoverer;
|
||||||
import org.springframework.boot.actuate.endpoint.jmx.ExposableJmxEndpoint;
|
import org.springframework.boot.actuate.endpoint.jmx.ExposableJmxEndpoint;
|
||||||
|
@ -32,7 +33,8 @@ class DiscoveredJmxEndpoint extends AbstractDiscoveredEndpoint<JmxOperation>
|
||||||
implements ExposableJmxEndpoint {
|
implements ExposableJmxEndpoint {
|
||||||
|
|
||||||
DiscoveredJmxEndpoint(EndpointDiscoverer<?, ?> discoverer, Object endpointBean,
|
DiscoveredJmxEndpoint(EndpointDiscoverer<?, ?> discoverer, Object endpointBean,
|
||||||
String id, boolean enabledByDefault, Collection<JmxOperation> operations) {
|
EndpointId id, boolean enabledByDefault,
|
||||||
|
Collection<JmxOperation> operations) {
|
||||||
super(discoverer, endpointBean, id, enabledByDefault, operations);
|
super(discoverer, endpointBean, id, enabledByDefault, operations);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@ import java.util.function.Supplier;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import org.springframework.boot.actuate.endpoint.EndpointId;
|
||||||
import org.springframework.boot.actuate.endpoint.annotation.AbstractDiscoveredOperation;
|
import org.springframework.boot.actuate.endpoint.annotation.AbstractDiscoveredOperation;
|
||||||
import org.springframework.boot.actuate.endpoint.annotation.DiscoveredOperationMethod;
|
import org.springframework.boot.actuate.endpoint.annotation.DiscoveredOperationMethod;
|
||||||
import org.springframework.boot.actuate.endpoint.invoke.OperationInvoker;
|
import org.springframework.boot.actuate.endpoint.invoke.OperationInvoker;
|
||||||
|
@ -59,8 +60,8 @@ class DiscoveredJmxOperation extends AbstractDiscoveredOperation implements JmxO
|
||||||
|
|
||||||
private final List<JmxOperationParameter> parameters;
|
private final List<JmxOperationParameter> parameters;
|
||||||
|
|
||||||
DiscoveredJmxOperation(String endpointId, DiscoveredOperationMethod operationMethod,
|
DiscoveredJmxOperation(EndpointId endpointId,
|
||||||
OperationInvoker invoker) {
|
DiscoveredOperationMethod operationMethod, OperationInvoker invoker) {
|
||||||
super(operationMethod, invoker);
|
super(operationMethod, invoker);
|
||||||
Method method = operationMethod.getMethod();
|
Method method = operationMethod.getMethod();
|
||||||
this.name = method.getName();
|
this.name = method.getName();
|
||||||
|
|
|
@ -19,6 +19,7 @@ package org.springframework.boot.actuate.endpoint.jmx.annotation;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
import org.springframework.boot.actuate.endpoint.EndpointFilter;
|
import org.springframework.boot.actuate.endpoint.EndpointFilter;
|
||||||
|
import org.springframework.boot.actuate.endpoint.EndpointId;
|
||||||
import org.springframework.boot.actuate.endpoint.annotation.DiscoveredOperationMethod;
|
import org.springframework.boot.actuate.endpoint.annotation.DiscoveredOperationMethod;
|
||||||
import org.springframework.boot.actuate.endpoint.annotation.EndpointDiscoverer;
|
import org.springframework.boot.actuate.endpoint.annotation.EndpointDiscoverer;
|
||||||
import org.springframework.boot.actuate.endpoint.invoke.OperationInvoker;
|
import org.springframework.boot.actuate.endpoint.invoke.OperationInvoker;
|
||||||
|
@ -54,15 +55,30 @@ public class JmxEndpointDiscoverer
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Deprecated
|
||||||
protected ExposableJmxEndpoint createEndpoint(Object endpointBean, String id,
|
protected ExposableJmxEndpoint createEndpoint(Object endpointBean, String id,
|
||||||
boolean enabledByDefault, Collection<JmxOperation> operations) {
|
boolean enabledByDefault, Collection<JmxOperation> operations) {
|
||||||
|
return createEndpoint(endpointBean, EndpointId.of(id), enabledByDefault,
|
||||||
|
operations);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ExposableJmxEndpoint createEndpoint(Object endpointBean, EndpointId id,
|
||||||
|
boolean enabledByDefault, Collection<JmxOperation> operations) {
|
||||||
return new DiscoveredJmxEndpoint(this, endpointBean, id, enabledByDefault,
|
return new DiscoveredJmxEndpoint(this, endpointBean, id, enabledByDefault,
|
||||||
operations);
|
operations);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Deprecated
|
||||||
protected JmxOperation createOperation(String endpointId,
|
protected JmxOperation createOperation(String endpointId,
|
||||||
DiscoveredOperationMethod operationMethod, OperationInvoker invoker) {
|
DiscoveredOperationMethod operationMethod, OperationInvoker invoker) {
|
||||||
|
return createOperation(EndpointId.of(endpointId), operationMethod, invoker);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected JmxOperation createOperation(EndpointId endpointId,
|
||||||
|
DiscoveredOperationMethod operationMethod, OperationInvoker invoker) {
|
||||||
return new DiscoveredJmxOperation(endpointId, operationMethod, invoker);
|
return new DiscoveredJmxOperation(endpointId, operationMethod, invoker);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -76,8 +76,9 @@ public class EndpointLinksResolver {
|
||||||
collectLinks(links, (ExposableWebEndpoint) endpoint, normalizedUrl);
|
collectLinks(links, (ExposableWebEndpoint) endpoint, normalizedUrl);
|
||||||
}
|
}
|
||||||
else if (endpoint instanceof PathMappedEndpoint) {
|
else if (endpoint instanceof PathMappedEndpoint) {
|
||||||
links.put(endpoint.getId(), createLink(normalizedUrl,
|
String rootPath = ((PathMappedEndpoint) endpoint).getRootPath();
|
||||||
((PathMappedEndpoint) endpoint).getRootPath()));
|
Link link = createLink(normalizedUrl, rootPath);
|
||||||
|
links.put(endpoint.getEndpointId().toLowerCaseString(), link);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return links;
|
return links;
|
||||||
|
|
|
@ -25,6 +25,7 @@ import java.util.Map;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import org.springframework.boot.actuate.endpoint.EndpointId;
|
||||||
import org.springframework.boot.actuate.endpoint.EndpointsSupplier;
|
import org.springframework.boot.actuate.endpoint.EndpointsSupplier;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
|
@ -37,7 +38,7 @@ public class PathMappedEndpoints implements Iterable<PathMappedEndpoint> {
|
||||||
|
|
||||||
private final String basePath;
|
private final String basePath;
|
||||||
|
|
||||||
private final Map<String, PathMappedEndpoint> endpoints;
|
private final Map<EndpointId, PathMappedEndpoint> endpoints;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new {@link PathMappedEndpoints} instance for the given supplier.
|
* Create a new {@link PathMappedEndpoints} instance for the given supplier.
|
||||||
|
@ -62,13 +63,14 @@ public class PathMappedEndpoints implements Iterable<PathMappedEndpoint> {
|
||||||
this.endpoints = getEndpoints(suppliers);
|
this.endpoints = getEndpoints(suppliers);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<String, PathMappedEndpoint> getEndpoints(
|
private Map<EndpointId, PathMappedEndpoint> getEndpoints(
|
||||||
Collection<EndpointsSupplier<?>> suppliers) {
|
Collection<EndpointsSupplier<?>> suppliers) {
|
||||||
Map<String, PathMappedEndpoint> endpoints = new LinkedHashMap<>();
|
Map<EndpointId, PathMappedEndpoint> endpoints = new LinkedHashMap<>();
|
||||||
suppliers.forEach((supplier) -> {
|
suppliers.forEach((supplier) -> {
|
||||||
supplier.getEndpoints().forEach((endpoint) -> {
|
supplier.getEndpoints().forEach((endpoint) -> {
|
||||||
if (endpoint instanceof PathMappedEndpoint) {
|
if (endpoint instanceof PathMappedEndpoint) {
|
||||||
endpoints.put(endpoint.getId(), (PathMappedEndpoint) endpoint);
|
endpoints.put(endpoint.getEndpointId(),
|
||||||
|
(PathMappedEndpoint) endpoint);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -88,8 +90,21 @@ public class PathMappedEndpoints implements Iterable<PathMappedEndpoint> {
|
||||||
* endpoint cannot be found.
|
* endpoint cannot be found.
|
||||||
* @param endpointId the endpoint ID
|
* @param endpointId the endpoint ID
|
||||||
* @return the root path or {@code null}
|
* @return the root path or {@code null}
|
||||||
|
* @deprecated since 2.0.6 in favor of {@link #getRootPath(EndpointId)}
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public String getRootPath(String endpointId) {
|
public String getRootPath(String endpointId) {
|
||||||
|
return getRootPath(EndpointId.of(endpointId));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the root path for the endpoint with the given ID or {@code null} if the
|
||||||
|
* endpoint cannot be found.
|
||||||
|
* @param endpointId the endpoint ID
|
||||||
|
* @return the root path or {@code null}
|
||||||
|
* @since 2.0.6
|
||||||
|
*/
|
||||||
|
public String getRootPath(EndpointId endpointId) {
|
||||||
PathMappedEndpoint endpoint = getEndpoint(endpointId);
|
PathMappedEndpoint endpoint = getEndpoint(endpointId);
|
||||||
return (endpoint != null) ? endpoint.getRootPath() : null;
|
return (endpoint != null) ? endpoint.getRootPath() : null;
|
||||||
}
|
}
|
||||||
|
@ -99,8 +114,21 @@ public class PathMappedEndpoints implements Iterable<PathMappedEndpoint> {
|
||||||
* endpoint cannot be found.
|
* endpoint cannot be found.
|
||||||
* @param endpointId the endpoint ID
|
* @param endpointId the endpoint ID
|
||||||
* @return the full path or {@code null}
|
* @return the full path or {@code null}
|
||||||
|
* @deprecated since 2.0.6 in favor of {@link #getPath(EndpointId)}
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public String getPath(String endpointId) {
|
public String getPath(String endpointId) {
|
||||||
|
return getPath(EndpointId.of(endpointId));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the full path for the endpoint with the given ID or {@code null} if the
|
||||||
|
* endpoint cannot be found.
|
||||||
|
* @param endpointId the endpoint ID
|
||||||
|
* @return the full path or {@code null}
|
||||||
|
* @since 2.0.6
|
||||||
|
*/
|
||||||
|
public String getPath(EndpointId endpointId) {
|
||||||
return getPath(getEndpoint(endpointId));
|
return getPath(getEndpoint(endpointId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,8 +153,21 @@ public class PathMappedEndpoints implements Iterable<PathMappedEndpoint> {
|
||||||
* endpoint cannot be found.
|
* endpoint cannot be found.
|
||||||
* @param endpointId the endpoint ID
|
* @param endpointId the endpoint ID
|
||||||
* @return the path mapped endpoint or {@code null}
|
* @return the path mapped endpoint or {@code null}
|
||||||
|
* @deprecated since 2.0.6 in favor of {@link #getEndpoint(EndpointId)}
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public PathMappedEndpoint getEndpoint(String endpointId) {
|
public PathMappedEndpoint getEndpoint(String endpointId) {
|
||||||
|
return getEndpoint(EndpointId.of(endpointId));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the {@link PathMappedEndpoint} with the given ID or {@code null} if the
|
||||||
|
* endpoint cannot be found.
|
||||||
|
* @param endpointId the endpoint ID
|
||||||
|
* @return the path mapped endpoint or {@code null}
|
||||||
|
* @since 2.0.6
|
||||||
|
*/
|
||||||
|
public PathMappedEndpoint getEndpoint(EndpointId endpointId) {
|
||||||
return this.endpoints.get(endpointId);
|
return this.endpoints.get(endpointId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
|
|
||||||
package org.springframework.boot.actuate.endpoint.web;
|
package org.springframework.boot.actuate.endpoint.web;
|
||||||
|
|
||||||
|
import org.springframework.boot.actuate.endpoint.EndpointId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Strategy interface used to provide a mapping between an endpoint ID and the root path
|
* Strategy interface used to provide a mapping between an endpoint ID and the root path
|
||||||
* where it will be exposed.
|
* where it will be exposed.
|
||||||
|
@ -31,15 +33,41 @@ public interface PathMapper {
|
||||||
* Resolve the root path for the endpoint with the specified {@code endpointId}.
|
* Resolve the root path for the endpoint with the specified {@code endpointId}.
|
||||||
* @param endpointId the id of an endpoint
|
* @param endpointId the id of an endpoint
|
||||||
* @return the path of the endpoint
|
* @return the path of the endpoint
|
||||||
|
* @since 2.0.6
|
||||||
*/
|
*/
|
||||||
|
default String getRootPath(EndpointId endpointId) {
|
||||||
|
return getRootPath((endpointId != null) ? endpointId.toString() : null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolve the root path for the endpoint with the specified {@code endpointId}.
|
||||||
|
* @param endpointId the id of an endpoint
|
||||||
|
* @return the path of the endpoint
|
||||||
|
* @deprecated since 2.0.6 in favor of {@link #getRootPath(EndpointId)}
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
String getRootPath(String endpointId);
|
String getRootPath(String endpointId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an {@link PathMapper} that uses the endpoint ID as the path.
|
* Returns an {@link PathMapper} that uses the endpoint ID as the path.
|
||||||
* @return an {@link PathMapper} that uses the endpoint ID as the path
|
* @return an {@link PathMapper} that uses the lowercase endpoint ID as the path
|
||||||
*/
|
*/
|
||||||
static PathMapper useEndpointId() {
|
static PathMapper useEndpointId() {
|
||||||
return (endpointId) -> endpointId;
|
return new PathMapper() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Deprecated
|
||||||
|
public String getRootPath(String endpointId) {
|
||||||
|
return getRootPath(EndpointId.of(endpointId));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getRootPath(EndpointId endpointId) {
|
||||||
|
return endpointId.toLowerCaseString();
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,7 +67,7 @@ public class ServletEndpointRegistrar implements ServletContextInitializer {
|
||||||
|
|
||||||
private void register(ServletContext servletContext,
|
private void register(ServletContext servletContext,
|
||||||
ExposableServletEndpoint endpoint) {
|
ExposableServletEndpoint endpoint) {
|
||||||
String name = endpoint.getId() + "-actuator-endpoint";
|
String name = endpoint.getEndpointId().toLowerCaseString() + "-actuator-endpoint";
|
||||||
String path = this.basePath + "/" + endpoint.getRootPath();
|
String path = this.basePath + "/" + endpoint.getRootPath();
|
||||||
String urlMapping = path.endsWith("/") ? path + "*" : path + "/*";
|
String urlMapping = path.endsWith("/") ? path + "*" : path + "/*";
|
||||||
EndpointServlet endpointServlet = endpoint.getEndpointServlet();
|
EndpointServlet endpointServlet = endpoint.getEndpointServlet();
|
||||||
|
|
|
@ -20,6 +20,7 @@ import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
||||||
import org.springframework.boot.actuate.endpoint.EndpointFilter;
|
import org.springframework.boot.actuate.endpoint.EndpointFilter;
|
||||||
|
import org.springframework.boot.actuate.endpoint.EndpointId;
|
||||||
import org.springframework.boot.actuate.endpoint.Operation;
|
import org.springframework.boot.actuate.endpoint.Operation;
|
||||||
import org.springframework.boot.actuate.endpoint.annotation.DiscoveredOperationMethod;
|
import org.springframework.boot.actuate.endpoint.annotation.DiscoveredOperationMethod;
|
||||||
import org.springframework.boot.actuate.endpoint.annotation.EndpointDiscoverer;
|
import org.springframework.boot.actuate.endpoint.annotation.EndpointDiscoverer;
|
||||||
|
@ -67,16 +68,31 @@ public class ControllerEndpointDiscoverer
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Deprecated
|
||||||
protected ExposableControllerEndpoint createEndpoint(Object endpointBean, String id,
|
protected ExposableControllerEndpoint createEndpoint(Object endpointBean, String id,
|
||||||
boolean enabledByDefault, Collection<Operation> operations) {
|
boolean enabledByDefault, Collection<Operation> operations) {
|
||||||
|
return createEndpoint(endpointBean, (id != null) ? EndpointId.of(id) : null,
|
||||||
|
enabledByDefault, operations);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ExposableControllerEndpoint createEndpoint(Object endpointBean,
|
||||||
|
EndpointId id, boolean enabledByDefault, Collection<Operation> operations) {
|
||||||
String rootPath = this.endpointPathMapper.getRootPath(id);
|
String rootPath = this.endpointPathMapper.getRootPath(id);
|
||||||
return new DiscoveredControllerEndpoint(this, endpointBean, id, rootPath,
|
return new DiscoveredControllerEndpoint(this, endpointBean, id, rootPath,
|
||||||
enabledByDefault);
|
enabledByDefault);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Deprecated
|
||||||
protected Operation createOperation(String endpointId,
|
protected Operation createOperation(String endpointId,
|
||||||
DiscoveredOperationMethod operationMethod, OperationInvoker invoker) {
|
DiscoveredOperationMethod operationMethod, OperationInvoker invoker) {
|
||||||
|
return createOperation(EndpointId.of(endpointId), operationMethod, invoker);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Operation createOperation(EndpointId endpointId,
|
||||||
|
DiscoveredOperationMethod operationMethod, OperationInvoker invoker) {
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException(
|
||||||
"ControllerEndpoints must not declare operations");
|
"ControllerEndpoints must not declare operations");
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ package org.springframework.boot.actuate.endpoint.web.annotation;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
||||||
|
import org.springframework.boot.actuate.endpoint.EndpointId;
|
||||||
import org.springframework.boot.actuate.endpoint.Operation;
|
import org.springframework.boot.actuate.endpoint.Operation;
|
||||||
import org.springframework.boot.actuate.endpoint.annotation.AbstractDiscoveredEndpoint;
|
import org.springframework.boot.actuate.endpoint.annotation.AbstractDiscoveredEndpoint;
|
||||||
import org.springframework.boot.actuate.endpoint.annotation.EndpointDiscoverer;
|
import org.springframework.boot.actuate.endpoint.annotation.EndpointDiscoverer;
|
||||||
|
@ -33,7 +34,7 @@ class DiscoveredControllerEndpoint extends AbstractDiscoveredEndpoint<Operation>
|
||||||
private final String rootPath;
|
private final String rootPath;
|
||||||
|
|
||||||
DiscoveredControllerEndpoint(EndpointDiscoverer<?, ?> discoverer, Object endpointBean,
|
DiscoveredControllerEndpoint(EndpointDiscoverer<?, ?> discoverer, Object endpointBean,
|
||||||
String id, String rootPath, boolean enabledByDefault) {
|
EndpointId id, String rootPath, boolean enabledByDefault) {
|
||||||
super(discoverer, endpointBean, id, enabledByDefault, Collections.emptyList());
|
super(discoverer, endpointBean, id, enabledByDefault, Collections.emptyList());
|
||||||
this.rootPath = rootPath;
|
this.rootPath = rootPath;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ package org.springframework.boot.actuate.endpoint.web.annotation;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
import org.springframework.boot.actuate.endpoint.EndpointId;
|
||||||
import org.springframework.boot.actuate.endpoint.Operation;
|
import org.springframework.boot.actuate.endpoint.Operation;
|
||||||
import org.springframework.boot.actuate.endpoint.annotation.AbstractDiscoveredEndpoint;
|
import org.springframework.boot.actuate.endpoint.annotation.AbstractDiscoveredEndpoint;
|
||||||
import org.springframework.boot.actuate.endpoint.annotation.EndpointDiscoverer;
|
import org.springframework.boot.actuate.endpoint.annotation.EndpointDiscoverer;
|
||||||
|
@ -39,7 +40,7 @@ class DiscoveredServletEndpoint extends AbstractDiscoveredEndpoint<Operation>
|
||||||
private final EndpointServlet endpointServlet;
|
private final EndpointServlet endpointServlet;
|
||||||
|
|
||||||
DiscoveredServletEndpoint(EndpointDiscoverer<?, ?> discoverer, Object endpointBean,
|
DiscoveredServletEndpoint(EndpointDiscoverer<?, ?> discoverer, Object endpointBean,
|
||||||
String id, String rootPath, boolean enabledByDefault) {
|
EndpointId id, String rootPath, boolean enabledByDefault) {
|
||||||
super(discoverer, endpointBean, id, enabledByDefault, Collections.emptyList());
|
super(discoverer, endpointBean, id, enabledByDefault, Collections.emptyList());
|
||||||
String beanType = endpointBean.getClass().getName();
|
String beanType = endpointBean.getClass().getName();
|
||||||
Assert.state(endpointBean instanceof Supplier,
|
Assert.state(endpointBean instanceof Supplier,
|
||||||
|
|
|
@ -18,6 +18,7 @@ package org.springframework.boot.actuate.endpoint.web.annotation;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import org.springframework.boot.actuate.endpoint.EndpointId;
|
||||||
import org.springframework.boot.actuate.endpoint.annotation.AbstractDiscoveredEndpoint;
|
import org.springframework.boot.actuate.endpoint.annotation.AbstractDiscoveredEndpoint;
|
||||||
import org.springframework.boot.actuate.endpoint.annotation.EndpointDiscoverer;
|
import org.springframework.boot.actuate.endpoint.annotation.EndpointDiscoverer;
|
||||||
import org.springframework.boot.actuate.endpoint.web.ExposableWebEndpoint;
|
import org.springframework.boot.actuate.endpoint.web.ExposableWebEndpoint;
|
||||||
|
@ -34,7 +35,7 @@ class DiscoveredWebEndpoint extends AbstractDiscoveredEndpoint<WebOperation>
|
||||||
private final String rootPath;
|
private final String rootPath;
|
||||||
|
|
||||||
DiscoveredWebEndpoint(EndpointDiscoverer<?, ?> discoverer, Object endpointBean,
|
DiscoveredWebEndpoint(EndpointDiscoverer<?, ?> discoverer, Object endpointBean,
|
||||||
String id, String rootPath, boolean enabledByDefault,
|
EndpointId id, String rootPath, boolean enabledByDefault,
|
||||||
Collection<WebOperation> operations) {
|
Collection<WebOperation> operations) {
|
||||||
super(discoverer, endpointBean, id, enabledByDefault, operations);
|
super(discoverer, endpointBean, id, enabledByDefault, operations);
|
||||||
this.rootPath = rootPath;
|
this.rootPath = rootPath;
|
||||||
|
|
|
@ -23,6 +23,7 @@ import java.util.stream.Stream;
|
||||||
|
|
||||||
import org.reactivestreams.Publisher;
|
import org.reactivestreams.Publisher;
|
||||||
|
|
||||||
|
import org.springframework.boot.actuate.endpoint.EndpointId;
|
||||||
import org.springframework.boot.actuate.endpoint.annotation.AbstractDiscoveredOperation;
|
import org.springframework.boot.actuate.endpoint.annotation.AbstractDiscoveredOperation;
|
||||||
import org.springframework.boot.actuate.endpoint.annotation.DiscoveredOperationMethod;
|
import org.springframework.boot.actuate.endpoint.annotation.DiscoveredOperationMethod;
|
||||||
import org.springframework.boot.actuate.endpoint.annotation.Selector;
|
import org.springframework.boot.actuate.endpoint.annotation.Selector;
|
||||||
|
@ -51,8 +52,9 @@ class DiscoveredWebOperation extends AbstractDiscoveredOperation implements WebO
|
||||||
|
|
||||||
private final WebOperationRequestPredicate requestPredicate;
|
private final WebOperationRequestPredicate requestPredicate;
|
||||||
|
|
||||||
DiscoveredWebOperation(String endpointId, DiscoveredOperationMethod operationMethod,
|
DiscoveredWebOperation(EndpointId endpointId,
|
||||||
OperationInvoker invoker, WebOperationRequestPredicate requestPredicate) {
|
DiscoveredOperationMethod operationMethod, OperationInvoker invoker,
|
||||||
|
WebOperationRequestPredicate requestPredicate) {
|
||||||
super(operationMethod, invoker);
|
super(operationMethod, invoker);
|
||||||
Method method = operationMethod.getMethod();
|
Method method = operationMethod.getMethod();
|
||||||
this.id = getId(endpointId, method);
|
this.id = getId(endpointId, method);
|
||||||
|
@ -60,7 +62,7 @@ class DiscoveredWebOperation extends AbstractDiscoveredOperation implements WebO
|
||||||
this.requestPredicate = requestPredicate;
|
this.requestPredicate = requestPredicate;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getId(String endpointId, Method method) {
|
private String getId(EndpointId endpointId, Method method) {
|
||||||
return endpointId + Stream.of(method.getParameters()).filter(this::hasSelector)
|
return endpointId + Stream.of(method.getParameters()).filter(this::hasSelector)
|
||||||
.map(this::dashName).collect(Collectors.joining());
|
.map(this::dashName).collect(Collectors.joining());
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ import java.util.Collections;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import org.springframework.boot.actuate.endpoint.EndpointId;
|
||||||
import org.springframework.boot.actuate.endpoint.OperationType;
|
import org.springframework.boot.actuate.endpoint.OperationType;
|
||||||
import org.springframework.boot.actuate.endpoint.annotation.DiscoveredOperationMethod;
|
import org.springframework.boot.actuate.endpoint.annotation.DiscoveredOperationMethod;
|
||||||
import org.springframework.boot.actuate.endpoint.annotation.Selector;
|
import org.springframework.boot.actuate.endpoint.annotation.Selector;
|
||||||
|
@ -50,7 +51,7 @@ class RequestPredicateFactory {
|
||||||
this.endpointMediaTypes = endpointMediaTypes;
|
this.endpointMediaTypes = endpointMediaTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public WebOperationRequestPredicate getRequestPredicate(String endpointId,
|
public WebOperationRequestPredicate getRequestPredicate(EndpointId endpointId,
|
||||||
String rootPath, DiscoveredOperationMethod operationMethod) {
|
String rootPath, DiscoveredOperationMethod operationMethod) {
|
||||||
Method method = operationMethod.getMethod();
|
Method method = operationMethod.getMethod();
|
||||||
String path = getPath(rootPath, method);
|
String path = getPath(rootPath, method);
|
||||||
|
|
|
@ -20,6 +20,7 @@ import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
||||||
import org.springframework.boot.actuate.endpoint.EndpointFilter;
|
import org.springframework.boot.actuate.endpoint.EndpointFilter;
|
||||||
|
import org.springframework.boot.actuate.endpoint.EndpointId;
|
||||||
import org.springframework.boot.actuate.endpoint.Operation;
|
import org.springframework.boot.actuate.endpoint.Operation;
|
||||||
import org.springframework.boot.actuate.endpoint.annotation.DiscoveredOperationMethod;
|
import org.springframework.boot.actuate.endpoint.annotation.DiscoveredOperationMethod;
|
||||||
import org.springframework.boot.actuate.endpoint.annotation.EndpointDiscoverer;
|
import org.springframework.boot.actuate.endpoint.annotation.EndpointDiscoverer;
|
||||||
|
@ -66,16 +67,31 @@ public class ServletEndpointDiscoverer
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Deprecated
|
||||||
protected ExposableServletEndpoint createEndpoint(Object endpointBean, String id,
|
protected ExposableServletEndpoint createEndpoint(Object endpointBean, String id,
|
||||||
boolean enabledByDefault, Collection<Operation> operations) {
|
boolean enabledByDefault, Collection<Operation> operations) {
|
||||||
|
return createEndpoint(endpointBean, EndpointId.of(id), enabledByDefault,
|
||||||
|
operations);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ExposableServletEndpoint createEndpoint(Object endpointBean, EndpointId id,
|
||||||
|
boolean enabledByDefault, Collection<Operation> operations) {
|
||||||
String rootPath = this.endpointPathMapper.getRootPath(id);
|
String rootPath = this.endpointPathMapper.getRootPath(id);
|
||||||
return new DiscoveredServletEndpoint(this, endpointBean, id, rootPath,
|
return new DiscoveredServletEndpoint(this, endpointBean, id, rootPath,
|
||||||
enabledByDefault);
|
enabledByDefault);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Deprecated
|
||||||
protected Operation createOperation(String endpointId,
|
protected Operation createOperation(String endpointId,
|
||||||
DiscoveredOperationMethod operationMethod, OperationInvoker invoker) {
|
DiscoveredOperationMethod operationMethod, OperationInvoker invoker) {
|
||||||
|
return createOperation(EndpointId.of(endpointId), operationMethod, invoker);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Operation createOperation(EndpointId endpointId,
|
||||||
|
DiscoveredOperationMethod operationMethod, OperationInvoker invoker) {
|
||||||
throw new IllegalStateException("ServletEndpoints must not declare operations");
|
throw new IllegalStateException("ServletEndpoints must not declare operations");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ package org.springframework.boot.actuate.endpoint.web.annotation;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
import org.springframework.boot.actuate.endpoint.EndpointFilter;
|
import org.springframework.boot.actuate.endpoint.EndpointFilter;
|
||||||
|
import org.springframework.boot.actuate.endpoint.EndpointId;
|
||||||
import org.springframework.boot.actuate.endpoint.annotation.DiscoveredOperationMethod;
|
import org.springframework.boot.actuate.endpoint.annotation.DiscoveredOperationMethod;
|
||||||
import org.springframework.boot.actuate.endpoint.annotation.EndpointDiscoverer;
|
import org.springframework.boot.actuate.endpoint.annotation.EndpointDiscoverer;
|
||||||
import org.springframework.boot.actuate.endpoint.invoke.OperationInvoker;
|
import org.springframework.boot.actuate.endpoint.invoke.OperationInvoker;
|
||||||
|
@ -68,16 +69,31 @@ public class WebEndpointDiscoverer
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Deprecated
|
||||||
protected ExposableWebEndpoint createEndpoint(Object endpointBean, String id,
|
protected ExposableWebEndpoint createEndpoint(Object endpointBean, String id,
|
||||||
boolean enabledByDefault, Collection<WebOperation> operations) {
|
boolean enabledByDefault, Collection<WebOperation> operations) {
|
||||||
|
return createEndpoint(endpointBean, EndpointId.of(id), enabledByDefault,
|
||||||
|
operations);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ExposableWebEndpoint createEndpoint(Object endpointBean, EndpointId id,
|
||||||
|
boolean enabledByDefault, Collection<WebOperation> operations) {
|
||||||
String rootPath = this.endpointPathMapper.getRootPath(id);
|
String rootPath = this.endpointPathMapper.getRootPath(id);
|
||||||
return new DiscoveredWebEndpoint(this, endpointBean, id, rootPath,
|
return new DiscoveredWebEndpoint(this, endpointBean, id, rootPath,
|
||||||
enabledByDefault, operations);
|
enabledByDefault, operations);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Deprecated
|
||||||
protected WebOperation createOperation(String endpointId,
|
protected WebOperation createOperation(String endpointId,
|
||||||
DiscoveredOperationMethod operationMethod, OperationInvoker invoker) {
|
DiscoveredOperationMethod operationMethod, OperationInvoker invoker) {
|
||||||
|
return createOperation(EndpointId.of(endpointId), operationMethod, invoker);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected WebOperation createOperation(EndpointId endpointId,
|
||||||
|
DiscoveredOperationMethod operationMethod, OperationInvoker invoker) {
|
||||||
String rootPath = this.endpointPathMapper.getRootPath(endpointId);
|
String rootPath = this.endpointPathMapper.getRootPath(endpointId);
|
||||||
WebOperationRequestPredicate requestPredicate = this.requestPredicateFactory
|
WebOperationRequestPredicate requestPredicate = this.requestPredicateFactory
|
||||||
.getRequestPredicate(endpointId, rootPath, operationMethod);
|
.getRequestPredicate(endpointId, rootPath, operationMethod);
|
||||||
|
|
|
@ -0,0 +1,102 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2012-2018 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
|
||||||
|
*
|
||||||
|
* http://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.junit.Rule;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.rules.ExpectedException;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for {@link EndpointId}.
|
||||||
|
*
|
||||||
|
* @author Phillip Webb
|
||||||
|
*/
|
||||||
|
public class EndpointIdTests {
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
public ExpectedException thrown = ExpectedException.none();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void ofWhenNullThorowsException() {
|
||||||
|
this.thrown.expect(IllegalArgumentException.class);
|
||||||
|
this.thrown.expectMessage("Value must not be empty");
|
||||||
|
EndpointId.of(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void ofWhenEmptyThrowsException() {
|
||||||
|
this.thrown.expect(IllegalArgumentException.class);
|
||||||
|
this.thrown.expectMessage("Value must not be empty");
|
||||||
|
EndpointId.of("");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void ofWhenContainsDashThrowsException() {
|
||||||
|
this.thrown.expect(IllegalArgumentException.class);
|
||||||
|
this.thrown.expectMessage("Value must be alpha-numeric");
|
||||||
|
EndpointId.of("foo-bar");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void ofWhenHasBadCharThrowsException() {
|
||||||
|
this.thrown.expect(IllegalArgumentException.class);
|
||||||
|
this.thrown.expectMessage("Value must be alpha-numeric");
|
||||||
|
EndpointId.of("foo!bar");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void ofWhenStartsWithNumberThrowsException() {
|
||||||
|
this.thrown.expect(IllegalArgumentException.class);
|
||||||
|
this.thrown.expectMessage("Value must not start with a number");
|
||||||
|
EndpointId.of("1foo");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void ofWhenStartsWithUppercaseLetterThrowsException() {
|
||||||
|
this.thrown.expect(IllegalArgumentException.class);
|
||||||
|
this.thrown.expectMessage("Value must not start with an uppercase letter");
|
||||||
|
EndpointId.of("Foo");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void equalsAndHashCode() {
|
||||||
|
EndpointId one = EndpointId.of("foobar");
|
||||||
|
EndpointId two = EndpointId.of("fooBar");
|
||||||
|
EndpointId three = EndpointId.of("barfoo");
|
||||||
|
assertThat(one.hashCode()).isEqualTo(two.hashCode());
|
||||||
|
assertThat(one).isEqualTo(one).isEqualTo(two).isNotEqualTo(three);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void toLowerCaseStringReturnsLowercase() {
|
||||||
|
assertThat(EndpointId.of("fooBar").toLowerCaseString()).isEqualTo("foobar");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void toStringReturnsString() {
|
||||||
|
assertThat(EndpointId.of("fooBar").toString()).isEqualTo("fooBar");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void fromPropertyValueStripsDashes() {
|
||||||
|
EndpointId fromPropertyValue = EndpointId.fromPropertyValue("foo-bar");
|
||||||
|
assertThat(fromPropertyValue).isEqualTo(EndpointId.of("fooBar"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -25,6 +25,7 @@ import java.util.Map;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.springframework.boot.actuate.endpoint.EndpointId;
|
||||||
import org.springframework.boot.actuate.endpoint.InvocationContext;
|
import org.springframework.boot.actuate.endpoint.InvocationContext;
|
||||||
import org.springframework.boot.actuate.endpoint.OperationType;
|
import org.springframework.boot.actuate.endpoint.OperationType;
|
||||||
import org.springframework.boot.actuate.endpoint.SecurityContext;
|
import org.springframework.boot.actuate.endpoint.SecurityContext;
|
||||||
|
@ -60,8 +61,8 @@ public class DiscoveredOperationsFactoryTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void createOperationsWhenHasReadMethodShouldCreateOperation() {
|
public void createOperationsWhenHasReadMethodShouldCreateOperation() {
|
||||||
Collection<TestOperation> operations = this.factory.createOperations("test",
|
Collection<TestOperation> operations = this.factory
|
||||||
new ExampleRead());
|
.createOperations(EndpointId.of("test"), new ExampleRead());
|
||||||
assertThat(operations).hasSize(1);
|
assertThat(operations).hasSize(1);
|
||||||
TestOperation operation = getFirst(operations);
|
TestOperation operation = getFirst(operations);
|
||||||
assertThat(operation.getType()).isEqualTo(OperationType.READ);
|
assertThat(operation.getType()).isEqualTo(OperationType.READ);
|
||||||
|
@ -69,8 +70,8 @@ public class DiscoveredOperationsFactoryTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void createOperationsWhenHasWriteMethodShouldCreateOperation() {
|
public void createOperationsWhenHasWriteMethodShouldCreateOperation() {
|
||||||
Collection<TestOperation> operations = this.factory.createOperations("test",
|
Collection<TestOperation> operations = this.factory
|
||||||
new ExampleWrite());
|
.createOperations(EndpointId.of("test"), new ExampleWrite());
|
||||||
assertThat(operations).hasSize(1);
|
assertThat(operations).hasSize(1);
|
||||||
TestOperation operation = getFirst(operations);
|
TestOperation operation = getFirst(operations);
|
||||||
assertThat(operation.getType()).isEqualTo(OperationType.WRITE);
|
assertThat(operation.getType()).isEqualTo(OperationType.WRITE);
|
||||||
|
@ -78,8 +79,8 @@ public class DiscoveredOperationsFactoryTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void createOperationsWhenHasDeleteMethodShouldCreateOperation() {
|
public void createOperationsWhenHasDeleteMethodShouldCreateOperation() {
|
||||||
Collection<TestOperation> operations = this.factory.createOperations("test",
|
Collection<TestOperation> operations = this.factory
|
||||||
new ExampleDelete());
|
.createOperations(EndpointId.of("test"), new ExampleDelete());
|
||||||
assertThat(operations).hasSize(1);
|
assertThat(operations).hasSize(1);
|
||||||
TestOperation operation = getFirst(operations);
|
TestOperation operation = getFirst(operations);
|
||||||
assertThat(operation.getType()).isEqualTo(OperationType.DELETE);
|
assertThat(operation.getType()).isEqualTo(OperationType.DELETE);
|
||||||
|
@ -87,8 +88,8 @@ public class DiscoveredOperationsFactoryTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void createOperationsWhenMultipleShouldReturnMultiple() {
|
public void createOperationsWhenMultipleShouldReturnMultiple() {
|
||||||
Collection<TestOperation> operations = this.factory.createOperations("test",
|
Collection<TestOperation> operations = this.factory
|
||||||
new ExampleMultiple());
|
.createOperations(EndpointId.of("test"), new ExampleMultiple());
|
||||||
assertThat(operations).hasSize(2);
|
assertThat(operations).hasSize(2);
|
||||||
assertThat(operations.stream().map(TestOperation::getType))
|
assertThat(operations.stream().map(TestOperation::getType))
|
||||||
.containsOnly(OperationType.READ, OperationType.WRITE);
|
.containsOnly(OperationType.READ, OperationType.WRITE);
|
||||||
|
@ -96,8 +97,8 @@ public class DiscoveredOperationsFactoryTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void createOperationsShouldProvideOperationMethod() {
|
public void createOperationsShouldProvideOperationMethod() {
|
||||||
TestOperation operation = getFirst(
|
TestOperation operation = getFirst(this.factory
|
||||||
this.factory.createOperations("test", new ExampleWithParams()));
|
.createOperations(EndpointId.of("test"), new ExampleWithParams()));
|
||||||
OperationMethod operationMethod = operation.getOperationMethod();
|
OperationMethod operationMethod = operation.getOperationMethod();
|
||||||
assertThat(operationMethod.getMethod().getName()).isEqualTo("read");
|
assertThat(operationMethod.getMethod().getName()).isEqualTo("read");
|
||||||
assertThat(operationMethod.getParameters().hasParameters()).isTrue();
|
assertThat(operationMethod.getParameters().hasParameters()).isTrue();
|
||||||
|
@ -105,8 +106,8 @@ public class DiscoveredOperationsFactoryTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void createOperationsShouldProviderInvoker() {
|
public void createOperationsShouldProviderInvoker() {
|
||||||
TestOperation operation = getFirst(
|
TestOperation operation = getFirst(this.factory
|
||||||
this.factory.createOperations("test", new ExampleWithParams()));
|
.createOperations(EndpointId.of("test"), new ExampleWithParams()));
|
||||||
Map<String, Object> params = Collections.singletonMap("name", 123);
|
Map<String, Object> params = Collections.singletonMap("name", 123);
|
||||||
Object result = operation
|
Object result = operation
|
||||||
.invoke(new InvocationContext(mock(SecurityContext.class), params));
|
.invoke(new InvocationContext(mock(SecurityContext.class), params));
|
||||||
|
@ -118,10 +119,10 @@ public class DiscoveredOperationsFactoryTests {
|
||||||
TestOperationInvokerAdvisor advisor = new TestOperationInvokerAdvisor();
|
TestOperationInvokerAdvisor advisor = new TestOperationInvokerAdvisor();
|
||||||
this.invokerAdvisors.add(advisor);
|
this.invokerAdvisors.add(advisor);
|
||||||
TestOperation operation = getFirst(
|
TestOperation operation = getFirst(
|
||||||
this.factory.createOperations("test", new ExampleRead()));
|
this.factory.createOperations(EndpointId.of("test"), new ExampleRead()));
|
||||||
operation.invoke(new InvocationContext(mock(SecurityContext.class),
|
operation.invoke(new InvocationContext(mock(SecurityContext.class),
|
||||||
Collections.emptyMap()));
|
Collections.emptyMap()));
|
||||||
assertThat(advisor.getEndpointId()).isEqualTo("test");
|
assertThat(advisor.getEndpointId()).isEqualTo(EndpointId.of("test"));
|
||||||
assertThat(advisor.getOperationType()).isEqualTo(OperationType.READ);
|
assertThat(advisor.getOperationType()).isEqualTo(OperationType.READ);
|
||||||
assertThat(advisor.getParameters()).isEmpty();
|
assertThat(advisor.getParameters()).isEmpty();
|
||||||
}
|
}
|
||||||
|
@ -189,7 +190,7 @@ public class DiscoveredOperationsFactoryTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected TestOperation createOperation(String endpointId,
|
protected TestOperation createOperation(EndpointId endpointId,
|
||||||
DiscoveredOperationMethod operationMethod, OperationInvoker invoker) {
|
DiscoveredOperationMethod operationMethod, OperationInvoker invoker) {
|
||||||
return new TestOperation(endpointId, operationMethod, invoker);
|
return new TestOperation(endpointId, operationMethod, invoker);
|
||||||
}
|
}
|
||||||
|
@ -198,7 +199,7 @@ public class DiscoveredOperationsFactoryTests {
|
||||||
|
|
||||||
static class TestOperation extends AbstractDiscoveredOperation {
|
static class TestOperation extends AbstractDiscoveredOperation {
|
||||||
|
|
||||||
TestOperation(String endpointId, DiscoveredOperationMethod operationMethod,
|
TestOperation(EndpointId endpointId, DiscoveredOperationMethod operationMethod,
|
||||||
OperationInvoker invoker) {
|
OperationInvoker invoker) {
|
||||||
super(operationMethod, invoker);
|
super(operationMethod, invoker);
|
||||||
}
|
}
|
||||||
|
@ -207,14 +208,14 @@ public class DiscoveredOperationsFactoryTests {
|
||||||
|
|
||||||
static class TestOperationInvokerAdvisor implements OperationInvokerAdvisor {
|
static class TestOperationInvokerAdvisor implements OperationInvokerAdvisor {
|
||||||
|
|
||||||
private String endpointId;
|
private EndpointId endpointId;
|
||||||
|
|
||||||
private OperationType operationType;
|
private OperationType operationType;
|
||||||
|
|
||||||
private OperationParameters parameters;
|
private OperationParameters parameters;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public OperationInvoker apply(String endpointId, OperationType operationType,
|
public OperationInvoker apply(EndpointId endpointId, OperationType operationType,
|
||||||
OperationParameters parameters, OperationInvoker invoker) {
|
OperationParameters parameters, OperationInvoker invoker) {
|
||||||
this.endpointId = endpointId;
|
this.endpointId = endpointId;
|
||||||
this.operationType = operationType;
|
this.operationType = operationType;
|
||||||
|
@ -222,7 +223,14 @@ public class DiscoveredOperationsFactoryTests {
|
||||||
return invoker;
|
return invoker;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getEndpointId() {
|
@Override
|
||||||
|
@Deprecated
|
||||||
|
public OperationInvoker apply(String endpointId, OperationType operationType,
|
||||||
|
OperationParameters parameters, OperationInvoker invoker) {
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public EndpointId getEndpointId() {
|
||||||
return this.endpointId;
|
return this.endpointId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,7 @@ import org.junit.Test;
|
||||||
import org.junit.rules.ExpectedException;
|
import org.junit.rules.ExpectedException;
|
||||||
|
|
||||||
import org.springframework.boot.actuate.endpoint.EndpointFilter;
|
import org.springframework.boot.actuate.endpoint.EndpointFilter;
|
||||||
|
import org.springframework.boot.actuate.endpoint.EndpointId;
|
||||||
import org.springframework.boot.actuate.endpoint.ExposableEndpoint;
|
import org.springframework.boot.actuate.endpoint.ExposableEndpoint;
|
||||||
import org.springframework.boot.actuate.endpoint.Operation;
|
import org.springframework.boot.actuate.endpoint.Operation;
|
||||||
import org.springframework.boot.actuate.endpoint.invoke.OperationInvoker;
|
import org.springframework.boot.actuate.endpoint.invoke.OperationInvoker;
|
||||||
|
@ -125,10 +126,11 @@ public class EndpointDiscovererTests {
|
||||||
public void getEndpointsWhenHasSubclassedEndpointShouldReturnEndpoint() {
|
public void getEndpointsWhenHasSubclassedEndpointShouldReturnEndpoint() {
|
||||||
load(TestEndpointSubclassConfiguration.class, (context) -> {
|
load(TestEndpointSubclassConfiguration.class, (context) -> {
|
||||||
TestEndpointDiscoverer discoverer = new TestEndpointDiscoverer(context);
|
TestEndpointDiscoverer discoverer = new TestEndpointDiscoverer(context);
|
||||||
Map<String, TestExposableEndpoint> endpoints = mapEndpoints(
|
Map<EndpointId, TestExposableEndpoint> endpoints = mapEndpoints(
|
||||||
discoverer.getEndpoints());
|
discoverer.getEndpoints());
|
||||||
assertThat(endpoints).containsOnlyKeys("test");
|
assertThat(endpoints).containsOnlyKeys(EndpointId.of("test"));
|
||||||
Map<Method, TestOperation> operations = mapOperations(endpoints.get("test"));
|
Map<Method, TestOperation> operations = mapOperations(
|
||||||
|
endpoints.get(EndpointId.of("test")));
|
||||||
assertThat(operations).hasSize(5);
|
assertThat(operations).hasSize(5);
|
||||||
assertThat(operations).containsKeys(testEndpointMethods());
|
assertThat(operations).containsKeys(testEndpointMethods());
|
||||||
assertThat(operations).containsKeys(ReflectionUtils.findMethod(
|
assertThat(operations).containsKeys(ReflectionUtils.findMethod(
|
||||||
|
@ -151,10 +153,11 @@ public class EndpointDiscovererTests {
|
||||||
load(TestEndpointConfiguration.class, (context) -> {
|
load(TestEndpointConfiguration.class, (context) -> {
|
||||||
TestEndpointDiscoverer discoverer = new TestEndpointDiscoverer(context,
|
TestEndpointDiscoverer discoverer = new TestEndpointDiscoverer(context,
|
||||||
(endpointId) -> 0L);
|
(endpointId) -> 0L);
|
||||||
Map<String, TestExposableEndpoint> endpoints = mapEndpoints(
|
Map<EndpointId, TestExposableEndpoint> endpoints = mapEndpoints(
|
||||||
discoverer.getEndpoints());
|
discoverer.getEndpoints());
|
||||||
assertThat(endpoints).containsOnlyKeys("test");
|
assertThat(endpoints).containsOnlyKeys(EndpointId.of("test"));
|
||||||
Map<Method, TestOperation> operations = mapOperations(endpoints.get("test"));
|
Map<Method, TestOperation> operations = mapOperations(
|
||||||
|
endpoints.get(EndpointId.of("test")));
|
||||||
operations.values().forEach((operation) -> assertThat(operation.getInvoker())
|
operations.values().forEach((operation) -> assertThat(operation.getInvoker())
|
||||||
.isNotInstanceOf(CachingOperationInvoker.class));
|
.isNotInstanceOf(CachingOperationInvoker.class));
|
||||||
});
|
});
|
||||||
|
@ -165,10 +168,11 @@ public class EndpointDiscovererTests {
|
||||||
load(TestEndpointConfiguration.class, (context) -> {
|
load(TestEndpointConfiguration.class, (context) -> {
|
||||||
TestEndpointDiscoverer discoverer = new TestEndpointDiscoverer(context,
|
TestEndpointDiscoverer discoverer = new TestEndpointDiscoverer(context,
|
||||||
(endpointId) -> (endpointId.equals("foo") ? 500L : 0L));
|
(endpointId) -> (endpointId.equals("foo") ? 500L : 0L));
|
||||||
Map<String, TestExposableEndpoint> endpoints = mapEndpoints(
|
Map<EndpointId, TestExposableEndpoint> endpoints = mapEndpoints(
|
||||||
discoverer.getEndpoints());
|
discoverer.getEndpoints());
|
||||||
assertThat(endpoints).containsOnlyKeys("test");
|
assertThat(endpoints).containsOnlyKeys(EndpointId.of("test"));
|
||||||
Map<Method, TestOperation> operations = mapOperations(endpoints.get("test"));
|
Map<Method, TestOperation> operations = mapOperations(
|
||||||
|
endpoints.get(EndpointId.of("test")));
|
||||||
operations.values().forEach((operation) -> assertThat(operation.getInvoker())
|
operations.values().forEach((operation) -> assertThat(operation.getInvoker())
|
||||||
.isNotInstanceOf(CachingOperationInvoker.class));
|
.isNotInstanceOf(CachingOperationInvoker.class));
|
||||||
});
|
});
|
||||||
|
@ -178,11 +182,13 @@ public class EndpointDiscovererTests {
|
||||||
public void getEndpointsWhenTtlSetByIdAndIdMatchesShouldCacheInvokeCalls() {
|
public void getEndpointsWhenTtlSetByIdAndIdMatchesShouldCacheInvokeCalls() {
|
||||||
load(TestEndpointConfiguration.class, (context) -> {
|
load(TestEndpointConfiguration.class, (context) -> {
|
||||||
TestEndpointDiscoverer discoverer = new TestEndpointDiscoverer(context,
|
TestEndpointDiscoverer discoverer = new TestEndpointDiscoverer(context,
|
||||||
(endpointId) -> (endpointId.equals("test") ? 500L : 0L));
|
(endpointId) -> (endpointId.equals(EndpointId.of("test")) ? 500L
|
||||||
Map<String, TestExposableEndpoint> endpoints = mapEndpoints(
|
: 0L));
|
||||||
|
Map<EndpointId, TestExposableEndpoint> endpoints = mapEndpoints(
|
||||||
discoverer.getEndpoints());
|
discoverer.getEndpoints());
|
||||||
assertThat(endpoints).containsOnlyKeys("test");
|
assertThat(endpoints).containsOnlyKeys(EndpointId.of("test"));
|
||||||
Map<Method, TestOperation> operations = mapOperations(endpoints.get("test"));
|
Map<Method, TestOperation> operations = mapOperations(
|
||||||
|
endpoints.get(EndpointId.of("test")));
|
||||||
TestOperation getAll = operations.get(findTestEndpointMethod("getAll"));
|
TestOperation getAll = operations.get(findTestEndpointMethod("getAll"));
|
||||||
TestOperation getOne = operations
|
TestOperation getOne = operations
|
||||||
.get(findTestEndpointMethod("getOne", String.class));
|
.get(findTestEndpointMethod("getOne", String.class));
|
||||||
|
@ -201,9 +207,9 @@ public class EndpointDiscovererTests {
|
||||||
public void getEndpointsWhenHasSpecializedFiltersInNonSpecializedDiscovererShouldFilterEndpoints() {
|
public void getEndpointsWhenHasSpecializedFiltersInNonSpecializedDiscovererShouldFilterEndpoints() {
|
||||||
load(SpecializedEndpointsConfiguration.class, (context) -> {
|
load(SpecializedEndpointsConfiguration.class, (context) -> {
|
||||||
TestEndpointDiscoverer discoverer = new TestEndpointDiscoverer(context);
|
TestEndpointDiscoverer discoverer = new TestEndpointDiscoverer(context);
|
||||||
Map<String, TestExposableEndpoint> endpoints = mapEndpoints(
|
Map<EndpointId, TestExposableEndpoint> endpoints = mapEndpoints(
|
||||||
discoverer.getEndpoints());
|
discoverer.getEndpoints());
|
||||||
assertThat(endpoints).containsOnlyKeys("test");
|
assertThat(endpoints).containsOnlyKeys(EndpointId.of("test"));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,9 +218,10 @@ public class EndpointDiscovererTests {
|
||||||
load(SpecializedEndpointsConfiguration.class, (context) -> {
|
load(SpecializedEndpointsConfiguration.class, (context) -> {
|
||||||
SpecializedEndpointDiscoverer discoverer = new SpecializedEndpointDiscoverer(
|
SpecializedEndpointDiscoverer discoverer = new SpecializedEndpointDiscoverer(
|
||||||
context);
|
context);
|
||||||
Map<String, SpecializedExposableEndpoint> endpoints = mapEndpoints(
|
Map<EndpointId, SpecializedExposableEndpoint> endpoints = mapEndpoints(
|
||||||
discoverer.getEndpoints());
|
discoverer.getEndpoints());
|
||||||
assertThat(endpoints).containsOnlyKeys("test", "specialized");
|
assertThat(endpoints).containsOnlyKeys(EndpointId.of("test"),
|
||||||
|
EndpointId.of("specialized"));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,10 +230,10 @@ public class EndpointDiscovererTests {
|
||||||
load(SpecializedEndpointsConfiguration.class, (context) -> {
|
load(SpecializedEndpointsConfiguration.class, (context) -> {
|
||||||
SpecializedEndpointDiscoverer discoverer = new SpecializedEndpointDiscoverer(
|
SpecializedEndpointDiscoverer discoverer = new SpecializedEndpointDiscoverer(
|
||||||
context);
|
context);
|
||||||
Map<String, SpecializedExposableEndpoint> endpoints = mapEndpoints(
|
Map<EndpointId, SpecializedExposableEndpoint> endpoints = mapEndpoints(
|
||||||
discoverer.getEndpoints());
|
discoverer.getEndpoints());
|
||||||
Map<Method, SpecializedOperation> operations = mapOperations(
|
Map<Method, SpecializedOperation> operations = mapOperations(
|
||||||
endpoints.get("specialized"));
|
endpoints.get(EndpointId.of("specialized")));
|
||||||
assertThat(operations).containsKeys(
|
assertThat(operations).containsKeys(
|
||||||
ReflectionUtils.findMethod(SpecializedExtension.class, "getSpecial"));
|
ReflectionUtils.findMethod(SpecializedExtension.class, "getSpecial"));
|
||||||
|
|
||||||
|
@ -238,10 +245,10 @@ public class EndpointDiscovererTests {
|
||||||
load(SubSpecializedEndpointsConfiguration.class, (context) -> {
|
load(SubSpecializedEndpointsConfiguration.class, (context) -> {
|
||||||
SpecializedEndpointDiscoverer discoverer = new SpecializedEndpointDiscoverer(
|
SpecializedEndpointDiscoverer discoverer = new SpecializedEndpointDiscoverer(
|
||||||
context);
|
context);
|
||||||
Map<String, SpecializedExposableEndpoint> endpoints = mapEndpoints(
|
Map<EndpointId, SpecializedExposableEndpoint> endpoints = mapEndpoints(
|
||||||
discoverer.getEndpoints());
|
discoverer.getEndpoints());
|
||||||
Map<Method, SpecializedOperation> operations = mapOperations(
|
Map<Method, SpecializedOperation> operations = mapOperations(
|
||||||
endpoints.get("specialized"));
|
endpoints.get(EndpointId.of("specialized")));
|
||||||
assertThat(operations).containsKeys(
|
assertThat(operations).containsKeys(
|
||||||
ReflectionUtils.findMethod(SpecializedTestEndpoint.class, "getAll"));
|
ReflectionUtils.findMethod(SpecializedTestEndpoint.class, "getAll"));
|
||||||
assertThat(operations).containsKeys(ReflectionUtils.findMethod(
|
assertThat(operations).containsKeys(ReflectionUtils.findMethod(
|
||||||
|
@ -261,18 +268,19 @@ public class EndpointDiscovererTests {
|
||||||
};
|
};
|
||||||
SpecializedEndpointDiscoverer discoverer = new SpecializedEndpointDiscoverer(
|
SpecializedEndpointDiscoverer discoverer = new SpecializedEndpointDiscoverer(
|
||||||
context, Collections.singleton(filter));
|
context, Collections.singleton(filter));
|
||||||
Map<String, SpecializedExposableEndpoint> endpoints = mapEndpoints(
|
Map<EndpointId, SpecializedExposableEndpoint> endpoints = mapEndpoints(
|
||||||
discoverer.getEndpoints());
|
discoverer.getEndpoints());
|
||||||
assertThat(endpoints).containsOnlyKeys("test");
|
assertThat(endpoints).containsOnlyKeys(EndpointId.of("test"));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void hasTestEndpoint(AnnotationConfigApplicationContext context) {
|
private void hasTestEndpoint(AnnotationConfigApplicationContext context) {
|
||||||
TestEndpointDiscoverer discoverer = new TestEndpointDiscoverer(context);
|
TestEndpointDiscoverer discoverer = new TestEndpointDiscoverer(context);
|
||||||
Map<String, TestExposableEndpoint> endpoints = mapEndpoints(
|
Map<EndpointId, TestExposableEndpoint> endpoints = mapEndpoints(
|
||||||
discoverer.getEndpoints());
|
discoverer.getEndpoints());
|
||||||
assertThat(endpoints).containsOnlyKeys("test");
|
assertThat(endpoints).containsOnlyKeys(EndpointId.of("test"));
|
||||||
Map<Method, TestOperation> operations = mapOperations(endpoints.get("test"));
|
Map<Method, TestOperation> operations = mapOperations(
|
||||||
|
endpoints.get(EndpointId.of("test")));
|
||||||
assertThat(operations).hasSize(4);
|
assertThat(operations).hasSize(4);
|
||||||
assertThat(operations).containsKeys();
|
assertThat(operations).containsKeys();
|
||||||
}
|
}
|
||||||
|
@ -290,14 +298,15 @@ public class EndpointDiscovererTests {
|
||||||
return ReflectionUtils.findMethod(TestEndpoint.class, name, paramTypes);
|
return ReflectionUtils.findMethod(TestEndpoint.class, name, paramTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
private <E extends ExposableEndpoint<?>> Map<String, E> mapEndpoints(
|
private <E extends ExposableEndpoint<?>> Map<EndpointId, E> mapEndpoints(
|
||||||
Collection<E> endpoints) {
|
Collection<E> endpoints) {
|
||||||
Map<String, E> byId = new LinkedHashMap<>();
|
Map<EndpointId, E> byId = new LinkedHashMap<>();
|
||||||
endpoints.forEach((endpoint) -> {
|
endpoints.forEach((endpoint) -> {
|
||||||
E existing = byId.put(endpoint.getId(), endpoint);
|
E existing = byId.put(endpoint.getEndpointId(), endpoint);
|
||||||
if (existing != null) {
|
if (existing != null) {
|
||||||
throw new AssertionError(String.format(
|
throw new AssertionError(
|
||||||
"Found endpoints with duplicate id '%s'", endpoint.getId()));
|
String.format("Found endpoints with duplicate id '%s'",
|
||||||
|
endpoint.getEndpointId()));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return byId;
|
return byId;
|
||||||
|
@ -491,12 +500,12 @@ public class EndpointDiscovererTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
TestEndpointDiscoverer(ApplicationContext applicationContext,
|
TestEndpointDiscoverer(ApplicationContext applicationContext,
|
||||||
Function<String, Long> timeToLive) {
|
Function<EndpointId, Long> timeToLive) {
|
||||||
this(applicationContext, timeToLive, Collections.emptyList());
|
this(applicationContext, timeToLive, Collections.emptyList());
|
||||||
}
|
}
|
||||||
|
|
||||||
TestEndpointDiscoverer(ApplicationContext applicationContext,
|
TestEndpointDiscoverer(ApplicationContext applicationContext,
|
||||||
Function<String, Long> timeToLive,
|
Function<EndpointId, Long> timeToLive,
|
||||||
Collection<EndpointFilter<TestExposableEndpoint>> filters) {
|
Collection<EndpointFilter<TestExposableEndpoint>> filters) {
|
||||||
this(applicationContext, new ConversionServiceParameterValueMapper(),
|
this(applicationContext, new ConversionServiceParameterValueMapper(),
|
||||||
Collections.singleton(new CachingOperationInvokerAdvisor(timeToLive)),
|
Collections.singleton(new CachingOperationInvokerAdvisor(timeToLive)),
|
||||||
|
@ -513,6 +522,12 @@ public class EndpointDiscovererTests {
|
||||||
@Override
|
@Override
|
||||||
protected TestExposableEndpoint createEndpoint(Object endpointBean, String id,
|
protected TestExposableEndpoint createEndpoint(Object endpointBean, String id,
|
||||||
boolean enabledByDefault, Collection<TestOperation> operations) {
|
boolean enabledByDefault, Collection<TestOperation> operations) {
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected TestExposableEndpoint createEndpoint(Object endpointBean, EndpointId id,
|
||||||
|
boolean enabledByDefault, Collection<TestOperation> operations) {
|
||||||
return new TestExposableEndpoint(this, endpointBean, id, enabledByDefault,
|
return new TestExposableEndpoint(this, endpointBean, id, enabledByDefault,
|
||||||
operations);
|
operations);
|
||||||
}
|
}
|
||||||
|
@ -548,6 +563,13 @@ public class EndpointDiscovererTests {
|
||||||
protected SpecializedExposableEndpoint createEndpoint(Object endpointBean,
|
protected SpecializedExposableEndpoint createEndpoint(Object endpointBean,
|
||||||
String id, boolean enabledByDefault,
|
String id, boolean enabledByDefault,
|
||||||
Collection<SpecializedOperation> operations) {
|
Collection<SpecializedOperation> operations) {
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected SpecializedExposableEndpoint createEndpoint(Object endpointBean,
|
||||||
|
EndpointId id, boolean enabledByDefault,
|
||||||
|
Collection<SpecializedOperation> operations) {
|
||||||
return new SpecializedExposableEndpoint(this, endpointBean, id,
|
return new SpecializedExposableEndpoint(this, endpointBean, id,
|
||||||
enabledByDefault, operations);
|
enabledByDefault, operations);
|
||||||
}
|
}
|
||||||
|
@ -569,7 +591,7 @@ public class EndpointDiscovererTests {
|
||||||
static class TestExposableEndpoint extends AbstractDiscoveredEndpoint<TestOperation> {
|
static class TestExposableEndpoint extends AbstractDiscoveredEndpoint<TestOperation> {
|
||||||
|
|
||||||
TestExposableEndpoint(EndpointDiscoverer<?, ?> discoverer, Object endpointBean,
|
TestExposableEndpoint(EndpointDiscoverer<?, ?> discoverer, Object endpointBean,
|
||||||
String id, boolean enabledByDefault,
|
EndpointId id, boolean enabledByDefault,
|
||||||
Collection<? extends TestOperation> operations) {
|
Collection<? extends TestOperation> operations) {
|
||||||
super(discoverer, endpointBean, id, enabledByDefault, operations);
|
super(discoverer, endpointBean, id, enabledByDefault, operations);
|
||||||
}
|
}
|
||||||
|
@ -580,7 +602,7 @@ public class EndpointDiscovererTests {
|
||||||
extends AbstractDiscoveredEndpoint<SpecializedOperation> {
|
extends AbstractDiscoveredEndpoint<SpecializedOperation> {
|
||||||
|
|
||||||
SpecializedExposableEndpoint(EndpointDiscoverer<?, ?> discoverer,
|
SpecializedExposableEndpoint(EndpointDiscoverer<?, ?> discoverer,
|
||||||
Object endpointBean, String id, boolean enabledByDefault,
|
Object endpointBean, EndpointId id, boolean enabledByDefault,
|
||||||
Collection<? extends SpecializedOperation> operations) {
|
Collection<? extends SpecializedOperation> operations) {
|
||||||
super(discoverer, endpointBean, id, enabledByDefault, operations);
|
super(discoverer, endpointBean, id, enabledByDefault, operations);
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ import org.junit.Test;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
|
|
||||||
|
import org.springframework.boot.actuate.endpoint.EndpointId;
|
||||||
import org.springframework.boot.actuate.endpoint.OperationType;
|
import org.springframework.boot.actuate.endpoint.OperationType;
|
||||||
import org.springframework.boot.actuate.endpoint.SecurityContext;
|
import org.springframework.boot.actuate.endpoint.SecurityContext;
|
||||||
import org.springframework.boot.actuate.endpoint.invoke.OperationInvoker;
|
import org.springframework.boot.actuate.endpoint.invoke.OperationInvoker;
|
||||||
|
@ -50,7 +51,7 @@ public class CachingOperationInvokerAdvisorTests {
|
||||||
private OperationInvoker invoker;
|
private OperationInvoker invoker;
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
private Function<String, Long> timeToLive;
|
private Function<EndpointId, Long> timeToLive;
|
||||||
|
|
||||||
private CachingOperationInvokerAdvisor advisor;
|
private CachingOperationInvokerAdvisor advisor;
|
||||||
|
|
||||||
|
@ -63,8 +64,8 @@ public class CachingOperationInvokerAdvisorTests {
|
||||||
@Test
|
@Test
|
||||||
public void applyWhenOperationIsNotReadShouldNotAddAdvise() {
|
public void applyWhenOperationIsNotReadShouldNotAddAdvise() {
|
||||||
OperationParameters parameters = getParameters("get");
|
OperationParameters parameters = getParameters("get");
|
||||||
OperationInvoker advised = this.advisor.apply("foo", OperationType.WRITE,
|
OperationInvoker advised = this.advisor.apply(EndpointId.of("foo"),
|
||||||
parameters, this.invoker);
|
OperationType.WRITE, parameters, this.invoker);
|
||||||
assertThat(advised).isSameAs(this.invoker);
|
assertThat(advised).isSameAs(this.invoker);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,8 +73,8 @@ public class CachingOperationInvokerAdvisorTests {
|
||||||
public void applyWhenHasAtLeaseOneMandatoryParameterShouldNotAddAdvise() {
|
public void applyWhenHasAtLeaseOneMandatoryParameterShouldNotAddAdvise() {
|
||||||
OperationParameters parameters = getParameters("getWithParameters", String.class,
|
OperationParameters parameters = getParameters("getWithParameters", String.class,
|
||||||
String.class);
|
String.class);
|
||||||
OperationInvoker advised = this.advisor.apply("foo", OperationType.READ,
|
OperationInvoker advised = this.advisor.apply(EndpointId.of("foo"),
|
||||||
parameters, this.invoker);
|
OperationType.READ, parameters, this.invoker);
|
||||||
assertThat(advised).isSameAs(this.invoker);
|
assertThat(advised).isSameAs(this.invoker);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,20 +82,20 @@ public class CachingOperationInvokerAdvisorTests {
|
||||||
public void applyWhenTimeToLiveReturnsNullShouldNotAddAdvise() {
|
public void applyWhenTimeToLiveReturnsNullShouldNotAddAdvise() {
|
||||||
OperationParameters parameters = getParameters("get");
|
OperationParameters parameters = getParameters("get");
|
||||||
given(this.timeToLive.apply(any())).willReturn(null);
|
given(this.timeToLive.apply(any())).willReturn(null);
|
||||||
OperationInvoker advised = this.advisor.apply("foo", OperationType.READ,
|
OperationInvoker advised = this.advisor.apply(EndpointId.of("foo"),
|
||||||
parameters, this.invoker);
|
OperationType.READ, parameters, this.invoker);
|
||||||
assertThat(advised).isSameAs(this.invoker);
|
assertThat(advised).isSameAs(this.invoker);
|
||||||
verify(this.timeToLive).apply("foo");
|
verify(this.timeToLive).apply(EndpointId.of("foo"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void applyWhenTimeToLiveIsZeroShouldNotAddAdvise() {
|
public void applyWhenTimeToLiveIsZeroShouldNotAddAdvise() {
|
||||||
OperationParameters parameters = getParameters("get");
|
OperationParameters parameters = getParameters("get");
|
||||||
given(this.timeToLive.apply(any())).willReturn(0L);
|
given(this.timeToLive.apply(any())).willReturn(0L);
|
||||||
OperationInvoker advised = this.advisor.apply("foo", OperationType.READ,
|
OperationInvoker advised = this.advisor.apply(EndpointId.of("foo"),
|
||||||
parameters, this.invoker);
|
OperationType.READ, parameters, this.invoker);
|
||||||
assertThat(advised).isSameAs(this.invoker);
|
assertThat(advised).isSameAs(this.invoker);
|
||||||
verify(this.timeToLive).apply("foo");
|
verify(this.timeToLive).apply(EndpointId.of("foo"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -121,8 +122,8 @@ public class CachingOperationInvokerAdvisorTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertAdviseIsApplied(OperationParameters parameters) {
|
private void assertAdviseIsApplied(OperationParameters parameters) {
|
||||||
OperationInvoker advised = this.advisor.apply("foo", OperationType.READ,
|
OperationInvoker advised = this.advisor.apply(EndpointId.of("foo"),
|
||||||
parameters, this.invoker);
|
OperationType.READ, parameters, this.invoker);
|
||||||
assertThat(advised).isInstanceOf(CachingOperationInvoker.class);
|
assertThat(advised).isInstanceOf(CachingOperationInvoker.class);
|
||||||
assertThat(ReflectionTestUtils.getField(advised, "invoker"))
|
assertThat(ReflectionTestUtils.getField(advised, "invoker"))
|
||||||
.isEqualTo(this.invoker);
|
.isEqualTo(this.invoker);
|
||||||
|
|
|
@ -190,9 +190,8 @@ public class JmxEndpointExporterTests {
|
||||||
@Override
|
@Override
|
||||||
public ObjectName getObjectName(ExposableJmxEndpoint endpoint)
|
public ObjectName getObjectName(ExposableJmxEndpoint endpoint)
|
||||||
throws MalformedObjectNameException {
|
throws MalformedObjectNameException {
|
||||||
return (endpoint != null)
|
return (endpoint != null) ? new ObjectName(
|
||||||
? new ObjectName("boot:type=Endpoint,name=" + endpoint.getId())
|
"boot:type=Endpoint,name=" + endpoint.getEndpointId()) : null;
|
||||||
: null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ import java.util.Map;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.springframework.boot.actuate.endpoint.EndpointId;
|
||||||
import org.springframework.boot.actuate.endpoint.OperationType;
|
import org.springframework.boot.actuate.endpoint.OperationType;
|
||||||
import org.springframework.boot.actuate.endpoint.annotation.DiscoveredOperationMethod;
|
import org.springframework.boot.actuate.endpoint.annotation.DiscoveredOperationMethod;
|
||||||
import org.springframework.boot.actuate.endpoint.invoke.OperationInvoker;
|
import org.springframework.boot.actuate.endpoint.invoke.OperationInvoker;
|
||||||
|
@ -126,8 +127,8 @@ public class DiscoveredJmxOperationTests {
|
||||||
annotationAttributes.put("produces", "application/xml");
|
annotationAttributes.put("produces", "application/xml");
|
||||||
DiscoveredOperationMethod operationMethod = new DiscoveredOperationMethod(method,
|
DiscoveredOperationMethod operationMethod = new DiscoveredOperationMethod(method,
|
||||||
OperationType.READ, annotationAttributes);
|
OperationType.READ, annotationAttributes);
|
||||||
DiscoveredJmxOperation operation = new DiscoveredJmxOperation("test",
|
DiscoveredJmxOperation operation = new DiscoveredJmxOperation(
|
||||||
operationMethod, mock(OperationInvoker.class));
|
EndpointId.of("test"), operationMethod, mock(OperationInvoker.class));
|
||||||
return operation;
|
return operation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@ import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.rules.ExpectedException;
|
import org.junit.rules.ExpectedException;
|
||||||
|
|
||||||
|
import org.springframework.boot.actuate.endpoint.EndpointId;
|
||||||
import org.springframework.boot.actuate.endpoint.annotation.DeleteOperation;
|
import org.springframework.boot.actuate.endpoint.annotation.DeleteOperation;
|
||||||
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
|
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
|
||||||
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
|
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
|
||||||
|
@ -70,10 +71,10 @@ public class JmxEndpointDiscovererTests {
|
||||||
@Test
|
@Test
|
||||||
public void getEndpointsShouldDiscoverStandardEndpoints() {
|
public void getEndpointsShouldDiscoverStandardEndpoints() {
|
||||||
load(TestEndpoint.class, (discoverer) -> {
|
load(TestEndpoint.class, (discoverer) -> {
|
||||||
Map<String, ExposableJmxEndpoint> endpoints = discover(discoverer);
|
Map<EndpointId, ExposableJmxEndpoint> endpoints = discover(discoverer);
|
||||||
assertThat(endpoints).containsOnlyKeys("test");
|
assertThat(endpoints).containsOnlyKeys(EndpointId.of("test"));
|
||||||
Map<String, JmxOperation> operationByName = mapOperations(
|
Map<String, JmxOperation> operationByName = mapOperations(
|
||||||
endpoints.get("test").getOperations());
|
endpoints.get(EndpointId.of("test")).getOperations());
|
||||||
assertThat(operationByName).containsOnlyKeys("getAll", "getSomething",
|
assertThat(operationByName).containsOnlyKeys("getAll", "getSomething",
|
||||||
"update", "deleteSomething");
|
"update", "deleteSomething");
|
||||||
JmxOperation getAll = operationByName.get("getAll");
|
JmxOperation getAll = operationByName.get("getAll");
|
||||||
|
@ -106,8 +107,9 @@ public class JmxEndpointDiscovererTests {
|
||||||
@Test
|
@Test
|
||||||
public void getEndpointsWhenHasFilteredEndpointShouldOnlyDiscoverJmxEndpoints() {
|
public void getEndpointsWhenHasFilteredEndpointShouldOnlyDiscoverJmxEndpoints() {
|
||||||
load(MultipleEndpointsConfiguration.class, (discoverer) -> {
|
load(MultipleEndpointsConfiguration.class, (discoverer) -> {
|
||||||
Map<String, ExposableJmxEndpoint> endpoints = discover(discoverer);
|
Map<EndpointId, ExposableJmxEndpoint> endpoints = discover(discoverer);
|
||||||
assertThat(endpoints).containsOnlyKeys("test", "jmx");
|
assertThat(endpoints).containsOnlyKeys(EndpointId.of("test"),
|
||||||
|
EndpointId.of("jmx"));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,19 +127,19 @@ public class JmxEndpointDiscovererTests {
|
||||||
@Test
|
@Test
|
||||||
public void getEndpointsWhenHasJmxExtensionShouldOverrideStandardEndpoint() {
|
public void getEndpointsWhenHasJmxExtensionShouldOverrideStandardEndpoint() {
|
||||||
load(OverriddenOperationJmxEndpointConfiguration.class, (discoverer) -> {
|
load(OverriddenOperationJmxEndpointConfiguration.class, (discoverer) -> {
|
||||||
Map<String, ExposableJmxEndpoint> endpoints = discover(discoverer);
|
Map<EndpointId, ExposableJmxEndpoint> endpoints = discover(discoverer);
|
||||||
assertThat(endpoints).containsOnlyKeys("test");
|
assertThat(endpoints).containsOnlyKeys(EndpointId.of("test"));
|
||||||
assertJmxTestEndpoint(endpoints.get("test"));
|
assertJmxTestEndpoint(endpoints.get(EndpointId.of("test")));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getEndpointsWhenHasJmxExtensionWithNewOperationAddsExtraOperation() {
|
public void getEndpointsWhenHasJmxExtensionWithNewOperationAddsExtraOperation() {
|
||||||
load(AdditionalOperationJmxEndpointConfiguration.class, (discoverer) -> {
|
load(AdditionalOperationJmxEndpointConfiguration.class, (discoverer) -> {
|
||||||
Map<String, ExposableJmxEndpoint> endpoints = discover(discoverer);
|
Map<EndpointId, ExposableJmxEndpoint> endpoints = discover(discoverer);
|
||||||
assertThat(endpoints).containsOnlyKeys("test");
|
assertThat(endpoints).containsOnlyKeys(EndpointId.of("test"));
|
||||||
Map<String, JmxOperation> operationByName = mapOperations(
|
Map<String, JmxOperation> operationByName = mapOperations(
|
||||||
endpoints.get("test").getOperations());
|
endpoints.get(EndpointId.of("test")).getOperations());
|
||||||
assertThat(operationByName).containsOnlyKeys("getAll", "getSomething",
|
assertThat(operationByName).containsOnlyKeys("getAll", "getSomething",
|
||||||
"update", "deleteSomething", "getAnother");
|
"update", "deleteSomething", "getAnother");
|
||||||
JmxOperation getAnother = operationByName.get("getAnother");
|
JmxOperation getAnother = operationByName.get("getAnother");
|
||||||
|
@ -150,10 +152,10 @@ public class JmxEndpointDiscovererTests {
|
||||||
@Test
|
@Test
|
||||||
public void getEndpointsWhenHasCacheWithTtlShouldCacheReadOperationWithTtlValue() {
|
public void getEndpointsWhenHasCacheWithTtlShouldCacheReadOperationWithTtlValue() {
|
||||||
load(TestEndpoint.class, (id) -> 500L, (discoverer) -> {
|
load(TestEndpoint.class, (id) -> 500L, (discoverer) -> {
|
||||||
Map<String, ExposableJmxEndpoint> endpoints = discover(discoverer);
|
Map<EndpointId, ExposableJmxEndpoint> endpoints = discover(discoverer);
|
||||||
assertThat(endpoints).containsOnlyKeys("test");
|
assertThat(endpoints).containsOnlyKeys(EndpointId.of("test"));
|
||||||
Map<String, JmxOperation> operationByName = mapOperations(
|
Map<String, JmxOperation> operationByName = mapOperations(
|
||||||
endpoints.get("test").getOperations());
|
endpoints.get(EndpointId.of("test")).getOperations());
|
||||||
assertThat(operationByName).containsOnlyKeys("getAll", "getSomething",
|
assertThat(operationByName).containsOnlyKeys("getAll", "getSomething",
|
||||||
"update", "deleteSomething");
|
"update", "deleteSomething");
|
||||||
JmxOperation getAll = operationByName.get("getAll");
|
JmxOperation getAll = operationByName.get("getAll");
|
||||||
|
@ -167,10 +169,11 @@ public class JmxEndpointDiscovererTests {
|
||||||
public void getEndpointsShouldCacheReadOperations() {
|
public void getEndpointsShouldCacheReadOperations() {
|
||||||
load(AdditionalOperationJmxEndpointConfiguration.class, (id) -> 500L,
|
load(AdditionalOperationJmxEndpointConfiguration.class, (id) -> 500L,
|
||||||
(discoverer) -> {
|
(discoverer) -> {
|
||||||
Map<String, ExposableJmxEndpoint> endpoints = discover(discoverer);
|
Map<EndpointId, ExposableJmxEndpoint> endpoints = discover(
|
||||||
assertThat(endpoints).containsOnlyKeys("test");
|
discoverer);
|
||||||
|
assertThat(endpoints).containsOnlyKeys(EndpointId.of("test"));
|
||||||
Map<String, JmxOperation> operationByName = mapOperations(
|
Map<String, JmxOperation> operationByName = mapOperations(
|
||||||
endpoints.get("test").getOperations());
|
endpoints.get(EndpointId.of("test")).getOperations());
|
||||||
assertThat(operationByName).containsOnlyKeys("getAll", "getSomething",
|
assertThat(operationByName).containsOnlyKeys("getAll", "getSomething",
|
||||||
"update", "deleteSomething", "getAnother");
|
"update", "deleteSomething", "getAnother");
|
||||||
JmxOperation getAll = operationByName.get("getAll");
|
JmxOperation getAll = operationByName.get("getAll");
|
||||||
|
@ -285,10 +288,11 @@ public class JmxEndpointDiscovererTests {
|
||||||
assertThat(parameter.getType()).isEqualTo(type);
|
assertThat(parameter.getType()).isEqualTo(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<String, ExposableJmxEndpoint> discover(JmxEndpointDiscoverer discoverer) {
|
private Map<EndpointId, ExposableJmxEndpoint> discover(
|
||||||
Map<String, ExposableJmxEndpoint> byId = new HashMap<>();
|
JmxEndpointDiscoverer discoverer) {
|
||||||
|
Map<EndpointId, ExposableJmxEndpoint> byId = new HashMap<>();
|
||||||
discoverer.getEndpoints()
|
discoverer.getEndpoints()
|
||||||
.forEach((endpoint) -> byId.put(endpoint.getId(), endpoint));
|
.forEach((endpoint) -> byId.put(endpoint.getEndpointId(), endpoint));
|
||||||
return byId;
|
return byId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -302,7 +306,7 @@ public class JmxEndpointDiscovererTests {
|
||||||
load(configuration, (id) -> null, consumer);
|
load(configuration, (id) -> null, consumer);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void load(Class<?> configuration, Function<String, Long> timeToLive,
|
private void load(Class<?> configuration, Function<EndpointId, Long> timeToLive,
|
||||||
Consumer<JmxEndpointDiscoverer> consumer) {
|
Consumer<JmxEndpointDiscoverer> consumer) {
|
||||||
try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
|
try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
|
||||||
configuration)) {
|
configuration)) {
|
||||||
|
|
|
@ -24,6 +24,7 @@ import java.util.Map;
|
||||||
import org.assertj.core.api.Condition;
|
import org.assertj.core.api.Condition;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.springframework.boot.actuate.endpoint.EndpointId;
|
||||||
import org.springframework.boot.actuate.endpoint.OperationType;
|
import org.springframework.boot.actuate.endpoint.OperationType;
|
||||||
import org.springframework.boot.actuate.endpoint.web.annotation.ExposableControllerEndpoint;
|
import org.springframework.boot.actuate.endpoint.web.annotation.ExposableControllerEndpoint;
|
||||||
|
|
||||||
|
@ -62,7 +63,7 @@ public class EndpointLinksResolverTests {
|
||||||
operations.add(operationWithPath("/alpha", "alpha"));
|
operations.add(operationWithPath("/alpha", "alpha"));
|
||||||
operations.add(operationWithPath("/alpha/{name}", "alpha-name"));
|
operations.add(operationWithPath("/alpha/{name}", "alpha-name"));
|
||||||
ExposableWebEndpoint endpoint = mock(ExposableWebEndpoint.class);
|
ExposableWebEndpoint endpoint = mock(ExposableWebEndpoint.class);
|
||||||
given(endpoint.getId()).willReturn("alpha");
|
given(endpoint.getEndpointId()).willReturn(EndpointId.of("alpha"));
|
||||||
given(endpoint.isEnableByDefault()).willReturn(true);
|
given(endpoint.isEnableByDefault()).willReturn(true);
|
||||||
given(endpoint.getOperations()).willReturn(operations);
|
given(endpoint.getOperations()).willReturn(operations);
|
||||||
String requestUrl = "https://api.example.com/actuator";
|
String requestUrl = "https://api.example.com/actuator";
|
||||||
|
@ -80,7 +81,7 @@ public class EndpointLinksResolverTests {
|
||||||
@Test
|
@Test
|
||||||
public void resolvedLinksContainsALinkForServletEndpoint() {
|
public void resolvedLinksContainsALinkForServletEndpoint() {
|
||||||
ExposableServletEndpoint servletEndpoint = mock(ExposableServletEndpoint.class);
|
ExposableServletEndpoint servletEndpoint = mock(ExposableServletEndpoint.class);
|
||||||
given(servletEndpoint.getId()).willReturn("alpha");
|
given(servletEndpoint.getEndpointId()).willReturn(EndpointId.of("alpha"));
|
||||||
given(servletEndpoint.isEnableByDefault()).willReturn(true);
|
given(servletEndpoint.isEnableByDefault()).willReturn(true);
|
||||||
given(servletEndpoint.getRootPath()).willReturn("alpha");
|
given(servletEndpoint.getRootPath()).willReturn("alpha");
|
||||||
String requestUrl = "https://api.example.com/actuator";
|
String requestUrl = "https://api.example.com/actuator";
|
||||||
|
@ -97,7 +98,7 @@ public class EndpointLinksResolverTests {
|
||||||
public void resolvedLinksContainsALinkForControllerEndpoint() {
|
public void resolvedLinksContainsALinkForControllerEndpoint() {
|
||||||
ExposableControllerEndpoint controllerEndpoint = mock(
|
ExposableControllerEndpoint controllerEndpoint = mock(
|
||||||
ExposableControllerEndpoint.class);
|
ExposableControllerEndpoint.class);
|
||||||
given(controllerEndpoint.getId()).willReturn("alpha");
|
given(controllerEndpoint.getEndpointId()).willReturn(EndpointId.of("alpha"));
|
||||||
given(controllerEndpoint.isEnableByDefault()).willReturn(true);
|
given(controllerEndpoint.isEnableByDefault()).willReturn(true);
|
||||||
given(controllerEndpoint.getRootPath()).willReturn("alpha");
|
given(controllerEndpoint.getRootPath()).willReturn("alpha");
|
||||||
String requestUrl = "https://api.example.com/actuator";
|
String requestUrl = "https://api.example.com/actuator";
|
||||||
|
|
|
@ -24,6 +24,7 @@ import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.rules.ExpectedException;
|
import org.junit.rules.ExpectedException;
|
||||||
|
|
||||||
|
import org.springframework.boot.actuate.endpoint.EndpointId;
|
||||||
import org.springframework.boot.actuate.endpoint.EndpointsSupplier;
|
import org.springframework.boot.actuate.endpoint.EndpointsSupplier;
|
||||||
import org.springframework.boot.actuate.endpoint.ExposableEndpoint;
|
import org.springframework.boot.actuate.endpoint.ExposableEndpoint;
|
||||||
import org.springframework.boot.actuate.endpoint.Operation;
|
import org.springframework.boot.actuate.endpoint.Operation;
|
||||||
|
@ -60,38 +61,41 @@ public class PathMappedEndpointsTests {
|
||||||
public void iteratorShouldReturnPathMappedEndpoints() {
|
public void iteratorShouldReturnPathMappedEndpoints() {
|
||||||
PathMappedEndpoints mapped = createTestMapped(null);
|
PathMappedEndpoints mapped = createTestMapped(null);
|
||||||
assertThat(mapped).hasSize(2);
|
assertThat(mapped).hasSize(2);
|
||||||
assertThat(mapped).extracting("id").containsExactly("e2", "e3");
|
assertThat(mapped).extracting("endpointId").containsExactly(EndpointId.of("e2"),
|
||||||
|
EndpointId.of("e3"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void streamShouldReturnPathMappedEndpoints() {
|
public void streamShouldReturnPathMappedEndpoints() {
|
||||||
PathMappedEndpoints mapped = createTestMapped(null);
|
PathMappedEndpoints mapped = createTestMapped(null);
|
||||||
assertThat(mapped.stream()).hasSize(2);
|
assertThat(mapped.stream()).hasSize(2);
|
||||||
assertThat(mapped.stream()).extracting("id").containsExactly("e2", "e3");
|
assertThat(mapped.stream()).extracting("endpointId")
|
||||||
|
.containsExactly(EndpointId.of("e2"), EndpointId.of("e3"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getRootPathWhenContainsIdShouldReturnRootPath() {
|
public void getRootPathWhenContainsIdShouldReturnRootPath() {
|
||||||
PathMappedEndpoints mapped = createTestMapped(null);
|
PathMappedEndpoints mapped = createTestMapped(null);
|
||||||
assertThat(mapped.getRootPath("e2")).isEqualTo("p2");
|
assertThat(mapped.getRootPath(EndpointId.of("e2"))).isEqualTo("p2");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getRootPathWhenMissingIdShouldReturnNull() {
|
public void getRootPathWhenMissingIdShouldReturnNull() {
|
||||||
PathMappedEndpoints mapped = createTestMapped(null);
|
PathMappedEndpoints mapped = createTestMapped(null);
|
||||||
assertThat(mapped.getRootPath("xx")).isNull();
|
assertThat(mapped.getRootPath(EndpointId.of("xx"))).isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getPathWhenContainsIdShouldReturnRootPath() {
|
public void getPathWhenContainsIdShouldReturnRootPath() {
|
||||||
assertThat(createTestMapped(null).getPath("e2")).isEqualTo("/p2");
|
assertThat(createTestMapped(null).getPath(EndpointId.of("e2"))).isEqualTo("/p2");
|
||||||
assertThat(createTestMapped("/x").getPath("e2")).isEqualTo("/x/p2");
|
assertThat(createTestMapped("/x").getPath(EndpointId.of("e2")))
|
||||||
|
.isEqualTo("/x/p2");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getPathWhenMissingIdShouldReturnNull() {
|
public void getPathWhenMissingIdShouldReturnNull() {
|
||||||
PathMappedEndpoints mapped = createTestMapped(null);
|
PathMappedEndpoints mapped = createTestMapped(null);
|
||||||
assertThat(mapped.getRootPath("xx")).isNull();
|
assertThat(mapped.getPath(EndpointId.of("xx"))).isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -110,34 +114,34 @@ public class PathMappedEndpointsTests {
|
||||||
@Test
|
@Test
|
||||||
public void getEndpointWhenContainsIdShouldReturnPathMappedEndpoint() {
|
public void getEndpointWhenContainsIdShouldReturnPathMappedEndpoint() {
|
||||||
PathMappedEndpoints mapped = createTestMapped(null);
|
PathMappedEndpoints mapped = createTestMapped(null);
|
||||||
assertThat(mapped.getEndpoint("e2").getRootPath()).isEqualTo("p2");
|
assertThat(mapped.getEndpoint(EndpointId.of("e2")).getRootPath()).isEqualTo("p2");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getEndpointWhenMissingIdShouldReturnNull() {
|
public void getEndpointWhenMissingIdShouldReturnNull() {
|
||||||
PathMappedEndpoints mapped = createTestMapped(null);
|
PathMappedEndpoints mapped = createTestMapped(null);
|
||||||
assertThat(mapped.getEndpoint("xx")).isNull();
|
assertThat(mapped.getEndpoint(EndpointId.of("xx"))).isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
private PathMappedEndpoints createTestMapped(String basePath) {
|
private PathMappedEndpoints createTestMapped(String basePath) {
|
||||||
List<ExposableEndpoint<?>> endpoints = new ArrayList<>();
|
List<ExposableEndpoint<?>> endpoints = new ArrayList<>();
|
||||||
endpoints.add(mockEndpoint("e1"));
|
endpoints.add(mockEndpoint(EndpointId.of("e1")));
|
||||||
endpoints.add(mockEndpoint("e2", "p2"));
|
endpoints.add(mockEndpoint(EndpointId.of("e2"), "p2"));
|
||||||
endpoints.add(mockEndpoint("e3", "p3"));
|
endpoints.add(mockEndpoint(EndpointId.of("e3"), "p3"));
|
||||||
endpoints.add(mockEndpoint("e4"));
|
endpoints.add(mockEndpoint(EndpointId.of("e4")));
|
||||||
return new PathMappedEndpoints(basePath, () -> endpoints);
|
return new PathMappedEndpoints(basePath, () -> endpoints);
|
||||||
}
|
}
|
||||||
|
|
||||||
private TestPathMappedEndpoint mockEndpoint(String id, String rootPath) {
|
private TestPathMappedEndpoint mockEndpoint(EndpointId id, String rootPath) {
|
||||||
TestPathMappedEndpoint endpoint = mock(TestPathMappedEndpoint.class);
|
TestPathMappedEndpoint endpoint = mock(TestPathMappedEndpoint.class);
|
||||||
given(endpoint.getId()).willReturn(id);
|
given(endpoint.getEndpointId()).willReturn(id);
|
||||||
given(endpoint.getRootPath()).willReturn(rootPath);
|
given(endpoint.getRootPath()).willReturn(rootPath);
|
||||||
return endpoint;
|
return endpoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
private TestEndpoint mockEndpoint(String id) {
|
private TestEndpoint mockEndpoint(EndpointId id) {
|
||||||
TestEndpoint endpoint = mock(TestEndpoint.class);
|
TestEndpoint endpoint = mock(TestEndpoint.class);
|
||||||
given(endpoint.getId()).willReturn(id);
|
given(endpoint.getEndpointId()).willReturn(id);
|
||||||
return endpoint;
|
return endpoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,8 @@ import org.mockito.Captor;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
|
|
||||||
|
import org.springframework.boot.actuate.endpoint.EndpointId;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.ArgumentMatchers.eq;
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
|
@ -124,7 +126,7 @@ public class ServletEndpointRegistrarTests {
|
||||||
|
|
||||||
private ExposableServletEndpoint mockEndpoint(EndpointServlet endpointServlet) {
|
private ExposableServletEndpoint mockEndpoint(EndpointServlet endpointServlet) {
|
||||||
ExposableServletEndpoint endpoint = mock(ExposableServletEndpoint.class);
|
ExposableServletEndpoint endpoint = mock(ExposableServletEndpoint.class);
|
||||||
given(endpoint.getId()).willReturn("test");
|
given(endpoint.getEndpointId()).willReturn(EndpointId.of("test"));
|
||||||
given(endpoint.getEndpointServlet()).willReturn(endpointServlet);
|
given(endpoint.getEndpointServlet()).willReturn(endpointServlet);
|
||||||
given(endpoint.getRootPath()).willReturn("test");
|
given(endpoint.getRootPath()).willReturn("test");
|
||||||
return endpoint;
|
return endpoint;
|
||||||
|
|
|
@ -26,6 +26,7 @@ import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.rules.ExpectedException;
|
import org.junit.rules.ExpectedException;
|
||||||
|
|
||||||
|
import org.springframework.boot.actuate.endpoint.EndpointId;
|
||||||
import org.springframework.boot.actuate.endpoint.ExposableEndpoint;
|
import org.springframework.boot.actuate.endpoint.ExposableEndpoint;
|
||||||
import org.springframework.boot.actuate.endpoint.annotation.DiscoveredEndpoint;
|
import org.springframework.boot.actuate.endpoint.annotation.DiscoveredEndpoint;
|
||||||
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
|
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
|
||||||
|
@ -70,7 +71,8 @@ public class ControllerEndpointDiscovererTests {
|
||||||
.getEndpoints();
|
.getEndpoints();
|
||||||
assertThat(endpoints).hasSize(1);
|
assertThat(endpoints).hasSize(1);
|
||||||
ExposableControllerEndpoint endpoint = endpoints.iterator().next();
|
ExposableControllerEndpoint endpoint = endpoints.iterator().next();
|
||||||
assertThat(endpoint.getId()).isEqualTo("testcontroller");
|
assertThat(endpoint.getEndpointId())
|
||||||
|
.isEqualTo(EndpointId.of("testcontroller"));
|
||||||
assertThat(endpoint.getController())
|
assertThat(endpoint.getController())
|
||||||
.isInstanceOf(TestControllerEndpoint.class);
|
.isInstanceOf(TestControllerEndpoint.class);
|
||||||
assertThat(endpoint).isInstanceOf(DiscoveredEndpoint.class);
|
assertThat(endpoint).isInstanceOf(DiscoveredEndpoint.class);
|
||||||
|
@ -87,7 +89,8 @@ public class ControllerEndpointDiscovererTests {
|
||||||
.getEndpoints();
|
.getEndpoints();
|
||||||
assertThat(endpoints).hasSize(1);
|
assertThat(endpoints).hasSize(1);
|
||||||
ExposableControllerEndpoint endpoint = endpoints.iterator().next();
|
ExposableControllerEndpoint endpoint = endpoints.iterator().next();
|
||||||
assertThat(endpoint.getId()).isEqualTo("testcontroller");
|
assertThat(endpoint.getEndpointId())
|
||||||
|
.isEqualTo(EndpointId.of("testcontroller"));
|
||||||
assertThat(endpoint.getController())
|
assertThat(endpoint.getController())
|
||||||
.isInstanceOf(TestProxyControllerEndpoint.class);
|
.isInstanceOf(TestProxyControllerEndpoint.class);
|
||||||
assertThat(endpoint).isInstanceOf(DiscoveredEndpoint.class);
|
assertThat(endpoint).isInstanceOf(DiscoveredEndpoint.class);
|
||||||
|
@ -102,7 +105,8 @@ public class ControllerEndpointDiscovererTests {
|
||||||
.getEndpoints();
|
.getEndpoints();
|
||||||
assertThat(endpoints).hasSize(1);
|
assertThat(endpoints).hasSize(1);
|
||||||
ExposableControllerEndpoint endpoint = endpoints.iterator().next();
|
ExposableControllerEndpoint endpoint = endpoints.iterator().next();
|
||||||
assertThat(endpoint.getId()).isEqualTo("testrestcontroller");
|
assertThat(endpoint.getEndpointId())
|
||||||
|
.isEqualTo(EndpointId.of("testrestcontroller"));
|
||||||
assertThat(endpoint.getController())
|
assertThat(endpoint.getController())
|
||||||
.isInstanceOf(TestRestControllerEndpoint.class);
|
.isInstanceOf(TestRestControllerEndpoint.class);
|
||||||
}));
|
}));
|
||||||
|
@ -118,7 +122,8 @@ public class ControllerEndpointDiscovererTests {
|
||||||
.getEndpoints();
|
.getEndpoints();
|
||||||
assertThat(endpoints).hasSize(1);
|
assertThat(endpoints).hasSize(1);
|
||||||
ExposableControllerEndpoint endpoint = endpoints.iterator().next();
|
ExposableControllerEndpoint endpoint = endpoints.iterator().next();
|
||||||
assertThat(endpoint.getId()).isEqualTo("testrestcontroller");
|
assertThat(endpoint.getEndpointId())
|
||||||
|
.isEqualTo(EndpointId.of("testrestcontroller"));
|
||||||
assertThat(endpoint.getController())
|
assertThat(endpoint.getController())
|
||||||
.isInstanceOf(TestProxyRestControllerEndpoint.class);
|
.isInstanceOf(TestProxyRestControllerEndpoint.class);
|
||||||
assertThat(endpoint).isInstanceOf(DiscoveredEndpoint.class);
|
assertThat(endpoint).isInstanceOf(DiscoveredEndpoint.class);
|
||||||
|
@ -131,9 +136,11 @@ public class ControllerEndpointDiscovererTests {
|
||||||
.run(assertDiscoverer((discoverer) -> {
|
.run(assertDiscoverer((discoverer) -> {
|
||||||
Collection<ExposableControllerEndpoint> endpoints = discoverer
|
Collection<ExposableControllerEndpoint> endpoints = discoverer
|
||||||
.getEndpoints();
|
.getEndpoints();
|
||||||
List<String> ids = endpoints.stream().map(ExposableEndpoint::getId)
|
List<EndpointId> ids = endpoints.stream()
|
||||||
|
.map(ExposableEndpoint::getEndpointId)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
assertThat(ids).containsOnly("testcontroller", "testrestcontroller");
|
assertThat(ids).containsOnly(EndpointId.of("testcontroller"),
|
||||||
|
EndpointId.of("testrestcontroller"));
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,7 @@ import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.rules.ExpectedException;
|
import org.junit.rules.ExpectedException;
|
||||||
|
|
||||||
|
import org.springframework.boot.actuate.endpoint.EndpointId;
|
||||||
import org.springframework.boot.actuate.endpoint.ExposableEndpoint;
|
import org.springframework.boot.actuate.endpoint.ExposableEndpoint;
|
||||||
import org.springframework.boot.actuate.endpoint.annotation.DiscoveredEndpoint;
|
import org.springframework.boot.actuate.endpoint.annotation.DiscoveredEndpoint;
|
||||||
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
|
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
|
||||||
|
@ -79,7 +80,8 @@ public class ServletEndpointDiscovererTests {
|
||||||
.getEndpoints();
|
.getEndpoints();
|
||||||
assertThat(endpoints).hasSize(1);
|
assertThat(endpoints).hasSize(1);
|
||||||
ExposableServletEndpoint endpoint = endpoints.iterator().next();
|
ExposableServletEndpoint endpoint = endpoints.iterator().next();
|
||||||
assertThat(endpoint.getId()).isEqualTo("testservlet");
|
assertThat(endpoint.getEndpointId())
|
||||||
|
.isEqualTo(EndpointId.of("testservlet"));
|
||||||
assertThat(endpoint.getEndpointServlet()).isNotNull();
|
assertThat(endpoint.getEndpointServlet()).isNotNull();
|
||||||
assertThat(endpoint).isInstanceOf(DiscoveredEndpoint.class);
|
assertThat(endpoint).isInstanceOf(DiscoveredEndpoint.class);
|
||||||
}));
|
}));
|
||||||
|
@ -95,7 +97,8 @@ public class ServletEndpointDiscovererTests {
|
||||||
.getEndpoints();
|
.getEndpoints();
|
||||||
assertThat(endpoints).hasSize(1);
|
assertThat(endpoints).hasSize(1);
|
||||||
ExposableServletEndpoint endpoint = endpoints.iterator().next();
|
ExposableServletEndpoint endpoint = endpoints.iterator().next();
|
||||||
assertThat(endpoint.getId()).isEqualTo("testservlet");
|
assertThat(endpoint.getEndpointId())
|
||||||
|
.isEqualTo(EndpointId.of("testservlet"));
|
||||||
assertThat(endpoint.getEndpointServlet()).isNotNull();
|
assertThat(endpoint.getEndpointServlet()).isNotNull();
|
||||||
assertThat(endpoint).isInstanceOf(DiscoveredEndpoint.class);
|
assertThat(endpoint).isInstanceOf(DiscoveredEndpoint.class);
|
||||||
}));
|
}));
|
||||||
|
@ -107,9 +110,10 @@ public class ServletEndpointDiscovererTests {
|
||||||
.run(assertDiscoverer((discoverer) -> {
|
.run(assertDiscoverer((discoverer) -> {
|
||||||
Collection<ExposableServletEndpoint> endpoints = discoverer
|
Collection<ExposableServletEndpoint> endpoints = discoverer
|
||||||
.getEndpoints();
|
.getEndpoints();
|
||||||
List<String> ids = endpoints.stream().map(ExposableEndpoint::getId)
|
List<EndpointId> ids = endpoints.stream()
|
||||||
|
.map(ExposableEndpoint::getEndpointId)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
assertThat(ids).containsOnly("testservlet");
|
assertThat(ids).containsOnly(EndpointId.of("testservlet"));
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,7 @@ import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.rules.ExpectedException;
|
import org.junit.rules.ExpectedException;
|
||||||
|
|
||||||
|
import org.springframework.boot.actuate.endpoint.EndpointId;
|
||||||
import org.springframework.boot.actuate.endpoint.annotation.DeleteOperation;
|
import org.springframework.boot.actuate.endpoint.annotation.DeleteOperation;
|
||||||
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
|
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
|
||||||
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
|
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
|
||||||
|
@ -91,19 +92,19 @@ public class WebEndpointDiscovererTests {
|
||||||
@Test
|
@Test
|
||||||
public void getEndpointsWhenHasFilteredEndpointShouldOnlyDiscoverWebEndpoints() {
|
public void getEndpointsWhenHasFilteredEndpointShouldOnlyDiscoverWebEndpoints() {
|
||||||
load(MultipleEndpointsConfiguration.class, (discoverer) -> {
|
load(MultipleEndpointsConfiguration.class, (discoverer) -> {
|
||||||
Map<String, ExposableWebEndpoint> endpoints = mapEndpoints(
|
Map<EndpointId, ExposableWebEndpoint> endpoints = mapEndpoints(
|
||||||
discoverer.getEndpoints());
|
discoverer.getEndpoints());
|
||||||
assertThat(endpoints).containsOnlyKeys("test");
|
assertThat(endpoints).containsOnlyKeys(EndpointId.of("test"));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getEndpointsWhenHasWebExtensionShouldOverrideStandardEndpoint() {
|
public void getEndpointsWhenHasWebExtensionShouldOverrideStandardEndpoint() {
|
||||||
load(OverriddenOperationWebEndpointExtensionConfiguration.class, (discoverer) -> {
|
load(OverriddenOperationWebEndpointExtensionConfiguration.class, (discoverer) -> {
|
||||||
Map<String, ExposableWebEndpoint> endpoints = mapEndpoints(
|
Map<EndpointId, ExposableWebEndpoint> endpoints = mapEndpoints(
|
||||||
discoverer.getEndpoints());
|
discoverer.getEndpoints());
|
||||||
assertThat(endpoints).containsOnlyKeys("test");
|
assertThat(endpoints).containsOnlyKeys(EndpointId.of("test"));
|
||||||
ExposableWebEndpoint endpoint = endpoints.get("test");
|
ExposableWebEndpoint endpoint = endpoints.get(EndpointId.of("test"));
|
||||||
assertThat(requestPredicates(endpoint)).has(
|
assertThat(requestPredicates(endpoint)).has(
|
||||||
requestPredicates(path("test").httpMethod(WebEndpointHttpMethod.GET)
|
requestPredicates(path("test").httpMethod(WebEndpointHttpMethod.GET)
|
||||||
.consumes().produces("application/json")));
|
.consumes().produces("application/json")));
|
||||||
|
@ -113,10 +114,10 @@ public class WebEndpointDiscovererTests {
|
||||||
@Test
|
@Test
|
||||||
public void getEndpointsWhenExtensionAddsOperationShouldHaveBothOperations() {
|
public void getEndpointsWhenExtensionAddsOperationShouldHaveBothOperations() {
|
||||||
load(AdditionalOperationWebEndpointConfiguration.class, (discoverer) -> {
|
load(AdditionalOperationWebEndpointConfiguration.class, (discoverer) -> {
|
||||||
Map<String, ExposableWebEndpoint> endpoints = mapEndpoints(
|
Map<EndpointId, ExposableWebEndpoint> endpoints = mapEndpoints(
|
||||||
discoverer.getEndpoints());
|
discoverer.getEndpoints());
|
||||||
assertThat(endpoints).containsOnlyKeys("test");
|
assertThat(endpoints).containsOnlyKeys(EndpointId.of("test"));
|
||||||
ExposableWebEndpoint endpoint = endpoints.get("test");
|
ExposableWebEndpoint endpoint = endpoints.get(EndpointId.of("test"));
|
||||||
assertThat(requestPredicates(endpoint)).has(requestPredicates(
|
assertThat(requestPredicates(endpoint)).has(requestPredicates(
|
||||||
path("test").httpMethod(WebEndpointHttpMethod.GET).consumes()
|
path("test").httpMethod(WebEndpointHttpMethod.GET).consumes()
|
||||||
.produces("application/json"),
|
.produces("application/json"),
|
||||||
|
@ -128,10 +129,10 @@ public class WebEndpointDiscovererTests {
|
||||||
@Test
|
@Test
|
||||||
public void getEndpointsWhenPredicateForWriteOperationThatReturnsVoidShouldHaveNoProducedMediaTypes() {
|
public void getEndpointsWhenPredicateForWriteOperationThatReturnsVoidShouldHaveNoProducedMediaTypes() {
|
||||||
load(VoidWriteOperationEndpointConfiguration.class, (discoverer) -> {
|
load(VoidWriteOperationEndpointConfiguration.class, (discoverer) -> {
|
||||||
Map<String, ExposableWebEndpoint> endpoints = mapEndpoints(
|
Map<EndpointId, ExposableWebEndpoint> endpoints = mapEndpoints(
|
||||||
discoverer.getEndpoints());
|
discoverer.getEndpoints());
|
||||||
assertThat(endpoints).containsOnlyKeys("voidwrite");
|
assertThat(endpoints).containsOnlyKeys(EndpointId.of("voidwrite"));
|
||||||
ExposableWebEndpoint endpoint = endpoints.get("voidwrite");
|
ExposableWebEndpoint endpoint = endpoints.get(EndpointId.of("voidwrite"));
|
||||||
assertThat(requestPredicates(endpoint)).has(requestPredicates(
|
assertThat(requestPredicates(endpoint)).has(requestPredicates(
|
||||||
path("voidwrite").httpMethod(WebEndpointHttpMethod.POST).produces()
|
path("voidwrite").httpMethod(WebEndpointHttpMethod.POST).produces()
|
||||||
.consumes("application/json")));
|
.consumes("application/json")));
|
||||||
|
@ -191,10 +192,10 @@ public class WebEndpointDiscovererTests {
|
||||||
@Test
|
@Test
|
||||||
public void getEndpointsWhenHasCacheWithTtlShouldCacheReadOperationWithTtlValue() {
|
public void getEndpointsWhenHasCacheWithTtlShouldCacheReadOperationWithTtlValue() {
|
||||||
load((id) -> 500L, (id) -> id, TestEndpointConfiguration.class, (discoverer) -> {
|
load((id) -> 500L, (id) -> id, TestEndpointConfiguration.class, (discoverer) -> {
|
||||||
Map<String, ExposableWebEndpoint> endpoints = mapEndpoints(
|
Map<EndpointId, ExposableWebEndpoint> endpoints = mapEndpoints(
|
||||||
discoverer.getEndpoints());
|
discoverer.getEndpoints());
|
||||||
assertThat(endpoints).containsOnlyKeys("test");
|
assertThat(endpoints).containsOnlyKeys(EndpointId.of("test"));
|
||||||
ExposableWebEndpoint endpoint = endpoints.get("test");
|
ExposableWebEndpoint endpoint = endpoints.get(EndpointId.of("test"));
|
||||||
assertThat(endpoint.getOperations()).hasSize(1);
|
assertThat(endpoint.getOperations()).hasSize(1);
|
||||||
WebOperation operation = endpoint.getOperations().iterator().next();
|
WebOperation operation = endpoint.getOperations().iterator().next();
|
||||||
Object invoker = ReflectionTestUtils.getField(operation, "invoker");
|
Object invoker = ReflectionTestUtils.getField(operation, "invoker");
|
||||||
|
@ -207,10 +208,10 @@ public class WebEndpointDiscovererTests {
|
||||||
@Test
|
@Test
|
||||||
public void getEndpointsWhenOperationReturnsResourceShouldProduceApplicationOctetStream() {
|
public void getEndpointsWhenOperationReturnsResourceShouldProduceApplicationOctetStream() {
|
||||||
load(ResourceEndpointConfiguration.class, (discoverer) -> {
|
load(ResourceEndpointConfiguration.class, (discoverer) -> {
|
||||||
Map<String, ExposableWebEndpoint> endpoints = mapEndpoints(
|
Map<EndpointId, ExposableWebEndpoint> endpoints = mapEndpoints(
|
||||||
discoverer.getEndpoints());
|
discoverer.getEndpoints());
|
||||||
assertThat(endpoints).containsOnlyKeys("resource");
|
assertThat(endpoints).containsOnlyKeys(EndpointId.of("resource"));
|
||||||
ExposableWebEndpoint endpoint = endpoints.get("resource");
|
ExposableWebEndpoint endpoint = endpoints.get(EndpointId.of("resource"));
|
||||||
assertThat(requestPredicates(endpoint)).has(requestPredicates(
|
assertThat(requestPredicates(endpoint)).has(requestPredicates(
|
||||||
path("resource").httpMethod(WebEndpointHttpMethod.GET).consumes()
|
path("resource").httpMethod(WebEndpointHttpMethod.GET).consumes()
|
||||||
.produces("application/octet-stream")));
|
.produces("application/octet-stream")));
|
||||||
|
@ -220,10 +221,11 @@ public class WebEndpointDiscovererTests {
|
||||||
@Test
|
@Test
|
||||||
public void getEndpointsWhenHasCustomMediaTypeShouldProduceCustomMediaType() {
|
public void getEndpointsWhenHasCustomMediaTypeShouldProduceCustomMediaType() {
|
||||||
load(CustomMediaTypesEndpointConfiguration.class, (discoverer) -> {
|
load(CustomMediaTypesEndpointConfiguration.class, (discoverer) -> {
|
||||||
Map<String, ExposableWebEndpoint> endpoints = mapEndpoints(
|
Map<EndpointId, ExposableWebEndpoint> endpoints = mapEndpoints(
|
||||||
discoverer.getEndpoints());
|
discoverer.getEndpoints());
|
||||||
assertThat(endpoints).containsOnlyKeys("custommediatypes");
|
assertThat(endpoints).containsOnlyKeys(EndpointId.of("custommediatypes"));
|
||||||
ExposableWebEndpoint endpoint = endpoints.get("custommediatypes");
|
ExposableWebEndpoint endpoint = endpoints
|
||||||
|
.get(EndpointId.of("custommediatypes"));
|
||||||
assertThat(requestPredicates(endpoint)).has(requestPredicates(
|
assertThat(requestPredicates(endpoint)).has(requestPredicates(
|
||||||
path("custommediatypes").httpMethod(WebEndpointHttpMethod.GET)
|
path("custommediatypes").httpMethod(WebEndpointHttpMethod.GET)
|
||||||
.consumes().produces("text/plain"),
|
.consumes().produces("text/plain"),
|
||||||
|
@ -238,10 +240,10 @@ public class WebEndpointDiscovererTests {
|
||||||
public void getEndpointsWhenHasCustomPathShouldReturnCustomPath() {
|
public void getEndpointsWhenHasCustomPathShouldReturnCustomPath() {
|
||||||
load((id) -> null, (id) -> "custom/" + id,
|
load((id) -> null, (id) -> "custom/" + id,
|
||||||
AdditionalOperationWebEndpointConfiguration.class, (discoverer) -> {
|
AdditionalOperationWebEndpointConfiguration.class, (discoverer) -> {
|
||||||
Map<String, ExposableWebEndpoint> endpoints = mapEndpoints(
|
Map<EndpointId, ExposableWebEndpoint> endpoints = mapEndpoints(
|
||||||
discoverer.getEndpoints());
|
discoverer.getEndpoints());
|
||||||
assertThat(endpoints).containsOnlyKeys("test");
|
assertThat(endpoints).containsOnlyKeys(EndpointId.of("test"));
|
||||||
ExposableWebEndpoint endpoint = endpoints.get("test");
|
ExposableWebEndpoint endpoint = endpoints.get(EndpointId.of("test"));
|
||||||
Condition<List<? extends WebOperationRequestPredicate>> expected = requestPredicates(
|
Condition<List<? extends WebOperationRequestPredicate>> expected = requestPredicates(
|
||||||
path("custom/test").httpMethod(WebEndpointHttpMethod.GET)
|
path("custom/test").httpMethod(WebEndpointHttpMethod.GET)
|
||||||
.consumes().produces("application/json"),
|
.consumes().produces("application/json"),
|
||||||
|
@ -255,8 +257,9 @@ public class WebEndpointDiscovererTests {
|
||||||
this.load((id) -> null, (id) -> id, configuration, consumer);
|
this.load((id) -> null, (id) -> id, configuration, consumer);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void load(Function<String, Long> timeToLive, PathMapper endpointPathMapper,
|
private void load(Function<EndpointId, Long> timeToLive,
|
||||||
Class<?> configuration, Consumer<WebEndpointDiscoverer> consumer) {
|
PathMapper endpointPathMapper, Class<?> configuration,
|
||||||
|
Consumer<WebEndpointDiscoverer> consumer) {
|
||||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
|
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
|
||||||
configuration);
|
configuration);
|
||||||
try {
|
try {
|
||||||
|
@ -276,10 +279,11 @@ public class WebEndpointDiscovererTests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<String, ExposableWebEndpoint> mapEndpoints(
|
private Map<EndpointId, ExposableWebEndpoint> mapEndpoints(
|
||||||
Collection<ExposableWebEndpoint> endpoints) {
|
Collection<ExposableWebEndpoint> endpoints) {
|
||||||
Map<String, ExposableWebEndpoint> endpointById = new HashMap<>();
|
Map<EndpointId, ExposableWebEndpoint> endpointById = new HashMap<>();
|
||||||
endpoints.forEach((endpoint) -> endpointById.put(endpoint.getId(), endpoint));
|
endpoints.forEach(
|
||||||
|
(endpoint) -> endpointById.put(endpoint.getEndpointId(), endpoint));
|
||||||
return endpointById;
|
return endpointById;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@ import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.rules.ExpectedException;
|
import org.junit.rules.ExpectedException;
|
||||||
|
|
||||||
|
import org.springframework.boot.actuate.endpoint.EndpointId;
|
||||||
import org.springframework.boot.actuate.endpoint.web.EndpointMapping;
|
import org.springframework.boot.actuate.endpoint.web.EndpointMapping;
|
||||||
import org.springframework.boot.actuate.endpoint.web.annotation.ControllerEndpoint;
|
import org.springframework.boot.actuate.endpoint.web.annotation.ControllerEndpoint;
|
||||||
import org.springframework.boot.actuate.endpoint.web.annotation.ExposableControllerEndpoint;
|
import org.springframework.boot.actuate.endpoint.web.annotation.ExposableControllerEndpoint;
|
||||||
|
@ -121,22 +122,22 @@ public class ControllerEndpointHandlerMappingTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
private ExposableControllerEndpoint firstEndpoint() {
|
private ExposableControllerEndpoint firstEndpoint() {
|
||||||
return mockEndpoint("first", new FirstTestMvcEndpoint());
|
return mockEndpoint(EndpointId.of("first"), new FirstTestMvcEndpoint());
|
||||||
}
|
}
|
||||||
|
|
||||||
private ExposableControllerEndpoint secondEndpoint() {
|
private ExposableControllerEndpoint secondEndpoint() {
|
||||||
return mockEndpoint("second", new SecondTestMvcEndpoint());
|
return mockEndpoint(EndpointId.of("second"), new SecondTestMvcEndpoint());
|
||||||
}
|
}
|
||||||
|
|
||||||
private ExposableControllerEndpoint pathlessEndpoint() {
|
private ExposableControllerEndpoint pathlessEndpoint() {
|
||||||
return mockEndpoint("pathless", new PathlessControllerEndpoint());
|
return mockEndpoint(EndpointId.of("pathless"), new PathlessControllerEndpoint());
|
||||||
}
|
}
|
||||||
|
|
||||||
private ExposableControllerEndpoint mockEndpoint(String id, Object controller) {
|
private ExposableControllerEndpoint mockEndpoint(EndpointId id, Object controller) {
|
||||||
ExposableControllerEndpoint endpoint = mock(ExposableControllerEndpoint.class);
|
ExposableControllerEndpoint endpoint = mock(ExposableControllerEndpoint.class);
|
||||||
given(endpoint.getId()).willReturn(id);
|
given(endpoint.getEndpointId()).willReturn(id);
|
||||||
given(endpoint.getController()).willReturn(controller);
|
given(endpoint.getController()).willReturn(controller);
|
||||||
given(endpoint.getRootPath()).willReturn(id);
|
given(endpoint.getRootPath()).willReturn(id.toString());
|
||||||
return endpoint;
|
return endpoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@ import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.rules.ExpectedException;
|
import org.junit.rules.ExpectedException;
|
||||||
|
|
||||||
|
import org.springframework.boot.actuate.endpoint.EndpointId;
|
||||||
import org.springframework.boot.actuate.endpoint.web.EndpointMapping;
|
import org.springframework.boot.actuate.endpoint.web.EndpointMapping;
|
||||||
import org.springframework.boot.actuate.endpoint.web.annotation.ControllerEndpoint;
|
import org.springframework.boot.actuate.endpoint.web.annotation.ControllerEndpoint;
|
||||||
import org.springframework.boot.actuate.endpoint.web.annotation.ExposableControllerEndpoint;
|
import org.springframework.boot.actuate.endpoint.web.annotation.ExposableControllerEndpoint;
|
||||||
|
@ -113,22 +114,22 @@ public class ControllerEndpointHandlerMappingTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
private ExposableControllerEndpoint firstEndpoint() {
|
private ExposableControllerEndpoint firstEndpoint() {
|
||||||
return mockEndpoint("first", new FirstTestMvcEndpoint());
|
return mockEndpoint(EndpointId.of("first"), new FirstTestMvcEndpoint());
|
||||||
}
|
}
|
||||||
|
|
||||||
private ExposableControllerEndpoint secondEndpoint() {
|
private ExposableControllerEndpoint secondEndpoint() {
|
||||||
return mockEndpoint("second", new SecondTestMvcEndpoint());
|
return mockEndpoint(EndpointId.of("second"), new SecondTestMvcEndpoint());
|
||||||
}
|
}
|
||||||
|
|
||||||
private ExposableControllerEndpoint pathlessEndpoint() {
|
private ExposableControllerEndpoint pathlessEndpoint() {
|
||||||
return mockEndpoint("pathless", new PathlessControllerEndpoint());
|
return mockEndpoint(EndpointId.of("pathless"), new PathlessControllerEndpoint());
|
||||||
}
|
}
|
||||||
|
|
||||||
private ExposableControllerEndpoint mockEndpoint(String id, Object controller) {
|
private ExposableControllerEndpoint mockEndpoint(EndpointId id, Object controller) {
|
||||||
ExposableControllerEndpoint endpoint = mock(ExposableControllerEndpoint.class);
|
ExposableControllerEndpoint endpoint = mock(ExposableControllerEndpoint.class);
|
||||||
given(endpoint.getId()).willReturn(id);
|
given(endpoint.getEndpointId()).willReturn(id);
|
||||||
given(endpoint.getController()).willReturn(controller);
|
given(endpoint.getController()).willReturn(controller);
|
||||||
given(endpoint.getRootPath()).willReturn(id);
|
given(endpoint.getRootPath()).willReturn(id.toString());
|
||||||
return endpoint;
|
return endpoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,7 @@ public class MetricsWebFilterTests {
|
||||||
MockClock clock = new MockClock();
|
MockClock clock = new MockClock();
|
||||||
this.registry = new SimpleMeterRegistry(SimpleConfig.DEFAULT, clock);
|
this.registry = new SimpleMeterRegistry(SimpleConfig.DEFAULT, clock);
|
||||||
this.webFilter = new MetricsWebFilter(this.registry,
|
this.webFilter = new MetricsWebFilter(this.registry,
|
||||||
new DefaultWebFluxTagsProvider(), REQUEST_METRICS_NAME);
|
new DefaultWebFluxTagsProvider(), REQUEST_METRICS_NAME, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
Loading…
Reference in New Issue