Polish endpoint parameter name discovery

Move logic from `ParameterNameMapper` into `ReflectiveOperationInvoker`
in order to reduce the surface area of the public API.

Also rename some classes for consistency.
This commit is contained in:
Phillip Webb 2017-11-01 19:55:19 -07:00
parent fdec841f48
commit 44d8e09aac
22 changed files with 198 additions and 210 deletions

View File

@ -20,7 +20,7 @@ import java.util.Arrays;
import org.springframework.boot.actuate.autoconfigure.endpoint.DefaultCachingConfigurationFactory;
import org.springframework.boot.actuate.autoconfigure.web.servlet.ServletManagementContextAutoConfiguration;
import org.springframework.boot.actuate.endpoint.OperationParameterMapper;
import org.springframework.boot.actuate.endpoint.ParameterMapper;
import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes;
import org.springframework.boot.actuate.endpoint.web.annotation.WebAnnotationEndpointDiscoverer;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
@ -76,7 +76,7 @@ public class CloudFoundryActuatorAutoConfiguration {
@Bean
public CloudFoundryWebEndpointServletHandlerMapping cloudFoundryWebEndpointServletHandlerMapping(
OperationParameterMapper parameterMapper,
ParameterMapper parameterMapper,
DefaultCachingConfigurationFactory cachingConfigurationFactory,
EndpointMediaTypes endpointMediaTypes, Environment environment,
RestTemplateBuilder builder) {

View File

@ -20,10 +20,10 @@ import java.util.Arrays;
import java.util.List;
import org.springframework.boot.actuate.endpoint.EndpointExposure;
import org.springframework.boot.actuate.endpoint.OperationParameterMapper;
import org.springframework.boot.actuate.endpoint.ParameterMapper;
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.actuate.endpoint.cache.CachingConfigurationFactory;
import org.springframework.boot.actuate.endpoint.convert.ConversionServiceOperationParameterMapper;
import org.springframework.boot.actuate.endpoint.convert.ConversionServiceParameterMapper;
import org.springframework.boot.actuate.endpoint.http.ActuatorMediaType;
import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes;
import org.springframework.boot.actuate.endpoint.web.EndpointPathResolver;
@ -49,13 +49,13 @@ import org.springframework.core.env.Environment;
public class EndpointAutoConfiguration {
@Bean
public OperationParameterMapper operationParameterMapper() {
return new ConversionServiceOperationParameterMapper();
public ParameterMapper endpointOperationParameterMapper() {
return new ConversionServiceParameterMapper();
}
@Bean
@ConditionalOnMissingBean(CachingConfigurationFactory.class)
public DefaultCachingConfigurationFactory cacheConfigurationFactory(
public DefaultCachingConfigurationFactory endpointCacheConfigurationFactory(
Environment environment) {
return new DefaultCachingConfigurationFactory(environment);
}
@ -80,14 +80,13 @@ public class EndpointAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public EndpointPathResolver endpointPathResolver(
Environment environment) {
public EndpointPathResolver endpointPathResolver(Environment environment) {
return new DefaultEndpointPathResolver(environment);
}
@Bean
public EndpointProvider<WebEndpointOperation> webEndpointProvider(
OperationParameterMapper parameterMapper,
ParameterMapper parameterMapper,
DefaultCachingConfigurationFactory cachingConfigurationFactory,
EndpointPathResolver endpointPathResolver) {
Environment environment = this.applicationContext.getEnvironment();

View File

@ -24,7 +24,7 @@ import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.actuate.autoconfigure.endpoint.DefaultCachingConfigurationFactory;
import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointProvider;
import org.springframework.boot.actuate.endpoint.EndpointExposure;
import org.springframework.boot.actuate.endpoint.OperationParameterMapper;
import org.springframework.boot.actuate.endpoint.ParameterMapper;
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.actuate.endpoint.jmx.EndpointMBeanRegistrar;
import org.springframework.boot.actuate.endpoint.jmx.JmxEndpointOperation;
@ -58,10 +58,10 @@ public class JmxEndpointAutoConfiguration {
@Bean
public JmxAnnotationEndpointDiscoverer jmxEndpointDiscoverer(
OperationParameterMapper operationParameterMapper,
ParameterMapper parameterMapper,
DefaultCachingConfigurationFactory cachingConfigurationFactory) {
return new JmxAnnotationEndpointDiscoverer(this.applicationContext,
operationParameterMapper, cachingConfigurationFactory);
parameterMapper, cachingConfigurationFactory);
}
@ConditionalOnSingleCandidate(MBeanServer.class)

View File

@ -24,13 +24,13 @@ import java.util.function.Consumer;
import org.junit.Test;
import org.springframework.boot.actuate.endpoint.OperationParameterMapper;
import org.springframework.boot.actuate.endpoint.ParameterMapper;
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
import org.springframework.boot.actuate.endpoint.annotation.Selector;
import org.springframework.boot.actuate.endpoint.annotation.WriteOperation;
import org.springframework.boot.actuate.endpoint.cache.CachingConfiguration;
import org.springframework.boot.actuate.endpoint.convert.ConversionServiceOperationParameterMapper;
import org.springframework.boot.actuate.endpoint.convert.ConversionServiceParameterMapper;
import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes;
import org.springframework.boot.actuate.endpoint.web.annotation.WebAnnotationEndpointDiscoverer;
import org.springframework.boot.endpoint.web.EndpointMapping;
@ -215,7 +215,7 @@ public class CloudFoundryMvcWebEndpointIntegrationTests {
public WebAnnotationEndpointDiscoverer webEndpointDiscoverer(
ApplicationContext applicationContext,
EndpointMediaTypes endpointMediaTypes) {
OperationParameterMapper parameterMapper = new ConversionServiceOperationParameterMapper(
ParameterMapper parameterMapper = new ConversionServiceParameterMapper(
DefaultConversionService.getSharedInstance());
return new WebAnnotationEndpointDiscoverer(applicationContext,
parameterMapper, (id) -> new CachingConfiguration(0),

View File

@ -17,23 +17,22 @@
package org.springframework.boot.actuate.endpoint;
/**
* An {@code OperationParameterMapper} is used to map parameters to the required type when
* invoking an endpoint.
* Maps parameters to the required type when invoking an endpoint.
*
* @author Stephane Nicoll
* @since 2.0.0
*/
@FunctionalInterface
public interface OperationParameterMapper {
public interface ParameterMapper {
/**
* Map the specified {@code input} parameter to the given {@code parameterType}.
* @param input a parameter value
* @param parameterType the required type of the parameter
* @param value a parameter value
* @param type the required type of the parameter
* @return a value suitable for that parameter
* @param <T> the actual type of the parameter
* @throws ParameterMappingException when a mapping failure occurs
*/
<T> T mapParameter(Object input, Class<T> parameterType);
<T> T mapParameter(Object value, Class<T> type);
}

View File

@ -18,7 +18,7 @@ package org.springframework.boot.actuate.endpoint;
/**
* A {@code ParameterMappingException} is thrown when a failure occurs during
* {@link OperationParameterMapper#mapParameter(Object, Class) operation parameter
* {@link ParameterMapper#mapParameter(Object, Class) operation parameter
* mapping}.
*
* @author Andy Wilkinson

View File

@ -1,71 +0,0 @@
/*
* Copyright 2012-2017 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.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.function.Function;
import org.springframework.core.DefaultParameterNameDiscoverer;
import org.springframework.core.ParameterNameDiscoverer;
/**
* Map method's parameter by name.
*
* @author Stephane Nicoll
* @since 2.0.0
* @see ParameterNameDiscoverer
*/
public class ParameterNameMapper implements Function<Method, Map<String, Parameter>> {
private final ParameterNameDiscoverer parameterNameDiscoverer;
public ParameterNameMapper(ParameterNameDiscoverer parameterNameDiscoverer) {
this.parameterNameDiscoverer = parameterNameDiscoverer;
}
public ParameterNameMapper() {
this(new DefaultParameterNameDiscoverer());
}
/**
* Map the {@link Parameter parameters} of the specified {@link Method} by parameter
* name.
* @param method the method to handle
* @return the parameters of the {@code method}, mapped by parameter name
*/
@Override
public Map<String, Parameter> apply(Method method) {
String[] parameterNames = this.parameterNameDiscoverer.getParameterNames(
method);
Map<String, Parameter> parameters = new LinkedHashMap<>();
if (parameterNames != null) {
for (int i = 0; i < parameterNames.length; i++) {
parameters.put(parameterNames[i], method.getParameters()[i]);
}
return parameters;
}
else {
throw new IllegalStateException("Failed to extract parameter names for "
+ method);
}
}
}

View File

@ -18,12 +18,18 @@ package org.springframework.boot.actuate.endpoint;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.function.BiFunction;
import java.util.stream.Collectors;
import org.springframework.core.DefaultParameterNameDiscoverer;
import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ReflectionUtils;
/**
@ -35,37 +41,91 @@ import org.springframework.util.ReflectionUtils;
*/
public class ReflectiveOperationInvoker implements OperationInvoker {
private final OperationParameterMapper parameterMapper;
private final Function<Method, Map<String, Parameter>> parameterNameMapper;
private static final ParameterNameDiscoverer DEFAULT_PARAMETER_NAME_DISCOVERER = new DefaultParameterNameDiscoverer();
private final Object target;
private final Method method;
private final ParameterMapper parameterMapper;
private final ParameterNameDiscoverer parameterNameDiscoverer;
/**
* 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 and the given
* {@code parameterNameMapper} will be used map parameters by name.
* @param parameterMapper the parameter mapper
* @param parameterNameMapper the parameter name mapper
* @param target the target of the reflective call
* @param method the method to call
* @param parameterMapper the parameter mapper
*/
public ReflectiveOperationInvoker(OperationParameterMapper parameterMapper,
Function<Method, Map<String, Parameter>> parameterNameMapper,
Object target, Method method) {
this.parameterMapper = parameterMapper;
this.parameterNameMapper = parameterNameMapper;
this.target = target;
public ReflectiveOperationInvoker(Object target, Method method,
ParameterMapper parameterMapper) {
this(target, method, parameterMapper, DEFAULT_PARAMETER_NAME_DISCOVERER);
}
/**
* 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 and the given
* {@code parameterNameMapper} will be used map parameters by name.
* @param target the target of the reflective call
* @param method the method to call
* @param parameterMapper the parameter mapper
* @param parameterNameDiscoverer the parameter name discoverer
*/
public ReflectiveOperationInvoker(Object target, Method method,
ParameterMapper parameterMapper,
ParameterNameDiscoverer parameterNameDiscoverer) {
Assert.notNull(target, "Target must not be null");
Assert.notNull(method, "Method must not be null");
Assert.notNull(parameterMapper, "ParameterMapper must not be null");
Assert.notNull(parameterNameDiscoverer,
"ParameterNameDiscoverer must not be null");
ReflectionUtils.makeAccessible(method);
this.target = target;
this.method = method;
this.parameterMapper = parameterMapper;
this.parameterNameDiscoverer = parameterNameDiscoverer;
}
/**
* Return the method that will be called on invocation.
* @return the method to be called
*/
public Method getMethod() {
return this.method;
}
/**
* Return the parameters of the method mapped using the given function.
* @param mapper a mapper {@link BiFunction} taking the discovered name and parameter
* as input and returning the mapped type.
* @param <T> the mapped type
* @return a list of parameters mapped to the desired type
*/
public <T> List<T> getParameters(BiFunction<String, Parameter, T> mapper) {
return getParameters().entrySet().stream()
.map((entry) -> mapper.apply(entry.getKey(), entry.getValue()))
.collect(Collectors.toCollection(ArrayList::new));
}
private Map<String, Parameter> getParameters() {
Parameter[] parameters = this.method.getParameters();
String[] names = this.parameterNameDiscoverer.getParameterNames(this.method);
Assert.state(names != null,
"Failed to extract parameter names for " + this.method);
Map<String, Parameter> result = new LinkedHashMap<>();
for (int i = 0; i < names.length; i++) {
result.put(names[i], parameters[i]);
}
return result;
}
@Override
public Object invoke(Map<String, Object> arguments) {
Map<String, Parameter> parameters = this.parameterNameMapper.apply(this.method);
Map<String, Parameter> parameters = getParameters();
validateRequiredParameters(parameters, arguments);
return ReflectionUtils.invokeMethod(this.method, this.target,
resolveArguments(parameters, arguments));
@ -99,7 +159,8 @@ public class ReflectiveOperationInvoker implements OperationInvoker {
(list) -> list.toArray(new Object[list.size()])));
}
private Object resolveArgument(String name, Parameter parameter, Map<String, Object> arguments) {
private Object resolveArgument(String name, Parameter parameter,
Map<String, Object> arguments) {
Object resolved = arguments.get(name);
return this.parameterMapper.mapParameter(resolved, parameter.getType());
}

View File

@ -68,6 +68,20 @@ public class CachingOperationInvoker implements OperationInvoker {
return cached.getResponse();
}
/**
* Apply caching configuration when appropriate to the given invoker.
* @param invoker the invoker to wrap
* @param timeToLive the maximum time in milliseconds that a response can be cached
* @return a caching version of the invoker or the original instance if caching is not
* required
*/
public static OperationInvoker apply(OperationInvoker invoker, long timeToLive) {
if (timeToLive > 0) {
return new CachingOperationInvoker(invoker, timeToLive);
}
return invoker;
}
/**
* A cached response that encapsulates the response itself and the time at which it
* was created.

View File

@ -16,26 +16,26 @@
package org.springframework.boot.actuate.endpoint.convert;
import org.springframework.boot.actuate.endpoint.OperationParameterMapper;
import org.springframework.boot.actuate.endpoint.ParameterMapper;
import org.springframework.boot.actuate.endpoint.ParameterMappingException;
import org.springframework.boot.context.properties.bind.convert.BinderConversionService;
import org.springframework.core.convert.ConversionService;
import org.springframework.format.support.DefaultFormattingConversionService;
/**
* {@link OperationParameterMapper} that uses a {@link ConversionService} to map parameter
* {@link ParameterMapper} that uses a {@link ConversionService} to map parameter
* values if necessary.
*
* @author Stephane Nicoll
* @author Phillip Webb
* @since 2.0.0
*/
public class ConversionServiceOperationParameterMapper
implements OperationParameterMapper {
public class ConversionServiceParameterMapper
implements ParameterMapper {
private final ConversionService conversionService;
public ConversionServiceOperationParameterMapper() {
public ConversionServiceParameterMapper() {
this(createDefaultConversionService());
}
@ -43,7 +43,7 @@ public class ConversionServiceOperationParameterMapper
* Create a new instance with the {@link ConversionService} to use.
* @param conversionService the conversion service
*/
public ConversionServiceOperationParameterMapper(
public ConversionServiceParameterMapper(
ConversionService conversionService) {
this.conversionService = new BinderConversionService(conversionService);
}

View File

@ -23,17 +23,13 @@ import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import org.springframework.boot.actuate.endpoint.EndpointExposure;
import org.springframework.boot.actuate.endpoint.EndpointInfo;
import org.springframework.boot.actuate.endpoint.OperationInvoker;
import org.springframework.boot.actuate.endpoint.OperationParameterMapper;
import org.springframework.boot.actuate.endpoint.OperationType;
import org.springframework.boot.actuate.endpoint.ParameterNameMapper;
import org.springframework.boot.actuate.endpoint.ParameterMapper;
import org.springframework.boot.actuate.endpoint.ReflectiveOperationInvoker;
import org.springframework.boot.actuate.endpoint.annotation.AnnotationEndpointDiscoverer;
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
@ -67,12 +63,12 @@ public class JmxAnnotationEndpointDiscoverer
* {@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
* @param parameterMapper the {@link ParameterMapper} used to convert arguments when
* an operation is invoked
* @param cachingConfigurationFactory the {@link CachingConfiguration} factory to use
*/
public JmxAnnotationEndpointDiscoverer(ApplicationContext applicationContext,
OperationParameterMapper parameterMapper,
ParameterMapper parameterMapper,
CachingConfigurationFactory cachingConfigurationFactory) {
super(applicationContext, new JmxEndpointOperationFactory(parameterMapper),
JmxEndpointOperation::getOperationName, cachingConfigurationFactory);
@ -109,11 +105,9 @@ public class JmxAnnotationEndpointDiscoverer
private static class JmxEndpointOperationFactory
implements EndpointOperationFactory<JmxEndpointOperation> {
private final OperationParameterMapper parameterMapper;
private final ParameterMapper parameterMapper;
private final Function<Method, Map<String, Parameter>> parameterNameMapper = new ParameterNameMapper();
JmxEndpointOperationFactory(OperationParameterMapper parameterMapper) {
JmxEndpointOperationFactory(ParameterMapper parameterMapper) {
this.parameterMapper = parameterMapper;
}
@ -121,18 +115,16 @@ public class JmxAnnotationEndpointDiscoverer
public JmxEndpointOperation createOperation(String endpointId,
AnnotationAttributes operationAttributes, Object target, Method method,
OperationType type, long timeToLive) {
ReflectiveOperationInvoker invoker = new ReflectiveOperationInvoker(
target, method, this.parameterMapper);
String operationName = method.getName();
Class<?> outputType = mapParameterType(method.getReturnType());
Class<?> outputType = getJmxType(method.getReturnType());
String description = getDescription(method,
() -> "Invoke " + operationName + " for endpoint " + endpointId);
List<JmxEndpointOperationParameterInfo> parameters = getParameters(method);
OperationInvoker invoker = new ReflectiveOperationInvoker(
this.parameterMapper, this.parameterNameMapper, target, method);
if (timeToLive > 0) {
invoker = new CachingOperationInvoker(invoker, timeToLive);
}
return new JmxEndpointOperation(type, invoker, operationName, outputType,
description, parameters);
List<JmxEndpointOperationParameterInfo> parameters = getParameters(invoker);
return new JmxEndpointOperation(type,
CachingOperationInvoker.apply(invoker, timeToLive), operationName,
outputType, description, parameters);
}
private String getDescription(Method method, Supplier<String> fallback) {
@ -145,58 +137,58 @@ public class JmxAnnotationEndpointDiscoverer
return fallback.get();
}
private List<JmxEndpointOperationParameterInfo> getParameters(Method method) {
Parameter[] methodParameters = method.getParameters();
if (methodParameters.length == 0) {
private List<JmxEndpointOperationParameterInfo> getParameters(
ReflectiveOperationInvoker invoker) {
if (invoker.getMethod().getParameterCount() == 0) {
return Collections.emptyList();
}
ManagedOperationParameter[] managedOperationParameters = jmxAttributeSource
.getManagedOperationParameters(method);
if (managedOperationParameters.length == 0) {
return getParametersInfo(method);
ManagedOperationParameter[] operationParameters = jmxAttributeSource
.getManagedOperationParameters(invoker.getMethod());
if (operationParameters.length == 0) {
return invoker.getParameters(this::getParameter);
}
return getParametersInfo(methodParameters, managedOperationParameters);
return mergeParameters(invoker.getMethod().getParameters(),
operationParameters);
}
private List<JmxEndpointOperationParameterInfo> getParametersInfo(Method method) {
Map<String, Parameter> methodParameters = this.parameterNameMapper
.apply(method);
List<JmxEndpointOperationParameterInfo> parameters = new ArrayList<>();
for (Map.Entry<String, Parameter> entry : methodParameters.entrySet()) {
String name = entry.getKey();
Class<?> type = mapParameterType(entry.getValue().getType());
parameters.add(new JmxEndpointOperationParameterInfo(name, type, null));
}
return parameters;
}
private List<JmxEndpointOperationParameterInfo> getParametersInfo(
private List<JmxEndpointOperationParameterInfo> mergeParameters(
Parameter[] methodParameters,
ManagedOperationParameter[] managedOperationParameters) {
ManagedOperationParameter[] operationParameters) {
List<JmxEndpointOperationParameterInfo> parameters = new ArrayList<>();
for (int i = 0; i < managedOperationParameters.length; i++) {
ManagedOperationParameter managedOperationParameter = managedOperationParameters[i];
for (int i = 0; i < operationParameters.length; i++) {
ManagedOperationParameter operationParameter = operationParameters[i];
Parameter methodParameter = methodParameters[i];
parameters.add(new JmxEndpointOperationParameterInfo(
managedOperationParameter.getName(),
mapParameterType(methodParameter.getType()),
managedOperationParameter.getDescription()));
JmxEndpointOperationParameterInfo parameter = getParameter(
operationParameter.getName(), methodParameter,
operationParameter.getDescription());
parameters.add(parameter);
}
return parameters;
}
private Class<?> mapParameterType(Class<?> parameter) {
if (parameter.isEnum()) {
private JmxEndpointOperationParameterInfo getParameter(String name,
Parameter methodParameter) {
return getParameter(name, methodParameter, null);
}
private JmxEndpointOperationParameterInfo getParameter(String name,
Parameter methodParameter, String description) {
return new JmxEndpointOperationParameterInfo(name,
getJmxType(methodParameter.getType()), description);
}
private Class<?> getJmxType(Class<?> type) {
if (type.isEnum()) {
return String.class;
}
if (Date.class.isAssignableFrom(parameter)) {
if (Date.class.isAssignableFrom(type)) {
return String.class;
}
if (parameter.getName().startsWith("java.")) {
return parameter;
if (type.getName().startsWith("java.")) {
return type;
}
if (parameter.equals(Void.TYPE)) {
return parameter;
if (type.equals(Void.TYPE)) {
return type;
}
return Object.class;
}

View File

@ -17,14 +17,11 @@
package org.springframework.boot.actuate.endpoint.web.annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@ -33,9 +30,8 @@ import org.reactivestreams.Publisher;
import org.springframework.boot.actuate.endpoint.EndpointExposure;
import org.springframework.boot.actuate.endpoint.EndpointInfo;
import org.springframework.boot.actuate.endpoint.OperationInvoker;
import org.springframework.boot.actuate.endpoint.OperationParameterMapper;
import org.springframework.boot.actuate.endpoint.ParameterMapper;
import org.springframework.boot.actuate.endpoint.OperationType;
import org.springframework.boot.actuate.endpoint.ParameterNameMapper;
import org.springframework.boot.actuate.endpoint.ReflectiveOperationInvoker;
import org.springframework.boot.actuate.endpoint.annotation.AnnotationEndpointDiscoverer;
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
@ -71,7 +67,7 @@ public class WebAnnotationEndpointDiscoverer extends
* {@link Endpoint endpoints} and {@link WebEndpointExtension web extensions} using
* the given {@link ApplicationContext}.
* @param applicationContext the application context
* @param operationParameterMapper the {@link OperationParameterMapper} used to
* @param parameterMapper the {@link ParameterMapper} used to
* convert arguments when an operation is invoked
* @param cachingConfigurationFactory the {@link CachingConfiguration} factory to use
* @param endpointMediaTypes the media types produced and consumed by web endpoint
@ -80,12 +76,12 @@ public class WebAnnotationEndpointDiscoverer extends
* endpoint paths
*/
public WebAnnotationEndpointDiscoverer(ApplicationContext applicationContext,
OperationParameterMapper operationParameterMapper,
ParameterMapper parameterMapper,
CachingConfigurationFactory cachingConfigurationFactory,
EndpointMediaTypes endpointMediaTypes,
EndpointPathResolver endpointPathResolver) {
super(applicationContext,
new WebEndpointOperationFactory(operationParameterMapper,
new WebEndpointOperationFactory(parameterMapper,
endpointMediaTypes, endpointPathResolver),
WebEndpointOperation::getRequestPredicate, cachingConfigurationFactory);
}
@ -125,15 +121,13 @@ public class WebAnnotationEndpointDiscoverer extends
"org.reactivestreams.Publisher",
WebEndpointOperationFactory.class.getClassLoader());
private final OperationParameterMapper parameterMapper;
private final ParameterMapper parameterMapper;
private final EndpointMediaTypes endpointMediaTypes;
private final EndpointPathResolver endpointPathResolver;
private final Function<Method, Map<String, Parameter>> parameterNameMapper = new ParameterNameMapper();
private WebEndpointOperationFactory(OperationParameterMapper parameterMapper,
private WebEndpointOperationFactory(ParameterMapper parameterMapper,
EndpointMediaTypes endpointMediaTypes,
EndpointPathResolver endpointPathResolver) {
this.parameterMapper = parameterMapper;
@ -152,7 +146,7 @@ public class WebAnnotationEndpointDiscoverer extends
determineProducedMediaTypes(
operationAttributes.getStringArray("produces"), method));
OperationInvoker invoker = new ReflectiveOperationInvoker(
this.parameterMapper, this.parameterNameMapper, target, method);
target, method, this.parameterMapper);
if (timeToLive > 0) {
invoker = new CachingOperationInvoker(invoker, timeToLive);
}

View File

@ -36,7 +36,7 @@ import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
/**
* Tests for {@link ConversionServiceOperationParameterMapper}.
* Tests for {@link ConversionServiceParameterMapper}.
*
* @author Phillip Webb
*/
@ -49,7 +49,7 @@ public class ConversionServiceOperationParameterMapperTests {
public void mapParameterShouldDelegateToConversionService() throws Exception {
DefaultFormattingConversionService conversionService = spy(
new DefaultFormattingConversionService());
ConversionServiceOperationParameterMapper mapper = new ConversionServiceOperationParameterMapper(
ConversionServiceParameterMapper mapper = new ConversionServiceParameterMapper(
conversionService);
Integer mapped = mapper.mapParameter("123", Integer.class);
assertThat(mapped).isEqualTo(123);
@ -62,7 +62,7 @@ public class ConversionServiceOperationParameterMapperTests {
ConversionService conversionService = mock(ConversionService.class);
RuntimeException error = new RuntimeException();
given(conversionService.convert(any(), any())).willThrow(error);
ConversionServiceOperationParameterMapper mapper = new ConversionServiceOperationParameterMapper(
ConversionServiceParameterMapper mapper = new ConversionServiceParameterMapper(
conversionService);
try {
mapper.mapParameter("123", Integer.class);
@ -77,7 +77,7 @@ public class ConversionServiceOperationParameterMapperTests {
@Test
public void createShouldRegisterIsoOffsetDateTimeConverter() throws Exception {
ConversionServiceOperationParameterMapper mapper = new ConversionServiceOperationParameterMapper();
ConversionServiceParameterMapper mapper = new ConversionServiceParameterMapper();
Date mapped = mapper.mapParameter("2011-12-03T10:15:30+01:00", Date.class);
assertThat(mapped).isNotNull();
}
@ -86,7 +86,7 @@ public class ConversionServiceOperationParameterMapperTests {
public void createWithConversionServiceShouldNotRegisterIsoOffsetDateTimeConverter()
throws Exception {
ConversionService conversionService = new DefaultConversionService();
ConversionServiceOperationParameterMapper mapper = new ConversionServiceOperationParameterMapper(
ConversionServiceParameterMapper mapper = new ConversionServiceParameterMapper(
conversionService);
this.thrown.expect(ParameterMappingException.class);
mapper.mapParameter("2011-12-03T10:15:30+01:00", Date.class);

View File

@ -46,7 +46,7 @@ import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
import org.springframework.boot.actuate.endpoint.annotation.WriteOperation;
import org.springframework.boot.actuate.endpoint.cache.CachingConfiguration;
import org.springframework.boot.actuate.endpoint.convert.ConversionServiceOperationParameterMapper;
import org.springframework.boot.actuate.endpoint.convert.ConversionServiceParameterMapper;
import org.springframework.boot.actuate.endpoint.jmx.annotation.JmxAnnotationEndpointDiscoverer;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.core.convert.support.DefaultConversionService;
@ -342,7 +342,7 @@ public class EndpointMBeanTests {
try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
configuration)) {
consumer.accept(new JmxAnnotationEndpointDiscoverer(context,
new ConversionServiceOperationParameterMapper(
new ConversionServiceParameterMapper(
DefaultConversionService.getSharedInstance()),
(id) -> new CachingConfiguration(0)));
}

View File

@ -36,7 +36,7 @@ import org.springframework.boot.actuate.endpoint.annotation.WriteOperation;
import org.springframework.boot.actuate.endpoint.cache.CachingConfiguration;
import org.springframework.boot.actuate.endpoint.cache.CachingConfigurationFactory;
import org.springframework.boot.actuate.endpoint.cache.CachingOperationInvoker;
import org.springframework.boot.actuate.endpoint.convert.ConversionServiceOperationParameterMapper;
import org.springframework.boot.actuate.endpoint.convert.ConversionServiceParameterMapper;
import org.springframework.boot.actuate.endpoint.jmx.JmxEndpointOperation;
import org.springframework.boot.actuate.endpoint.jmx.JmxEndpointOperationParameterInfo;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
@ -322,7 +322,7 @@ public class JmxAnnotationEndpointDiscovererTests {
try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
configuration)) {
consumer.accept(new JmxAnnotationEndpointDiscoverer(context,
new ConversionServiceOperationParameterMapper(
new ConversionServiceParameterMapper(
DefaultConversionService.getSharedInstance()),
cachingConfigurationFactory));
}

View File

@ -29,14 +29,14 @@ import org.junit.Test;
import reactor.core.publisher.Mono;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
import org.springframework.boot.actuate.endpoint.OperationParameterMapper;
import org.springframework.boot.actuate.endpoint.ParameterMapper;
import org.springframework.boot.actuate.endpoint.annotation.DeleteOperation;
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
import org.springframework.boot.actuate.endpoint.annotation.Selector;
import org.springframework.boot.actuate.endpoint.annotation.WriteOperation;
import org.springframework.boot.actuate.endpoint.cache.CachingConfiguration;
import org.springframework.boot.actuate.endpoint.convert.ConversionServiceOperationParameterMapper;
import org.springframework.boot.actuate.endpoint.convert.ConversionServiceParameterMapper;
import org.springframework.boot.actuate.endpoint.web.annotation.WebAnnotationEndpointDiscoverer;
import org.springframework.boot.web.embedded.tomcat.TomcatEmbeddedWebappClassLoader;
import org.springframework.context.ApplicationContext;
@ -381,7 +381,7 @@ public abstract class AbstractWebEndpointIntegrationTests<T extends Configurable
@Bean
public WebAnnotationEndpointDiscoverer webEndpointDiscoverer(
ApplicationContext applicationContext) {
OperationParameterMapper parameterMapper = new ConversionServiceOperationParameterMapper(
ParameterMapper parameterMapper = new ConversionServiceParameterMapper(
DefaultConversionService.getSharedInstance());
return new WebAnnotationEndpointDiscoverer(applicationContext,
parameterMapper, (id) -> new CachingConfiguration(0),

View File

@ -43,7 +43,7 @@ import org.springframework.boot.actuate.endpoint.annotation.WriteOperation;
import org.springframework.boot.actuate.endpoint.cache.CachingConfiguration;
import org.springframework.boot.actuate.endpoint.cache.CachingConfigurationFactory;
import org.springframework.boot.actuate.endpoint.cache.CachingOperationInvoker;
import org.springframework.boot.actuate.endpoint.convert.ConversionServiceOperationParameterMapper;
import org.springframework.boot.actuate.endpoint.convert.ConversionServiceParameterMapper;
import org.springframework.boot.actuate.endpoint.web.AbstractWebEndpointIntegrationTests.BaseConfiguration;
import org.springframework.boot.actuate.endpoint.web.annotation.WebAnnotationEndpointDiscoverer;
import org.springframework.boot.actuate.endpoint.web.annotation.WebEndpointExtension;
@ -266,7 +266,7 @@ public class WebAnnotationEndpointDiscovererTests {
try {
consumer.accept(
new WebAnnotationEndpointDiscoverer(context,
new ConversionServiceOperationParameterMapper(
new ConversionServiceParameterMapper(
DefaultConversionService.getSharedInstance()),
cachingConfigurationFactory,
new EndpointMediaTypes(

View File

@ -28,7 +28,7 @@ import org.glassfish.jersey.server.model.Resource;
import org.junit.runners.BlockJUnit4ClassRunner;
import org.junit.runners.model.InitializationError;
import org.springframework.boot.actuate.endpoint.convert.ConversionServiceOperationParameterMapper;
import org.springframework.boot.actuate.endpoint.convert.ConversionServiceParameterMapper;
import org.springframework.boot.actuate.endpoint.http.ActuatorMediaType;
import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes;
import org.springframework.boot.actuate.endpoint.web.annotation.WebAnnotationEndpointDiscoverer;
@ -98,7 +98,7 @@ class JerseyEndpointsRunner extends AbstractWebEndpointRunner {
mediaTypes);
WebAnnotationEndpointDiscoverer discoverer = new WebAnnotationEndpointDiscoverer(
this.applicationContext,
new ConversionServiceOperationParameterMapper(), (id) -> null,
new ConversionServiceParameterMapper(), (id) -> null,
endpointMediaTypes, (id) -> id);
Collection<Resource> resources = new JerseyEndpointResourceFactory()
.createEndpointResources(new EndpointMapping("/application"),

View File

@ -22,7 +22,7 @@ import java.util.List;
import org.junit.runners.BlockJUnit4ClassRunner;
import org.junit.runners.model.InitializationError;
import org.springframework.boot.actuate.endpoint.convert.ConversionServiceOperationParameterMapper;
import org.springframework.boot.actuate.endpoint.convert.ConversionServiceParameterMapper;
import org.springframework.boot.actuate.endpoint.http.ActuatorMediaType;
import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes;
import org.springframework.boot.actuate.endpoint.web.annotation.WebAnnotationEndpointDiscoverer;
@ -104,7 +104,7 @@ class WebFluxEndpointsRunner extends AbstractWebEndpointRunner {
mediaTypes);
WebAnnotationEndpointDiscoverer discoverer = new WebAnnotationEndpointDiscoverer(
this.applicationContext,
new ConversionServiceOperationParameterMapper(), (id) -> null,
new ConversionServiceParameterMapper(), (id) -> null,
endpointMediaTypes, (id) -> id);
return new WebFluxEndpointHandlerMapping(new EndpointMapping("/application"),
discoverer.discoverEndpoints(), endpointMediaTypes,

View File

@ -22,7 +22,7 @@ import java.util.List;
import org.junit.runners.BlockJUnit4ClassRunner;
import org.junit.runners.model.InitializationError;
import org.springframework.boot.actuate.endpoint.convert.ConversionServiceOperationParameterMapper;
import org.springframework.boot.actuate.endpoint.convert.ConversionServiceParameterMapper;
import org.springframework.boot.actuate.endpoint.http.ActuatorMediaType;
import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes;
import org.springframework.boot.actuate.endpoint.web.annotation.WebAnnotationEndpointDiscoverer;
@ -87,7 +87,7 @@ class WebMvcEndpointRunner extends AbstractWebEndpointRunner {
mediaTypes);
WebAnnotationEndpointDiscoverer discoverer = new WebAnnotationEndpointDiscoverer(
this.applicationContext,
new ConversionServiceOperationParameterMapper(), (id) -> null,
new ConversionServiceParameterMapper(), (id) -> null,
endpointMediaTypes, (id) -> id);
return new WebMvcEndpointHandlerMapping(new EndpointMapping("/application"),
discoverer.discoverEndpoints(), endpointMediaTypes,

View File

@ -24,11 +24,11 @@ import org.springframework.security.config.annotation.web.configuration.WebSecur
/**
* If there is a bean of type WebSecurityConfigurerAdapter, this adds the
* {@link EnableWebSecurity} annotation. This will make
* sure that the annotation is present with default security auto-configuration and also
* if the user adds custom security and forgets to add the annotation. If {@link EnableWebSecurity}
* has already been added or if a bean with name springSecurityFilterChain
* has been configured by the user, this will back-off.
* {@link EnableWebSecurity} annotation. This will make sure that the annotation is
* present with default security auto-configuration and also if the user adds custom
* security and forgets to add the annotation. If {@link EnableWebSecurity} has already
* been added or if a bean with name springSecurityFilterChain has been configured by the
* user, this will back-off.
*
* @author Madhura Bhave
* @since 2.0.0

View File

@ -24,8 +24,8 @@ import org.springframework.security.web.server.WebFilterChainProxy;
/**
* Switches on {@link EnableWebFluxSecurity} for a reactive web application if this
* annotation has not been added by the user. This configuration also backs off if a
* bean of type {@link WebFilterChainProxy} has been configured in any other way.
* annotation has not been added by the user. This configuration also backs off if a bean
* of type {@link WebFilterChainProxy} has been configured in any other way.
*
* @author Madhura Bhave
*/