dubbo-spring-boot-actuator compatible with Spring Boot Actuator 2.6.x (#9394) (#9426)

This commit is contained in:
gitchenjh 2021-12-17 14:32:24 +08:00 committed by GitHub
parent 5acc9b2485
commit 9492880d26
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 33 additions and 27 deletions

View File

@ -150,7 +150,7 @@ Actuator endpoint `dubbo` supports Actuator Endpoints :
| ------------------- | ----------- | ----------------------------------- | ------------------ | ------------------ | ------------------ |
| `dubbo` | `true` | `/actuator/dubbo` | `GET` | Exposes Dubbo's meta data | `application/json` |
| `dubboproperties` | `true` | `/actuator/dubbo/properties` | `GET` | Exposes all Dubbo's Properties | `application/json` |
| `dubboservices` | `false` | `/dubbo/services` | `GET` | Exposes all Dubbo's `ServiceBean` | `application/json` |
| `dubboservices` | `false` | `/actuator/dubbo/services` | `GET` | Exposes all Dubbo's `ServiceBean` | `application/json` |
| `dubboreferences` | `false` | `/actuator/dubbo/references` | `GET` | Exposes all Dubbo's `ReferenceBean` | `application/json` |
| `dubboconfigs` | `true` | `/actuator/dubbo/configs` | `GET` | Exposes all Dubbo's `*Config` | `application/json` |
| `dubboshutdown` | `false` | `/actuator/dubbo/shutdown` | `POST` | Shutdown Dubbo services | `application/json` |

View File

@ -24,6 +24,7 @@ import org.apache.dubbo.spring.boot.actuate.endpoint.DubboServicesMetadataEndpoi
import org.apache.dubbo.spring.boot.actuate.endpoint.DubboShutdownEndpoint;
import org.apache.dubbo.spring.boot.actuate.endpoint.condition.CompatibleConditionalOnEnabledEndpoint;
import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint;
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
@ -45,6 +46,7 @@ public class DubboEndpointAnnotationAutoConfiguration {
@Bean
@ConditionalOnMissingBean
@ConditionalOnAvailableEndpoint
@CompatibleConditionalOnEnabledEndpoint
public DubboMetadataEndpoint dubboEndpoint() {
return new DubboMetadataEndpoint();
@ -52,6 +54,7 @@ public class DubboEndpointAnnotationAutoConfiguration {
@Bean
@ConditionalOnMissingBean
@ConditionalOnAvailableEndpoint
@CompatibleConditionalOnEnabledEndpoint
public DubboConfigsMetadataEndpoint dubboConfigsMetadataEndpoint() {
return new DubboConfigsMetadataEndpoint();
@ -59,6 +62,7 @@ public class DubboEndpointAnnotationAutoConfiguration {
@Bean
@ConditionalOnMissingBean
@ConditionalOnAvailableEndpoint
@CompatibleConditionalOnEnabledEndpoint
public DubboPropertiesMetadataEndpoint dubboPropertiesEndpoint() {
return new DubboPropertiesMetadataEndpoint();
@ -66,6 +70,7 @@ public class DubboEndpointAnnotationAutoConfiguration {
@Bean
@ConditionalOnMissingBean
@ConditionalOnAvailableEndpoint
@CompatibleConditionalOnEnabledEndpoint
public DubboReferencesMetadataEndpoint dubboReferencesMetadataEndpoint() {
return new DubboReferencesMetadataEndpoint();
@ -73,6 +78,7 @@ public class DubboEndpointAnnotationAutoConfiguration {
@Bean
@ConditionalOnMissingBean
@ConditionalOnAvailableEndpoint
@CompatibleConditionalOnEnabledEndpoint
public DubboServicesMetadataEndpoint dubboServicesMetadataEndpoint() {
return new DubboServicesMetadataEndpoint();
@ -80,6 +86,7 @@ public class DubboEndpointAnnotationAutoConfiguration {
@Bean
@ConditionalOnMissingBean
@ConditionalOnAvailableEndpoint
@CompatibleConditionalOnEnabledEndpoint
public DubboShutdownEndpoint dubboShutdownEndpoint() {
return new DubboShutdownEndpoint();

View File

@ -16,6 +16,9 @@
*/
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;
@ -23,8 +26,6 @@ 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 @@ import java.util.stream.Stream;
*/
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);
}
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;
}
// No condition class found
LOGGER.warn(String.format("No condition class found, Dubbo Health Endpoint [%s] will not expose", metadata));
return false;
}
}