diff --git a/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/pom.xml b/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/pom.xml index 54ebf34e..58f70c86 100644 --- a/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/pom.xml +++ b/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/pom.xml @@ -54,6 +54,15 @@ 2.2.5.RELEASE true + + + com.ctrip.framework.apollo + apollo-client + ${apollo.version} + compile + true + + diff --git a/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/config/BootstrapCoreProperties.java b/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/config/BootstrapCoreProperties.java index bd7233b5..2076a075 100644 --- a/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/config/BootstrapCoreProperties.java +++ b/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/config/BootstrapCoreProperties.java @@ -1,5 +1,6 @@ package cn.hippo4j.core.starter.config; +import cn.hippo4j.core.starter.parser.ConfigFileTypeEnum; import lombok.Getter; import lombok.Setter; import org.springframework.boot.context.properties.ConfigurationProperties; @@ -38,7 +39,7 @@ public class BootstrapCoreProperties { /** * Config file type. */ - private String configFileType; + private ConfigFileTypeEnum configFileType; /** * Nacos config. diff --git a/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/config/DynamicThreadPoolCoreAutoConfiguration.java b/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/config/DynamicThreadPoolCoreAutoConfiguration.java index dc5aba1d..8bca08ff 100644 --- a/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/config/DynamicThreadPoolCoreAutoConfiguration.java +++ b/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/config/DynamicThreadPoolCoreAutoConfiguration.java @@ -12,18 +12,17 @@ import cn.hippo4j.common.notify.platform.WeChatSendMessageHandler; import cn.hippo4j.core.config.UtilAutoConfiguration; import cn.hippo4j.core.executor.ThreadPoolNotifyAlarmHandler; import cn.hippo4j.core.starter.notify.CoreNotifyConfigBuilder; +import cn.hippo4j.core.starter.parser.ConfigParserHandler; +import cn.hippo4j.core.starter.refresher.ApolloRefresherHandler; import cn.hippo4j.core.starter.refresher.NacosCloudRefresherHandler; import cn.hippo4j.core.starter.refresher.NacosRefresherHandler; -import cn.hippo4j.core.starter.refresher.config.ConfigParser; -import cn.hippo4j.core.starter.refresher.config.impl.PropConfigParser; -import cn.hippo4j.core.starter.refresher.config.impl.YmlConfigParser; import cn.hippo4j.core.starter.support.DynamicThreadPoolPostProcessor; import com.alibaba.cloud.nacos.NacosConfigManager; import com.alibaba.nacos.api.config.ConfigService; -import com.google.common.collect.Lists; import lombok.AllArgsConstructor; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; @@ -31,8 +30,6 @@ import org.springframework.context.annotation.Configuration; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; -import java.util.List; - /** * Dynamic thread pool auto configuration. * @@ -51,8 +48,7 @@ public class DynamicThreadPoolCoreAutoConfiguration { private static final String NACOS_CONFIG_KEY = "com.alibaba.nacos.api.config"; - private final List yamlList = Lists.newArrayList("yaml", "yml"); - private final List propList = Lists.newArrayList("properties"); + private static final String APOLLO_CONFIG_KEY = "com.ctrip.framework.apollo.ConfigService.class"; @Bean @Order(Ordered.HIGHEST_PRECEDENCE) @@ -106,32 +102,25 @@ public class DynamicThreadPoolCoreAutoConfiguration { @ConditionalOnMissingClass(NACOS_CONFIG_MANAGER_KEY) public NacosRefresherHandler nacosRefresherHandler(ConfigService configService, ThreadPoolNotifyAlarmHandler threadPoolNotifyAlarmHandler, - ConfigParser configParser, BootstrapCoreProperties bootstrapCoreProperties) { - return new NacosRefresherHandler(configService, threadPoolNotifyAlarmHandler, configParser, bootstrapCoreProperties); + return new NacosRefresherHandler(configService, threadPoolNotifyAlarmHandler, bootstrapCoreProperties); } @Bean @ConditionalOnClass(name = NACOS_CONFIG_MANAGER_KEY) public NacosCloudRefresherHandler nacosCloudRefresherHandler(NacosConfigManager nacosConfigManager, ThreadPoolNotifyAlarmHandler threadPoolNotifyAlarmHandler, - ConfigParser configParser, BootstrapCoreProperties bootstrapCoreProperties) { - return new NacosCloudRefresherHandler(nacosConfigManager, threadPoolNotifyAlarmHandler, configParser, bootstrapCoreProperties); + return new NacosCloudRefresherHandler(nacosConfigManager, threadPoolNotifyAlarmHandler, bootstrapCoreProperties); } @Bean - public ConfigParser configParserHandler() { - // return new ConfigParserHandler(); - String configFileType = bootstrapCoreProperties.getConfigFileType(); - if (yamlList.contains(configFileType)) { - return new YmlConfigParser(); - } - if (propList.contains(configFileType)) { - return new PropConfigParser(); - } - - throw new UnsupportedOperationException("暂不支持的配置文件类型: " + configFileType); + @ConditionalOnMissingBean + @ConditionalOnClass(name = APOLLO_CONFIG_KEY) + public ApolloRefresherHandler apolloRefresher(ThreadPoolNotifyAlarmHandler threadPoolNotifyAlarmHandler, + BootstrapCoreProperties bootstrapCoreProperties) { + return new ApolloRefresherHandler(threadPoolNotifyAlarmHandler, bootstrapCoreProperties); } + } diff --git a/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/parser/AbstractConfigParser.java b/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/parser/AbstractConfigParser.java new file mode 100644 index 00000000..9664243d --- /dev/null +++ b/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/parser/AbstractConfigParser.java @@ -0,0 +1,15 @@ +package cn.hippo4j.core.starter.parser; + +/** + * @author : wh + * @date : 2022/3/1 07:50 + * @description: + */ +public abstract class AbstractConfigParser implements ConfigParser{ + + @Override + public boolean supports(ConfigFileTypeEnum type) { + return getConfigFileTypes().contains(type); + } + +} diff --git a/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/parser/ConfigFileTypeEnum.java b/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/parser/ConfigFileTypeEnum.java new file mode 100644 index 00000000..cba9c46d --- /dev/null +++ b/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/parser/ConfigFileTypeEnum.java @@ -0,0 +1,35 @@ +package cn.hippo4j.core.starter.parser; + +import lombok.Getter; + +/** + * @author : wh + * @date : 2022/3/1 07:47 + * @description: + */ +@Getter +public enum ConfigFileTypeEnum { + + PROPERTIES("properties"), + XML("xml"), + JSON("json"), + YML("yml"), + YAML("yaml"), + TXT("txt"); + + private final String value; + + ConfigFileTypeEnum(String value) { + this.value = value; + } + + public static ConfigFileTypeEnum of(String value) { + for (ConfigFileTypeEnum typeEnum : ConfigFileTypeEnum.values()) { + if (typeEnum.value.equals(value)) { + return typeEnum; + } + } + return PROPERTIES; + } + +} diff --git a/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/parser/ConfigParser.java b/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/parser/ConfigParser.java new file mode 100644 index 00000000..b692e6ca --- /dev/null +++ b/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/parser/ConfigParser.java @@ -0,0 +1,20 @@ +package cn.hippo4j.core.starter.parser; + +import java.io.IOException; +import java.util.List; +import java.util.Map; + +/** + * @author : wh + * @date : 2022/3/1 07:47 + * @description: + */ +public interface ConfigParser { + + boolean supports(ConfigFileTypeEnum type); + + Map doParse(String content) throws IOException; + + List getConfigFileTypes(); + +} diff --git a/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/parser/ConfigParserHandler.java b/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/parser/ConfigParserHandler.java new file mode 100644 index 00000000..62e05226 --- /dev/null +++ b/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/parser/ConfigParserHandler.java @@ -0,0 +1,47 @@ +package cn.hippo4j.core.starter.parser; + +import com.google.common.collect.Lists; + +import java.io.IOException; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.ServiceLoader; + +/** + * @author : wh + * @date : 2022/3/1 08:02 + * @description: + */ +public class ConfigParserHandler { + + private static final List PARSERS = Lists.newArrayList(); + + private ConfigParserHandler() { + ServiceLoader loader = ServiceLoader.load(ConfigParser.class); + for (ConfigParser configParser : loader) { + PARSERS.add(configParser); + } + + PARSERS.add(new PropertiesConfigParser()); + PARSERS.add(new YamlConfigParser()); + } + + public Map parseConfig(String content, ConfigFileTypeEnum type) throws IOException { + for (ConfigParser parser : PARSERS) { + if (parser.supports(type)) { + return parser.doParse(content); + } + } + return Collections.emptyMap(); + } + + public static ConfigParserHandler getInstance() { + return ConfigParserHandlerHolder.INSTANCE; + } + + private static class ConfigParserHandlerHolder { + private static final ConfigParserHandler INSTANCE = new ConfigParserHandler(); + } + +} diff --git a/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/parser/PropertiesConfigParser.java b/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/parser/PropertiesConfigParser.java new file mode 100644 index 00000000..28de7000 --- /dev/null +++ b/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/parser/PropertiesConfigParser.java @@ -0,0 +1,30 @@ +package cn.hippo4j.core.starter.parser; + +import com.google.common.collect.Lists; + +import java.io.IOException; +import java.io.StringReader; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +/** + * @author : wh + * @date : 2022/3/1 07:49 + * @description: + */ +public class PropertiesConfigParser extends AbstractConfigParser{ + + + @Override + public Map doParse(String content) throws IOException { + Properties properties = new Properties(); + properties.load(new StringReader(content)); + return properties; + } + + @Override + public List getConfigFileTypes() { + return Lists.newArrayList(ConfigFileTypeEnum.PROPERTIES); + } +} diff --git a/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/parser/YamlConfigParser.java b/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/parser/YamlConfigParser.java new file mode 100644 index 00000000..88b1d7b1 --- /dev/null +++ b/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/parser/YamlConfigParser.java @@ -0,0 +1,33 @@ +package cn.hippo4j.core.starter.parser; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import org.springframework.beans.factory.config.YamlPropertiesFactoryBean; +import org.springframework.core.io.ByteArrayResource; +import org.springframework.util.StringUtils; + +import java.util.List; +import java.util.Map; + +/** + * @author : wh + * @date : 2022/3/1 07:57 + * @description: + */ +public class YamlConfigParser extends AbstractConfigParser{ + + @Override + public Map doParse(String content) { + if (StringUtils.isEmpty(content)) { + return Maps.newHashMapWithExpectedSize(0); + } + YamlPropertiesFactoryBean bean = new YamlPropertiesFactoryBean(); + bean.setResources(new ByteArrayResource(content.getBytes())); + return bean.getObject(); + } + + @Override + public List getConfigFileTypes() { + return Lists.newArrayList(ConfigFileTypeEnum.YML, ConfigFileTypeEnum.YAML); + } +} diff --git a/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/refresher/AbstractCoreThreadPoolDynamicRefresh.java b/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/refresher/AbstractCoreThreadPoolDynamicRefresh.java index 4267c261..4a91797a 100644 --- a/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/refresher/AbstractCoreThreadPoolDynamicRefresh.java +++ b/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/refresher/AbstractCoreThreadPoolDynamicRefresh.java @@ -9,7 +9,7 @@ import cn.hippo4j.core.executor.support.*; import cn.hippo4j.core.proxy.RejectedProxyUtil; import cn.hippo4j.core.starter.config.BootstrapCoreProperties; import cn.hippo4j.core.starter.config.ExecutorProperties; -import cn.hippo4j.core.starter.refresher.config.ConfigParser; +import cn.hippo4j.core.starter.parser.ConfigParserHandler; import cn.hippo4j.core.starter.support.GlobalCoreThreadPoolManage; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -18,6 +18,7 @@ import org.springframework.boot.context.properties.bind.Binder; import org.springframework.boot.context.properties.source.ConfigurationPropertySource; import org.springframework.boot.context.properties.source.MapConfigurationPropertySource; +import java.io.IOException; import java.util.List; import java.util.Map; import java.util.Objects; @@ -41,8 +42,6 @@ public abstract class AbstractCoreThreadPoolDynamicRefresh implements ThreadPool private final ThreadPoolNotifyAlarmHandler threadPoolNotifyAlarmHandler; - private final ConfigParser configParser; - protected final BootstrapCoreProperties bootstrapCoreProperties; protected final ExecutorService dynamicRefreshExecutorService = ThreadPoolBuilder.builder() @@ -51,8 +50,15 @@ public abstract class AbstractCoreThreadPoolDynamicRefresh implements ThreadPool .build(); @Override - public void dynamicRefresh(String content) { - Map configInfo = configParser.parseConfig(content); + public void dynamicRefresh(String content){ + Map configInfo = null; + try { + configInfo = ConfigParserHandler.getInstance().parseConfig(content, bootstrapCoreProperties.getConfigFileType()); + } catch (IOException e) { + log.error("dynamic-thread-pool parse config file error, content: {}, fileType: {}", + content, bootstrapCoreProperties.getConfigFileType(), e); + return; + } ConfigurationPropertySource sources = new MapConfigurationPropertySource(configInfo); Binder binder = new Binder(sources); diff --git a/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/refresher/ApolloRefresherHandler.java b/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/refresher/ApolloRefresherHandler.java new file mode 100644 index 00000000..2f19c927 --- /dev/null +++ b/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/refresher/ApolloRefresherHandler.java @@ -0,0 +1,50 @@ +package cn.hippo4j.core.starter.refresher; + +import cn.hippo4j.core.executor.ThreadPoolNotifyAlarmHandler; +import cn.hippo4j.core.starter.config.BootstrapCoreProperties; +import com.ctrip.framework.apollo.Config; +import com.ctrip.framework.apollo.ConfigChangeListener; +import com.ctrip.framework.apollo.ConfigFile; +import com.ctrip.framework.apollo.ConfigService; +import com.ctrip.framework.apollo.core.enums.ConfigFileFormat; +import com.ctrip.framework.apollo.model.ConfigChangeEvent; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.annotation.Value; + +/** + * @author : wh + * @date : 2022/2/28 21:32 + * @description: + */ +@Slf4j +public class ApolloRefresherHandler extends AbstractCoreThreadPoolDynamicRefresh implements ConfigChangeListener, InitializingBean { + + private static final String APOLLO_PROPERTY = "${apollo.bootstrap.namespaces:application}"; + + @Value(APOLLO_PROPERTY) + private String namespace; + + + public ApolloRefresherHandler(ThreadPoolNotifyAlarmHandler threadPoolNotifyAlarmHandler , BootstrapCoreProperties bootstrapCoreProperties) { + super(threadPoolNotifyAlarmHandler, bootstrapCoreProperties); + } + + @Override + public void onChange(ConfigChangeEvent configChangeEvent) { + ConfigFile configFile = ConfigService.getConfigFile(namespace, + ConfigFileFormat.fromString(bootstrapCoreProperties.getConfigFileType().getValue())); + String configInfo = configFile.getContent(); + dynamicRefresh(configInfo); + } + + @Override + public void afterPropertiesSet() { + String[] apolloNamespaces = this.namespace.split(","); + this.namespace = apolloNamespaces[0]; + Config config = ConfigService.getConfig(namespace); + config.addChangeListener(this); + log.info("dynamic-thread-pool refresher, add apollo listener success, namespace: {}", namespace); + } + +} diff --git a/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/refresher/NacosCloudRefresherHandler.java b/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/refresher/NacosCloudRefresherHandler.java index 954fce04..48a5badf 100644 --- a/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/refresher/NacosCloudRefresherHandler.java +++ b/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/refresher/NacosCloudRefresherHandler.java @@ -2,7 +2,6 @@ package cn.hippo4j.core.starter.refresher; import cn.hippo4j.core.executor.ThreadPoolNotifyAlarmHandler; import cn.hippo4j.core.starter.config.BootstrapCoreProperties; -import cn.hippo4j.core.starter.refresher.config.ConfigParser; import com.alibaba.cloud.nacos.NacosConfigManager; import com.alibaba.nacos.api.config.listener.Listener; import lombok.extern.slf4j.Slf4j; @@ -24,9 +23,8 @@ public class NacosCloudRefresherHandler extends AbstractCoreThreadPoolDynamicRef public NacosCloudRefresherHandler(NacosConfigManager nacosConfigManager, ThreadPoolNotifyAlarmHandler threadPoolNotifyAlarmHandler, - ConfigParser configParser, BootstrapCoreProperties bootstrapCoreProperties) { - super(threadPoolNotifyAlarmHandler, configParser, bootstrapCoreProperties); + super(threadPoolNotifyAlarmHandler, bootstrapCoreProperties); this.nacosConfigManager = nacosConfigManager; } diff --git a/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/refresher/NacosRefresherHandler.java b/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/refresher/NacosRefresherHandler.java index 37262ebb..323fd7de 100644 --- a/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/refresher/NacosRefresherHandler.java +++ b/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/refresher/NacosRefresherHandler.java @@ -2,7 +2,6 @@ package cn.hippo4j.core.starter.refresher; import cn.hippo4j.core.executor.ThreadPoolNotifyAlarmHandler; import cn.hippo4j.core.starter.config.BootstrapCoreProperties; -import cn.hippo4j.core.starter.refresher.config.ConfigParser; import com.alibaba.nacos.api.config.ConfigService; import com.alibaba.nacos.api.config.listener.Listener; import lombok.extern.slf4j.Slf4j; @@ -24,9 +23,8 @@ public class NacosRefresherHandler extends AbstractCoreThreadPoolDynamicRefresh public NacosRefresherHandler(ConfigService configService, ThreadPoolNotifyAlarmHandler threadPoolNotifyAlarmHandler, - ConfigParser configParser, BootstrapCoreProperties bootstrapCoreProperties) { - super(threadPoolNotifyAlarmHandler, configParser, bootstrapCoreProperties); + super(threadPoolNotifyAlarmHandler, bootstrapCoreProperties); this.configService = configService; } diff --git a/pom.xml b/pom.xml index 6fed273b..8877229d 100644 --- a/pom.xml +++ b/pom.xml @@ -47,6 +47,7 @@ 1.2.3 3.4.2 2.3.2.RELEASE + 1.9.1 false UTF-8