Polish endpoint
This commit is contained in:
committed by
Stephane Nicoll
parent
98455e30dc
commit
f9e5b07eec
@@ -19,10 +19,10 @@ package org.springframework.boot.endpoint;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
@@ -32,6 +32,7 @@ import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.core.MethodIntrospector;
|
||||
import org.springframework.core.annotation.AnnotatedElementUtils;
|
||||
import org.springframework.core.annotation.AnnotationAttributes;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
@@ -45,7 +46,7 @@ import org.springframework.util.ObjectUtils;
|
||||
* @author Stephane Nicoll
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public abstract class AnnotationEndpointDiscoverer<T extends EndpointOperation, K>
|
||||
public abstract class AnnotationEndpointDiscoverer<T extends Operation, K>
|
||||
implements EndpointDiscoverer<T> {
|
||||
|
||||
private final ApplicationContext applicationContext;
|
||||
@@ -69,15 +70,15 @@ public abstract class AnnotationEndpointDiscoverer<T extends EndpointOperation,
|
||||
/**
|
||||
* Perform endpoint discovery, including discovery and merging of extensions.
|
||||
* @param extensionType the annotation type of the extension
|
||||
* @param endpointType the {@link EndpointType} that should be considered
|
||||
* @param delivery the {@link EndpointDelivery} that should be considered
|
||||
* @return the list of {@link EndpointInfo EndpointInfos} that describes the
|
||||
* discovered endpoints matching the specified {@link EndpointType}
|
||||
* discovered endpoints matching the specified {@link EndpointDelivery}
|
||||
*/
|
||||
protected Collection<EndpointInfoDescriptor<T, K>> discoverEndpointsWithExtension(
|
||||
Class<? extends Annotation> extensionType, EndpointType endpointType) {
|
||||
Map<Class<?>, EndpointInfo<T>> endpoints = discoverGenericEndpoints(endpointType);
|
||||
protected Collection<EndpointInfoDescriptor<T, K>> discoverEndpoints(
|
||||
Class<? extends Annotation> extensionType, EndpointDelivery delivery) {
|
||||
Map<Class<?>, EndpointInfo<T>> endpoints = discoverEndpoints(delivery);
|
||||
Map<Class<?>, EndpointExtensionInfo<T>> extensions = discoverExtensions(endpoints,
|
||||
extensionType, endpointType);
|
||||
extensionType, delivery);
|
||||
Collection<EndpointInfoDescriptor<T, K>> result = new ArrayList<>();
|
||||
endpoints.forEach((endpointClass, endpointInfo) -> {
|
||||
EndpointExtensionInfo<T> extension = extensions.remove(endpointClass);
|
||||
@@ -86,169 +87,156 @@ public abstract class AnnotationEndpointDiscoverer<T extends EndpointOperation,
|
||||
return result;
|
||||
}
|
||||
|
||||
private EndpointInfoDescriptor<T, K> createDescriptor(Class<?> endpointType,
|
||||
EndpointInfo<T> endpoint, EndpointExtensionInfo<T> extension) {
|
||||
Map<OperationKey<K>, List<T>> endpointOperations = indexOperations(
|
||||
endpoint.getId(), endpointType, endpoint.getOperations());
|
||||
private Map<Class<?>, EndpointInfo<T>> discoverEndpoints(EndpointDelivery delivery) {
|
||||
String[] beanNames = this.applicationContext
|
||||
.getBeanNamesForAnnotation(Endpoint.class);
|
||||
Map<Class<?>, EndpointInfo<T>> endpoints = new LinkedHashMap<>();
|
||||
Map<String, EndpointInfo<T>> endpointsById = new LinkedHashMap<>();
|
||||
for (String beanName : beanNames) {
|
||||
Class<?> beanType = this.applicationContext.getType(beanName);
|
||||
AnnotationAttributes attributes = AnnotatedElementUtils
|
||||
.findMergedAnnotationAttributes(beanType, Endpoint.class, true, true);
|
||||
if (isDeliveredOver(attributes, delivery)) {
|
||||
EndpointInfo<T> info = createEndpointInfo(beanName, beanType, attributes);
|
||||
EndpointInfo<T> previous = endpointsById.putIfAbsent(info.getId(), info);
|
||||
Assert.state(previous == null, () -> "Found two endpoints with the id '"
|
||||
+ info.getId() + "': " + info + " and " + previous);
|
||||
endpoints.put(beanType, info);
|
||||
}
|
||||
}
|
||||
return endpoints;
|
||||
}
|
||||
|
||||
private EndpointInfo<T> createEndpointInfo(String beanName, Class<?> beanType,
|
||||
AnnotationAttributes attributes) {
|
||||
String id = attributes.getString("id");
|
||||
boolean enabledByDefault = attributes.getBoolean("enabledByDefault");
|
||||
Map<Method, T> operations = discoverOperations(id, beanName, beanType);
|
||||
return new EndpointInfo<>(id, enabledByDefault, operations.values());
|
||||
}
|
||||
|
||||
private Map<Class<?>, EndpointExtensionInfo<T>> discoverExtensions(
|
||||
Map<Class<?>, EndpointInfo<T>> endpoints,
|
||||
Class<? extends Annotation> extensionType, EndpointDelivery delivery) {
|
||||
if (extensionType == null) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
String[] beanNames = this.applicationContext
|
||||
.getBeanNamesForAnnotation(extensionType);
|
||||
Map<Class<?>, EndpointExtensionInfo<T>> extensions = new HashMap<>();
|
||||
for (String beanName : beanNames) {
|
||||
Class<?> beanType = this.applicationContext.getType(beanName);
|
||||
Class<?> endpointType = getEndpointType(extensionType, beanType);
|
||||
AnnotationAttributes endpointAttributes = AnnotatedElementUtils
|
||||
.getMergedAnnotationAttributes(endpointType, Endpoint.class);
|
||||
Assert.state(isDeliveredOver(endpointAttributes, delivery),
|
||||
"Invalid extension " + beanType.getName() + "': endpoint '"
|
||||
+ endpointType.getName()
|
||||
+ "' does not support such extension");
|
||||
EndpointInfo<T> info = getEndpointInfo(endpoints, beanType, endpointType);
|
||||
Map<Method, T> operations = discoverOperations(info.getId(), beanName,
|
||||
beanType);
|
||||
EndpointExtensionInfo<T> extension = new EndpointExtensionInfo<>(beanType,
|
||||
operations.values());
|
||||
EndpointExtensionInfo<T> previous = extensions.putIfAbsent(endpointType,
|
||||
extension);
|
||||
Assert.state(previous == null,
|
||||
() -> "Found two extensions for the same endpoint '"
|
||||
+ endpointType.getName() + "': "
|
||||
+ extension.getExtensionType().getName() + " and "
|
||||
+ previous.getExtensionType().getName());
|
||||
}
|
||||
return extensions;
|
||||
|
||||
}
|
||||
|
||||
private EndpointInfo<T> getEndpointInfo(Map<Class<?>, EndpointInfo<T>> endpoints,
|
||||
Class<?> beanType, Class<?> endpointClass) {
|
||||
EndpointInfo<T> endpoint = endpoints.get(endpointClass);
|
||||
Assert.state(endpoint != null, "Invalid extension '" + beanType.getName()
|
||||
+ "': no endpoint found with type '" + endpointClass.getName() + "'");
|
||||
return endpoint;
|
||||
}
|
||||
|
||||
private Class<?> getEndpointType(Class<? extends Annotation> extensionType,
|
||||
Class<?> beanType) {
|
||||
AnnotationAttributes attributes = AnnotatedElementUtils
|
||||
.getMergedAnnotationAttributes(beanType, extensionType);
|
||||
return (Class<?>) attributes.get("endpoint");
|
||||
}
|
||||
|
||||
private EndpointInfoDescriptor<T, K> createDescriptor(Class<?> type,
|
||||
EndpointInfo<T> info, EndpointExtensionInfo<T> extension) {
|
||||
Map<OperationKey<K>, List<T>> operations = indexOperations(info.getId(), type,
|
||||
info.getOperations());
|
||||
if (extension != null) {
|
||||
endpointOperations.putAll(indexOperations(endpoint.getId(),
|
||||
extension.getEndpointExtensionType(), extension.getOperations()));
|
||||
return new EndpointInfoDescriptor<>(mergeEndpoint(endpoint, extension),
|
||||
endpointOperations);
|
||||
}
|
||||
else {
|
||||
return new EndpointInfoDescriptor<>(endpoint, endpointOperations);
|
||||
operations.putAll(indexOperations(info.getId(), extension.getExtensionType(),
|
||||
extension.getOperations()));
|
||||
return new EndpointInfoDescriptor<>(mergeEndpoint(info, extension),
|
||||
operations);
|
||||
}
|
||||
return new EndpointInfoDescriptor<>(info, operations);
|
||||
}
|
||||
|
||||
private EndpointInfo<T> mergeEndpoint(EndpointInfo<T> endpoint,
|
||||
EndpointExtensionInfo<T> extension) {
|
||||
Map<K, T> operations = new HashMap<>();
|
||||
Consumer<T> operationConsumer = (operation) -> operations
|
||||
Consumer<T> consumer = (operation) -> operations
|
||||
.put(this.operationKeyFactory.apply(operation), operation);
|
||||
endpoint.getOperations().forEach(operationConsumer);
|
||||
extension.getOperations().forEach(operationConsumer);
|
||||
endpoint.getOperations().forEach(consumer);
|
||||
extension.getOperations().forEach(consumer);
|
||||
return new EndpointInfo<>(endpoint.getId(), endpoint.isEnabledByDefault(),
|
||||
operations.values());
|
||||
}
|
||||
|
||||
private Map<OperationKey<K>, List<T>> indexOperations(String endpointId,
|
||||
Class<?> target, Collection<T> operations) {
|
||||
LinkedMultiValueMap<OperationKey<K>, T> operationByKey = new LinkedMultiValueMap<>();
|
||||
operations
|
||||
.forEach(
|
||||
(operation) -> operationByKey.add(
|
||||
new OperationKey<>(endpointId, target,
|
||||
this.operationKeyFactory.apply(operation)),
|
||||
operation));
|
||||
return operationByKey;
|
||||
LinkedMultiValueMap<OperationKey<K>, T> result = new LinkedMultiValueMap<>();
|
||||
operations.forEach((operation) -> {
|
||||
K key = this.operationKeyFactory.apply(operation);
|
||||
result.add(new OperationKey<>(endpointId, target, key), operation);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
private Map<Class<?>, EndpointInfo<T>> discoverGenericEndpoints(
|
||||
EndpointType endpointType) {
|
||||
String[] endpointBeanNames = this.applicationContext
|
||||
.getBeanNamesForAnnotation(Endpoint.class);
|
||||
Map<String, EndpointInfo<T>> endpointsById = new HashMap<>();
|
||||
Map<Class<?>, EndpointInfo<T>> endpointsByClass = new HashMap<>();
|
||||
for (String beanName : endpointBeanNames) {
|
||||
Class<?> beanType = this.applicationContext.getType(beanName);
|
||||
AnnotationAttributes endpointAttributes = AnnotatedElementUtils
|
||||
.findMergedAnnotationAttributes(beanType, Endpoint.class, true, true);
|
||||
String endpointId = endpointAttributes.getString("id");
|
||||
if (matchEndpointType(endpointAttributes, endpointType)) {
|
||||
EndpointInfo<T> endpointInfo = createEndpointInfo(endpointsById, beanName,
|
||||
beanType, endpointAttributes, endpointId);
|
||||
endpointsByClass.put(beanType, endpointInfo);
|
||||
}
|
||||
}
|
||||
return endpointsByClass;
|
||||
}
|
||||
|
||||
private EndpointInfo<T> createEndpointInfo(Map<String, EndpointInfo<T>> endpointsById,
|
||||
String beanName, Class<?> beanType, AnnotationAttributes endpointAttributes,
|
||||
String endpointId) {
|
||||
Map<Method, T> operationMethods = discoverOperations(endpointId, beanName,
|
||||
beanType);
|
||||
EndpointInfo<T> endpointInfo = new EndpointInfo<>(endpointId,
|
||||
endpointAttributes.getBoolean("enabledByDefault"),
|
||||
operationMethods.values());
|
||||
EndpointInfo<T> previous = endpointsById.putIfAbsent(endpointInfo.getId(),
|
||||
endpointInfo);
|
||||
if (previous != null) {
|
||||
throw new IllegalStateException("Found two endpoints with the id '"
|
||||
+ endpointInfo.getId() + "': " + endpointInfo + " and " + previous);
|
||||
}
|
||||
return endpointInfo;
|
||||
}
|
||||
|
||||
private Map<Class<?>, EndpointExtensionInfo<T>> discoverExtensions(
|
||||
Map<Class<?>, EndpointInfo<T>> endpoints,
|
||||
Class<? extends Annotation> extensionType, EndpointType endpointType) {
|
||||
if (extensionType == null) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
String[] extensionBeanNames = this.applicationContext
|
||||
.getBeanNamesForAnnotation(extensionType);
|
||||
Map<Class<?>, EndpointExtensionInfo<T>> extensionsByEndpoint = new HashMap<>();
|
||||
for (String beanName : extensionBeanNames) {
|
||||
Class<?> beanType = this.applicationContext.getType(beanName);
|
||||
AnnotationAttributes extensionAttributes = AnnotatedElementUtils
|
||||
.getMergedAnnotationAttributes(beanType, extensionType);
|
||||
Class<?> endpointClass = (Class<?>) extensionAttributes.get("endpoint");
|
||||
AnnotationAttributes endpointAttributes = AnnotatedElementUtils
|
||||
.getMergedAnnotationAttributes(endpointClass, Endpoint.class);
|
||||
if (!matchEndpointType(endpointAttributes, endpointType)) {
|
||||
throw new IllegalStateException(String.format(
|
||||
"Invalid extension %s': "
|
||||
+ "endpoint '%s' does not support such extension",
|
||||
beanType.getName(), endpointClass.getName()));
|
||||
}
|
||||
EndpointInfo<T> endpoint = endpoints.get(endpointClass);
|
||||
if (endpoint == null) {
|
||||
throw new IllegalStateException(String.format(
|
||||
"Invalid extension '%s': no endpoint found with type '%s'",
|
||||
beanType.getName(), endpointClass.getName()));
|
||||
}
|
||||
Map<Method, T> operationMethods = discoverOperations(endpoint.getId(),
|
||||
beanName, beanType);
|
||||
EndpointExtensionInfo<T> extension = new EndpointExtensionInfo<>(beanType,
|
||||
operationMethods.values());
|
||||
EndpointExtensionInfo<T> previous = extensionsByEndpoint
|
||||
.putIfAbsent(endpointClass, extension);
|
||||
if (previous != null) {
|
||||
throw new IllegalStateException(
|
||||
"Found two extensions for the same endpoint '"
|
||||
+ endpointClass.getName() + "': "
|
||||
+ extension.getEndpointExtensionType().getName() + " and "
|
||||
+ previous.getEndpointExtensionType().getName());
|
||||
}
|
||||
}
|
||||
return extensionsByEndpoint;
|
||||
}
|
||||
|
||||
private boolean matchEndpointType(AnnotationAttributes endpointAttributes,
|
||||
EndpointType endpointType) {
|
||||
if (endpointType == null) {
|
||||
private boolean isDeliveredOver(AnnotationAttributes attributes,
|
||||
EndpointDelivery delivery) {
|
||||
if (delivery == null) {
|
||||
return true;
|
||||
}
|
||||
Object types = endpointAttributes.get("types");
|
||||
if (ObjectUtils.isEmpty(types)) {
|
||||
return true;
|
||||
}
|
||||
return Arrays.stream((EndpointType[]) types)
|
||||
.anyMatch((t) -> t.equals(endpointType));
|
||||
EndpointDelivery[] supported = (EndpointDelivery[]) attributes.get("delivery");
|
||||
return ObjectUtils.isEmpty(supported)
|
||||
|| ObjectUtils.containsElement(supported, delivery);
|
||||
}
|
||||
|
||||
private Map<Method, T> discoverOperations(String endpointId, String beanName,
|
||||
Class<?> beanType) {
|
||||
return MethodIntrospector.selectMethods(beanType,
|
||||
private Map<Method, T> discoverOperations(String id, String name, Class<?> type) {
|
||||
return MethodIntrospector.selectMethods(type,
|
||||
(MethodIntrospector.MetadataLookup<T>) (
|
||||
method) -> createOperationIfPossible(endpointId, beanName,
|
||||
method));
|
||||
method) -> createOperationIfPossible(id, name, method));
|
||||
}
|
||||
|
||||
private T createOperationIfPossible(String endpointId, String beanName,
|
||||
Method method) {
|
||||
T readOperation = createReadOperationIfPossible(endpointId, beanName, method);
|
||||
return readOperation != null ? readOperation
|
||||
: createWriteOperationIfPossible(endpointId, beanName, method);
|
||||
return (readOperation != null ? readOperation
|
||||
: createWriteOperationIfPossible(endpointId, beanName, method));
|
||||
}
|
||||
|
||||
private T createReadOperationIfPossible(String endpointId, String beanName,
|
||||
Method method) {
|
||||
return createOperationIfPossible(endpointId, beanName, method,
|
||||
ReadOperation.class, EndpointOperationType.READ);
|
||||
ReadOperation.class, OperationType.READ);
|
||||
}
|
||||
|
||||
private T createWriteOperationIfPossible(String endpointId, String beanName,
|
||||
Method method) {
|
||||
return createOperationIfPossible(endpointId, beanName, method,
|
||||
WriteOperation.class, EndpointOperationType.WRITE);
|
||||
WriteOperation.class, OperationType.WRITE);
|
||||
}
|
||||
|
||||
private T createOperationIfPossible(String endpointId, String beanName, Method method,
|
||||
Class<? extends Annotation> operationAnnotation,
|
||||
EndpointOperationType operationType) {
|
||||
OperationType operationType) {
|
||||
AnnotationAttributes operationAttributes = AnnotatedElementUtils
|
||||
.getMergedAnnotationAttributes(method, operationAnnotation);
|
||||
if (operationAttributes == null) {
|
||||
@@ -262,9 +250,9 @@ public abstract class AnnotationEndpointDiscoverer<T extends EndpointOperation,
|
||||
}
|
||||
|
||||
private long determineTimeToLive(CachingConfiguration cachingConfiguration,
|
||||
EndpointOperationType operationType, Method method) {
|
||||
OperationType operationType, Method method) {
|
||||
if (cachingConfiguration != null && cachingConfiguration.getTimeToLive() > 0
|
||||
&& operationType == EndpointOperationType.READ
|
||||
&& operationType == OperationType.READ
|
||||
&& method.getParameters().length == 0) {
|
||||
return cachingConfiguration.getTimeToLive();
|
||||
}
|
||||
@@ -272,13 +260,13 @@ public abstract class AnnotationEndpointDiscoverer<T extends EndpointOperation,
|
||||
}
|
||||
|
||||
/**
|
||||
* An {@code EndpointOperationFactory} creates an {@link EndpointOperation} for an
|
||||
* operation on an endpoint.
|
||||
* An {@code EndpointOperationFactory} creates an {@link Operation} for an operation
|
||||
* on an endpoint.
|
||||
*
|
||||
* @param <T> the {@link EndpointOperation} type
|
||||
* @param <T> the {@link Operation} type
|
||||
*/
|
||||
@FunctionalInterface
|
||||
protected interface EndpointOperationFactory<T extends EndpointOperation> {
|
||||
protected interface EndpointOperationFactory<T extends Operation> {
|
||||
|
||||
/**
|
||||
* Creates an {@code EndpointOperation} for an operation on an endpoint.
|
||||
@@ -291,8 +279,8 @@ public abstract class AnnotationEndpointDiscoverer<T extends EndpointOperation,
|
||||
* @return the operation info that describes the operation
|
||||
*/
|
||||
T createOperation(String endpointId, AnnotationAttributes operationAttributes,
|
||||
Object target, Method operationMethod,
|
||||
EndpointOperationType operationType, long timeToLive);
|
||||
Object target, Method operationMethod, OperationType operationType,
|
||||
long timeToLive);
|
||||
|
||||
}
|
||||
|
||||
@@ -300,20 +288,19 @@ public abstract class AnnotationEndpointDiscoverer<T extends EndpointOperation,
|
||||
* Describes a tech-specific extension of an endpoint.
|
||||
* @param <T> the type of the operation
|
||||
*/
|
||||
private static final class EndpointExtensionInfo<T extends EndpointOperation> {
|
||||
private static final class EndpointExtensionInfo<T extends Operation> {
|
||||
|
||||
private final Class<?> endpointExtensionType;
|
||||
private final Class<?> extensionType;
|
||||
|
||||
private final Collection<T> operations;
|
||||
|
||||
private EndpointExtensionInfo(Class<?> endpointExtensionType,
|
||||
Collection<T> operations) {
|
||||
this.endpointExtensionType = endpointExtensionType;
|
||||
private EndpointExtensionInfo(Class<?> extensionType, Collection<T> operations) {
|
||||
this.extensionType = extensionType;
|
||||
this.operations = operations;
|
||||
}
|
||||
|
||||
private Class<?> getEndpointExtensionType() {
|
||||
return this.endpointExtensionType;
|
||||
private Class<?> getExtensionType() {
|
||||
return this.extensionType;
|
||||
}
|
||||
|
||||
private Collection<T> getOperations() {
|
||||
@@ -328,7 +315,7 @@ public abstract class AnnotationEndpointDiscoverer<T extends EndpointOperation,
|
||||
* @param <T> the type of the operation
|
||||
* @param <K> the type of the operation key
|
||||
*/
|
||||
protected static class EndpointInfoDescriptor<T extends EndpointOperation, K> {
|
||||
protected static class EndpointInfoDescriptor<T extends Operation, K> {
|
||||
|
||||
private final EndpointInfo<T> endpointInfo;
|
||||
|
||||
@@ -377,22 +364,18 @@ public abstract class AnnotationEndpointDiscoverer<T extends EndpointOperation,
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
if (o == this) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
OperationKey<?> that = (OperationKey<?>) o;
|
||||
|
||||
if (!this.endpointId.equals(that.endpointId)) {
|
||||
return false;
|
||||
}
|
||||
if (!this.endpointType.equals(that.endpointType)) {
|
||||
return false;
|
||||
}
|
||||
return this.key.equals(that.key);
|
||||
OperationKey<?> other = (OperationKey<?>) o;
|
||||
Boolean result = true;
|
||||
result = result && this.endpointId.equals(other.endpointId);
|
||||
result = result && this.endpointType.equals(other.endpointType);
|
||||
result = result && this.key.equals(other.key);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
package org.springframework.boot.endpoint;
|
||||
|
||||
/**
|
||||
* {@link EndpointPathResolver} implementation that does not support
|
||||
* resolving endpoint paths.
|
||||
* {@link EndpointPathResolver} implementation that does not support resolving endpoint
|
||||
* paths.
|
||||
*
|
||||
* @author Madhura Bhave
|
||||
* @since 2.0.0
|
||||
@@ -31,4 +31,3 @@ public class DefaultEndpointPathResolver implements EndpointPathResolver {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -41,11 +41,11 @@ public @interface Endpoint {
|
||||
String id();
|
||||
|
||||
/**
|
||||
* Defines the endpoint {@link EndpointType types} that should be exposed. By default,
|
||||
* all types are exposed.
|
||||
* @return the endpoint types to expose
|
||||
* Defines the {@link EndpointDelivery delivery technologies} over which the
|
||||
* endpoint should be delivered over. By default, all technologies are supported.
|
||||
* @return the supported endpoint delivery technologies
|
||||
*/
|
||||
EndpointType[] types() default {};
|
||||
EndpointDelivery[] delivery() default {};
|
||||
|
||||
/**
|
||||
* Whether or not the endpoint is enabled by default.
|
||||
|
||||
@@ -17,12 +17,12 @@
|
||||
package org.springframework.boot.endpoint;
|
||||
|
||||
/**
|
||||
* An enumeration of the available {@link Endpoint} types.
|
||||
* An enumeration of the available {@link Endpoint} delivery technologies.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public enum EndpointType {
|
||||
public enum EndpointDelivery {
|
||||
|
||||
/**
|
||||
* Expose the endpoint as a JMX MBean.
|
||||
@@ -36,11 +36,12 @@ public enum EndpointType {
|
||||
|
||||
private final boolean enabledByDefault;
|
||||
|
||||
EndpointType(boolean enabledByDefault) {
|
||||
EndpointDelivery(boolean enabledByDefault) {
|
||||
this.enabledByDefault = enabledByDefault;
|
||||
}
|
||||
|
||||
public boolean isEnabledByDefault() {
|
||||
return this.enabledByDefault;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -27,7 +27,7 @@ import java.util.Collection;
|
||||
* @since 2.0.0
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface EndpointDiscoverer<T extends EndpointOperation> {
|
||||
public interface EndpointDiscoverer<T extends Operation> {
|
||||
|
||||
/**
|
||||
* Perform endpoint discovery.
|
||||
|
||||
@@ -25,7 +25,7 @@ import java.util.Collection;
|
||||
* @author Andy Wilkinson
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public class EndpointInfo<T extends EndpointOperation> {
|
||||
public class EndpointInfo<T extends Operation> {
|
||||
|
||||
private final String id;
|
||||
|
||||
|
||||
@@ -22,11 +22,11 @@ package org.springframework.boot.endpoint;
|
||||
* @author Andy Wilkinson
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public class EndpointOperation {
|
||||
public class Operation {
|
||||
|
||||
private final EndpointOperationType type;
|
||||
private final OperationType type;
|
||||
|
||||
private final OperationInvoker operationInvoker;
|
||||
private final OperationInvoker invoker;
|
||||
|
||||
private final boolean blocking;
|
||||
|
||||
@@ -37,18 +37,18 @@ public class EndpointOperation {
|
||||
* @param operationInvoker used to perform the operation
|
||||
* @param blocking whether or not this is a blocking operation
|
||||
*/
|
||||
public EndpointOperation(EndpointOperationType type,
|
||||
public Operation(OperationType type,
|
||||
OperationInvoker operationInvoker, boolean blocking) {
|
||||
this.type = type;
|
||||
this.operationInvoker = operationInvoker;
|
||||
this.invoker = operationInvoker;
|
||||
this.blocking = blocking;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link EndpointOperationType type} of the operation.
|
||||
* Returns the {@link OperationType type} of the operation.
|
||||
* @return the type
|
||||
*/
|
||||
public EndpointOperationType getType() {
|
||||
public OperationType getType() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
@@ -57,8 +57,8 @@ public class EndpointOperation {
|
||||
* operation.
|
||||
* @return the operation invoker
|
||||
*/
|
||||
public OperationInvoker getOperationInvoker() {
|
||||
return this.operationInvoker;
|
||||
public OperationInvoker getInvoker() {
|
||||
return this.invoker;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -22,7 +22,7 @@ package org.springframework.boot.endpoint;
|
||||
* @author Andy Wilkinson
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public enum EndpointOperationType {
|
||||
public enum OperationType {
|
||||
|
||||
/**
|
||||
* A read operation.
|
||||
@@ -47,7 +47,6 @@ public class ParameterMappingException extends RuntimeException {
|
||||
|
||||
/**
|
||||
* Returns the input that was to be mapped.
|
||||
*
|
||||
* @return the input
|
||||
*/
|
||||
public Object getInput() {
|
||||
@@ -56,7 +55,6 @@ public class ParameterMappingException extends RuntimeException {
|
||||
|
||||
/**
|
||||
* Returns the type to be mapped to.
|
||||
*
|
||||
* @return the type
|
||||
*/
|
||||
public Class<?> getType() {
|
||||
|
||||
@@ -42,7 +42,6 @@ public class ReflectiveOperationInvoker implements OperationInvoker {
|
||||
* Creates a new {code ReflectiveOperationInvoker} that will invoke the given
|
||||
* {@code method} on the given {@code target}. The given {@code parameterMapper} will
|
||||
* be used to map parameters to the required types.
|
||||
*
|
||||
* @param parameterMapper the parameter mapper
|
||||
* @param target the target of the reflective call
|
||||
* @param method the method to call
|
||||
|
||||
@@ -74,16 +74,12 @@ public class EndpointMBean implements DynamicMBean {
|
||||
@Override
|
||||
public Object invoke(String actionName, Object[] params, String[] signature)
|
||||
throws MBeanException, ReflectionException {
|
||||
JmxEndpointOperation operationInfo = this.endpointInfo.getOperations()
|
||||
JmxEndpointOperation operation = this.endpointInfo.getOperations()
|
||||
.get(actionName);
|
||||
if (operationInfo != null) {
|
||||
Map<String, Object> arguments = new HashMap<>();
|
||||
List<JmxEndpointOperationParameterInfo> parameters = operationInfo
|
||||
.getParameters();
|
||||
for (int i = 0; i < params.length; i++) {
|
||||
arguments.put(parameters.get(i).getName(), params[i]);
|
||||
}
|
||||
Object result = operationInfo.getOperationInvoker().invoke(arguments);
|
||||
if (operation != null) {
|
||||
Map<String, Object> arguments = getArguments(params,
|
||||
operation.getParameters());
|
||||
Object result = operation.getInvoker().invoke(arguments);
|
||||
if (REACTOR_PRESENT) {
|
||||
result = ReactiveHandler.handle(result);
|
||||
}
|
||||
@@ -94,6 +90,15 @@ public class EndpointMBean implements DynamicMBean {
|
||||
this.endpointInfo.getEndpointId(), actionName)));
|
||||
}
|
||||
|
||||
private Map<String, Object> getArguments(Object[] params,
|
||||
List<JmxEndpointOperationParameterInfo> parameters) {
|
||||
Map<String, Object> arguments = new HashMap<>();
|
||||
for (int i = 0; i < params.length; i++) {
|
||||
arguments.put(parameters.get(i).getName(), params[i]);
|
||||
}
|
||||
return arguments;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getAttribute(String attribute)
|
||||
throws AttributeNotFoundException, MBeanException, ReflectionException {
|
||||
|
||||
@@ -21,11 +21,11 @@ import java.util.Map;
|
||||
import javax.management.MBeanInfo;
|
||||
|
||||
import org.springframework.boot.endpoint.EndpointInfo;
|
||||
import org.springframework.boot.endpoint.EndpointOperation;
|
||||
import org.springframework.boot.endpoint.Operation;
|
||||
|
||||
/**
|
||||
* The {@link MBeanInfo} for a particular {@link EndpointInfo endpoint}. Maps operation
|
||||
* names to an {@link EndpointOperation}.
|
||||
* names to an {@link Operation}.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @since 2.0.0
|
||||
|
||||
@@ -31,7 +31,7 @@ import javax.management.modelmbean.ModelMBeanNotificationInfo;
|
||||
import javax.management.modelmbean.ModelMBeanOperationInfo;
|
||||
|
||||
import org.springframework.boot.endpoint.EndpointInfo;
|
||||
import org.springframework.boot.endpoint.EndpointOperationType;
|
||||
import org.springframework.boot.endpoint.OperationType;
|
||||
|
||||
/**
|
||||
* Gathers the management operations of a particular {@link EndpointInfo endpoint}.
|
||||
@@ -61,7 +61,6 @@ class EndpointMBeanInfoAssembler {
|
||||
.toArray(new ModelMBeanOperationInfo[] {});
|
||||
Map<String, JmxEndpointOperation> operationsInfo = new LinkedHashMap<>();
|
||||
operationsMapping.forEach((name, t) -> operationsInfo.put(name, t.operation));
|
||||
|
||||
MBeanInfo info = new ModelMBeanInfoSupport(EndpointMBean.class.getName(),
|
||||
getDescription(endpointInfo), new ModelMBeanAttributeInfo[0],
|
||||
new ModelMBeanConstructorInfo[0], operationsMBeanInfo,
|
||||
@@ -100,11 +99,11 @@ class EndpointMBeanInfoAssembler {
|
||||
.toArray(new MBeanParameterInfo[parameterInfos.size()])));
|
||||
}
|
||||
|
||||
private int mapOperationType(EndpointOperationType type) {
|
||||
if (type == EndpointOperationType.READ) {
|
||||
private int mapOperationType(OperationType type) {
|
||||
if (type == OperationType.READ) {
|
||||
return MBeanOperationInfo.INFO;
|
||||
}
|
||||
if (type == EndpointOperationType.WRITE) {
|
||||
if (type == OperationType.WRITE) {
|
||||
return MBeanOperationInfo.ACTION;
|
||||
}
|
||||
return MBeanOperationInfo.UNKNOWN;
|
||||
|
||||
@@ -68,24 +68,21 @@ public class EndpointMBeanRegistrar {
|
||||
Assert.notNull(endpoint, "Endpoint must not be null");
|
||||
try {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(String.format(
|
||||
"Registering endpoint with id '%s' to " + "the JMX domain",
|
||||
endpoint.getEndpointId()));
|
||||
logger.debug("Registering endpoint with id '" + endpoint.getEndpointId()
|
||||
+ "' to the JMX domain");
|
||||
}
|
||||
ObjectName objectName = this.objectNameFactory.generate(endpoint);
|
||||
this.mBeanServer.registerMBean(endpoint, objectName);
|
||||
return objectName;
|
||||
}
|
||||
catch (MalformedObjectNameException ex) {
|
||||
throw new IllegalStateException(
|
||||
String.format("Invalid ObjectName for " + "endpoint with id '%s'",
|
||||
endpoint.getEndpointId()),
|
||||
ex);
|
||||
throw new IllegalStateException("Invalid ObjectName for endpoint with id '"
|
||||
+ endpoint.getEndpointId() + "'", ex);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new MBeanExportException(
|
||||
String.format("Failed to register MBean for endpoint with id '%s'",
|
||||
endpoint.getEndpointId()),
|
||||
"Failed to register MBean for endpoint with id '"
|
||||
+ endpoint.getEndpointId() + "'",
|
||||
ex);
|
||||
}
|
||||
}
|
||||
@@ -99,8 +96,8 @@ public class EndpointMBeanRegistrar {
|
||||
public boolean unregisterEndpointMbean(ObjectName objectName) {
|
||||
try {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(String.format("Unregister endpoint with ObjectName '%s' "
|
||||
+ "from the JMX domain", objectName));
|
||||
logger.debug("Unregister endpoint with ObjectName '" + objectName + "' "
|
||||
+ "from the JMX domain");
|
||||
}
|
||||
this.mBeanServer.unregisterMBean(objectName);
|
||||
return true;
|
||||
@@ -110,8 +107,7 @@ public class EndpointMBeanRegistrar {
|
||||
}
|
||||
catch (MBeanRegistrationException ex) {
|
||||
throw new JmxException(
|
||||
String.format("Failed to unregister MBean with" + "ObjectName '%s'",
|
||||
objectName),
|
||||
"Failed to unregister MBean with ObjectName '" + objectName + "'",
|
||||
ex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Parameter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
@@ -30,11 +31,11 @@ import org.springframework.boot.endpoint.AnnotationEndpointDiscoverer;
|
||||
import org.springframework.boot.endpoint.CachingConfiguration;
|
||||
import org.springframework.boot.endpoint.CachingOperationInvoker;
|
||||
import org.springframework.boot.endpoint.Endpoint;
|
||||
import org.springframework.boot.endpoint.EndpointDelivery;
|
||||
import org.springframework.boot.endpoint.EndpointInfo;
|
||||
import org.springframework.boot.endpoint.EndpointOperationType;
|
||||
import org.springframework.boot.endpoint.EndpointType;
|
||||
import org.springframework.boot.endpoint.OperationInvoker;
|
||||
import org.springframework.boot.endpoint.OperationParameterMapper;
|
||||
import org.springframework.boot.endpoint.OperationType;
|
||||
import org.springframework.boot.endpoint.ReflectiveOperationInvoker;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.core.annotation.AnnotationAttributes;
|
||||
@@ -60,7 +61,6 @@ public class JmxAnnotationEndpointDiscoverer
|
||||
* Creates a new {@link JmxAnnotationEndpointDiscoverer} that will discover
|
||||
* {@link Endpoint endpoints} and {@link JmxEndpointExtension jmx extensions} using
|
||||
* the given {@link ApplicationContext}.
|
||||
*
|
||||
* @param applicationContext the application context
|
||||
* @param parameterMapper the {@link OperationParameterMapper} used to convert
|
||||
* arguments when an operation is invoked
|
||||
@@ -75,8 +75,8 @@ public class JmxAnnotationEndpointDiscoverer
|
||||
|
||||
@Override
|
||||
public Collection<EndpointInfo<JmxEndpointOperation>> discoverEndpoints() {
|
||||
Collection<EndpointInfoDescriptor<JmxEndpointOperation, String>> endpointDescriptors = discoverEndpointsWithExtension(
|
||||
JmxEndpointExtension.class, EndpointType.JMX);
|
||||
Collection<EndpointInfoDescriptor<JmxEndpointOperation, String>> endpointDescriptors = discoverEndpoints(
|
||||
JmxEndpointExtension.class, EndpointDelivery.JMX);
|
||||
verifyThatOperationsHaveDistinctName(endpointDescriptors);
|
||||
return endpointDescriptors.stream().map(EndpointInfoDescriptor::getEndpointInfo)
|
||||
.collect(Collectors.toList());
|
||||
@@ -113,7 +113,7 @@ public class JmxAnnotationEndpointDiscoverer
|
||||
@Override
|
||||
public JmxEndpointOperation createOperation(String endpointId,
|
||||
AnnotationAttributes operationAttributes, Object target, Method method,
|
||||
EndpointOperationType type, long timeToLive) {
|
||||
OperationType type, long timeToLive) {
|
||||
String operationName = method.getName();
|
||||
Class<?> outputType = mapParameterType(method.getReturnType());
|
||||
String description = getDescription(method,
|
||||
@@ -139,29 +139,40 @@ public class JmxAnnotationEndpointDiscoverer
|
||||
}
|
||||
|
||||
private List<JmxEndpointOperationParameterInfo> getParameters(Method method) {
|
||||
List<JmxEndpointOperationParameterInfo> parameters = new ArrayList<>();
|
||||
Parameter[] methodParameters = method.getParameters();
|
||||
if (methodParameters.length == 0) {
|
||||
return parameters;
|
||||
return Collections.emptyList();
|
||||
}
|
||||
ManagedOperationParameter[] managedOperationParameters = jmxAttributeSource
|
||||
.getManagedOperationParameters(method);
|
||||
if (managedOperationParameters.length > 0) {
|
||||
for (int i = 0; i < managedOperationParameters.length; i++) {
|
||||
ManagedOperationParameter mBeanParameter = managedOperationParameters[i];
|
||||
Parameter methodParameter = methodParameters[i];
|
||||
parameters.add(new JmxEndpointOperationParameterInfo(
|
||||
mBeanParameter.getName(),
|
||||
mapParameterType(methodParameter.getType()),
|
||||
mBeanParameter.getDescription()));
|
||||
}
|
||||
if (managedOperationParameters.length == 0) {
|
||||
return getParametersInfo(methodParameters);
|
||||
}
|
||||
else {
|
||||
for (Parameter parameter : methodParameters) {
|
||||
parameters.add(
|
||||
new JmxEndpointOperationParameterInfo(parameter.getName(),
|
||||
mapParameterType(parameter.getType()), null));
|
||||
}
|
||||
return getParametersInfo(methodParameters, managedOperationParameters);
|
||||
}
|
||||
|
||||
private List<JmxEndpointOperationParameterInfo> getParametersInfo(
|
||||
Parameter[] methodParameters) {
|
||||
List<JmxEndpointOperationParameterInfo> parameters = new ArrayList<>();
|
||||
for (Parameter methodParameter : methodParameters) {
|
||||
String name = methodParameter.getName();
|
||||
Class<?> type = mapParameterType(methodParameter.getType());
|
||||
parameters.add(new JmxEndpointOperationParameterInfo(name, type, null));
|
||||
}
|
||||
return parameters;
|
||||
}
|
||||
|
||||
private List<JmxEndpointOperationParameterInfo> getParametersInfo(
|
||||
Parameter[] methodParameters,
|
||||
ManagedOperationParameter[] managedOperationParameters) {
|
||||
List<JmxEndpointOperationParameterInfo> parameters = new ArrayList<>();
|
||||
for (int i = 0; i < managedOperationParameters.length; i++) {
|
||||
ManagedOperationParameter managedOperationParameter = managedOperationParameters[i];
|
||||
Parameter methodParameter = methodParameters[i];
|
||||
parameters.add(new JmxEndpointOperationParameterInfo(
|
||||
managedOperationParameter.getName(),
|
||||
mapParameterType(methodParameter.getType()),
|
||||
managedOperationParameter.getDescription()));
|
||||
}
|
||||
return parameters;
|
||||
}
|
||||
|
||||
@@ -51,11 +51,13 @@ public class JmxEndpointMBeanFactory {
|
||||
*/
|
||||
public Collection<EndpointMBean> createMBeans(
|
||||
Collection<EndpointInfo<JmxEndpointOperation>> endpoints) {
|
||||
return endpoints.stream().map((endpointInfo) -> {
|
||||
EndpointMBeanInfo endpointMBeanInfo = this.assembler
|
||||
.createEndpointMBeanInfo(endpointInfo);
|
||||
return new EndpointMBean(this.resultMapper::mapResponse, endpointMBeanInfo);
|
||||
}).collect(Collectors.toList());
|
||||
return endpoints.stream().map(this::createMBean).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private EndpointMBean createMBean(EndpointInfo<JmxEndpointOperation> endpointInfo) {
|
||||
EndpointMBeanInfo endpointMBeanInfo = this.assembler
|
||||
.createEndpointMBeanInfo(endpointInfo);
|
||||
return new EndpointMBean(this.resultMapper::mapResponse, endpointMBeanInfo);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,9 +19,9 @@ package org.springframework.boot.endpoint.jmx;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.boot.endpoint.EndpointOperation;
|
||||
import org.springframework.boot.endpoint.EndpointOperationType;
|
||||
import org.springframework.boot.endpoint.Operation;
|
||||
import org.springframework.boot.endpoint.OperationInvoker;
|
||||
import org.springframework.boot.endpoint.OperationType;
|
||||
|
||||
/**
|
||||
* An operation on a JMX endpoint.
|
||||
@@ -30,7 +30,7 @@ import org.springframework.boot.endpoint.OperationInvoker;
|
||||
* @author Andy Wilkinson
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public class JmxEndpointOperation extends EndpointOperation {
|
||||
public class JmxEndpointOperation extends Operation {
|
||||
|
||||
private final String operationName;
|
||||
|
||||
@@ -50,7 +50,7 @@ public class JmxEndpointOperation extends EndpointOperation {
|
||||
* @param description the description of the operation
|
||||
* @param parameters the parameters of the operation
|
||||
*/
|
||||
public JmxEndpointOperation(EndpointOperationType type, OperationInvoker invoker,
|
||||
public JmxEndpointOperation(OperationType type, OperationInvoker invoker,
|
||||
String operationName, Class<?> outputType, String description,
|
||||
List<JmxEndpointOperationParameterInfo> parameters) {
|
||||
super(type, invoker, true);
|
||||
|
||||
@@ -33,7 +33,6 @@ public class EndpointLinksResolver {
|
||||
/**
|
||||
* Resolves links to the operations of the given {code webEndpoints} based on a
|
||||
* request with the given {@code requestUrl}.
|
||||
*
|
||||
* @param webEndpoints the web endpoints
|
||||
* @param requestUrl the url of the request for the endpoint links
|
||||
* @return the links
|
||||
|
||||
@@ -111,26 +111,16 @@ public class OperationRequestPredicate {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
if (obj == null || getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
OperationRequestPredicate other = (OperationRequestPredicate) obj;
|
||||
if (!this.consumes.equals(other.consumes)) {
|
||||
return false;
|
||||
}
|
||||
if (this.httpMethod != other.httpMethod) {
|
||||
return false;
|
||||
}
|
||||
if (!this.canonicalPath.equals(other.canonicalPath)) {
|
||||
return false;
|
||||
}
|
||||
if (!this.produces.equals(other.produces)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
boolean result = true;
|
||||
result = result && this.consumes.equals(other.consumes);
|
||||
result = result && this.httpMethod == other.httpMethod;
|
||||
result = result && this.canonicalPath.equals(other.canonicalPath);
|
||||
result = result && this.produces.equals(other.produces);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -31,11 +31,11 @@ import org.springframework.boot.endpoint.AnnotationEndpointDiscoverer;
|
||||
import org.springframework.boot.endpoint.CachingConfiguration;
|
||||
import org.springframework.boot.endpoint.CachingOperationInvoker;
|
||||
import org.springframework.boot.endpoint.Endpoint;
|
||||
import org.springframework.boot.endpoint.EndpointDelivery;
|
||||
import org.springframework.boot.endpoint.EndpointInfo;
|
||||
import org.springframework.boot.endpoint.EndpointOperationType;
|
||||
import org.springframework.boot.endpoint.EndpointType;
|
||||
import org.springframework.boot.endpoint.OperationInvoker;
|
||||
import org.springframework.boot.endpoint.OperationParameterMapper;
|
||||
import org.springframework.boot.endpoint.OperationType;
|
||||
import org.springframework.boot.endpoint.ReflectiveOperationInvoker;
|
||||
import org.springframework.boot.endpoint.Selector;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
@@ -79,8 +79,8 @@ public class WebAnnotationEndpointDiscoverer extends
|
||||
|
||||
@Override
|
||||
public Collection<EndpointInfo<WebEndpointOperation>> discoverEndpoints() {
|
||||
Collection<EndpointInfoDescriptor<WebEndpointOperation, OperationRequestPredicate>> endpoints = discoverEndpointsWithExtension(
|
||||
WebEndpointExtension.class, EndpointType.WEB);
|
||||
Collection<EndpointInfoDescriptor<WebEndpointOperation, OperationRequestPredicate>> endpoints = discoverEndpoints(
|
||||
WebEndpointExtension.class, EndpointDelivery.WEB);
|
||||
verifyThatOperationsHaveDistinctPredicates(endpoints);
|
||||
return endpoints.stream().map(EndpointInfoDescriptor::getEndpointInfo)
|
||||
.collect(Collectors.toList());
|
||||
@@ -129,7 +129,7 @@ public class WebAnnotationEndpointDiscoverer extends
|
||||
@Override
|
||||
public WebEndpointOperation createOperation(String endpointId,
|
||||
AnnotationAttributes operationAttributes, Object target, Method method,
|
||||
EndpointOperationType type, long timeToLive) {
|
||||
OperationType type, long timeToLive) {
|
||||
WebEndpointHttpMethod httpMethod = determineHttpMethod(type);
|
||||
OperationRequestPredicate requestPredicate = new OperationRequestPredicate(
|
||||
determinePath(endpointId, method), httpMethod,
|
||||
@@ -201,9 +201,8 @@ public class WebAnnotationEndpointDiscoverer extends
|
||||
(parameter) -> parameter.getAnnotation(Selector.class) == null);
|
||||
}
|
||||
|
||||
private WebEndpointHttpMethod determineHttpMethod(
|
||||
EndpointOperationType operationType) {
|
||||
if (operationType == EndpointOperationType.WRITE) {
|
||||
private WebEndpointHttpMethod determineHttpMethod(OperationType operationType) {
|
||||
if (operationType == OperationType.WRITE) {
|
||||
return WebEndpointHttpMethod.POST;
|
||||
}
|
||||
return WebEndpointHttpMethod.GET;
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
|
||||
package org.springframework.boot.endpoint.web;
|
||||
|
||||
import org.springframework.boot.endpoint.EndpointOperation;
|
||||
import org.springframework.boot.endpoint.EndpointOperationType;
|
||||
import org.springframework.boot.endpoint.Operation;
|
||||
import org.springframework.boot.endpoint.OperationInvoker;
|
||||
import org.springframework.boot.endpoint.OperationType;
|
||||
|
||||
/**
|
||||
* An operation on a web endpoint.
|
||||
@@ -26,7 +26,7 @@ import org.springframework.boot.endpoint.OperationInvoker;
|
||||
* @author Andy Wilkinson
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public class WebEndpointOperation extends EndpointOperation {
|
||||
public class WebEndpointOperation extends Operation {
|
||||
|
||||
private final OperationRequestPredicate requestPredicate;
|
||||
|
||||
@@ -42,9 +42,8 @@ public class WebEndpointOperation extends EndpointOperation {
|
||||
* @param requestPredicate the predicate for requests that can be handled by the
|
||||
* @param id the id of the operation, unique within its endpoint operation
|
||||
*/
|
||||
public WebEndpointOperation(EndpointOperationType type,
|
||||
OperationInvoker operationInvoker, boolean blocking,
|
||||
OperationRequestPredicate requestPredicate, String id) {
|
||||
public WebEndpointOperation(OperationType type, OperationInvoker operationInvoker,
|
||||
boolean blocking, OperationRequestPredicate requestPredicate, String id) {
|
||||
super(type, operationInvoker, blocking);
|
||||
this.requestPredicate = requestPredicate;
|
||||
this.id = id;
|
||||
|
||||
@@ -80,7 +80,7 @@ public class JerseyEndpointResourceFactory {
|
||||
resourceBuilder.addMethod(requestPredicate.getHttpMethod().name())
|
||||
.consumes(toStringArray(requestPredicate.getConsumes()))
|
||||
.produces(toStringArray(requestPredicate.getProduces()))
|
||||
.handledBy(new EndpointInvokingInflector(operation.getOperationInvoker(),
|
||||
.handledBy(new EndpointInvokingInflector(operation.getInvoker(),
|
||||
!requestPredicate.getConsumes().isEmpty()));
|
||||
return resourceBuilder.build();
|
||||
}
|
||||
@@ -110,28 +110,32 @@ public class JerseyEndpointResourceFactory {
|
||||
this.readBody = readBody;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public Response apply(ContainerRequestContext data) {
|
||||
Map<String, Object> arguments = new HashMap<>();
|
||||
if (this.readBody) {
|
||||
Map<String, Object> body = ((ContainerRequest) data)
|
||||
.readEntity(Map.class);
|
||||
if (body != null) {
|
||||
arguments.putAll(body);
|
||||
}
|
||||
arguments.putAll(extractBodyArguments(data));
|
||||
}
|
||||
arguments.putAll(extractPathParameters(data));
|
||||
arguments.putAll(extractQueryParameters(data));
|
||||
try {
|
||||
return convertToJaxRsResponse(this.operationInvoker.invoke(arguments),
|
||||
data.getRequest().getMethod());
|
||||
Object response = this.operationInvoker.invoke(arguments);
|
||||
return convertToJaxRsResponse(response, data.getRequest().getMethod());
|
||||
}
|
||||
catch (ParameterMappingException ex) {
|
||||
return Response.status(Status.BAD_REQUEST).build();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Map<String, Object> extractBodyArguments(ContainerRequestContext data) {
|
||||
Map<?, ?> entity = ((ContainerRequest) data).readEntity(Map.class);
|
||||
if (entity == null) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
return (Map<String, Object>) entity;
|
||||
}
|
||||
|
||||
private Map<String, Object> extractPathParameters(
|
||||
ContainerRequestContext requestContext) {
|
||||
return extract(requestContext.getUriInfo().getPathParameters());
|
||||
@@ -155,8 +159,9 @@ public class JerseyEndpointResourceFactory {
|
||||
|
||||
private Response convertToJaxRsResponse(Object response, String httpMethod) {
|
||||
if (response == null) {
|
||||
return Response.status(HttpMethod.GET.equals(httpMethod)
|
||||
? Status.NOT_FOUND : Status.NO_CONTENT).build();
|
||||
boolean isGet = HttpMethod.GET.equals(httpMethod);
|
||||
Status status = (isGet ? Status.NOT_FOUND : Status.NO_CONTENT);
|
||||
return Response.status(status).build();
|
||||
}
|
||||
try {
|
||||
if (!(response instanceof WebEndpointResponse)) {
|
||||
|
||||
@@ -47,8 +47,8 @@ import org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMappi
|
||||
* @author Madhura Bhave
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public abstract class AbstractWebEndpointServletHandlerMapping extends RequestMappingInfoHandlerMapping
|
||||
implements InitializingBean {
|
||||
public abstract class AbstractWebEndpointServletHandlerMapping
|
||||
extends RequestMappingInfoHandlerMapping implements InitializingBean {
|
||||
|
||||
private final String endpointPath;
|
||||
|
||||
@@ -96,9 +96,12 @@ public abstract class AbstractWebEndpointServletHandlerMapping extends RequestMa
|
||||
this.webEndpoints.stream()
|
||||
.flatMap((webEndpoint) -> webEndpoint.getOperations().stream())
|
||||
.forEach(this::registerMappingForOperation);
|
||||
registerMapping(new RequestMappingInfo(patternsRequestConditionForPattern(""),
|
||||
new RequestMethodsRequestCondition(RequestMethod.GET), null, null, null,
|
||||
null, null), this, getLinks());
|
||||
PatternsRequestCondition patterns = patternsRequestConditionForPattern("");
|
||||
RequestMethodsRequestCondition methods = new RequestMethodsRequestCondition(
|
||||
RequestMethod.GET);
|
||||
RequestMappingInfo mapping = new RequestMappingInfo(patterns, methods, null, null,
|
||||
null, null, null);
|
||||
registerMapping(mapping, this, getLinks());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -114,23 +117,22 @@ public abstract class AbstractWebEndpointServletHandlerMapping extends RequestMa
|
||||
protected RequestMappingInfo createRequestMappingInfo(
|
||||
WebEndpointOperation operationInfo) {
|
||||
OperationRequestPredicate requestPredicate = operationInfo.getRequestPredicate();
|
||||
return new RequestMappingInfo(null,
|
||||
patternsRequestConditionForPattern(requestPredicate.getPath()),
|
||||
new RequestMethodsRequestCondition(
|
||||
RequestMethod.valueOf(requestPredicate.getHttpMethod().name())),
|
||||
null, null,
|
||||
new ConsumesRequestCondition(
|
||||
toStringArray(requestPredicate.getConsumes())),
|
||||
new ProducesRequestCondition(
|
||||
toStringArray(requestPredicate.getProduces())),
|
||||
null);
|
||||
PatternsRequestCondition patterns = patternsRequestConditionForPattern(
|
||||
requestPredicate.getPath());
|
||||
RequestMethodsRequestCondition methods = new RequestMethodsRequestCondition(
|
||||
RequestMethod.valueOf(requestPredicate.getHttpMethod().name()));
|
||||
ConsumesRequestCondition consumes = new ConsumesRequestCondition(
|
||||
toStringArray(requestPredicate.getConsumes()));
|
||||
ProducesRequestCondition produces = new ProducesRequestCondition(
|
||||
toStringArray(requestPredicate.getProduces()));
|
||||
return new RequestMappingInfo(null, patterns, methods, null, null, consumes,
|
||||
produces, null);
|
||||
}
|
||||
|
||||
private PatternsRequestCondition patternsRequestConditionForPattern(String path) {
|
||||
return new PatternsRequestCondition(
|
||||
new String[] { this.endpointPath
|
||||
+ (StringUtils.hasText(path) ? "/" + path : "") },
|
||||
null, null, false, false);
|
||||
String[] patterns = new String[] {
|
||||
this.endpointPath + (StringUtils.hasText(path) ? "/" + path : "") };
|
||||
return new PatternsRequestCondition(patterns, null, null, false, false);
|
||||
}
|
||||
|
||||
private String[] toStringArray(Collection<String> collection) {
|
||||
@@ -172,5 +174,4 @@ public abstract class AbstractWebEndpointServletHandlerMapping extends RequestMa
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -49,7 +49,8 @@ import org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMappi
|
||||
* @author Andy Wilkinson
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public class WebEndpointServletHandlerMapping extends AbstractWebEndpointServletHandlerMapping {
|
||||
public class WebEndpointServletHandlerMapping
|
||||
extends AbstractWebEndpointServletHandlerMapping {
|
||||
|
||||
private final Method handle = ReflectionUtils.findMethod(OperationHandler.class,
|
||||
"handle", HttpServletRequest.class, Map.class);
|
||||
@@ -84,11 +85,13 @@ public class WebEndpointServletHandlerMapping extends AbstractWebEndpointServlet
|
||||
setOrder(-100);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void registerMappingForOperation(WebEndpointOperation operation) {
|
||||
registerMapping(createRequestMappingInfo(operation),
|
||||
new OperationHandler(operation.getOperationInvoker()), this.handle);
|
||||
new OperationHandler(operation.getInvoker()), this.handle);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Method getLinks() {
|
||||
return this.links;
|
||||
}
|
||||
|
||||
@@ -24,8 +24,8 @@ import java.util.Map;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.boot.endpoint.EndpointInfo;
|
||||
import org.springframework.boot.endpoint.EndpointOperationType;
|
||||
import org.springframework.boot.endpoint.OperationInvoker;
|
||||
import org.springframework.boot.endpoint.OperationType;
|
||||
import org.springframework.boot.endpoint.ParameterMappingException;
|
||||
import org.springframework.boot.endpoint.web.EndpointLinksResolver;
|
||||
import org.springframework.boot.endpoint.web.Link;
|
||||
@@ -126,29 +126,28 @@ public class WebEndpointReactiveHandlerMapping extends RequestMappingInfoHandler
|
||||
}
|
||||
|
||||
private void registerMappingForOperation(WebEndpointOperation operation) {
|
||||
EndpointOperationType operationType = operation.getType();
|
||||
OperationType operationType = operation.getType();
|
||||
registerMapping(createRequestMappingInfo(operation),
|
||||
operationType == EndpointOperationType.WRITE
|
||||
? new WriteOperationHandler(operation.getOperationInvoker())
|
||||
: new ReadOperationHandler(operation.getOperationInvoker()),
|
||||
operationType == EndpointOperationType.WRITE ? this.handleWrite
|
||||
operationType == OperationType.WRITE
|
||||
? new WriteOperationHandler(operation.getInvoker())
|
||||
: new ReadOperationHandler(operation.getInvoker()),
|
||||
operationType == OperationType.WRITE ? this.handleWrite
|
||||
: this.handleRead);
|
||||
}
|
||||
|
||||
private RequestMappingInfo createRequestMappingInfo(
|
||||
WebEndpointOperation operationInfo) {
|
||||
OperationRequestPredicate requestPredicate = operationInfo.getRequestPredicate();
|
||||
return new RequestMappingInfo(null,
|
||||
new PatternsRequestCondition(pathPatternParser
|
||||
.parse(this.endpointPath + "/" + requestPredicate.getPath())),
|
||||
new RequestMethodsRequestCondition(
|
||||
RequestMethod.valueOf(requestPredicate.getHttpMethod().name())),
|
||||
null, null,
|
||||
new ConsumesRequestCondition(
|
||||
toStringArray(requestPredicate.getConsumes())),
|
||||
new ProducesRequestCondition(
|
||||
toStringArray(requestPredicate.getProduces())),
|
||||
null);
|
||||
PatternsRequestCondition patterns = new PatternsRequestCondition(pathPatternParser
|
||||
.parse(this.endpointPath + "/" + requestPredicate.getPath()));
|
||||
RequestMethodsRequestCondition methods = new RequestMethodsRequestCondition(
|
||||
RequestMethod.valueOf(requestPredicate.getHttpMethod().name()));
|
||||
ConsumesRequestCondition consumes = new ConsumesRequestCondition(
|
||||
toStringArray(requestPredicate.getConsumes()));
|
||||
ProducesRequestCondition produces = new ProducesRequestCondition(
|
||||
toStringArray(requestPredicate.getProduces()));
|
||||
return new RequestMappingInfo(null, patterns, methods, null, null, consumes,
|
||||
produces, null);
|
||||
}
|
||||
|
||||
private String[] toStringArray(Collection<String> collection) {
|
||||
|
||||
@@ -116,7 +116,7 @@ public class AnnotationEndpointDiscovererTests {
|
||||
endpoints.get("test"));
|
||||
assertThat(operations).hasSize(3);
|
||||
operations.values()
|
||||
.forEach(operation -> assertThat(operation.getOperationInvoker())
|
||||
.forEach(operation -> assertThat(operation.getInvoker())
|
||||
.isNotInstanceOf(CachingOperationInvoker.class));
|
||||
});
|
||||
}
|
||||
@@ -135,7 +135,7 @@ public class AnnotationEndpointDiscovererTests {
|
||||
endpoints.get("test"));
|
||||
assertThat(operations).hasSize(3);
|
||||
operations.values()
|
||||
.forEach(operation -> assertThat(operation.getOperationInvoker())
|
||||
.forEach(operation -> assertThat(operation.getInvoker())
|
||||
.isNotInstanceOf(CachingOperationInvoker.class));
|
||||
});
|
||||
}
|
||||
@@ -154,16 +154,16 @@ public class AnnotationEndpointDiscovererTests {
|
||||
endpoints.get("test"));
|
||||
OperationInvoker getAllOperationInvoker = operations
|
||||
.get(ReflectionUtils.findMethod(TestEndpoint.class, "getAll"))
|
||||
.getOperationInvoker();
|
||||
.getInvoker();
|
||||
assertThat(getAllOperationInvoker)
|
||||
.isInstanceOf(CachingOperationInvoker.class);
|
||||
assertThat(((CachingOperationInvoker) getAllOperationInvoker).getTimeToLive())
|
||||
.isEqualTo(500);
|
||||
assertThat(operations.get(ReflectionUtils.findMethod(TestEndpoint.class,
|
||||
"getOne", String.class)).getOperationInvoker())
|
||||
"getOne", String.class)).getInvoker())
|
||||
.isNotInstanceOf(CachingOperationInvoker.class);
|
||||
assertThat(operations.get(ReflectionUtils.findMethod(TestEndpoint.class,
|
||||
"update", String.class, String.class)).getOperationInvoker())
|
||||
"update", String.class, String.class)).getInvoker())
|
||||
.isNotInstanceOf(CachingOperationInvoker.class);
|
||||
});
|
||||
}
|
||||
@@ -186,7 +186,7 @@ public class AnnotationEndpointDiscovererTests {
|
||||
EndpointInfo<TestEndpointOperation> endpoint) {
|
||||
Map<Method, TestEndpointOperation> operationByMethod = new HashMap<>();
|
||||
endpoint.getOperations().forEach((operation) -> {
|
||||
EndpointOperation existing = operationByMethod
|
||||
Operation existing = operationByMethod
|
||||
.put(operation.getOperationMethod(), operation);
|
||||
if (existing != null) {
|
||||
throw new AssertionError(String.format(
|
||||
@@ -281,11 +281,11 @@ public class AnnotationEndpointDiscovererTests {
|
||||
}
|
||||
}
|
||||
|
||||
private static final class TestEndpointOperation extends EndpointOperation {
|
||||
private static final class TestEndpointOperation extends Operation {
|
||||
|
||||
private final Method operationMethod;
|
||||
|
||||
private TestEndpointOperation(EndpointOperationType type,
|
||||
private TestEndpointOperation(OperationType type,
|
||||
OperationInvoker operationInvoker, Method operationMethod) {
|
||||
super(type, operationInvoker, true);
|
||||
this.operationMethod = operationMethod;
|
||||
@@ -313,7 +313,7 @@ public class AnnotationEndpointDiscovererTests {
|
||||
|
||||
@Override
|
||||
public Collection<EndpointInfo<TestEndpointOperation>> discoverEndpoints() {
|
||||
return discoverEndpointsWithExtension(null, null).stream()
|
||||
return discoverEndpoints(null, null).stream()
|
||||
.map(EndpointInfoDescriptor::getEndpointInfo)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
@@ -324,7 +324,7 @@ public class AnnotationEndpointDiscovererTests {
|
||||
@Override
|
||||
public TestEndpointOperation createOperation(String endpointId,
|
||||
AnnotationAttributes operationAttributes, Object target,
|
||||
Method operationMethod, EndpointOperationType operationType,
|
||||
Method operationMethod, OperationType operationType,
|
||||
long timeToLive) {
|
||||
return new TestEndpointOperation(operationType,
|
||||
createOperationInvoker(timeToLive), operationMethod);
|
||||
|
||||
@@ -26,8 +26,8 @@ import javax.management.MBeanParameterInfo;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.boot.endpoint.EndpointInfo;
|
||||
import org.springframework.boot.endpoint.EndpointOperationType;
|
||||
import org.springframework.boot.endpoint.OperationInvoker;
|
||||
import org.springframework.boot.endpoint.OperationType;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.entry;
|
||||
@@ -44,9 +44,9 @@ public class EndpointMBeanInfoAssemblerTests {
|
||||
|
||||
@Test
|
||||
public void exposeSimpleReadOperation() {
|
||||
JmxEndpointOperation operation = new JmxEndpointOperation(
|
||||
EndpointOperationType.READ, new DummyOperationInvoker(), "getAll",
|
||||
Object.class, "Test operation", Collections.emptyList());
|
||||
JmxEndpointOperation operation = new JmxEndpointOperation(OperationType.READ,
|
||||
new DummyOperationInvoker(), "getAll", Object.class, "Test operation",
|
||||
Collections.emptyList());
|
||||
EndpointInfo<JmxEndpointOperation> endpoint = new EndpointInfo<>("test", true,
|
||||
Collections.singletonList(operation));
|
||||
EndpointMBeanInfo endpointMBeanInfo = this.mBeanInfoAssembler
|
||||
@@ -73,9 +73,8 @@ public class EndpointMBeanInfoAssemblerTests {
|
||||
|
||||
@Test
|
||||
public void exposeSimpleWriteOperation() {
|
||||
JmxEndpointOperation operation = new JmxEndpointOperation(
|
||||
EndpointOperationType.WRITE, new DummyOperationInvoker(), "update",
|
||||
Object.class, "Update operation",
|
||||
JmxEndpointOperation operation = new JmxEndpointOperation(OperationType.WRITE,
|
||||
new DummyOperationInvoker(), "update", Object.class, "Update operation",
|
||||
Collections.singletonList(new JmxEndpointOperationParameterInfo("test",
|
||||
String.class, "Test argument")));
|
||||
EndpointInfo<JmxEndpointOperation> endpoint = new EndpointInfo<>("another", true,
|
||||
|
||||
@@ -31,8 +31,8 @@ import org.springframework.boot.endpoint.CachingConfiguration;
|
||||
import org.springframework.boot.endpoint.CachingOperationInvoker;
|
||||
import org.springframework.boot.endpoint.ConversionServiceOperationParameterMapper;
|
||||
import org.springframework.boot.endpoint.Endpoint;
|
||||
import org.springframework.boot.endpoint.EndpointDelivery;
|
||||
import org.springframework.boot.endpoint.EndpointInfo;
|
||||
import org.springframework.boot.endpoint.EndpointType;
|
||||
import org.springframework.boot.endpoint.ReadOperation;
|
||||
import org.springframework.boot.endpoint.ReflectiveOperationInvoker;
|
||||
import org.springframework.boot.endpoint.WriteOperation;
|
||||
@@ -77,7 +77,7 @@ public class JmxAnnotationEndpointDiscovererTests {
|
||||
.isEqualTo("Invoke getAll for endpoint test");
|
||||
assertThat(getAll.getOutputType()).isEqualTo(Object.class);
|
||||
assertThat(getAll.getParameters()).isEmpty();
|
||||
assertThat(getAll.getOperationInvoker())
|
||||
assertThat(getAll.getInvoker())
|
||||
.isInstanceOf(ReflectiveOperationInvoker.class);
|
||||
JmxEndpointOperation getSomething = operationByName.get("getSomething");
|
||||
assertThat(getSomething.getDescription())
|
||||
@@ -155,10 +155,9 @@ public class JmxAnnotationEndpointDiscovererTests {
|
||||
assertThat(operationByName).containsOnlyKeys("getAll", "getSomething",
|
||||
"update");
|
||||
JmxEndpointOperation getAll = operationByName.get("getAll");
|
||||
assertThat(getAll.getOperationInvoker())
|
||||
.isInstanceOf(CachingOperationInvoker.class);
|
||||
assertThat(((CachingOperationInvoker) getAll.getOperationInvoker())
|
||||
.getTimeToLive()).isEqualTo(500);
|
||||
assertThat(getAll.getInvoker()).isInstanceOf(CachingOperationInvoker.class);
|
||||
assertThat(((CachingOperationInvoker) getAll.getInvoker()).getTimeToLive())
|
||||
.isEqualTo(500);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -174,16 +173,15 @@ public class JmxAnnotationEndpointDiscovererTests {
|
||||
assertThat(operationByName).containsOnlyKeys("getAll", "getSomething",
|
||||
"update", "getAnother");
|
||||
JmxEndpointOperation getAll = operationByName.get("getAll");
|
||||
assertThat(getAll.getOperationInvoker())
|
||||
assertThat(getAll.getInvoker())
|
||||
.isInstanceOf(CachingOperationInvoker.class);
|
||||
assertThat(((CachingOperationInvoker) getAll.getOperationInvoker())
|
||||
assertThat(((CachingOperationInvoker) getAll.getInvoker())
|
||||
.getTimeToLive()).isEqualTo(500);
|
||||
JmxEndpointOperation getAnother = operationByName.get("getAnother");
|
||||
assertThat(getAnother.getOperationInvoker())
|
||||
assertThat(getAnother.getInvoker())
|
||||
.isInstanceOf(CachingOperationInvoker.class);
|
||||
assertThat(
|
||||
((CachingOperationInvoker) getAnother.getOperationInvoker())
|
||||
.getTimeToLive()).isEqualTo(500);
|
||||
assertThat(((CachingOperationInvoker) getAnother.getInvoker())
|
||||
.getTimeToLive()).isEqualTo(500);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -333,7 +331,7 @@ public class JmxAnnotationEndpointDiscovererTests {
|
||||
|
||||
}
|
||||
|
||||
@Endpoint(id = "jmx", types = EndpointType.JMX)
|
||||
@Endpoint(id = "jmx", delivery = EndpointDelivery.JMX)
|
||||
private static class TestJmxEndpoint {
|
||||
|
||||
@ReadOperation
|
||||
@@ -412,7 +410,7 @@ public class JmxAnnotationEndpointDiscovererTests {
|
||||
|
||||
}
|
||||
|
||||
@Endpoint(id = "nonjmx", types = EndpointType.WEB)
|
||||
@Endpoint(id = "nonjmx", delivery = EndpointDelivery.WEB)
|
||||
private static class NonJmxEndpoint {
|
||||
|
||||
@ReadOperation
|
||||
|
||||
@@ -24,7 +24,7 @@ import org.assertj.core.api.Condition;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.boot.endpoint.EndpointInfo;
|
||||
import org.springframework.boot.endpoint.EndpointOperationType;
|
||||
import org.springframework.boot.endpoint.OperationType;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@@ -74,7 +74,7 @@ public class EndpointLinksResolverTests {
|
||||
}
|
||||
|
||||
private WebEndpointOperation operationWithPath(String path, String id) {
|
||||
return new WebEndpointOperation(EndpointOperationType.READ, null, false,
|
||||
return new WebEndpointOperation(OperationType.READ, null, false,
|
||||
new OperationRequestPredicate(path, WebEndpointHttpMethod.GET,
|
||||
Collections.emptyList(), Collections.emptyList()),
|
||||
id);
|
||||
|
||||
@@ -37,8 +37,8 @@ import org.springframework.boot.endpoint.CachingConfiguration;
|
||||
import org.springframework.boot.endpoint.CachingOperationInvoker;
|
||||
import org.springframework.boot.endpoint.ConversionServiceOperationParameterMapper;
|
||||
import org.springframework.boot.endpoint.Endpoint;
|
||||
import org.springframework.boot.endpoint.EndpointDelivery;
|
||||
import org.springframework.boot.endpoint.EndpointInfo;
|
||||
import org.springframework.boot.endpoint.EndpointType;
|
||||
import org.springframework.boot.endpoint.OperationInvoker;
|
||||
import org.springframework.boot.endpoint.ReadOperation;
|
||||
import org.springframework.boot.endpoint.Selector;
|
||||
@@ -194,7 +194,7 @@ public class WebAnnotationEndpointDiscovererTests {
|
||||
EndpointInfo<WebEndpointOperation> endpoint = endpoints.get("test");
|
||||
assertThat(endpoint.getOperations()).hasSize(1);
|
||||
OperationInvoker operationInvoker = endpoint.getOperations()
|
||||
.iterator().next().getOperationInvoker();
|
||||
.iterator().next().getInvoker();
|
||||
assertThat(operationInvoker)
|
||||
.isInstanceOf(CachingOperationInvoker.class);
|
||||
assertThat(
|
||||
@@ -375,7 +375,7 @@ public class WebAnnotationEndpointDiscovererTests {
|
||||
|
||||
}
|
||||
|
||||
@Endpoint(id = "nonweb", types = EndpointType.JMX)
|
||||
@Endpoint(id = "nonweb", delivery = EndpointDelivery.JMX)
|
||||
static class NonWebEndpoint {
|
||||
|
||||
@ReadOperation
|
||||
|
||||
Reference in New Issue
Block a user