Commit 44d8e09a authored by Phillip Webb's avatar Phillip Webb

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.
parent fdec841f
...@@ -20,7 +20,7 @@ import java.util.Arrays; ...@@ -20,7 +20,7 @@ import java.util.Arrays;
import org.springframework.boot.actuate.autoconfigure.endpoint.DefaultCachingConfigurationFactory; import org.springframework.boot.actuate.autoconfigure.endpoint.DefaultCachingConfigurationFactory;
import org.springframework.boot.actuate.autoconfigure.web.servlet.ServletManagementContextAutoConfiguration; 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.EndpointMediaTypes;
import org.springframework.boot.actuate.endpoint.web.annotation.WebAnnotationEndpointDiscoverer; import org.springframework.boot.actuate.endpoint.web.annotation.WebAnnotationEndpointDiscoverer;
import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.AutoConfigureAfter;
...@@ -76,7 +76,7 @@ public class CloudFoundryActuatorAutoConfiguration { ...@@ -76,7 +76,7 @@ public class CloudFoundryActuatorAutoConfiguration {
@Bean @Bean
public CloudFoundryWebEndpointServletHandlerMapping cloudFoundryWebEndpointServletHandlerMapping( public CloudFoundryWebEndpointServletHandlerMapping cloudFoundryWebEndpointServletHandlerMapping(
OperationParameterMapper parameterMapper, ParameterMapper parameterMapper,
DefaultCachingConfigurationFactory cachingConfigurationFactory, DefaultCachingConfigurationFactory cachingConfigurationFactory,
EndpointMediaTypes endpointMediaTypes, Environment environment, EndpointMediaTypes endpointMediaTypes, Environment environment,
RestTemplateBuilder builder) { RestTemplateBuilder builder) {
......
...@@ -20,10 +20,10 @@ import java.util.Arrays; ...@@ -20,10 +20,10 @@ import java.util.Arrays;
import java.util.List; import java.util.List;
import org.springframework.boot.actuate.endpoint.EndpointExposure; 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.annotation.Endpoint;
import org.springframework.boot.actuate.endpoint.cache.CachingConfigurationFactory; 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.http.ActuatorMediaType;
import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes; import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes;
import org.springframework.boot.actuate.endpoint.web.EndpointPathResolver; import org.springframework.boot.actuate.endpoint.web.EndpointPathResolver;
...@@ -49,13 +49,13 @@ import org.springframework.core.env.Environment; ...@@ -49,13 +49,13 @@ import org.springframework.core.env.Environment;
public class EndpointAutoConfiguration { public class EndpointAutoConfiguration {
@Bean @Bean
public OperationParameterMapper operationParameterMapper() { public ParameterMapper endpointOperationParameterMapper() {
return new ConversionServiceOperationParameterMapper(); return new ConversionServiceParameterMapper();
} }
@Bean @Bean
@ConditionalOnMissingBean(CachingConfigurationFactory.class) @ConditionalOnMissingBean(CachingConfigurationFactory.class)
public DefaultCachingConfigurationFactory cacheConfigurationFactory( public DefaultCachingConfigurationFactory endpointCacheConfigurationFactory(
Environment environment) { Environment environment) {
return new DefaultCachingConfigurationFactory(environment); return new DefaultCachingConfigurationFactory(environment);
} }
...@@ -80,14 +80,13 @@ public class EndpointAutoConfiguration { ...@@ -80,14 +80,13 @@ public class EndpointAutoConfiguration {
@Bean @Bean
@ConditionalOnMissingBean @ConditionalOnMissingBean
public EndpointPathResolver endpointPathResolver( public EndpointPathResolver endpointPathResolver(Environment environment) {
Environment environment) {
return new DefaultEndpointPathResolver(environment); return new DefaultEndpointPathResolver(environment);
} }
@Bean @Bean
public EndpointProvider<WebEndpointOperation> webEndpointProvider( public EndpointProvider<WebEndpointOperation> webEndpointProvider(
OperationParameterMapper parameterMapper, ParameterMapper parameterMapper,
DefaultCachingConfigurationFactory cachingConfigurationFactory, DefaultCachingConfigurationFactory cachingConfigurationFactory,
EndpointPathResolver endpointPathResolver) { EndpointPathResolver endpointPathResolver) {
Environment environment = this.applicationContext.getEnvironment(); Environment environment = this.applicationContext.getEnvironment();
......
...@@ -24,7 +24,7 @@ import org.springframework.beans.factory.ObjectProvider; ...@@ -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.DefaultCachingConfigurationFactory;
import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointProvider; import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointProvider;
import org.springframework.boot.actuate.endpoint.EndpointExposure; 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.annotation.Endpoint;
import org.springframework.boot.actuate.endpoint.jmx.EndpointMBeanRegistrar; import org.springframework.boot.actuate.endpoint.jmx.EndpointMBeanRegistrar;
import org.springframework.boot.actuate.endpoint.jmx.JmxEndpointOperation; import org.springframework.boot.actuate.endpoint.jmx.JmxEndpointOperation;
...@@ -58,10 +58,10 @@ public class JmxEndpointAutoConfiguration { ...@@ -58,10 +58,10 @@ public class JmxEndpointAutoConfiguration {
@Bean @Bean
public JmxAnnotationEndpointDiscoverer jmxEndpointDiscoverer( public JmxAnnotationEndpointDiscoverer jmxEndpointDiscoverer(
OperationParameterMapper operationParameterMapper, ParameterMapper parameterMapper,
DefaultCachingConfigurationFactory cachingConfigurationFactory) { DefaultCachingConfigurationFactory cachingConfigurationFactory) {
return new JmxAnnotationEndpointDiscoverer(this.applicationContext, return new JmxAnnotationEndpointDiscoverer(this.applicationContext,
operationParameterMapper, cachingConfigurationFactory); parameterMapper, cachingConfigurationFactory);
} }
@ConditionalOnSingleCandidate(MBeanServer.class) @ConditionalOnSingleCandidate(MBeanServer.class)
......
...@@ -24,13 +24,13 @@ import java.util.function.Consumer; ...@@ -24,13 +24,13 @@ import java.util.function.Consumer;
import org.junit.Test; 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.Endpoint;
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation; import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
import org.springframework.boot.actuate.endpoint.annotation.Selector; import org.springframework.boot.actuate.endpoint.annotation.Selector;
import org.springframework.boot.actuate.endpoint.annotation.WriteOperation; import org.springframework.boot.actuate.endpoint.annotation.WriteOperation;
import org.springframework.boot.actuate.endpoint.cache.CachingConfiguration; 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.EndpointMediaTypes;
import org.springframework.boot.actuate.endpoint.web.annotation.WebAnnotationEndpointDiscoverer; import org.springframework.boot.actuate.endpoint.web.annotation.WebAnnotationEndpointDiscoverer;
import org.springframework.boot.endpoint.web.EndpointMapping; import org.springframework.boot.endpoint.web.EndpointMapping;
...@@ -215,7 +215,7 @@ public class CloudFoundryMvcWebEndpointIntegrationTests { ...@@ -215,7 +215,7 @@ public class CloudFoundryMvcWebEndpointIntegrationTests {
public WebAnnotationEndpointDiscoverer webEndpointDiscoverer( public WebAnnotationEndpointDiscoverer webEndpointDiscoverer(
ApplicationContext applicationContext, ApplicationContext applicationContext,
EndpointMediaTypes endpointMediaTypes) { EndpointMediaTypes endpointMediaTypes) {
OperationParameterMapper parameterMapper = new ConversionServiceOperationParameterMapper( ParameterMapper parameterMapper = new ConversionServiceParameterMapper(
DefaultConversionService.getSharedInstance()); DefaultConversionService.getSharedInstance());
return new WebAnnotationEndpointDiscoverer(applicationContext, return new WebAnnotationEndpointDiscoverer(applicationContext,
parameterMapper, (id) -> new CachingConfiguration(0), parameterMapper, (id) -> new CachingConfiguration(0),
......
...@@ -17,23 +17,22 @@ ...@@ -17,23 +17,22 @@
package org.springframework.boot.actuate.endpoint; package org.springframework.boot.actuate.endpoint;
/** /**
* An {@code OperationParameterMapper} is used to map parameters to the required type when * Maps parameters to the required type when invoking an endpoint.
* invoking an endpoint.
* *
* @author Stephane Nicoll * @author Stephane Nicoll
* @since 2.0.0 * @since 2.0.0
*/ */
@FunctionalInterface @FunctionalInterface
public interface OperationParameterMapper { public interface ParameterMapper {
/** /**
* Map the specified {@code input} parameter to the given {@code parameterType}. * Map the specified {@code input} parameter to the given {@code parameterType}.
* @param input a parameter value * @param value a parameter value
* @param parameterType the required type of the parameter * @param type the required type of the parameter
* @return a value suitable for that parameter * @return a value suitable for that parameter
* @param <T> the actual type of the parameter * @param <T> the actual type of the parameter
* @throws ParameterMappingException when a mapping failure occurs * @throws ParameterMappingException when a mapping failure occurs
*/ */
<T> T mapParameter(Object input, Class<T> parameterType); <T> T mapParameter(Object value, Class<T> type);
} }
...@@ -18,7 +18,7 @@ package org.springframework.boot.actuate.endpoint; ...@@ -18,7 +18,7 @@ package org.springframework.boot.actuate.endpoint;
/** /**
* A {@code ParameterMappingException} is thrown when a failure occurs during * 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}. * mapping}.
* *
* @author Andy Wilkinson * @author Andy Wilkinson
......
/*
* 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);
}
}
}
...@@ -18,12 +18,18 @@ package org.springframework.boot.actuate.endpoint; ...@@ -18,12 +18,18 @@ package org.springframework.boot.actuate.endpoint;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Parameter; import java.lang.reflect.Parameter;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.function.Function; import java.util.function.BiFunction;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.springframework.core.DefaultParameterNameDiscoverer;
import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ReflectionUtils; import org.springframework.util.ReflectionUtils;
/** /**
...@@ -35,37 +41,91 @@ import org.springframework.util.ReflectionUtils; ...@@ -35,37 +41,91 @@ import org.springframework.util.ReflectionUtils;
*/ */
public class ReflectiveOperationInvoker implements OperationInvoker { public class ReflectiveOperationInvoker implements OperationInvoker {
private final OperationParameterMapper parameterMapper; private static final ParameterNameDiscoverer DEFAULT_PARAMETER_NAME_DISCOVERER = new DefaultParameterNameDiscoverer();
private final Function<Method, Map<String, Parameter>> parameterNameMapper;
private final Object target; private final Object target;
private final Method method; private final Method method;
private final ParameterMapper parameterMapper;
private final ParameterNameDiscoverer parameterNameDiscoverer;
/** /**
* Creates a new {code ReflectiveOperationInvoker} that will invoke the given * Creates a new {code ReflectiveOperationInvoker} that will invoke the given
* {@code method} on the given {@code target}. The given {@code parameterMapper} will * {@code method} on the given {@code target}. The given {@code parameterMapper} will
* be used to map parameters to the required types and the given * be used to map parameters to the required types and the given
* {@code parameterNameMapper} will be used map parameters by name. * {@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 parameterMapper the parameter mapper
* @param parameterNameMapper the parameter name mapper */
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 target the target of the reflective call
* @param method the method to call * @param method the method to call
* @param parameterMapper the parameter mapper
* @param parameterNameDiscoverer the parameter name discoverer
*/ */
public ReflectiveOperationInvoker(OperationParameterMapper parameterMapper, public ReflectiveOperationInvoker(Object target, Method method,
Function<Method, Map<String, Parameter>> parameterNameMapper, ParameterMapper parameterMapper,
Object target, Method method) { ParameterNameDiscoverer parameterNameDiscoverer) {
this.parameterMapper = parameterMapper; Assert.notNull(target, "Target must not be null");
this.parameterNameMapper = parameterNameMapper; Assert.notNull(method, "Method must not be null");
this.target = target; Assert.notNull(parameterMapper, "ParameterMapper must not be null");
Assert.notNull(parameterNameDiscoverer,
"ParameterNameDiscoverer must not be null");
ReflectionUtils.makeAccessible(method); ReflectionUtils.makeAccessible(method);
this.target = target;
this.method = method; 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 @Override
public Object invoke(Map<String, Object> arguments) { public Object invoke(Map<String, Object> arguments) {
Map<String, Parameter> parameters = this.parameterNameMapper.apply(this.method); Map<String, Parameter> parameters = getParameters();
validateRequiredParameters(parameters, arguments); validateRequiredParameters(parameters, arguments);
return ReflectionUtils.invokeMethod(this.method, this.target, return ReflectionUtils.invokeMethod(this.method, this.target,
resolveArguments(parameters, arguments)); resolveArguments(parameters, arguments));
...@@ -99,7 +159,8 @@ public class ReflectiveOperationInvoker implements OperationInvoker { ...@@ -99,7 +159,8 @@ public class ReflectiveOperationInvoker implements OperationInvoker {
(list) -> list.toArray(new Object[list.size()]))); (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); Object resolved = arguments.get(name);
return this.parameterMapper.mapParameter(resolved, parameter.getType()); return this.parameterMapper.mapParameter(resolved, parameter.getType());
} }
......
...@@ -68,6 +68,20 @@ public class CachingOperationInvoker implements OperationInvoker { ...@@ -68,6 +68,20 @@ public class CachingOperationInvoker implements OperationInvoker {
return cached.getResponse(); 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 * A cached response that encapsulates the response itself and the time at which it
* was created. * was created.
......
...@@ -16,26 +16,26 @@ ...@@ -16,26 +16,26 @@
package org.springframework.boot.actuate.endpoint.convert; 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.actuate.endpoint.ParameterMappingException;
import org.springframework.boot.context.properties.bind.convert.BinderConversionService; import org.springframework.boot.context.properties.bind.convert.BinderConversionService;
import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.ConversionService;
import org.springframework.format.support.DefaultFormattingConversionService; 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. * values if necessary.
* *
* @author Stephane Nicoll * @author Stephane Nicoll
* @author Phillip Webb * @author Phillip Webb
* @since 2.0.0 * @since 2.0.0
*/ */
public class ConversionServiceOperationParameterMapper public class ConversionServiceParameterMapper
implements OperationParameterMapper { implements ParameterMapper {
private final ConversionService conversionService; private final ConversionService conversionService;
public ConversionServiceOperationParameterMapper() { public ConversionServiceParameterMapper() {
this(createDefaultConversionService()); this(createDefaultConversionService());
} }
...@@ -43,7 +43,7 @@ public class ConversionServiceOperationParameterMapper ...@@ -43,7 +43,7 @@ public class ConversionServiceOperationParameterMapper
* Create a new instance with the {@link ConversionService} to use. * Create a new instance with the {@link ConversionService} to use.
* @param conversionService the conversion service * @param conversionService the conversion service
*/ */
public ConversionServiceOperationParameterMapper( public ConversionServiceParameterMapper(
ConversionService conversionService) { ConversionService conversionService) {
this.conversionService = new BinderConversionService(conversionService); this.conversionService = new BinderConversionService(conversionService);
} }
......
...@@ -23,17 +23,13 @@ import java.util.Collection; ...@@ -23,17 +23,13 @@ import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.function.Supplier; import java.util.function.Supplier;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.springframework.boot.actuate.endpoint.EndpointExposure; import org.springframework.boot.actuate.endpoint.EndpointExposure;
import org.springframework.boot.actuate.endpoint.EndpointInfo; 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.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.ReflectiveOperationInvoker;
import org.springframework.boot.actuate.endpoint.annotation.AnnotationEndpointDiscoverer; import org.springframework.boot.actuate.endpoint.annotation.AnnotationEndpointDiscoverer;
import org.springframework.boot.actuate.endpoint.annotation.Endpoint; import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
...@@ -67,12 +63,12 @@ public class JmxAnnotationEndpointDiscoverer ...@@ -67,12 +63,12 @@ public class JmxAnnotationEndpointDiscoverer
* {@link Endpoint endpoints} and {@link JmxEndpointExtension jmx extensions} using * {@link Endpoint endpoints} and {@link JmxEndpointExtension jmx extensions} using
* the given {@link ApplicationContext}. * the given {@link ApplicationContext}.
* @param applicationContext the application context * @param applicationContext the application context
* @param parameterMapper the {@link OperationParameterMapper} used to convert * @param parameterMapper the {@link ParameterMapper} used to convert arguments when
* arguments when an operation is invoked * an operation is invoked
* @param cachingConfigurationFactory the {@link CachingConfiguration} factory to use * @param cachingConfigurationFactory the {@link CachingConfiguration} factory to use
*/ */
public JmxAnnotationEndpointDiscoverer(ApplicationContext applicationContext, public JmxAnnotationEndpointDiscoverer(ApplicationContext applicationContext,
OperationParameterMapper parameterMapper, ParameterMapper parameterMapper,
CachingConfigurationFactory cachingConfigurationFactory) { CachingConfigurationFactory cachingConfigurationFactory) {
super(applicationContext, new JmxEndpointOperationFactory(parameterMapper), super(applicationContext, new JmxEndpointOperationFactory(parameterMapper),
JmxEndpointOperation::getOperationName, cachingConfigurationFactory); JmxEndpointOperation::getOperationName, cachingConfigurationFactory);
...@@ -109,11 +105,9 @@ public class JmxAnnotationEndpointDiscoverer ...@@ -109,11 +105,9 @@ public class JmxAnnotationEndpointDiscoverer
private static class JmxEndpointOperationFactory private static class JmxEndpointOperationFactory
implements EndpointOperationFactory<JmxEndpointOperation> { implements EndpointOperationFactory<JmxEndpointOperation> {
private final OperationParameterMapper parameterMapper; private final ParameterMapper parameterMapper;
private final Function<Method, Map<String, Parameter>> parameterNameMapper = new ParameterNameMapper(); JmxEndpointOperationFactory(ParameterMapper parameterMapper) {
JmxEndpointOperationFactory(OperationParameterMapper parameterMapper) {
this.parameterMapper = parameterMapper; this.parameterMapper = parameterMapper;
} }
...@@ -121,18 +115,16 @@ public class JmxAnnotationEndpointDiscoverer ...@@ -121,18 +115,16 @@ public class JmxAnnotationEndpointDiscoverer
public JmxEndpointOperation createOperation(String endpointId, public JmxEndpointOperation createOperation(String endpointId,
AnnotationAttributes operationAttributes, Object target, Method method, AnnotationAttributes operationAttributes, Object target, Method method,
OperationType type, long timeToLive) { OperationType type, long timeToLive) {
ReflectiveOperationInvoker invoker = new ReflectiveOperationInvoker(
target, method, this.parameterMapper);
String operationName = method.getName(); String operationName = method.getName();
Class<?> outputType = mapParameterType(method.getReturnType()); Class<?> outputType = getJmxType(method.getReturnType());
String description = getDescription(method, String description = getDescription(method,
() -> "Invoke " + operationName + " for endpoint " + endpointId); () -> "Invoke " + operationName + " for endpoint " + endpointId);
List<JmxEndpointOperationParameterInfo> parameters = getParameters(method); List<JmxEndpointOperationParameterInfo> parameters = getParameters(invoker);
OperationInvoker invoker = new ReflectiveOperationInvoker( return new JmxEndpointOperation(type,
this.parameterMapper, this.parameterNameMapper, target, method); CachingOperationInvoker.apply(invoker, timeToLive), operationName,
if (timeToLive > 0) { outputType, description, parameters);
invoker = new CachingOperationInvoker(invoker, timeToLive);
}
return new JmxEndpointOperation(type, invoker, operationName, outputType,
description, parameters);
} }
private String getDescription(Method method, Supplier<String> fallback) { private String getDescription(Method method, Supplier<String> fallback) {
...@@ -145,58 +137,58 @@ public class JmxAnnotationEndpointDiscoverer ...@@ -145,58 +137,58 @@ public class JmxAnnotationEndpointDiscoverer
return fallback.get(); return fallback.get();
} }
private List<JmxEndpointOperationParameterInfo> getParameters(Method method) { private List<JmxEndpointOperationParameterInfo> getParameters(
Parameter[] methodParameters = method.getParameters(); ReflectiveOperationInvoker invoker) {
if (methodParameters.length == 0) { if (invoker.getMethod().getParameterCount() == 0) {
return Collections.emptyList(); return Collections.emptyList();
} }
ManagedOperationParameter[] managedOperationParameters = jmxAttributeSource ManagedOperationParameter[] operationParameters = jmxAttributeSource
.getManagedOperationParameters(method); .getManagedOperationParameters(invoker.getMethod());
if (managedOperationParameters.length == 0) { if (operationParameters.length == 0) {
return getParametersInfo(method); return invoker.getParameters(this::getParameter);
} }
return getParametersInfo(methodParameters, managedOperationParameters); return mergeParameters(invoker.getMethod().getParameters(),
operationParameters);
} }
private List<JmxEndpointOperationParameterInfo> getParametersInfo(Method method) { private List<JmxEndpointOperationParameterInfo> mergeParameters(
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(
Parameter[] methodParameters, Parameter[] methodParameters,
ManagedOperationParameter[] managedOperationParameters) { ManagedOperationParameter[] operationParameters) {
List<JmxEndpointOperationParameterInfo> parameters = new ArrayList<>(); List<JmxEndpointOperationParameterInfo> parameters = new ArrayList<>();
for (int i = 0; i < managedOperationParameters.length; i++) { for (int i = 0; i < operationParameters.length; i++) {
ManagedOperationParameter managedOperationParameter = managedOperationParameters[i]; ManagedOperationParameter operationParameter = operationParameters[i];
Parameter methodParameter = methodParameters[i]; Parameter methodParameter = methodParameters[i];
parameters.add(new JmxEndpointOperationParameterInfo( JmxEndpointOperationParameterInfo parameter = getParameter(
managedOperationParameter.getName(), operationParameter.getName(), methodParameter,
mapParameterType(methodParameter.getType()), operationParameter.getDescription());
managedOperationParameter.getDescription())); parameters.add(parameter);
} }
return parameters; return parameters;
} }
private Class<?> mapParameterType(Class<?> parameter) { private JmxEndpointOperationParameterInfo getParameter(String name,
if (parameter.isEnum()) { 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; return String.class;
} }
if (Date.class.isAssignableFrom(parameter)) { if (Date.class.isAssignableFrom(type)) {
return String.class; return String.class;
} }
if (parameter.getName().startsWith("java.")) { if (type.getName().startsWith("java.")) {
return parameter; return type;
} }
if (parameter.equals(Void.TYPE)) { if (type.equals(Void.TYPE)) {
return parameter; return type;
} }
return Object.class; return Object.class;
} }
......
...@@ -17,14 +17,11 @@ ...@@ -17,14 +17,11 @@
package org.springframework.boot.actuate.endpoint.web.annotation; package org.springframework.boot.actuate.endpoint.web.annotation;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
...@@ -33,9 +30,8 @@ import org.reactivestreams.Publisher; ...@@ -33,9 +30,8 @@ import org.reactivestreams.Publisher;
import org.springframework.boot.actuate.endpoint.EndpointExposure; import org.springframework.boot.actuate.endpoint.EndpointExposure;
import org.springframework.boot.actuate.endpoint.EndpointInfo; import org.springframework.boot.actuate.endpoint.EndpointInfo;
import org.springframework.boot.actuate.endpoint.OperationInvoker; 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.OperationType;
import org.springframework.boot.actuate.endpoint.ParameterNameMapper;
import org.springframework.boot.actuate.endpoint.ReflectiveOperationInvoker; import org.springframework.boot.actuate.endpoint.ReflectiveOperationInvoker;
import org.springframework.boot.actuate.endpoint.annotation.AnnotationEndpointDiscoverer; import org.springframework.boot.actuate.endpoint.annotation.AnnotationEndpointDiscoverer;
import org.springframework.boot.actuate.endpoint.annotation.Endpoint; import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
...@@ -71,7 +67,7 @@ public class WebAnnotationEndpointDiscoverer extends ...@@ -71,7 +67,7 @@ public class WebAnnotationEndpointDiscoverer extends
* {@link Endpoint endpoints} and {@link WebEndpointExtension web extensions} using * {@link Endpoint endpoints} and {@link WebEndpointExtension web extensions} using
* the given {@link ApplicationContext}. * the given {@link ApplicationContext}.
* @param applicationContext the application context * @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 * convert arguments when an operation is invoked
* @param cachingConfigurationFactory the {@link CachingConfiguration} factory to use * @param cachingConfigurationFactory the {@link CachingConfiguration} factory to use
* @param endpointMediaTypes the media types produced and consumed by web endpoint * @param endpointMediaTypes the media types produced and consumed by web endpoint
...@@ -80,12 +76,12 @@ public class WebAnnotationEndpointDiscoverer extends ...@@ -80,12 +76,12 @@ public class WebAnnotationEndpointDiscoverer extends
* endpoint paths * endpoint paths
*/ */
public WebAnnotationEndpointDiscoverer(ApplicationContext applicationContext, public WebAnnotationEndpointDiscoverer(ApplicationContext applicationContext,
OperationParameterMapper operationParameterMapper, ParameterMapper parameterMapper,
CachingConfigurationFactory cachingConfigurationFactory, CachingConfigurationFactory cachingConfigurationFactory,
EndpointMediaTypes endpointMediaTypes, EndpointMediaTypes endpointMediaTypes,
EndpointPathResolver endpointPathResolver) { EndpointPathResolver endpointPathResolver) {
super(applicationContext, super(applicationContext,
new WebEndpointOperationFactory(operationParameterMapper, new WebEndpointOperationFactory(parameterMapper,
endpointMediaTypes, endpointPathResolver), endpointMediaTypes, endpointPathResolver),
WebEndpointOperation::getRequestPredicate, cachingConfigurationFactory); WebEndpointOperation::getRequestPredicate, cachingConfigurationFactory);
} }
...@@ -125,15 +121,13 @@ public class WebAnnotationEndpointDiscoverer extends ...@@ -125,15 +121,13 @@ public class WebAnnotationEndpointDiscoverer extends
"org.reactivestreams.Publisher", "org.reactivestreams.Publisher",
WebEndpointOperationFactory.class.getClassLoader()); WebEndpointOperationFactory.class.getClassLoader());
private final OperationParameterMapper parameterMapper; private final ParameterMapper parameterMapper;
private final EndpointMediaTypes endpointMediaTypes; private final EndpointMediaTypes endpointMediaTypes;
private final EndpointPathResolver endpointPathResolver; private final EndpointPathResolver endpointPathResolver;
private final Function<Method, Map<String, Parameter>> parameterNameMapper = new ParameterNameMapper(); private WebEndpointOperationFactory(ParameterMapper parameterMapper,
private WebEndpointOperationFactory(OperationParameterMapper parameterMapper,
EndpointMediaTypes endpointMediaTypes, EndpointMediaTypes endpointMediaTypes,
EndpointPathResolver endpointPathResolver) { EndpointPathResolver endpointPathResolver) {
this.parameterMapper = parameterMapper; this.parameterMapper = parameterMapper;
...@@ -152,7 +146,7 @@ public class WebAnnotationEndpointDiscoverer extends ...@@ -152,7 +146,7 @@ public class WebAnnotationEndpointDiscoverer extends
determineProducedMediaTypes( determineProducedMediaTypes(
operationAttributes.getStringArray("produces"), method)); operationAttributes.getStringArray("produces"), method));
OperationInvoker invoker = new ReflectiveOperationInvoker( OperationInvoker invoker = new ReflectiveOperationInvoker(
this.parameterMapper, this.parameterNameMapper, target, method); target, method, this.parameterMapper);
if (timeToLive > 0) { if (timeToLive > 0) {
invoker = new CachingOperationInvoker(invoker, timeToLive); invoker = new CachingOperationInvoker(invoker, timeToLive);
} }
......
...@@ -36,7 +36,7 @@ import static org.mockito.Mockito.spy; ...@@ -36,7 +36,7 @@ import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
/** /**
* Tests for {@link ConversionServiceOperationParameterMapper}. * Tests for {@link ConversionServiceParameterMapper}.
* *
* @author Phillip Webb * @author Phillip Webb
*/ */
...@@ -49,7 +49,7 @@ public class ConversionServiceOperationParameterMapperTests { ...@@ -49,7 +49,7 @@ public class ConversionServiceOperationParameterMapperTests {
public void mapParameterShouldDelegateToConversionService() throws Exception { public void mapParameterShouldDelegateToConversionService() throws Exception {
DefaultFormattingConversionService conversionService = spy( DefaultFormattingConversionService conversionService = spy(
new DefaultFormattingConversionService()); new DefaultFormattingConversionService());
ConversionServiceOperationParameterMapper mapper = new ConversionServiceOperationParameterMapper( ConversionServiceParameterMapper mapper = new ConversionServiceParameterMapper(
conversionService); conversionService);
Integer mapped = mapper.mapParameter("123", Integer.class); Integer mapped = mapper.mapParameter("123", Integer.class);
assertThat(mapped).isEqualTo(123); assertThat(mapped).isEqualTo(123);
...@@ -62,7 +62,7 @@ public class ConversionServiceOperationParameterMapperTests { ...@@ -62,7 +62,7 @@ public class ConversionServiceOperationParameterMapperTests {
ConversionService conversionService = mock(ConversionService.class); ConversionService conversionService = mock(ConversionService.class);
RuntimeException error = new RuntimeException(); RuntimeException error = new RuntimeException();
given(conversionService.convert(any(), any())).willThrow(error); given(conversionService.convert(any(), any())).willThrow(error);
ConversionServiceOperationParameterMapper mapper = new ConversionServiceOperationParameterMapper( ConversionServiceParameterMapper mapper = new ConversionServiceParameterMapper(
conversionService); conversionService);
try { try {
mapper.mapParameter("123", Integer.class); mapper.mapParameter("123", Integer.class);
...@@ -77,7 +77,7 @@ public class ConversionServiceOperationParameterMapperTests { ...@@ -77,7 +77,7 @@ public class ConversionServiceOperationParameterMapperTests {
@Test @Test
public void createShouldRegisterIsoOffsetDateTimeConverter() throws Exception { 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); Date mapped = mapper.mapParameter("2011-12-03T10:15:30+01:00", Date.class);
assertThat(mapped).isNotNull(); assertThat(mapped).isNotNull();
} }
...@@ -86,7 +86,7 @@ public class ConversionServiceOperationParameterMapperTests { ...@@ -86,7 +86,7 @@ public class ConversionServiceOperationParameterMapperTests {
public void createWithConversionServiceShouldNotRegisterIsoOffsetDateTimeConverter() public void createWithConversionServiceShouldNotRegisterIsoOffsetDateTimeConverter()
throws Exception { throws Exception {
ConversionService conversionService = new DefaultConversionService(); ConversionService conversionService = new DefaultConversionService();
ConversionServiceOperationParameterMapper mapper = new ConversionServiceOperationParameterMapper( ConversionServiceParameterMapper mapper = new ConversionServiceParameterMapper(
conversionService); conversionService);
this.thrown.expect(ParameterMappingException.class); this.thrown.expect(ParameterMappingException.class);
mapper.mapParameter("2011-12-03T10:15:30+01:00", Date.class); mapper.mapParameter("2011-12-03T10:15:30+01:00", Date.class);
......
...@@ -46,7 +46,7 @@ import org.springframework.boot.actuate.endpoint.annotation.Endpoint; ...@@ -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.ReadOperation;
import org.springframework.boot.actuate.endpoint.annotation.WriteOperation; import org.springframework.boot.actuate.endpoint.annotation.WriteOperation;
import org.springframework.boot.actuate.endpoint.cache.CachingConfiguration; 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.boot.actuate.endpoint.jmx.annotation.JmxAnnotationEndpointDiscoverer;
import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.core.convert.support.DefaultConversionService; import org.springframework.core.convert.support.DefaultConversionService;
...@@ -342,7 +342,7 @@ public class EndpointMBeanTests { ...@@ -342,7 +342,7 @@ public class EndpointMBeanTests {
try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext( try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
configuration)) { configuration)) {
consumer.accept(new JmxAnnotationEndpointDiscoverer(context, consumer.accept(new JmxAnnotationEndpointDiscoverer(context,
new ConversionServiceOperationParameterMapper( new ConversionServiceParameterMapper(
DefaultConversionService.getSharedInstance()), DefaultConversionService.getSharedInstance()),
(id) -> new CachingConfiguration(0))); (id) -> new CachingConfiguration(0)));
} }
......
...@@ -36,7 +36,7 @@ import org.springframework.boot.actuate.endpoint.annotation.WriteOperation; ...@@ -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.CachingConfiguration;
import org.springframework.boot.actuate.endpoint.cache.CachingConfigurationFactory; import org.springframework.boot.actuate.endpoint.cache.CachingConfigurationFactory;
import org.springframework.boot.actuate.endpoint.cache.CachingOperationInvoker; 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.JmxEndpointOperation;
import org.springframework.boot.actuate.endpoint.jmx.JmxEndpointOperationParameterInfo; import org.springframework.boot.actuate.endpoint.jmx.JmxEndpointOperationParameterInfo;
import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext;
...@@ -322,7 +322,7 @@ public class JmxAnnotationEndpointDiscovererTests { ...@@ -322,7 +322,7 @@ public class JmxAnnotationEndpointDiscovererTests {
try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext( try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
configuration)) { configuration)) {
consumer.accept(new JmxAnnotationEndpointDiscoverer(context, consumer.accept(new JmxAnnotationEndpointDiscoverer(context,
new ConversionServiceOperationParameterMapper( new ConversionServiceParameterMapper(
DefaultConversionService.getSharedInstance()), DefaultConversionService.getSharedInstance()),
cachingConfigurationFactory)); cachingConfigurationFactory));
} }
......
...@@ -29,14 +29,14 @@ import org.junit.Test; ...@@ -29,14 +29,14 @@ import org.junit.Test;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer; 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.DeleteOperation;
import org.springframework.boot.actuate.endpoint.annotation.Endpoint; import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation; import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
import org.springframework.boot.actuate.endpoint.annotation.Selector; import org.springframework.boot.actuate.endpoint.annotation.Selector;
import org.springframework.boot.actuate.endpoint.annotation.WriteOperation; import org.springframework.boot.actuate.endpoint.annotation.WriteOperation;
import org.springframework.boot.actuate.endpoint.cache.CachingConfiguration; 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.actuate.endpoint.web.annotation.WebAnnotationEndpointDiscoverer;
import org.springframework.boot.web.embedded.tomcat.TomcatEmbeddedWebappClassLoader; import org.springframework.boot.web.embedded.tomcat.TomcatEmbeddedWebappClassLoader;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
...@@ -381,7 +381,7 @@ public abstract class AbstractWebEndpointIntegrationTests<T extends Configurable ...@@ -381,7 +381,7 @@ public abstract class AbstractWebEndpointIntegrationTests<T extends Configurable
@Bean @Bean
public WebAnnotationEndpointDiscoverer webEndpointDiscoverer( public WebAnnotationEndpointDiscoverer webEndpointDiscoverer(
ApplicationContext applicationContext) { ApplicationContext applicationContext) {
OperationParameterMapper parameterMapper = new ConversionServiceOperationParameterMapper( ParameterMapper parameterMapper = new ConversionServiceParameterMapper(
DefaultConversionService.getSharedInstance()); DefaultConversionService.getSharedInstance());
return new WebAnnotationEndpointDiscoverer(applicationContext, return new WebAnnotationEndpointDiscoverer(applicationContext,
parameterMapper, (id) -> new CachingConfiguration(0), parameterMapper, (id) -> new CachingConfiguration(0),
......
...@@ -43,7 +43,7 @@ import org.springframework.boot.actuate.endpoint.annotation.WriteOperation; ...@@ -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.CachingConfiguration;
import org.springframework.boot.actuate.endpoint.cache.CachingConfigurationFactory; import org.springframework.boot.actuate.endpoint.cache.CachingConfigurationFactory;
import org.springframework.boot.actuate.endpoint.cache.CachingOperationInvoker; 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.AbstractWebEndpointIntegrationTests.BaseConfiguration;
import org.springframework.boot.actuate.endpoint.web.annotation.WebAnnotationEndpointDiscoverer; import org.springframework.boot.actuate.endpoint.web.annotation.WebAnnotationEndpointDiscoverer;
import org.springframework.boot.actuate.endpoint.web.annotation.WebEndpointExtension; import org.springframework.boot.actuate.endpoint.web.annotation.WebEndpointExtension;
...@@ -266,7 +266,7 @@ public class WebAnnotationEndpointDiscovererTests { ...@@ -266,7 +266,7 @@ public class WebAnnotationEndpointDiscovererTests {
try { try {
consumer.accept( consumer.accept(
new WebAnnotationEndpointDiscoverer(context, new WebAnnotationEndpointDiscoverer(context,
new ConversionServiceOperationParameterMapper( new ConversionServiceParameterMapper(
DefaultConversionService.getSharedInstance()), DefaultConversionService.getSharedInstance()),
cachingConfigurationFactory, cachingConfigurationFactory,
new EndpointMediaTypes( new EndpointMediaTypes(
......
...@@ -28,7 +28,7 @@ import org.glassfish.jersey.server.model.Resource; ...@@ -28,7 +28,7 @@ import org.glassfish.jersey.server.model.Resource;
import org.junit.runners.BlockJUnit4ClassRunner; import org.junit.runners.BlockJUnit4ClassRunner;
import org.junit.runners.model.InitializationError; 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.http.ActuatorMediaType;
import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes; import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes;
import org.springframework.boot.actuate.endpoint.web.annotation.WebAnnotationEndpointDiscoverer; import org.springframework.boot.actuate.endpoint.web.annotation.WebAnnotationEndpointDiscoverer;
...@@ -98,7 +98,7 @@ class JerseyEndpointsRunner extends AbstractWebEndpointRunner { ...@@ -98,7 +98,7 @@ class JerseyEndpointsRunner extends AbstractWebEndpointRunner {
mediaTypes); mediaTypes);
WebAnnotationEndpointDiscoverer discoverer = new WebAnnotationEndpointDiscoverer( WebAnnotationEndpointDiscoverer discoverer = new WebAnnotationEndpointDiscoverer(
this.applicationContext, this.applicationContext,
new ConversionServiceOperationParameterMapper(), (id) -> null, new ConversionServiceParameterMapper(), (id) -> null,
endpointMediaTypes, (id) -> id); endpointMediaTypes, (id) -> id);
Collection<Resource> resources = new JerseyEndpointResourceFactory() Collection<Resource> resources = new JerseyEndpointResourceFactory()
.createEndpointResources(new EndpointMapping("/application"), .createEndpointResources(new EndpointMapping("/application"),
......
...@@ -22,7 +22,7 @@ import java.util.List; ...@@ -22,7 +22,7 @@ import java.util.List;
import org.junit.runners.BlockJUnit4ClassRunner; import org.junit.runners.BlockJUnit4ClassRunner;
import org.junit.runners.model.InitializationError; 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.http.ActuatorMediaType;
import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes; import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes;
import org.springframework.boot.actuate.endpoint.web.annotation.WebAnnotationEndpointDiscoverer; import org.springframework.boot.actuate.endpoint.web.annotation.WebAnnotationEndpointDiscoverer;
...@@ -104,7 +104,7 @@ class WebFluxEndpointsRunner extends AbstractWebEndpointRunner { ...@@ -104,7 +104,7 @@ class WebFluxEndpointsRunner extends AbstractWebEndpointRunner {
mediaTypes); mediaTypes);
WebAnnotationEndpointDiscoverer discoverer = new WebAnnotationEndpointDiscoverer( WebAnnotationEndpointDiscoverer discoverer = new WebAnnotationEndpointDiscoverer(
this.applicationContext, this.applicationContext,
new ConversionServiceOperationParameterMapper(), (id) -> null, new ConversionServiceParameterMapper(), (id) -> null,
endpointMediaTypes, (id) -> id); endpointMediaTypes, (id) -> id);
return new WebFluxEndpointHandlerMapping(new EndpointMapping("/application"), return new WebFluxEndpointHandlerMapping(new EndpointMapping("/application"),
discoverer.discoverEndpoints(), endpointMediaTypes, discoverer.discoverEndpoints(), endpointMediaTypes,
......
...@@ -22,7 +22,7 @@ import java.util.List; ...@@ -22,7 +22,7 @@ import java.util.List;
import org.junit.runners.BlockJUnit4ClassRunner; import org.junit.runners.BlockJUnit4ClassRunner;
import org.junit.runners.model.InitializationError; 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.http.ActuatorMediaType;
import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes; import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes;
import org.springframework.boot.actuate.endpoint.web.annotation.WebAnnotationEndpointDiscoverer; import org.springframework.boot.actuate.endpoint.web.annotation.WebAnnotationEndpointDiscoverer;
...@@ -87,7 +87,7 @@ class WebMvcEndpointRunner extends AbstractWebEndpointRunner { ...@@ -87,7 +87,7 @@ class WebMvcEndpointRunner extends AbstractWebEndpointRunner {
mediaTypes); mediaTypes);
WebAnnotationEndpointDiscoverer discoverer = new WebAnnotationEndpointDiscoverer( WebAnnotationEndpointDiscoverer discoverer = new WebAnnotationEndpointDiscoverer(
this.applicationContext, this.applicationContext,
new ConversionServiceOperationParameterMapper(), (id) -> null, new ConversionServiceParameterMapper(), (id) -> null,
endpointMediaTypes, (id) -> id); endpointMediaTypes, (id) -> id);
return new WebMvcEndpointHandlerMapping(new EndpointMapping("/application"), return new WebMvcEndpointHandlerMapping(new EndpointMapping("/application"),
discoverer.discoverEndpoints(), endpointMediaTypes, discoverer.discoverEndpoints(), endpointMediaTypes,
......
...@@ -24,11 +24,11 @@ import org.springframework.security.config.annotation.web.configuration.WebSecur ...@@ -24,11 +24,11 @@ import org.springframework.security.config.annotation.web.configuration.WebSecur
/** /**
* If there is a bean of type WebSecurityConfigurerAdapter, this adds the * If there is a bean of type WebSecurityConfigurerAdapter, this adds the
* {@link EnableWebSecurity} annotation. This will make * {@link EnableWebSecurity} annotation. This will make sure that the annotation is
* sure that the annotation is present with default security auto-configuration and also * present with default security auto-configuration and also if the user adds custom
* if the user adds custom security and forgets to add the annotation. If {@link EnableWebSecurity} * security and forgets to add the annotation. If {@link EnableWebSecurity} has already
* has already been added or if a bean with name springSecurityFilterChain * been added or if a bean with name springSecurityFilterChain has been configured by the
* has been configured by the user, this will back-off. * user, this will back-off.
* *
* @author Madhura Bhave * @author Madhura Bhave
* @since 2.0.0 * @since 2.0.0
......
...@@ -24,8 +24,8 @@ import org.springframework.security.web.server.WebFilterChainProxy; ...@@ -24,8 +24,8 @@ import org.springframework.security.web.server.WebFilterChainProxy;
/** /**
* Switches on {@link EnableWebFluxSecurity} for a reactive web application if this * 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 * annotation has not been added by the user. This configuration also backs off if a bean
* bean of type {@link WebFilterChainProxy} has been configured in any other way. * of type {@link WebFilterChainProxy} has been configured in any other way.
* *
* @author Madhura Bhave * @author Madhura Bhave
*/ */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment