Commit fd505e51 authored by Phillip Webb's avatar Phillip Webb

Merge branch '2.2.x'

Closes gh-21444
parents 5acd115c 49a21ded
...@@ -58,21 +58,21 @@ public class CloudFoundryWebEndpointDiscoverer extends WebEndpointDiscoverer { ...@@ -58,21 +58,21 @@ public class CloudFoundryWebEndpointDiscoverer extends WebEndpointDiscoverer {
} }
@Override @Override
protected boolean isExtensionExposed(Object extensionBean) { protected boolean isExtensionTypeExposed(Class<?> extensionBeanType) {
if (isHealthEndpointExtension(extensionBean) && !isCloudFoundryHealthEndpointExtension(extensionBean)) { if (isHealthEndpointExtension(extensionBeanType) && !isCloudFoundryHealthEndpointExtension(extensionBeanType)) {
// Filter regular health endpoint extensions so a CF version can replace them // Filter regular health endpoint extensions so a CF version can replace them
return false; return false;
} }
return true; return true;
} }
private boolean isHealthEndpointExtension(Object extensionBean) { private boolean isHealthEndpointExtension(Class<?> extensionBeanType) {
return MergedAnnotations.from(extensionBean.getClass()).get(EndpointWebExtension.class) return MergedAnnotations.from(extensionBeanType).get(EndpointWebExtension.class)
.getValue("endpoint", Class.class).map(HealthEndpoint.class::isAssignableFrom).orElse(false); .getValue("endpoint", Class.class).map(HealthEndpoint.class::isAssignableFrom).orElse(false);
} }
private boolean isCloudFoundryHealthEndpointExtension(Object extensionBean) { private boolean isCloudFoundryHealthEndpointExtension(Class<?> extensionBeanType) {
return MergedAnnotations.from(extensionBean.getClass()).isPresent(EndpointCloudFoundryExtension.class); return MergedAnnotations.from(extensionBeanType).isPresent(EndpointCloudFoundryExtension.class);
} }
} }
...@@ -49,6 +49,7 @@ import org.springframework.core.annotation.MergedAnnotations; ...@@ -49,6 +49,7 @@ import org.springframework.core.annotation.MergedAnnotations;
import org.springframework.core.annotation.MergedAnnotations.SearchStrategy; import org.springframework.core.annotation.MergedAnnotations.SearchStrategy;
import org.springframework.core.env.Environment; import org.springframework.core.env.Environment;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap; import org.springframework.util.MultiValueMap;
...@@ -140,8 +141,9 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten ...@@ -140,8 +141,9 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten
} }
private EndpointBean createEndpointBean(String beanName) { private EndpointBean createEndpointBean(String beanName) {
Object bean = this.applicationContext.getBean(beanName); Class<?> beanType = ClassUtils.getUserClass(this.applicationContext.getType(beanName, false));
return new EndpointBean(this.applicationContext.getEnvironment(), beanName, bean); Supplier<Object> beanSupplier = () -> this.applicationContext.getBean(beanName);
return new EndpointBean(this.applicationContext.getEnvironment(), beanName, beanType, beanSupplier);
} }
private void addExtensionBeans(Collection<EndpointBean> endpointBeans) { private void addExtensionBeans(Collection<EndpointBean> endpointBeans) {
...@@ -159,8 +161,9 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten ...@@ -159,8 +161,9 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten
} }
private ExtensionBean createExtensionBean(String beanName) { private ExtensionBean createExtensionBean(String beanName) {
Object bean = this.applicationContext.getBean(beanName); Class<?> beanType = ClassUtils.getUserClass(this.applicationContext.getType(beanName));
return new ExtensionBean(this.applicationContext.getEnvironment(), beanName, bean); Supplier<Object> beanSupplier = () -> this.applicationContext.getBean(beanName);
return new ExtensionBean(this.applicationContext.getEnvironment(), beanName, beanType, beanSupplier);
} }
private void addExtensionBean(EndpointBean endpointBean, ExtensionBean extensionBean) { private void addExtensionBean(EndpointBean endpointBean, ExtensionBean extensionBean) {
...@@ -233,7 +236,8 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten ...@@ -233,7 +236,8 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten
} }
private boolean isExtensionExposed(EndpointBean endpointBean, ExtensionBean extensionBean) { private boolean isExtensionExposed(EndpointBean endpointBean, ExtensionBean extensionBean) {
return isFilterMatch(extensionBean.getFilter(), endpointBean) && isExtensionExposed(extensionBean.getBean()); return isFilterMatch(extensionBean.getFilter(), endpointBean)
&& isExtensionTypeExposed(extensionBean.getBeanType());
} }
/** /**
...@@ -242,10 +246,21 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten ...@@ -242,10 +246,21 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten
* @param extensionBean the extension bean * @param extensionBean the extension bean
* @return {@code true} if the extension is exposed * @return {@code true} if the extension is exposed
*/ */
@Deprecated
protected boolean isExtensionExposed(Object extensionBean) { protected boolean isExtensionExposed(Object extensionBean) {
return true; return true;
} }
/**
* Determine if an extension bean should be exposed. Subclasses can override this
* method to provide additional logic.
* @param extensionBeanType the extension bean type
* @return {@code true} if the extension is exposed
*/
protected boolean isExtensionTypeExposed(Class<?> extensionBeanType) {
return true;
}
private boolean isEndpointExposed(EndpointBean endpointBean) { private boolean isEndpointExposed(EndpointBean endpointBean) {
return isFilterMatch(endpointBean.getFilter(), endpointBean) && !isEndpointFiltered(endpointBean) return isFilterMatch(endpointBean.getFilter(), endpointBean) && !isEndpointFiltered(endpointBean)
&& isEndpointExposed(endpointBean.getBean()); && isEndpointExposed(endpointBean.getBean());
...@@ -257,10 +272,21 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten ...@@ -257,10 +272,21 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten
* @param endpointBean the endpoint bean * @param endpointBean the endpoint bean
* @return {@code true} if the endpoint is exposed * @return {@code true} if the endpoint is exposed
*/ */
@Deprecated
protected boolean isEndpointExposed(Object endpointBean) { protected boolean isEndpointExposed(Object endpointBean) {
return true; return true;
} }
/**
* Determine if an endpoint bean should be exposed. Subclasses can override this
* method to provide additional logic.
* @param beanType the endpoint bean type
* @return {@code true} if the endpoint is exposed
*/
protected boolean isEndpointTypeExposed(Class<?> beanType) {
return true;
}
private boolean isEndpointFiltered(EndpointBean endpointBean) { private boolean isEndpointFiltered(EndpointBean endpointBean) {
for (EndpointFilter<E> filter : this.filters) { for (EndpointFilter<E> filter : this.filters) {
if (!isFilterMatch(filter, endpointBean)) { if (!isFilterMatch(filter, endpointBean)) {
...@@ -272,7 +298,7 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten ...@@ -272,7 +298,7 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private boolean isFilterMatch(Class<?> filter, EndpointBean endpointBean) { private boolean isFilterMatch(Class<?> filter, EndpointBean endpointBean) {
if (!isEndpointExposed(endpointBean.getBean())) { if (!isEndpointTypeExposed(endpointBean.getBeanType())) {
return false; return false;
} }
if (filter == null) { if (filter == null) {
...@@ -392,7 +418,9 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten ...@@ -392,7 +418,9 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten
private final String beanName; private final String beanName;
private final Object bean; private final Class<?> beanType;
private final Supplier<Object> beanSupplier;
private final EndpointId id; private final EndpointId id;
...@@ -402,17 +430,18 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten ...@@ -402,17 +430,18 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten
private Set<ExtensionBean> extensions = new LinkedHashSet<>(); private Set<ExtensionBean> extensions = new LinkedHashSet<>();
EndpointBean(Environment environment, String beanName, Object bean) { EndpointBean(Environment environment, String beanName, Class<?> beanType, Supplier<Object> beanSupplier) {
MergedAnnotation<Endpoint> annotation = MergedAnnotations MergedAnnotation<Endpoint> annotation = MergedAnnotations.from(beanType, SearchStrategy.TYPE_HIERARCHY)
.from(bean.getClass(), SearchStrategy.TYPE_HIERARCHY).get(Endpoint.class); .get(Endpoint.class);
String id = annotation.getString("id"); String id = annotation.getString("id");
Assert.state(StringUtils.hasText(id), Assert.state(StringUtils.hasText(id),
() -> "No @Endpoint id attribute specified for " + bean.getClass().getName()); () -> "No @Endpoint id attribute specified for " + beanType.getName());
this.beanName = beanName; this.beanName = beanName;
this.bean = bean; this.beanType = beanType;
this.beanSupplier = beanSupplier;
this.id = EndpointId.of(environment, id); this.id = EndpointId.of(environment, id);
this.enabledByDefault = annotation.getBoolean("enableByDefault"); this.enabledByDefault = annotation.getBoolean("enableByDefault");
this.filter = getFilter(this.bean.getClass()); this.filter = getFilter(beanType);
} }
void addExtension(ExtensionBean extensionBean) { void addExtension(ExtensionBean extensionBean) {
...@@ -432,8 +461,12 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten ...@@ -432,8 +461,12 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten
return this.beanName; return this.beanName;
} }
Class<?> getBeanType() {
return this.beanType;
}
Object getBean() { Object getBean() {
return this.bean; return this.beanSupplier.get();
} }
EndpointId getId() { EndpointId getId() {
...@@ -457,17 +490,20 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten ...@@ -457,17 +490,20 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten
private final String beanName; private final String beanName;
private final Object bean; private final Class<?> beanType;
private final Supplier<Object> beanSupplier;
private final EndpointId endpointId; private final EndpointId endpointId;
private final Class<?> filter; private final Class<?> filter;
ExtensionBean(Environment environment, String beanName, Object bean) { ExtensionBean(Environment environment, String beanName, Class<?> beanType, Supplier<Object> beanSupplier) {
this.bean = bean;
this.beanName = beanName; this.beanName = beanName;
this.beanType = beanType;
this.beanSupplier = beanSupplier;
MergedAnnotation<EndpointExtension> extensionAnnotation = MergedAnnotations MergedAnnotation<EndpointExtension> extensionAnnotation = MergedAnnotations
.from(bean.getClass(), SearchStrategy.TYPE_HIERARCHY).get(EndpointExtension.class); .from(beanType, SearchStrategy.TYPE_HIERARCHY).get(EndpointExtension.class);
Class<?> endpointType = extensionAnnotation.getClass("endpoint"); Class<?> endpointType = extensionAnnotation.getClass("endpoint");
MergedAnnotation<Endpoint> endpointAnnotation = MergedAnnotations MergedAnnotation<Endpoint> endpointAnnotation = MergedAnnotations
.from(endpointType, SearchStrategy.TYPE_HIERARCHY).get(Endpoint.class); .from(endpointType, SearchStrategy.TYPE_HIERARCHY).get(Endpoint.class);
...@@ -481,8 +517,12 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten ...@@ -481,8 +517,12 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten
return this.beanName; return this.beanName;
} }
Class<?> getBeanType() {
return this.beanType;
}
Object getBean() { Object getBean() {
return this.bean; return this.beanSupplier.get();
} }
EndpointId getEndpointId() { EndpointId getEndpointId() {
......
...@@ -30,7 +30,7 @@ import org.springframework.boot.actuate.endpoint.invoke.ParameterValueMapper; ...@@ -30,7 +30,7 @@ import org.springframework.boot.actuate.endpoint.invoke.ParameterValueMapper;
import org.springframework.boot.actuate.endpoint.web.PathMapper; import org.springframework.boot.actuate.endpoint.web.PathMapper;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.core.annotation.MergedAnnotations; import org.springframework.core.annotation.MergedAnnotations;
import org.springframework.util.ClassUtils; import org.springframework.core.annotation.MergedAnnotations.SearchStrategy;
/** /**
* {@link EndpointDiscoverer} for {@link ExposableControllerEndpoint controller * {@link EndpointDiscoverer} for {@link ExposableControllerEndpoint controller
...@@ -57,9 +57,8 @@ public class ControllerEndpointDiscoverer extends EndpointDiscoverer<ExposableCo ...@@ -57,9 +57,8 @@ public class ControllerEndpointDiscoverer extends EndpointDiscoverer<ExposableCo
} }
@Override @Override
protected boolean isEndpointExposed(Object endpointBean) { protected boolean isEndpointTypeExposed(Class<?> beanType) {
Class<?> type = ClassUtils.getUserClass(endpointBean.getClass()); MergedAnnotations annotations = MergedAnnotations.from(beanType, SearchStrategy.SUPERCLASS);
MergedAnnotations annotations = MergedAnnotations.from(type);
return annotations.isPresent(ControllerEndpoint.class) || annotations.isPresent(RestControllerEndpoint.class); return annotations.isPresent(ControllerEndpoint.class) || annotations.isPresent(RestControllerEndpoint.class);
} }
......
...@@ -31,7 +31,7 @@ import org.springframework.boot.actuate.endpoint.web.ExposableServletEndpoint; ...@@ -31,7 +31,7 @@ import org.springframework.boot.actuate.endpoint.web.ExposableServletEndpoint;
import org.springframework.boot.actuate.endpoint.web.PathMapper; import org.springframework.boot.actuate.endpoint.web.PathMapper;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.core.annotation.MergedAnnotations; import org.springframework.core.annotation.MergedAnnotations;
import org.springframework.util.ClassUtils; import org.springframework.core.annotation.MergedAnnotations.SearchStrategy;
/** /**
* {@link EndpointDiscoverer} for {@link ExposableServletEndpoint servlet endpoints}. * {@link EndpointDiscoverer} for {@link ExposableServletEndpoint servlet endpoints}.
...@@ -57,9 +57,8 @@ public class ServletEndpointDiscoverer extends EndpointDiscoverer<ExposableServl ...@@ -57,9 +57,8 @@ public class ServletEndpointDiscoverer extends EndpointDiscoverer<ExposableServl
} }
@Override @Override
protected boolean isEndpointExposed(Object endpointBean) { protected boolean isEndpointTypeExposed(Class<?> beanType) {
Class<?> type = ClassUtils.getUserClass(endpointBean.getClass()); return MergedAnnotations.from(beanType, SearchStrategy.SUPERCLASS).isPresent(ServletEndpoint.class);
return MergedAnnotations.from(type).isPresent(ServletEndpoint.class);
} }
@Override @Override
......
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