New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[3.0] dubbo-spring-boot-actuator compatible with Spring Boot Actuator 2.6.x #9426
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,15 +16,16 @@ | |
*/ | ||
package org.apache.dubbo.spring.boot.actuate.endpoint.condition; | ||
|
||
import org.apache.dubbo.common.logger.Logger; | ||
import org.apache.dubbo.common.logger.LoggerFactory; | ||
|
||
import org.springframework.beans.BeanUtils; | ||
import org.springframework.context.annotation.Condition; | ||
import org.springframework.context.annotation.ConditionContext; | ||
import org.springframework.context.annotation.Conditional; | ||
import org.springframework.core.type.AnnotatedTypeMetadata; | ||
import org.springframework.util.ClassUtils; | ||
|
||
import java.util.stream.Stream; | ||
|
||
/** | ||
* {@link Conditional} that checks whether or not an endpoint is enabled, which is compatible with | ||
* org.springframework.boot.actuate.autoconfigure.endpoint.condition.OnEnabledEndpointCondition | ||
|
@@ -35,35 +36,33 @@ | |
*/ | ||
class CompatibleOnEnabledEndpointCondition implements Condition { | ||
|
||
static String[] CONDITION_CLASS_NAMES = { | ||
"org.springframework.boot.actuate.autoconfigure.endpoint.condition.OnAvailableEndpointCondition", // 2.2.0+ | ||
"org.springframework.boot.actuate.autoconfigure.endpoint.condition.OnEnabledEndpointCondition" // [2.0.0 , 2.2.x] | ||
}; | ||
private static final Logger LOGGER = LoggerFactory.getLogger(CompatibleOnEnabledEndpointCondition.class); | ||
|
||
// Spring Boot [2.0.0 , 2.2.x] | ||
static String CONDITION_CLASS_NAME_OLD = | ||
"org.springframework.boot.actuate.autoconfigure.endpoint.condition.OnEnabledEndpointCondition"; | ||
|
||
// Spring Boot 2.2.0 + | ||
static String CONDITION_CLASS_NAME_NEW = | ||
"org.springframework.boot.actuate.autoconfigure.endpoint.condition.OnAvailableEndpointCondition"; | ||
|
||
|
||
@Override | ||
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { | ||
ClassLoader classLoader = context.getClassLoader(); | ||
|
||
Condition condition = Stream.of(CONDITION_CLASS_NAMES) // Iterate class names | ||
.filter(className -> ClassUtils.isPresent(className, classLoader)) // Search class existing or not by name | ||
.findFirst() // Find the first candidate | ||
.map(className -> ClassUtils.resolveClassName(className, classLoader)) // Resolve class name to Class | ||
.filter(Condition.class::isAssignableFrom) // Accept the Condition implementation | ||
.map(BeanUtils::instantiateClass) // Instantiate Class to be instance | ||
.map(Condition.class::cast) // Cast the instance to be Condition one | ||
.orElse(NegativeCondition.INSTANCE); // Or else get a negative condition | ||
|
||
return condition.matches(context, metadata); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please try fix error of //OnAvailableEndpointCondition of Spring Boot 2.6.1 @Override
public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {
Environment environment = context.getEnvironment();
MergedAnnotation<ConditionalOnAvailableEndpoint> conditionAnnotation = metadata.getAnnotations()
.get(ConditionalOnAvailableEndpoint.class);
Class<?> target = getTarget(context, metadata, conditionAnnotation);
MergedAnnotation<Endpoint> endpointAnnotation = getEndpointAnnotation(target);
return getMatchOutcome(environment, conditionAnnotation, endpointAnnotation);
} There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @gitchenjh If it can work in Spring Boot <2.2.0, it is more compatible to use ConditionalOnAvailableEndpoint directly. The only problem is that the code is a bit difficult to understand. |
||
} | ||
|
||
private static class NegativeCondition implements Condition { | ||
|
||
static final NegativeCondition INSTANCE = new NegativeCondition(); | ||
|
||
@Override | ||
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { | ||
return false; | ||
if (ClassUtils.isPresent(CONDITION_CLASS_NAME_OLD, classLoader)) { | ||
Class<?> cls = ClassUtils.resolveClassName(CONDITION_CLASS_NAME_OLD, classLoader); | ||
if (Condition.class.isAssignableFrom(cls)) { | ||
Condition condition = Condition.class.cast(BeanUtils.instantiateClass(cls)); | ||
return condition.matches(context, metadata); | ||
} | ||
} | ||
// Check by org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint | ||
if (ClassUtils.isPresent(CONDITION_CLASS_NAME_NEW, classLoader)) { | ||
return true; | ||
Comment on lines
51
to
+62
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's good. The There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That is |
||
} | ||
// No condition class found | ||
LOGGER.warn(String.format("No condition class found, Dubbo Health Endpoint [%s] will not expose", metadata)); | ||
return false; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ConditionalOnAvailableEndpoint
is available sine Spring Boot 2.2.0, see https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/actuate/autoconfigure/endpoint/condition/ConditionalOnAvailableEndpoint.htmlIf we reference
@ConditionalOnAvailableEndpoint
directly, it may cause loading failed on Spring Boot version < 2.2.0.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems missing annotation class will not cause ClassNotFoundException, please check it on Spring Boot version < 2.2.0.