diff --git a/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/custom/SentinelDataSourceHandler.java b/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/custom/SentinelDataSourceHandler.java index 696a8c54..2cee62aa 100644 --- a/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/custom/SentinelDataSourceHandler.java +++ b/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/custom/SentinelDataSourceHandler.java @@ -18,11 +18,9 @@ package org.springframework.cloud.alibaba.sentinel.custom; import java.lang.reflect.Field; import java.util.Arrays; -import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Set; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -35,13 +33,11 @@ import org.springframework.cloud.alibaba.sentinel.datasource.config.DataSourcePr import org.springframework.cloud.alibaba.sentinel.datasource.converter.JsonConverter; import org.springframework.cloud.alibaba.sentinel.datasource.converter.XmlConverter; import org.springframework.core.env.Environment; -import org.springframework.util.CollectionUtils; import org.springframework.util.ReflectionUtils; import org.springframework.util.StringUtils; import com.alibaba.csp.sentinel.datasource.AbstractDataSource; import com.alibaba.csp.sentinel.datasource.ReadableDataSource; -import com.alibaba.csp.sentinel.slots.block.AbstractRule; /** * Sentinel {@link ReadableDataSource} Handler Handle the configurations of @@ -210,61 +206,8 @@ public class SentinelDataSourceHandler implements SmartInitializingSingleton { AbstractDataSource newDataSource = (AbstractDataSource) this.beanFactory .getBean(dataSourceName); - logAndCheckRuleType(newDataSource, dataSourceName, - dataSourceProperties.getRuleType().getClazz()); - // register property in RuleManager dataSourceProperties.postRegister(newDataSource); } - private void logAndCheckRuleType(AbstractDataSource dataSource, String dataSourceName, - Class extends AbstractRule> ruleClass) { - Object ruleConfig; - try { - ruleConfig = dataSource.loadConfig(); - } - catch (Exception e) { - log.error("[Sentinel Starter] DataSource " + dataSourceName - + " loadConfig error: " + e.getMessage(), e); - return; - } - if (ruleConfig instanceof List || ruleConfig instanceof Set) { - Collection convertedRuleList = (Collection) ruleConfig; - if (CollectionUtils.isEmpty(convertedRuleList)) { - log.warn("[Sentinel Starter] DataSource {} rule list is empty.", - dataSourceName); - return; - } - int matchCount = 0; - for (Object rule : convertedRuleList) { - if (rule.getClass() == ruleClass) { - matchCount++; - } - } - if (matchCount == 0) { - log.error("[Sentinel Starter] DataSource {} none rules are {} type.", - dataSourceName, ruleClass.getSimpleName()); - throw new IllegalArgumentException("[Sentinel Starter] DataSource " - + dataSourceName + " none rules are " + ruleClass.getSimpleName() - + " type."); - } - else if (matchCount != convertedRuleList.size()) { - log.warn("[Sentinel Starter] DataSource {} all rules are not {} type.", - dataSourceName, ruleClass.getSimpleName()); - } - else { - log.info("[Sentinel Starter] DataSource {} load {} {}", dataSourceName, - convertedRuleList.size(), ruleClass.getSimpleName()); - } - } - else { - log.error("[Sentinel Starter] DataSource " + dataSourceName - + " rule class is not List<" + ruleClass.getSimpleName() - + ">. Class: " + ruleConfig.getClass()); - throw new IllegalArgumentException("[Sentinel Starter] DataSource " - + dataSourceName + " rule class is not List<" - + ruleClass.getSimpleName() + ">. Class: " + ruleConfig.getClass()); - } - } - } diff --git a/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/endpoint/SentinelEndpointAutoConfiguration.java b/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/endpoint/SentinelEndpointAutoConfiguration.java index b49fb20e..b436e364 100644 --- a/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/endpoint/SentinelEndpointAutoConfiguration.java +++ b/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/endpoint/SentinelEndpointAutoConfiguration.java @@ -16,6 +16,8 @@ package org.springframework.cloud.alibaba.sentinel.endpoint; +import org.springframework.beans.factory.support.DefaultListableBeanFactory; +import org.springframework.boot.actuate.autoconfigure.ConditionalOnEnabledHealthIndicator; import org.springframework.boot.actuate.condition.ConditionalOnEnabledEndpoint; import org.springframework.boot.actuate.endpoint.Endpoint; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; @@ -38,4 +40,13 @@ public class SentinelEndpointAutoConfiguration { return new SentinelEndpoint(sentinelProperties); } + @Bean + @ConditionalOnMissingBean + @ConditionalOnEnabledHealthIndicator("sentinel") + public SentinelHealthIndicator sentinelHealthIndicator( + DefaultListableBeanFactory beanFactory, + SentinelProperties sentinelProperties) { + return new SentinelHealthIndicator(beanFactory, sentinelProperties); + } + } diff --git a/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/endpoint/SentinelHealthIndicator.java b/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/endpoint/SentinelHealthIndicator.java new file mode 100644 index 00000000..b8fae17b --- /dev/null +++ b/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/endpoint/SentinelHealthIndicator.java @@ -0,0 +1,154 @@ +/* + * Copyright (C) 2018 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.cloud.alibaba.sentinel.endpoint; + +import java.util.HashMap; +import java.util.Map; + +import org.springframework.beans.factory.support.DefaultListableBeanFactory; +import org.springframework.boot.actuate.health.AbstractHealthIndicator; +import org.springframework.boot.actuate.health.Health; +import org.springframework.boot.actuate.health.HealthIndicator; +import org.springframework.boot.actuate.health.Status; +import org.springframework.cloud.alibaba.sentinel.SentinelProperties; +import org.springframework.util.StringUtils; + +import com.alibaba.csp.sentinel.datasource.AbstractDataSource; +import com.alibaba.csp.sentinel.heartbeat.HeartbeatSenderProvider; +import com.alibaba.csp.sentinel.transport.HeartbeatSender; +import com.alibaba.csp.sentinel.transport.config.TransportConfig; + +/** + * A {@link HealthIndicator} for Sentinel, which checks the status of Sentinel Dashboard + * and DataSource. + * + *
+ * Check the status of Sentinel Dashboard by sending a heartbeat message to it. If return + * true, it's OK. + * + * Check the status of Sentinel DataSource by calling loadConfig method of + * {@link AbstractDataSource}. If no Exception thrown, it's OK. + * + * If Dashboard and DataSource are both OK, the health status is UP. + *
+ * + *+ * Note: If Sentinel isn't enabled, the health status is up. If Sentinel Dashboard isn't + * configured, it's OK and mark the status of Dashboard with UNKNOWN. More informations + * are provided in details. + *
+ * + * @author cdfive + */ +public class SentinelHealthIndicator extends AbstractHealthIndicator { + + private DefaultListableBeanFactory beanFactory; + + private SentinelProperties sentinelProperties; + + public SentinelHealthIndicator(DefaultListableBeanFactory beanFactory, + SentinelProperties sentinelProperties) { + this.beanFactory = beanFactory; + this.sentinelProperties = sentinelProperties; + } + + @Override + protected void doHealthCheck(Health.Builder builder) throws Exception { + Map