From d7bd99b3637ff905af32580e414cccceb1c4de58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E6=88=90=E5=85=B4?= <49221670+Createsequence@users.noreply.github.com> Date: Tue, 22 Nov 2022 18:46:59 +0800 Subject: [PATCH 1/3] fix: The thread pool that is not managed by spring will also be destroyed (#990) (#1003) * fix: The thread pool that is not managed by spring will also be destroyed (#990) * optimize code and comments --- .../executor/DynamicThreadPoolExecutor.java | 29 +++++- .../DynamicThreadPoolExecutorTest.java | 23 ++++- .../DynamicThreadPoolAutoConfiguration.java | 7 ++ ...AdaptedThreadPoolDestroyPostProcessor.java | 91 +++++++++++++++++++ 4 files changed, 146 insertions(+), 4 deletions(-) create mode 100644 hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/springboot/starter/support/AdaptedThreadPoolDestroyPostProcessor.java diff --git a/hippo4j-core/src/main/java/cn/hippo4j/core/executor/DynamicThreadPoolExecutor.java b/hippo4j-core/src/main/java/cn/hippo4j/core/executor/DynamicThreadPoolExecutor.java index 011e4148..a33c6b83 100644 --- a/hippo4j-core/src/main/java/cn/hippo4j/core/executor/DynamicThreadPoolExecutor.java +++ b/hippo4j-core/src/main/java/cn/hippo4j/core/executor/DynamicThreadPoolExecutor.java @@ -37,6 +37,7 @@ import java.util.concurrent.BlockingQueue; import java.util.concurrent.RejectedExecutionHandler; import java.util.concurrent.ThreadFactory; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicLong; /** @@ -45,6 +46,12 @@ import java.util.concurrent.atomic.AtomicLong; @Slf4j public class DynamicThreadPoolExecutor extends ExtensibleThreadPoolExecutor implements DisposableBean { + /** + * A flag used to indicate whether destroy() method has been called, + * after the flag is set to false, calling destroy() method again will not take effect + */ + private final AtomicBoolean active; + /** * Wait for tasks to complete on shutdown */ @@ -92,11 +99,22 @@ public class DynamicThreadPoolExecutor extends ExtensibleThreadPoolExecutor impl threadPoolId, new DefaultThreadPoolPluginManager().setPluginComparator(AnnotationAwareOrderComparator.INSTANCE), corePoolSize, maximumPoolSize, keepAliveTime, unit, blockingQueue, threadFactory, rejectedExecutionHandler); - log.info("Initializing ExecutorService {}", threadPoolId); + log.info("Initializing ExecutorService '{}'", threadPoolId); this.waitForTasksToCompleteOnShutdown = waitForTasksToCompleteOnShutdown; // Init default plugins. new DefaultThreadPoolPluginRegistrar(executeTimeOut, awaitTerminationMillis) .doRegister(this); + this.active = new AtomicBoolean(true); + } + + /** + *

Whether the current instance is in the active state.
+ * It returns false when the xx method is called at least once. + * + * @return true if current instance is in the active state, false otherwise + */ + public boolean isActive() { + return active.get(); } /** @@ -104,12 +122,21 @@ public class DynamicThreadPoolExecutor extends ExtensibleThreadPoolExecutor impl */ @Override public void destroy() { + // instance has been destroyed, not need to call this method again + if (!isActive()) { + log.warn("Failed to destroy ExecutorService '{}' because it has already been destroyed", getThreadPoolId()); + return; + } if (isWaitForTasksToCompleteOnShutdown()) { super.shutdown(); } else { super.shutdownNow(); } getThreadPoolPluginManager().clear(); + log.info("ExecutorService '{}' has been destroyed", getThreadPoolId()); + + // modify the flag to false avoid the method being called repeatedly + active.set(false); } /** diff --git a/hippo4j-core/src/test/java/cn/hippo4j/core/executor/DynamicThreadPoolExecutorTest.java b/hippo4j-core/src/test/java/cn/hippo4j/core/executor/DynamicThreadPoolExecutorTest.java index 63d362af..275cd915 100644 --- a/hippo4j-core/src/test/java/cn/hippo4j/core/executor/DynamicThreadPoolExecutorTest.java +++ b/hippo4j-core/src/test/java/cn/hippo4j/core/executor/DynamicThreadPoolExecutorTest.java @@ -95,7 +95,7 @@ public class DynamicThreadPoolExecutorTest { }); executor.destroy(); - // waitting for terminated + // waiting for terminated while (!executor.isTerminated()) { } ; Assert.assertEquals(2, count.get()); @@ -119,9 +119,9 @@ public class DynamicThreadPoolExecutorTest { }); executor.destroy(); - // waitting for terminated + // waiting for terminated while (!executor.isTerminated()) { - } ; + } Assert.assertEquals(1, count.get()); } @@ -157,4 +157,21 @@ public class DynamicThreadPoolExecutorTest { Assert.assertFalse(executor.isWaitForTasksToCompleteOnShutdown()); } + @Test + public void testIsActive() { + DynamicThreadPoolExecutor executor = new DynamicThreadPoolExecutor( + 1, 1, 1000L, TimeUnit.MILLISECONDS, + 1000L, true, 1000L, + new ArrayBlockingQueue<>(1), "test", Thread::new, new ThreadPoolExecutor.DiscardOldestPolicy()); + Assert.assertTrue(executor.isActive()); + + // waiting for terminated + executor.destroy(); + while (!executor.isTerminated()) { + } + Assert.assertFalse(executor.isActive()); + executor.destroy(); + Assert.assertFalse(executor.isActive()); + } + } diff --git a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/springboot/starter/config/DynamicThreadPoolAutoConfiguration.java b/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/springboot/starter/config/DynamicThreadPoolAutoConfiguration.java index 8614c4fc..c271fac4 100644 --- a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/springboot/starter/config/DynamicThreadPoolAutoConfiguration.java +++ b/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/springboot/starter/config/DynamicThreadPoolAutoConfiguration.java @@ -57,6 +57,7 @@ import cn.hippo4j.springboot.starter.remote.HttpAgent; import cn.hippo4j.springboot.starter.remote.HttpScheduledHealthCheck; import cn.hippo4j.springboot.starter.remote.ServerHealthCheck; import cn.hippo4j.springboot.starter.remote.ServerHttpAgent; +import cn.hippo4j.springboot.starter.support.AdaptedThreadPoolDestroyPostProcessor; import cn.hippo4j.springboot.starter.support.DynamicThreadPoolConfigService; import cn.hippo4j.springboot.starter.support.DynamicThreadPoolPostProcessor; import cn.hippo4j.springboot.starter.support.ThreadPoolPluginRegisterPostProcessor; @@ -68,6 +69,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.info.BuildProperties; +import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.Ordered; @@ -120,6 +122,11 @@ public class DynamicThreadPoolAutoConfiguration { return new DynamicThreadPoolConfigService(httpAgent, properties, notifyConfigBuilder, hippo4jBaseSendMessageService, dynamicThreadPoolSubscribeConfig); } + @Bean + public AdaptedThreadPoolDestroyPostProcessor adaptedThreadPoolDestroyPostProcessor(ApplicationContext applicationContext) { + return new AdaptedThreadPoolDestroyPostProcessor(applicationContext); + } + @Bean @SuppressWarnings("all") public DynamicThreadPoolPostProcessor threadPoolBeanPostProcessor(HttpAgent httpAgent, diff --git a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/springboot/starter/support/AdaptedThreadPoolDestroyPostProcessor.java b/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/springboot/starter/support/AdaptedThreadPoolDestroyPostProcessor.java new file mode 100644 index 00000000..61b8418d --- /dev/null +++ b/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/springboot/starter/support/AdaptedThreadPoolDestroyPostProcessor.java @@ -0,0 +1,91 @@ +/* + * 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.springboot.starter.support; + +import cn.hippo4j.core.executor.DynamicThreadPoolExecutor; +import cn.hippo4j.core.executor.DynamicThreadPoolWrapper; +import cn.hippo4j.core.executor.manage.GlobalThreadPoolManage; +import cn.hippo4j.core.executor.support.adpter.DynamicThreadPoolAdapter; +import cn.hippo4j.core.executor.support.adpter.DynamicThreadPoolAdapterChoose; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor; +import org.springframework.context.ApplicationContext; + +import java.util.Optional; + +/** + *

Adapted thread pool destroy post processor.
+ * The processor is used to destroy the internal {@link DynamicThreadPoolExecutor} instance + * in the instance adapted by {@link DynamicThreadPoolAdapter} in the spring context. + * + * @see DynamicThreadPoolAdapter + */ +@RequiredArgsConstructor +@Slf4j +public class AdaptedThreadPoolDestroyPostProcessor implements DestructionAwareBeanPostProcessor { + + /** + * Application context. + */ + private final ApplicationContext applicationContext; + + /** + * If {@link DynamicThreadPoolAdapterChoose#match} method returns true, + * try to destroy its internal {@link DynamicThreadPoolExecutor} instance. + * + * @param bean the bean instance to check + * @return {@code true} if {@link DynamicThreadPoolAdapterChoose#match} method returns true, false otherwise + * @see DynamicThreadPoolAdapterChoose#match + */ + @Override + public boolean requiresDestruction(Object bean) { + return DynamicThreadPoolAdapterChoose.match(bean); + } + + /** + * If the internal {@link DynamicThreadPoolExecutor} instance in the adapted bean is not managed by spring, + * call its {@link DynamicThreadPoolExecutor#destroy()} directly. + * + * @param bean the bean instance to be destroyed + * @param beanName the name of the bean + * @throws BeansException in case of errors + * @see DynamicThreadPoolExecutor#destroy() + */ + @Override + public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException { + Optional.ofNullable(DynamicThreadPoolAdapterChoose.unwrap(bean)) + .map(DynamicThreadPoolExecutor::getThreadPoolId) + // the internal thread pool is also managed by spring, no manual destruction required + .filter(applicationContext::containsBeanDefinition) + .map(GlobalThreadPoolManage::getExecutorService) + .ifPresent(executor -> destroyAdaptedThreadPoolExecutor(beanName, executor)); + } + + private void destroyAdaptedThreadPoolExecutor(String beanName, DynamicThreadPoolWrapper executor) { + try { + if (log.isDebugEnabled()) { + log.debug("Destroy internal dynamic thread pool '{}' for bean '{}'", executor.getThreadPoolId(), beanName); + } + executor.destroy(); + } catch (Exception e) { + log.warn("Failed to destroy internal dynamic thread pool '{}' for bean '{}'", executor.getThreadPoolId(), beanName); + } + } +} From 196238b28f331882a88bba8c574a27ab65f553b9 Mon Sep 17 00:00:00 2001 From: atomFix <43168451+atomFix@users.noreply.github.com> Date: Tue, 22 Nov 2022 18:54:49 +0800 Subject: [PATCH 2/3] completed #728 (#1005) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * unit test: ExecutorFactoryTest 补充测试用例 #728 * unit test #728 : format of normative notes * unit test #728 : format of normative notes to En; eliminate the impact of common objects on the current test flow in other scenarios. Co-authored-by: liukairong1 --- .../common/executor/ExecutorFactoryTest.java | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/hippo4j-common/src/test/java/cn/hippo4j/common/executor/ExecutorFactoryTest.java b/hippo4j-common/src/test/java/cn/hippo4j/common/executor/ExecutorFactoryTest.java index 8cd8e010..f25e3721 100644 --- a/hippo4j-common/src/test/java/cn/hippo4j/common/executor/ExecutorFactoryTest.java +++ b/hippo4j-common/src/test/java/cn/hippo4j/common/executor/ExecutorFactoryTest.java @@ -17,5 +17,74 @@ package cn.hippo4j.common.executor; +import cn.hippo4j.common.design.builder.ThreadFactoryBuilder; +import cn.hippo4j.common.toolkit.MapUtil; +import cn.hippo4j.common.toolkit.ReflectUtil; +import org.junit.Assert; +import org.junit.Test; + +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ThreadFactory; +import java.util.stream.IntStream; + public final class ExecutorFactoryTest { + + ThreadFactory threadFactory = new ThreadFactoryBuilder().prefix("test").build(); + + /** + * data range min + */ + Integer rangeMin = 1; + /** + * data range max + */ + Integer rangeMax = 10; + /** + * default test index + */ + Integer defaultIndex = 0; + + @Test + public void assertNewSingleScheduledExecutorService() { + // init data snapshot + ThreadPoolManager poolManager = (ThreadPoolManager) ReflectUtil.getFieldValue(ExecutorFactory.Managed.class, "THREAD_POOL_MANAGER"); + String poolName = (String) ReflectUtil.getFieldValue(ExecutorFactory.Managed.class, "DEFAULT_NAMESPACE"); + Map>> manager = (Map>>) ReflectUtil.getFieldValue(poolManager, "resourcesManager"); + Map> initRelationMap = manager.get(poolName); + int defaultManagerSize = manager.size(); + int defaultRelationSize = MapUtil.isEmpty(initRelationMap) ? 0 : initRelationMap.size(); + + // test begin + ScheduledExecutorService executorService = ExecutorFactory.Managed.newSingleScheduledExecutorService(String.format("test-group-%s", defaultIndex), threadFactory); + + Assert.assertNotNull(executorService); + + // check default init + Assert.assertEquals(1, manager.size() - defaultManagerSize); + + // check multiple registrations and check to see if it is still an instance + IntStream.rangeClosed(rangeMin, rangeMax).forEach(index -> ExecutorFactory.Managed.newSingleScheduledExecutorService(String.format("test-group-%s", index), threadFactory)); + Assert.assertEquals(1, manager.size() - defaultManagerSize); + + // check group size + Map> relationMap = manager.get(poolName); + Assert.assertEquals(11, relationMap.size() - defaultRelationSize); + // check the number of threads between the group and the thread pool + IntStream.rangeClosed(rangeMin, rangeMax).forEach(index -> { + String relationKey = String.format("test-group-%s", index); + Assert.assertNotNull(relationMap.get(relationKey)); + Assert.assertEquals(1, relationMap.get(relationKey).size()); + }); + + // instantiate the same group a second time and check the corresponding quantitative relationship + IntStream.rangeClosed(defaultIndex, rangeMax).forEach(index -> ExecutorFactory.Managed.newSingleScheduledExecutorService(String.format("test-group-%s", index), threadFactory)); + // chek group size + Assert.assertEquals(11, manager.get(poolName).size() - defaultRelationSize); + // check the number of threads between the group and the thread pool + IntStream.rangeClosed(rangeMin, rangeMax).forEach(index -> Assert.assertEquals(2, relationMap.get(String.format("test-group-%s", index)).size())); + } + } From b5b959c80bd877dd225e332aa78c79f413ac6394 Mon Sep 17 00:00:00 2001 From: "chen.ma" Date: Tue, 22 Nov 2022 21:07:15 +0800 Subject: [PATCH 3/3] Code logic update --- .github/FUNDING.yml | 2 +- .../server/hippo4j-server-monitor.md | 10 ++++++++++ docs/docusaurus.config.js | 2 +- .../server/hippo4j-server-monitor.md | 10 ++++++++++ .../server/hippo4j-server-monitor.md | 10 ++++++++++ .../server/hippo4j-server-monitor.md | 10 ++++++++++ .../platform/DingSendMessageHandler.java | 19 ++++++++++++++----- .../DynamicThreadPoolAutoConfiguration.java | 8 ++++---- ...ava => ConfigModeNotifyConfigBuilder.java} | 4 ++-- .../DynamicThreadPoolRefreshListener.java | 8 ++++---- .../event/PlatformsRefreshListener.java | 4 ++-- .../DynamicThreadPoolAutoConfiguration.java | 8 ++++---- ...ava => ServerModeNotifyConfigBuilder.java} | 4 ++-- .../DynamicThreadPoolConfigService.java | 6 +++--- 14 files changed, 77 insertions(+), 28 deletions(-) rename hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/notify/{CoreNotifyConfigBuilder.java => ConfigModeNotifyConfigBuilder.java} (98%) rename hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/springboot/starter/notify/{ServerNotifyConfigBuilder.java => ServerModeNotifyConfigBuilder.java} (97%) diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index eb15bc5e..6e54c6c7 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,3 +1,3 @@ # These are supported funding model platforms -custom: ['https://hippo4j.cn/docs/community/sponsor'] +custom: ['https://hippo4j.cn/community/sponsor'] diff --git a/docs/docs/user_docs/getting_started/server/hippo4j-server-monitor.md b/docs/docs/user_docs/getting_started/server/hippo4j-server-monitor.md index b743c790..4a81a47b 100644 --- a/docs/docs/user_docs/getting_started/server/hippo4j-server-monitor.md +++ b/docs/docs/user_docs/getting_started/server/hippo4j-server-monitor.md @@ -47,6 +47,16 @@ spring: thread-pool-types: dynamic # 采集线程池的类型。eg:dynamic、web、adapter。可任意配置,默认 dynamic ``` +如果使用 `micrometer` 类型的监控指标,需要添加以下依赖。 + +```xml + + cn.hippo4j + hippo4j-spring-boot-starter-monitor-micrometer + 1.4.3-upgrade + +``` + 项目启动,访问 `http://localhost:29999/actuator/prometheus` 出现 `dynamic_thread_pool_` 前缀的指标,即为成功。 ![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220912220401016.png) diff --git a/docs/docusaurus.config.js b/docs/docusaurus.config.js index 7c38db7b..8ff7a975 100644 --- a/docs/docusaurus.config.js +++ b/docs/docusaurus.config.js @@ -116,7 +116,7 @@ const config = { }, { href: 'https://xiaomage.info/knowledge-planet', - label: '🥇代码实战课', + label: '知识星球', position: 'left', }, { diff --git a/docs/i18n/zh/docusaurus-plugin-content-docs/current/user_docs/getting_started/server/hippo4j-server-monitor.md b/docs/i18n/zh/docusaurus-plugin-content-docs/current/user_docs/getting_started/server/hippo4j-server-monitor.md index b743c790..4a81a47b 100644 --- a/docs/i18n/zh/docusaurus-plugin-content-docs/current/user_docs/getting_started/server/hippo4j-server-monitor.md +++ b/docs/i18n/zh/docusaurus-plugin-content-docs/current/user_docs/getting_started/server/hippo4j-server-monitor.md @@ -47,6 +47,16 @@ spring: thread-pool-types: dynamic # 采集线程池的类型。eg:dynamic、web、adapter。可任意配置,默认 dynamic ``` +如果使用 `micrometer` 类型的监控指标,需要添加以下依赖。 + +```xml + + cn.hippo4j + hippo4j-spring-boot-starter-monitor-micrometer + 1.4.3-upgrade + +``` + 项目启动,访问 `http://localhost:29999/actuator/prometheus` 出现 `dynamic_thread_pool_` 前缀的指标,即为成功。 ![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220912220401016.png) diff --git a/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/getting_started/server/hippo4j-server-monitor.md b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/getting_started/server/hippo4j-server-monitor.md index b743c790..4a81a47b 100644 --- a/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/getting_started/server/hippo4j-server-monitor.md +++ b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/getting_started/server/hippo4j-server-monitor.md @@ -47,6 +47,16 @@ spring: thread-pool-types: dynamic # 采集线程池的类型。eg:dynamic、web、adapter。可任意配置,默认 dynamic ``` +如果使用 `micrometer` 类型的监控指标,需要添加以下依赖。 + +```xml + + cn.hippo4j + hippo4j-spring-boot-starter-monitor-micrometer + 1.4.3-upgrade + +``` + 项目启动,访问 `http://localhost:29999/actuator/prometheus` 出现 `dynamic_thread_pool_` 前缀的指标,即为成功。 ![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220912220401016.png) diff --git a/docs/versioned_docs/version-1.4.3/user_docs/getting_started/server/hippo4j-server-monitor.md b/docs/versioned_docs/version-1.4.3/user_docs/getting_started/server/hippo4j-server-monitor.md index b743c790..4a81a47b 100644 --- a/docs/versioned_docs/version-1.4.3/user_docs/getting_started/server/hippo4j-server-monitor.md +++ b/docs/versioned_docs/version-1.4.3/user_docs/getting_started/server/hippo4j-server-monitor.md @@ -47,6 +47,16 @@ spring: thread-pool-types: dynamic # 采集线程池的类型。eg:dynamic、web、adapter。可任意配置,默认 dynamic ``` +如果使用 `micrometer` 类型的监控指标,需要添加以下依赖。 + +```xml + + cn.hippo4j + hippo4j-spring-boot-starter-monitor-micrometer + 1.4.3-upgrade + +``` + 项目启动,访问 `http://localhost:29999/actuator/prometheus` 出现 `dynamic_thread_pool_` 前缀的指标,即为成功。 ![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220912220401016.png) diff --git a/hippo4j-message/src/main/java/cn/hippo4j/message/platform/DingSendMessageHandler.java b/hippo4j-message/src/main/java/cn/hippo4j/message/platform/DingSendMessageHandler.java index a8329e07..e7c078e3 100644 --- a/hippo4j-message/src/main/java/cn/hippo4j/message/platform/DingSendMessageHandler.java +++ b/hippo4j-message/src/main/java/cn/hippo4j/message/platform/DingSendMessageHandler.java @@ -92,13 +92,11 @@ public class DingSendMessageHandler extends AbstractRobotSendMessageHandler { String title = Objects.equals(notifyConfig.getType(), "CONFIG") ? DING_NOTICE_TITLE : DING_ALARM_TITLE; String text = robotMessageExecuteDTO.getText(); ArrayList atMobiles = CollectionUtil.newArrayList(notifyConfig.getReceives().split(",")); - HashMap markdown = new HashMap<>(); markdown.put("title", title); markdown.put("text", text); HashMap at = new HashMap<>(); at.put("atMobiles", atMobiles); - HashMap markdownJson = new HashMap<>(); markdownJson.put("msgtype", "markdown"); markdownJson.put("markdown", markdown); @@ -106,18 +104,29 @@ public class DingSendMessageHandler extends AbstractRobotSendMessageHandler { try { String responseBody = HttpUtil.post(serverUrl, markdownJson); DingRobotResponse response = JSONUtil.parseObject(responseBody, DingRobotResponse.class); - Assert.isTrue(response != null, "response is null"); + Assert.isTrue(response != null, "Response is null."); if (response.getErrcode() != 0) { - log.error("Ding failed to send message,reason : {}", response.errmsg); + log.error("Ding failed to send message, reason : {}", response.errmsg); } } catch (Exception ex) { - log.error("Ding failed to send message", ex); + log.error("Ding failed to send message.", ex); } } + /** + * Ding robot response. + */ @Data static class DingRobotResponse { + + /** + * Error code + */ private Long errcode; + + /** + * Error message + */ private String errmsg; } } diff --git a/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/config/DynamicThreadPoolAutoConfiguration.java b/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/config/DynamicThreadPoolAutoConfiguration.java index 51edf16c..62467060 100644 --- a/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/config/DynamicThreadPoolAutoConfiguration.java +++ b/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/config/DynamicThreadPoolAutoConfiguration.java @@ -21,7 +21,7 @@ import cn.hippo4j.common.api.ThreadPoolCheckAlarm; import cn.hippo4j.common.api.ThreadPoolConfigChange; import cn.hippo4j.common.config.ApplicationContextHolder; import cn.hippo4j.config.springboot.starter.monitor.ThreadPoolMonitorExecutor; -import cn.hippo4j.config.springboot.starter.notify.CoreNotifyConfigBuilder; +import cn.hippo4j.config.springboot.starter.notify.ConfigModeNotifyConfigBuilder; import cn.hippo4j.config.springboot.starter.refresher.event.AdapterExecutorsRefreshListener; import cn.hippo4j.config.springboot.starter.refresher.event.DynamicThreadPoolRefreshListener; import cn.hippo4j.config.springboot.starter.refresher.event.PlatformsRefreshListener; @@ -77,7 +77,7 @@ public class DynamicThreadPoolAutoConfiguration { @Bean public NotifyConfigBuilder notifyConfigBuilder(AlarmControlHandler alarmControlHandler) { - return new CoreNotifyConfigBuilder(alarmControlHandler, bootstrapConfigProperties); + return new ConfigModeNotifyConfigBuilder(alarmControlHandler, bootstrapConfigProperties); } @Bean @@ -105,9 +105,9 @@ public class DynamicThreadPoolAutoConfiguration { @Bean @SuppressWarnings("all") public DynamicThreadPoolRefreshListener hippo4jExecutorsListener(ThreadPoolConfigChange threadPoolConfigChange, - CoreNotifyConfigBuilder coreNotifyConfigBuilder, + ConfigModeNotifyConfigBuilder configModeNotifyConfigBuilder, Hippo4jBaseSendMessageService hippoBaseSendMessageService) { - return new DynamicThreadPoolRefreshListener(threadPoolConfigChange, coreNotifyConfigBuilder, hippoBaseSendMessageService); + return new DynamicThreadPoolRefreshListener(threadPoolConfigChange, configModeNotifyConfigBuilder, hippoBaseSendMessageService); } @Bean diff --git a/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/notify/CoreNotifyConfigBuilder.java b/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/notify/ConfigModeNotifyConfigBuilder.java similarity index 98% rename from hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/notify/CoreNotifyConfigBuilder.java rename to hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/notify/ConfigModeNotifyConfigBuilder.java index 9dba54a8..7a01ae4e 100644 --- a/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/notify/CoreNotifyConfigBuilder.java +++ b/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/notify/ConfigModeNotifyConfigBuilder.java @@ -32,11 +32,11 @@ import java.util.*; import java.util.stream.Collectors; /** - * Core notify config builder. + * Config mode notify config builder. */ @AllArgsConstructor @Slf4j -public class CoreNotifyConfigBuilder implements NotifyConfigBuilder { +public class ConfigModeNotifyConfigBuilder implements NotifyConfigBuilder { private final AlarmControlHandler alarmControlHandler; diff --git a/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/refresher/event/DynamicThreadPoolRefreshListener.java b/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/refresher/event/DynamicThreadPoolRefreshListener.java index fe30533c..4ed28af4 100644 --- a/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/refresher/event/DynamicThreadPoolRefreshListener.java +++ b/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/refresher/event/DynamicThreadPoolRefreshListener.java @@ -24,7 +24,7 @@ import cn.hippo4j.common.executor.support.ResizableCapacityLinkedBlockingQueue; import cn.hippo4j.common.toolkit.CollectionUtil; import cn.hippo4j.config.springboot.starter.config.BootstrapConfigProperties; import cn.hippo4j.config.springboot.starter.config.ExecutorProperties; -import cn.hippo4j.config.springboot.starter.notify.CoreNotifyConfigBuilder; +import cn.hippo4j.config.springboot.starter.notify.ConfigModeNotifyConfigBuilder; import cn.hippo4j.config.springboot.starter.support.GlobalCoreThreadPoolManage; import cn.hippo4j.core.executor.DynamicThreadPoolExecutor; import cn.hippo4j.core.executor.manage.GlobalThreadPoolManage; @@ -60,7 +60,7 @@ public class DynamicThreadPoolRefreshListener extends AbstractRefreshListener changeKeys = new ArrayList<>(); - Map> newDynamicThreadPoolNotifyMap = coreNotifyConfigBuilder.buildSingleNotifyConfig(executorProperties); + Map> newDynamicThreadPoolNotifyMap = configModeNotifyConfigBuilder.buildSingleNotifyConfig(executorProperties); Map> notifyConfigs = hippo4jBaseSendMessageService.getNotifyConfigs(); if (CollectionUtil.isNotEmpty(notifyConfigs)) { for (Map.Entry> each : newDynamicThreadPoolNotifyMap.entrySet()) { @@ -183,7 +183,7 @@ public class DynamicThreadPoolRefreshListener extends AbstractRefreshListener> notifyConfig = configBuilder.buildSingleNotifyConfig(executorProperties); sendMessageService.putPlatform(notifyConfig); wrapper.setInitFlag(Boolean.TRUE); diff --git a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/springboot/starter/config/DynamicThreadPoolAutoConfiguration.java b/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/springboot/starter/config/DynamicThreadPoolAutoConfiguration.java index c271fac4..2650fb11 100644 --- a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/springboot/starter/config/DynamicThreadPoolAutoConfiguration.java +++ b/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/springboot/starter/config/DynamicThreadPoolAutoConfiguration.java @@ -52,7 +52,7 @@ import cn.hippo4j.springboot.starter.monitor.ReportingEventExecutor; import cn.hippo4j.springboot.starter.monitor.collect.RunTimeInfoCollector; import cn.hippo4j.springboot.starter.monitor.send.MessageSender; import cn.hippo4j.springboot.starter.monitor.send.http.HttpConnectSender; -import cn.hippo4j.springboot.starter.notify.ServerNotifyConfigBuilder; +import cn.hippo4j.springboot.starter.notify.ServerModeNotifyConfigBuilder; import cn.hippo4j.springboot.starter.remote.HttpAgent; import cn.hippo4j.springboot.starter.remote.HttpScheduledHealthCheck; import cn.hippo4j.springboot.starter.remote.ServerHealthCheck; @@ -116,10 +116,10 @@ public class DynamicThreadPoolAutoConfiguration { @SuppressWarnings("all") public DynamicThreadPoolService dynamicThreadPoolConfigService(HttpAgent httpAgent, ServerHealthCheck serverHealthCheck, - ServerNotifyConfigBuilder notifyConfigBuilder, + ServerModeNotifyConfigBuilder serverModeNotifyConfigBuilder, Hippo4jBaseSendMessageService hippo4jBaseSendMessageService, DynamicThreadPoolSubscribeConfig dynamicThreadPoolSubscribeConfig) { - return new DynamicThreadPoolConfigService(httpAgent, properties, notifyConfigBuilder, hippo4jBaseSendMessageService, dynamicThreadPoolSubscribeConfig); + return new DynamicThreadPoolConfigService(httpAgent, properties, serverModeNotifyConfigBuilder, hippo4jBaseSendMessageService, dynamicThreadPoolSubscribeConfig); } @Bean @@ -205,7 +205,7 @@ public class DynamicThreadPoolAutoConfiguration { public NotifyConfigBuilder serverNotifyConfigBuilder(HttpAgent httpAgent, BootstrapProperties properties, AlarmControlHandler alarmControlHandler) { - return new ServerNotifyConfigBuilder(httpAgent, properties, alarmControlHandler); + return new ServerModeNotifyConfigBuilder(httpAgent, properties, alarmControlHandler); } @Bean diff --git a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/springboot/starter/notify/ServerNotifyConfigBuilder.java b/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/springboot/starter/notify/ServerModeNotifyConfigBuilder.java similarity index 97% rename from hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/springboot/starter/notify/ServerNotifyConfigBuilder.java rename to hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/springboot/starter/notify/ServerModeNotifyConfigBuilder.java index 8aeedb98..3cfbe586 100644 --- a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/springboot/starter/notify/ServerNotifyConfigBuilder.java +++ b/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/springboot/starter/notify/ServerModeNotifyConfigBuilder.java @@ -41,11 +41,11 @@ import java.util.Objects; import static cn.hippo4j.common.constant.Constants.BASE_PATH; /** - * Server notify config builder. + * Server mode notify config builder. */ @Slf4j @AllArgsConstructor -public class ServerNotifyConfigBuilder implements NotifyConfigBuilder { +public class ServerModeNotifyConfigBuilder implements NotifyConfigBuilder { private final HttpAgent httpAgent; diff --git a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/springboot/starter/support/DynamicThreadPoolConfigService.java b/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/springboot/starter/support/DynamicThreadPoolConfigService.java index 663b07dc..f648b346 100644 --- a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/springboot/starter/support/DynamicThreadPoolConfigService.java +++ b/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/springboot/starter/support/DynamicThreadPoolConfigService.java @@ -35,7 +35,7 @@ import cn.hippo4j.message.service.Hippo4jBaseSendMessageService; import cn.hippo4j.message.service.ThreadPoolNotifyAlarm; import cn.hippo4j.springboot.starter.config.BootstrapProperties; import cn.hippo4j.springboot.starter.core.DynamicThreadPoolSubscribeConfig; -import cn.hippo4j.springboot.starter.notify.ServerNotifyConfigBuilder; +import cn.hippo4j.springboot.starter.notify.ServerModeNotifyConfigBuilder; import cn.hippo4j.springboot.starter.remote.HttpAgent; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -58,7 +58,7 @@ public class DynamicThreadPoolConfigService extends AbstractDynamicThreadPoolSer private final BootstrapProperties properties; - private final ServerNotifyConfigBuilder notifyConfigBuilder; + private final ServerModeNotifyConfigBuilder serverModeNotifyConfigBuilder; private final Hippo4jBaseSendMessageService hippo4jBaseSendMessageService; @@ -108,7 +108,7 @@ public class DynamicThreadPoolConfigService extends AbstractDynamicThreadPoolSer registerParameter.getActiveAlarm(), registerParameter.getCapacityAlarm()); GlobalNotifyAlarmManage.put(registerParameter.getThreadPoolId(), threadPoolNotifyAlarm); - Map> builderNotify = notifyConfigBuilder.getAndInitNotify(CollectionUtil.newArrayList(registerParameter.getThreadPoolId())); + Map> builderNotify = serverModeNotifyConfigBuilder.getAndInitNotify(CollectionUtil.newArrayList(registerParameter.getThreadPoolId())); hippo4jBaseSendMessageService.putPlatform(builderNotify); }