diff --git a/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/config/AdapterExecutorProperties.java b/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/config/AdapterExecutorProperties.java index f78a2539..c70d7328 100644 --- a/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/config/AdapterExecutorProperties.java +++ b/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/config/AdapterExecutorProperties.java @@ -44,4 +44,9 @@ public class AdapterExecutorProperties { * Maximum pool size */ private Integer maximumPoolSize; + + /** + * nodes,application startup is not affect,change properties is effect + */ + private String nodes; } diff --git a/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/config/BootstrapConfigProperties.java b/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/config/BootstrapConfigProperties.java index d939e371..8a534f69 100644 --- a/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/config/BootstrapConfigProperties.java +++ b/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/config/BootstrapConfigProperties.java @@ -20,9 +20,6 @@ package cn.hippo4j.config.springboot.starter.config; import java.util.List; import java.util.Map; -import java.util.List; -import java.util.Map; - import cn.hippo4j.core.config.BootstrapPropertiesInterface; import cn.hippo4j.config.springboot.starter.parser.ConfigFileTypeEnum; import lombok.Getter; diff --git a/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/config/ConfigHandlerConfiguration.java b/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/config/ConfigHandlerConfiguration.java index bff13549..c77536a8 100644 --- a/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/config/ConfigHandlerConfiguration.java +++ b/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/config/ConfigHandlerConfiguration.java @@ -17,11 +17,7 @@ package cn.hippo4j.config.springboot.starter.config; -import cn.hippo4j.config.springboot.starter.refresher.ApolloRefresherHandler; -import cn.hippo4j.config.springboot.starter.refresher.NacosCloudRefresherHandler; -import cn.hippo4j.config.springboot.starter.refresher.NacosRefresherHandler; -import cn.hippo4j.config.springboot.starter.refresher.ZookeeperRefresherHandler; -import cn.hippo4j.config.springboot.starter.refresher.EtcdRefresherHandler; +import cn.hippo4j.config.springboot.starter.refresher.*; import com.alibaba.cloud.nacos.NacosConfigManager; import com.alibaba.nacos.api.config.ConfigService; import io.etcd.jetcd.Client; diff --git a/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/config/DynamicThreadPoolCoreAutoConfiguration.java b/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/config/DynamicThreadPoolCoreAutoConfiguration.java index 0817b202..aa24eaeb 100644 --- a/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/config/DynamicThreadPoolCoreAutoConfiguration.java +++ b/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/config/DynamicThreadPoolCoreAutoConfiguration.java @@ -38,7 +38,6 @@ import cn.hippo4j.message.service.Hippo4jBaseSendMessageService; import cn.hippo4j.message.service.Hippo4jSendMessageService; import cn.hippo4j.springboot.starter.adapter.web.EnableWebAdapter; import lombok.AllArgsConstructor; - import org.springframework.boot.autoconfigure.ImportAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; diff --git a/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/config/ExecutorProperties.java b/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/config/ExecutorProperties.java index 71cc5f69..ccf8aa0d 100644 --- a/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/config/ExecutorProperties.java +++ b/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/config/ExecutorProperties.java @@ -102,4 +102,9 @@ public class ExecutorProperties { * Notify */ private DynamicThreadPoolNotifyProperties notify; + + /** + * nodes,application startup is not affect,change properties is effect + */ + private String nodes; } diff --git a/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/config/WebThreadPoolProperties.java b/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/config/WebThreadPoolProperties.java index 437f8d8e..941f876b 100644 --- a/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/config/WebThreadPoolProperties.java +++ b/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/config/WebThreadPoolProperties.java @@ -39,4 +39,9 @@ public class WebThreadPoolProperties { * Keep alive time */ private Integer keepAliveTime; + + /** + * nodes,application startup is not affect,change properties is effect + */ + private String nodes; } diff --git a/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/refresher/event/AbstractRefreshListener.java b/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/refresher/event/AbstractRefreshListener.java new file mode 100644 index 00000000..051a61f8 --- /dev/null +++ b/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/refresher/event/AbstractRefreshListener.java @@ -0,0 +1,179 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 cn.hippo4j.config.springboot.starter.refresher.event; + +import cn.hippo4j.common.config.ApplicationContextHolder; +import cn.hippo4j.common.toolkit.Assert; +import cn.hippo4j.common.toolkit.StringUtil; +import cn.hippo4j.core.toolkit.inet.InetUtils; +import lombok.Data; +import lombok.extern.log4j.Log4j2; +import org.springframework.boot.web.context.WebServerInitializedEvent; +import org.springframework.context.event.EventListener; + +import java.util.Arrays; +import java.util.Objects; + +/** + * Refresh listener abstract base class. + */ +@Log4j2 +public abstract class AbstractRefreshListener implements RefreshListener { + + protected static final String ALL = "*"; + + protected static final String SPOT = "\\."; + + protected static final String SEPARATOR = ","; + + protected static final String COLON = ":"; + + /** + * application ip + */ + protected final String[] ipSegment; + + /** + * application post + */ + protected String port; + + AbstractRefreshListener() { + InetUtils inetUtils = ApplicationContextHolder.getBean(InetUtils.class); + InetUtils.HostInfo loopbackHostInfo = inetUtils.findFirstNonLoopbackHostInfo(); + Assert.notNull(loopbackHostInfo, "Unable to get the application IP address"); + ipSegment = loopbackHostInfo.getIpAddress().split(SPOT); + } + + @EventListener(WebServerInitializedEvent.class) + public void webServerInitializedListener(WebServerInitializedEvent event) { + port = String.valueOf(event.getWebServer().getPort()); + } + + /** + * Matching nodes
+ * nodes is ip + port.Get 'nodes' in the new Properties,Compare this with the ip + port of Application.
+ * support prefix pattern matching. e.g:
+ * + * The format of ip + port is ip : port. + * + * @param properties new Properties + */ + @Override + public boolean match(M properties) { + return false; + } + + /** + * check all + * + * @param nodes nodes + */ + protected boolean checkArray(String nodes) { + if (StringUtil.isEmpty(nodes) || ALL.equals(nodes)) { + return true; + } + String[] splitNodes = nodes.split(SEPARATOR); + return Arrays.stream(splitNodes) + .distinct() + .map(IpAndPort::build) + .filter(Objects::nonNull) + .anyMatch(i -> i.check(ipSegment, port)); + } + + /** + * ip + port + */ + @Data + protected static class IpAndPort { + + private String ip; + private String port; + private String[] propIpSegment; + + private IpAndPort(String ip, String port) { + this.ip = ip; + this.port = port; + this.propIpSegment = ip.split(SPOT); + } + + public static IpAndPort build(String node) { + if (ALL.equals(node)) { + return new IpAndPort(ALL, ALL); + } + String[] ipPort = node.split(COLON); + if (ipPort.length != 2) { + log.error("The IP address format is error:{}", node); + return null; + } + return new IpAndPort(ipPort[0], ipPort[1]); + } + + /** + * check + * + * @param appIpSegment application ip segment + * @param port application port + */ + public boolean check(String[] appIpSegment, String port) { + return checkPort(port) && checkIp(appIpSegment); + } + + /** + * check ip + * + * @param appIpSegment application ip segment + */ + protected boolean checkIp(String[] appIpSegment) { + if (ALL.equals(this.ip)) { + return true; + } + boolean flag = true; + for (int i = 0; i < propIpSegment.length && flag; i++) { + String propIp = propIpSegment[i]; + String appIp = appIpSegment[i]; + flag = contrastSegment(appIp, propIp); + } + return flag; + } + + /** + * check port + * + * @param port application port + */ + protected boolean checkPort(String port) { + return contrastSegment(port, this.port); + } + + /** + * Check whether the strings are the same + * + * @param appIp appIp + * @param propIp propIp + */ + protected boolean contrastSegment(String appIp, String propIp) { + return ALL.equals(propIp) || appIp.equals(propIp); + } + } +} \ No newline at end of file diff --git a/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/refresher/event/AdapterExecutorsRefreshListener.java b/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/refresher/event/AdapterExecutorsRefreshListener.java index 70fd664e..09838838 100644 --- a/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/refresher/event/AdapterExecutorsRefreshListener.java +++ b/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/refresher/event/AdapterExecutorsRefreshListener.java @@ -25,7 +25,6 @@ import cn.hippo4j.config.springboot.starter.config.AdapterExecutorProperties; import cn.hippo4j.config.springboot.starter.support.DynamicThreadPoolAdapterRegister; import cn.hutool.core.bean.BeanUtil; import lombok.extern.slf4j.Slf4j; -import org.springframework.context.ApplicationListener; import org.springframework.core.annotation.Order; import java.util.List; @@ -40,7 +39,13 @@ import static cn.hippo4j.config.springboot.starter.refresher.event.Hippo4jConfig */ @Slf4j @Order(ADAPTER_EXECUTORS_LISTENER) -public class AdapterExecutorsRefreshListener implements ApplicationListener { +public class AdapterExecutorsRefreshListener extends AbstractRefreshListener { + + @Override + public boolean match(AdapterExecutorProperties properties) { + String nodes = properties.getNodes(); + return checkArray(nodes); + } @Override public void onApplicationEvent(Hippo4jConfigDynamicRefreshEvent event) { @@ -52,7 +57,7 @@ public class AdapterExecutorsRefreshListener implements ApplicationListener { +public class DynamicThreadPoolRefreshListener extends AbstractRefreshListener { private final ThreadPoolNotifyAlarmHandler threadPoolNotifyAlarmHandler; @@ -68,13 +67,22 @@ public class DynamicThreadPoolRefreshListener implements ApplicationListener executors = bindableConfigProperties.getExecutors(); for (ExecutorProperties properties : executors) { String threadPoolId = properties.getThreadPoolId(); - /** + if (!match(properties)) { + continue; + } + /* * Check whether the notification configuration is consistent, this operation will not trigger the notification. */ checkNotifyConsistencyAndReplace(properties); diff --git a/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/refresher/event/PlatformsRefreshListener.java b/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/refresher/event/PlatformsRefreshListener.java index ec380bad..f6601b75 100644 --- a/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/refresher/event/PlatformsRefreshListener.java +++ b/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/refresher/event/PlatformsRefreshListener.java @@ -25,7 +25,6 @@ import cn.hippo4j.core.executor.DynamicThreadPoolWrapper; import cn.hippo4j.core.executor.manage.GlobalThreadPoolManage; import cn.hippo4j.message.dto.NotifyConfigDTO; import cn.hippo4j.message.service.Hippo4jBaseSendMessageService; -import org.springframework.context.ApplicationListener; import org.springframework.core.annotation.Order; import java.util.List; @@ -37,7 +36,7 @@ import static cn.hippo4j.config.springboot.starter.refresher.event.Hippo4jConfig * Platforms refresh listener. */ @Order(PLATFORMS_LISTENER) -public class PlatformsRefreshListener implements ApplicationListener { +public class PlatformsRefreshListener extends AbstractRefreshListener { @Override public void onApplicationEvent(Hippo4jConfigDynamicRefreshEvent threadPoolDynamicRefreshEvent) { diff --git a/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/refresher/event/RefreshListener.java b/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/refresher/event/RefreshListener.java new file mode 100644 index 00000000..bd072c04 --- /dev/null +++ b/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/refresher/event/RefreshListener.java @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 cn.hippo4j.config.springboot.starter.refresher.event; + +import cn.hippo4j.common.function.Matcher; +import org.springframework.context.ApplicationEvent; +import org.springframework.context.ApplicationListener; + +/** + * Refresh listener interface. + * T:event. + * M:properties. + */ +public interface RefreshListener extends ApplicationListener, Matcher { + +} diff --git a/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/refresher/event/WebExecutorRefreshListener.java b/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/refresher/event/WebExecutorRefreshListener.java index 5e01320c..6068750c 100644 --- a/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/refresher/event/WebExecutorRefreshListener.java +++ b/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/refresher/event/WebExecutorRefreshListener.java @@ -25,7 +25,6 @@ import cn.hippo4j.common.model.ThreadPoolParameterInfo; import cn.hippo4j.config.springboot.starter.config.BootstrapConfigProperties; import cn.hippo4j.config.springboot.starter.config.WebThreadPoolProperties; import lombok.extern.slf4j.Slf4j; -import org.springframework.context.ApplicationListener; import org.springframework.core.annotation.Order; import java.util.Objects; @@ -37,7 +36,13 @@ import static cn.hippo4j.config.springboot.starter.refresher.event.Hippo4jConfig */ @Slf4j @Order(WEB_EXECUTOR_LISTENER) -public class WebExecutorRefreshListener implements ApplicationListener { +public class WebExecutorRefreshListener extends AbstractRefreshListener { + + @Override + public boolean match(WebThreadPoolProperties properties) { + String nodes = properties.getNodes(); + return checkArray(nodes); + } @Override public void onApplicationEvent(Hippo4jConfigDynamicRefreshEvent threadPoolDynamicRefreshEvent) { @@ -75,7 +80,7 @@ public class WebExecutorRefreshListener implements ApplicationListener