Merge branch 'opengoofy:develop' into develop

pull/883/head
黄成兴 3 years ago committed by GitHub
commit befa0f094d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,26 @@
#
# 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.
#
coverage:
status:
patch:
default:
threshold: 0.1%
ignore:
- "hippo4j-example/.*"
- "docs/.*"
- "dev-support/.*"

@ -65,3 +65,25 @@ jobs:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- name: Build with Maven - name: Build with Maven
run: echo y | mvn clean install -Dskip.gpg=true -Dspotless.apply.skip=true -Dmaven.javadoc.skip=true run: echo y | mvn clean install -Dskip.gpg=true -Dspotless.apply.skip=true -Dmaven.javadoc.skip=true
test-coverage:
if: github.repository == 'opengoofy/hippo4j'
name: Test coverage report
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Cache Maven Repos
uses: actions/cache@v3
with:
path: ~/.m2/repository
key: hippo4j-maven-third-party-${{ hashFiles('**/pom.xml') }}
restore-keys: |
hippo4j-maven-third-party-
- uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: 8
- name: Test with Maven
run: echo y | mvn -T1C clean install -Dskip.gpg=true -Dspotless.apply.skip=true -Dskip.jacoco.plugin=false
- name: Upload to Codecov
run: bash <(curl -s https://codecov.io/bash)

@ -1,8 +1,8 @@
<img align="center" width="400" alt="image" src="https://user-images.githubusercontent.com/77398366/181906454-b46f6a14-7c2c-4b8f-8b0a-40432521bed8.png"> <img align="center" width="300" alt="image" src="https://user-images.githubusercontent.com/77398366/181906454-b46f6a14-7c2c-4b8f-8b0a-40432521bed8.png">
# Dynamic and observable thread pool framework # Dynamic and observable thread pool framework
[![Gitee](https://gitee.com/itmachen/hippo4j/badge/star.svg?theme=gvp)](https://gitee.com/itmachen/hippo4j) [![GitHub](https://img.shields.io/github/stars/opengoofy/hippo4j)](https://github.com/opengoofy/hippo4j) [![Docker Pulls](https://img.shields.io/docker/pulls/hippo4j/hippo4j-server.svg)](https://store.docker.com/community/images/hippo4j/hippo4j-server) [![Contributors](https://img.shields.io/github/contributors/opengoofy/hippo4j?color=3ba272)](https://github.com/opengoofy/hippo4j/graphs/contributors) [![License](https://img.shields.io/github/license/opengoofy/hippo4j?color=5470c6)](https://github.com/opengoofy/hippo4j/blob/develop/LICENSE) [![Gitee](https://gitee.com/magegoofy/hippo4j/badge/star.svg?theme=gvp)](https://gitee.com/magegoofy/hippo4j) [![GitHub](https://img.shields.io/github/stars/opengoofy/hippo4j?color=5470c6)](https://github.com/opengoofy/hippo4j) [![Contributors](https://img.shields.io/github/contributors/opengoofy/hippo4j?color=3ba272)](https://github.com/opengoofy/hippo4j/graphs/contributors) [![Docker Pulls](https://img.shields.io/docker/pulls/hippo4j/hippo4j-server.svg?label=docker%20pulls&color=fac858)](https://store.docker.com/community/images/hippo4j/hippo4j-server) [![codecov](https://codecov.io/gh/opengoofy/hippo4j/branch/develop/graph/badge.svg?token=WBUVJN107I)](https://codecov.io/gh/opengoofy/hippo4j)
------- -------

@ -1,10 +1,10 @@
<img align="center" width="400" alt="image" src="https://user-images.githubusercontent.com/77398366/181906454-b46f6a14-7c2c-4b8f-8b0a-40432521bed8.png"> <img align="center" width="300" alt="image" src="https://user-images.githubusercontent.com/77398366/181906454-b46f6a14-7c2c-4b8f-8b0a-40432521bed8.png">
中文 | [English](https://github.com/opengoofy/hippo4j/blob/develop/README-EN.md) 中文 | [English](https://github.com/opengoofy/hippo4j/blob/develop/README-EN.md)
# 动态可观测线程池框架,提高线上运行保障能力 # 动态可观测线程池框架,提高线上运行保障能力
[![Gitee](https://gitee.com/itmachen/hippo4j/badge/star.svg?theme=gvp)](https://gitee.com/itmachen/hippo4j) [![GitHub](https://img.shields.io/github/stars/opengoofy/hippo4j)](https://github.com/opengoofy/hippo4j) [![Docker Pulls](https://img.shields.io/docker/pulls/hippo4j/hippo4j-server.svg)](https://store.docker.com/community/images/hippo4j/hippo4j-server) [![Contributors](https://img.shields.io/github/contributors/opengoofy/hippo4j?color=3ba272)](https://github.com/opengoofy/hippo4j/graphs/contributors) [![License](https://img.shields.io/github/license/opengoofy/hippo4j?color=5470c6)](https://github.com/opengoofy/hippo4j/blob/develop/LICENSE) [![Gitee](https://gitee.com/magegoofy/hippo4j/badge/star.svg?theme=gvp)](https://gitee.com/magegoofy/hippo4j) [![GitHub](https://img.shields.io/github/stars/opengoofy/hippo4j?color=5470c6)](https://github.com/opengoofy/hippo4j) [![Contributors](https://img.shields.io/github/contributors/opengoofy/hippo4j?color=3ba272)](https://github.com/opengoofy/hippo4j/graphs/contributors) [![Docker Pulls](https://img.shields.io/docker/pulls/hippo4j/hippo4j-server.svg?label=docker%20pulls&color=fac858)](https://store.docker.com/community/images/hippo4j/hippo4j-server) [![codecov](https://codecov.io/gh/opengoofy/hippo4j/branch/develop/graph/badge.svg?token=WBUVJN107I)](https://codecov.io/gh/opengoofy/hippo4j)
------- -------

@ -13,10 +13,10 @@ sidebar_position: 2
<td align="center" width="26%">联系方式</td> <td align="center" width="26%">联系方式</td>
</tr> </tr>
<tr> <tr>
<td align="center" ><a href="https://github.com/itmachen"><img src="https://avatars.githubusercontent.com/u/77398366?v=4?s=64" width="64px;"/></a></td> <td align="center" ><a href="https://github.com/magegoofy"><img src="https://avatars.githubusercontent.com/u/77398366?v=4?s=64" width="64px;"/></a></td>
<td align="center" >马称</td> <td align="center" >马称</td>
<td align="center" ><a href="https://github.com/itmachen">itmachen</a></td> <td align="center" ><a href="https://github.com/magegoofy">magegoofy</a></td>
<td align="center" ><a href="http://www.xiaomage.info/">小马哥的技术专栏</a></td> <td align="center" ><a href="https://www.xiaomage.info/">小马哥的技术专栏</a></td>
<td align="center" >machen@apache.org</td> <td align="center" >machen@apache.org</td>
</tr> </tr>
<tr> <tr>
@ -62,3 +62,21 @@ sidebar_position: 2
<td align="center" >17855368071@163.com</td> <td align="center" >17855368071@163.com</td>
</tr> </tr>
</table> </table>
## 成为核心开发者
持续对 Hippo-4J 进行贡献, 粗略评估,完成 10 次 PR 贡献即可成为核心开发者。 其中包括完成 2 个 [good pro issue](https://github.com/opengoofy/hippo4j/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+pro+issue%22) 或以上,以及 6 个 [good first issue]((https://github.com/opengoofy/hippo4j/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22)) 或以上。
:::note
会根据 PR 质量提供个性化评估,有可能一个或两个质量较高 PR 即可成为核心开发者。参考:[重构 DynamicThreadPoolExecutor 功能扩展逻辑](https://github.com/opengoofy/hippo4j/pull/854)
:::
成为核心开发者后,会为该 GitHub 账号获取 Jetbrains 全家桶 Licenses有效期为 1 年。不用再为破解而烦恼,感受随时升级的快乐。
:::note
距离到期两周前,会再次申请 Jetbrains Licenses。有点类似于无限续约的感觉在此感谢 Jetbrains 公司对开源的支持。
:::
截至 `2022-10-30` 当天,已为登记的 7 位核心开发者成功申请 Licenses。
![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20221030134303060.png)

@ -12,7 +12,7 @@ sidebar_position: 3
## 谁在使用 Hippo4J ## 谁在使用 Hippo4J
共计 19+ 家公司生产接入 Hippo4J。按照公司登记时间排序。 共计 20+ 家公司生产接入 Hippo4J。按照公司登记时间排序。
- [身边云](https://serviceshare.com) - [身边云](https://serviceshare.com)
- [Medbanks](https://www.medbanks.cn) - [Medbanks](https://www.medbanks.cn)
@ -33,3 +33,4 @@ sidebar_position: 3
- [深圳航天信息有限公司](http://sz.aisino.com/) - [深圳航天信息有限公司](http://sz.aisino.com/)
- [新东方教育科技集团](https://www.xdf.cn/) - [新东方教育科技集团](https://www.xdf.cn/)
- [远眺网络科技有限公司](https://www.yuantiaokj.com/) - [远眺网络科技有限公司](https://www.yuantiaokj.com/)
- [浙江吉利控股集团有限公司](https://www.geely.com/)

@ -4,18 +4,20 @@ sidebar_position: 4
# 支持开源 # 支持开源
如果您正在使用这个项目并感觉良好,或者是想支持我继续开发。通过以下二维码 一次性捐款,我多半会买一杯咖啡或茶~ 如果您正在使用这个项目并感觉良好,或者是想支持我继续开发,通过以下二维码一次性捐款。
> [GitHub](https://github.com/opengoofy/hippo4j) 或 [Gitee](https://gitee.com/agentart/hippo4j) Star 才是最大动力~ 在这里承诺将,将收到的所有赞助支持资金完全公开化,且后续资金用途仅 Hippo-4J 项目的运转。
![](https://images-machen.oss-cn-beijing.aliyuncs.com/IMG_6719_2.jpg?x-oss-process=image/resize,h_180,w_180) ![](https://images-machen.oss-cn-beijing.aliyuncs.com/IMG_6719_2.jpg?x-oss-process=image/resize,h_180,w_180)
感谢给予支持的朋友,您的支持是前进的动力 🎉 感谢给予支持的朋友,您的支持是 Hippo-4J 社区前进的动力 🎉
| | ID | 赞赏金额 | 时间 | 备注 | | | ID | 赞赏金额 | 时间 | 备注 |
|-----|--------|-------|------------|--------------------| |-----|--|-------|------------|--------------------|
| 1 | 六月飞雪 | 30.00 | 2021-12-30 | 代码设计很优雅的一款框架,继续加油! | | 1 | 六月飞雪 | 30.00 | 2021-12-30 | 代码设计很优雅的一款框架,继续加油! |
| 2 | 孙大圣 | 26.6 | 2022-03-23 | 学习一下😁😁 | | 2 | 孙大圣 | 26.6 | 2022-03-23 | 学习一下😁😁 |
| 3 | Easy 点 | 66.00 | 2022-04-09 | 好货好技术当加赏 | | 3 | Easy 点 | 66.00 | 2022-04-09 | 好货好技术当加赏 |
| 4 | 捷克 | 30.00 | 2022-05-21 | 非常不错的框架,点赞 | | 4 | 捷克 | 30.00 | 2022-05-21 | 非常不错的框架,点赞 |
| 5 | 吃猫的饼干 | 88.00 | 2022-08-21 | 👍 | | 5 | 吃猫的饼干 | 88.00 | 2022-08-21 | 👍 |
| 6 | 不忘初心· | 66.00 | 2022-10-28 | Nice |
| 7 | 时刻· | 6.00 | 2022-10-30 | - |

@ -16,6 +16,7 @@ docker run -d -p 6691:6691 --name hippo4j-server hippo4j/hippo4j-server
```shell ```shell
docker run -d -p 6691:6691 --name hippo4j-server \ docker run -d -p 6691:6691 --name hippo4j-server \
-e DATASOURCE_MODE=mysql \
-e DATASOURCE_HOST=xxx.xxx.xxx.xxx \ -e DATASOURCE_HOST=xxx.xxx.xxx.xxx \
-e DATASOURCE_PORT=3306 \ -e DATASOURCE_PORT=3306 \
-e DATASOURCE_DB=hippo4j_manager \ -e DATASOURCE_DB=hippo4j_manager \

@ -20,6 +20,7 @@ package cn.hippo4j.common.toolkit;
import cn.hippo4j.common.api.JsonFacade; import cn.hippo4j.common.api.JsonFacade;
import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.core.type.TypeReference;
import java.util.Collections;
import java.util.List; import java.util.List;
/** /**
@ -52,7 +53,7 @@ public class JSONUtil {
public static <T> List<T> parseArray(String text, Class<T> clazz) { public static <T> List<T> parseArray(String text, Class<T> clazz) {
if (StringUtil.isBlank(text)) { if (StringUtil.isBlank(text)) {
return null; return Collections.emptyList();
} }
return JSON_FACADE.parseArray(text, clazz); return JSON_FACADE.parseArray(text, clazz);
} }

@ -17,13 +17,21 @@
package cn.hippo4j.common.toolkit; package cn.hippo4j.common.toolkit;
import com.github.dozermapper.core.converters.ConversionException; import lombok.AllArgsConstructor;
import lombok.*; import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.*; import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class BeanUtilTest { public class BeanUtilTest {
@ -95,7 +103,7 @@ public class BeanUtilTest {
/** /**
* *
*/ */
@Test(expected = ConversionException.class) // @Test(expected = ConversionException.class)
public void mapToBeanWinErrorTest() { public void mapToBeanWinErrorTest() {
final Map<String, String> map = new HashMap<>(); final Map<String, String> map = new HashMap<>();
map.put("age", "Hippo4j"); map.put("age", "Hippo4j");

@ -26,6 +26,7 @@ import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.List; import java.util.List;
public class JSONUtilTest { public class JSONUtilTest {
@ -65,8 +66,8 @@ public class JSONUtilTest {
@Test @Test
public void assertParseArray() { public void assertParseArray() {
Assert.assertNull(JSONUtil.parseArray(null, Foo.class)); Assert.assertEquals(Collections.emptyList(), JSONUtil.parseArray(null, Foo.class));
Assert.assertNull(JSONUtil.parseArray(" ", Foo.class)); Assert.assertEquals(Collections.emptyList(), JSONUtil.parseArray(" ", Foo.class));
Assert.assertEquals( Assert.assertEquals(
EXPECTED_FOO_ARRAY, EXPECTED_FOO_ARRAY,
JSONUtil.parseArray(EXPECTED_FOO_JSON_ARRAY, Foo.class)); JSONUtil.parseArray(EXPECTED_FOO_JSON_ARRAY, Foo.class));

@ -57,13 +57,13 @@ public class ReflectUtilTest {
Assert.assertNotNull(field); Assert.assertNotNull(field);
} }
@Test // @Test
public void getFieldsTest() { public void getFieldsTest() {
Field[] fields = ReflectUtil.getFields(TestSubClass.class); Field[] fields = ReflectUtil.getFields(TestSubClass.class);
Assert.assertEquals(4, fields.length); Assert.assertEquals(4, fields.length);
} }
@Test // @Test
public void getFieldsDirectlyTest() { public void getFieldsDirectlyTest() {
Field[] fields = ReflectUtil.getFieldsDirectly(TestSubClass.class, false); Field[] fields = ReflectUtil.getFieldsDirectly(TestSubClass.class, false);
Assert.assertEquals(2, fields.length); Assert.assertEquals(2, fields.length);

@ -23,7 +23,6 @@ import lombok.Setter;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import java.net.SocketTimeoutException;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -72,7 +71,7 @@ public class HttpUtilsTest {
Assert.assertNotNull(data); Assert.assertNotNull(data);
} }
@Test(expected = SocketTimeoutException.class) // @Test(expected = SocketTimeoutException.class)
public void testRestApiPostTimeout() { public void testRestApiPostTimeout() {
String loginUrl = postUrl + "auth/login"; String loginUrl = postUrl + "auth/login";
LoginInfo loginInfo = new LoginInfo(); LoginInfo loginInfo = new LoginInfo();

@ -51,6 +51,7 @@ public class DynamicThreadPoolWrapper implements DisposableBean {
public DynamicThreadPoolWrapper(String threadPoolId, ThreadPoolExecutor threadPoolExecutor) { public DynamicThreadPoolWrapper(String threadPoolId, ThreadPoolExecutor threadPoolExecutor) {
this.threadPoolId = threadPoolId; this.threadPoolId = threadPoolId;
this.executor = threadPoolExecutor; this.executor = threadPoolExecutor;
this.subscribeFlag = true;
} }
public void execute(Runnable command) { public void execute(Runnable command) {
@ -67,7 +68,7 @@ public class DynamicThreadPoolWrapper implements DisposableBean {
@Override @Override
public void destroy() throws Exception { public void destroy() throws Exception {
if (executor != null && executor instanceof AbstractDynamicExecutorSupport) { if (executor instanceof AbstractDynamicExecutorSupport) {
((AbstractDynamicExecutorSupport) executor).destroy(); ((AbstractDynamicExecutorSupport) executor).destroy();
} }
} }

@ -27,12 +27,27 @@ import java.util.concurrent.ConcurrentHashMap;
*/ */
public class GlobalNotifyAlarmManage { public class GlobalNotifyAlarmManage {
/**
* Notify alarm map.
*/
private static final Map<String, ThreadPoolNotifyAlarm> NOTIFY_ALARM_MAP = new ConcurrentHashMap(); private static final Map<String, ThreadPoolNotifyAlarm> NOTIFY_ALARM_MAP = new ConcurrentHashMap();
/**
* Get thread-pool notify alarm.
*
* @param key thread-pool key
* @return thread-pool notify alarm
*/
public static ThreadPoolNotifyAlarm get(String key) { public static ThreadPoolNotifyAlarm get(String key) {
return NOTIFY_ALARM_MAP.get(key); return NOTIFY_ALARM_MAP.get(key);
} }
/**
* Put thread-pool notify alarm.
*
* @param key thread-pool key
* @param val thread-pool notify alarm
*/
public static void put(String key, ThreadPoolNotifyAlarm val) { public static void put(String key, ThreadPoolNotifyAlarm val) {
NOTIFY_ALARM_MAP.put(key, val); NOTIFY_ALARM_MAP.put(key, val);
} }

@ -48,8 +48,8 @@ public class GlobalThreadPoolManage {
/** /**
* Get the dynamic thread pool wrapper class. * Get the dynamic thread pool wrapper class.
* *
* @param threadPoolId * @param threadPoolId thread-pool id
* @return * @return dynamic thread-pool wrapper
*/ */
public static DynamicThreadPoolWrapper getExecutorService(String threadPoolId) { public static DynamicThreadPoolWrapper getExecutorService(String threadPoolId) {
return EXECUTOR_MAP.get(threadPoolId); return EXECUTOR_MAP.get(threadPoolId);
@ -58,8 +58,8 @@ public class GlobalThreadPoolManage {
/** /**
* Get the dynamic thread pool wrapper class. * Get the dynamic thread pool wrapper class.
* *
* @param threadPoolId * @param threadPoolId thread-pool id
* @return * @return thread-pool executor
*/ */
public static ThreadPoolExecutor getExecutor(String threadPoolId) { public static ThreadPoolExecutor getExecutor(String threadPoolId) {
return Optional.ofNullable(EXECUTOR_MAP.get(threadPoolId)).map(each -> each.getExecutor()).orElse(null); return Optional.ofNullable(EXECUTOR_MAP.get(threadPoolId)).map(each -> each.getExecutor()).orElse(null);
@ -68,8 +68,8 @@ public class GlobalThreadPoolManage {
/** /**
* Get dynamic thread pool parameters. * Get dynamic thread pool parameters.
* *
* @param threadPoolId * @param threadPoolId thread-pool id
* @return * @return thread-pool parameter
*/ */
public static ThreadPoolParameter getPoolParameter(String threadPoolId) { public static ThreadPoolParameter getPoolParameter(String threadPoolId) {
return POOL_PARAMETER.get(threadPoolId); return POOL_PARAMETER.get(threadPoolId);
@ -78,9 +78,9 @@ public class GlobalThreadPoolManage {
/** /**
* Register dynamic thread pool wrapper and parameters. * Register dynamic thread pool wrapper and parameters.
* *
* @param threadPoolId * @param threadPoolId thread-pool id
* @param threadPoolParameter * @param threadPoolParameter thread-pool parameter
* @param executor * @param executor executor
*/ */
public static void register(String threadPoolId, ThreadPoolParameter threadPoolParameter, DynamicThreadPoolWrapper executor) { public static void register(String threadPoolId, ThreadPoolParameter threadPoolParameter, DynamicThreadPoolWrapper executor) {
registerPool(threadPoolId, executor); registerPool(threadPoolId, executor);
@ -90,8 +90,8 @@ public class GlobalThreadPoolManage {
/** /**
* Register dynamic thread pool. * Register dynamic thread pool.
* *
* @param threadPoolId * @param threadPoolId thread-pool id
* @param executor * @param executor executor
*/ */
public static void registerPool(String threadPoolId, DynamicThreadPoolWrapper executor) { public static void registerPool(String threadPoolId, DynamicThreadPoolWrapper executor) {
EXECUTOR_MAP.put(threadPoolId, executor); EXECUTOR_MAP.put(threadPoolId, executor);
@ -100,17 +100,17 @@ public class GlobalThreadPoolManage {
/** /**
* Register dynamic thread pool parameters. * Register dynamic thread pool parameters.
* *
* @param threadPoolId * @param threadPoolId thread-pool id
* @param poolParameter * @param threadPoolParameter thread-pool parameter
*/ */
public static void registerPoolParameter(String threadPoolId, ThreadPoolParameter poolParameter) { public static void registerPoolParameter(String threadPoolId, ThreadPoolParameter threadPoolParameter) {
POOL_PARAMETER.put(threadPoolId, poolParameter); POOL_PARAMETER.put(threadPoolId, threadPoolParameter);
} }
/** /**
* Dynamically register thread pool records and notification records. * Dynamically register thread pool records and notification records.
* *
* @param registerWrapper * @param registerWrapper register wrapper
*/ */
public static ThreadPoolExecutor dynamicRegister(DynamicThreadPoolRegisterWrapper registerWrapper) { public static ThreadPoolExecutor dynamicRegister(DynamicThreadPoolRegisterWrapper registerWrapper) {
DynamicThreadPoolService dynamicThreadPoolService = ApplicationContextHolder.getBean(DynamicThreadPoolService.class); DynamicThreadPoolService dynamicThreadPoolService = ApplicationContextHolder.getBean(DynamicThreadPoolService.class);
@ -120,7 +120,7 @@ public class GlobalThreadPoolManage {
/** /**
* Get the dynamic thread pool identifier collection. * Get the dynamic thread pool identifier collection.
* *
* @return * @return thread-pool id list
*/ */
public static List<String> listThreadPoolId() { public static List<String> listThreadPoolId() {
return new ArrayList<>(EXECUTOR_MAP.keySet()); return new ArrayList<>(EXECUTOR_MAP.keySet());
@ -128,11 +128,10 @@ public class GlobalThreadPoolManage {
/** /**
* Get the number of dynamic thread pools. * Get the number of dynamic thread pools.
* <p> * <p> The data may be inaccurate when the project is initially
* The data may be inaccurate when the project is initially
* launched because registration is done asynchronously. * launched because registration is done asynchronously.
* *
* @return * @return thread-pool num
*/ */
public static Integer getThreadPoolNum() { public static Integer getThreadPoolNum() {
return listThreadPoolId().size(); return listThreadPoolId().size();

@ -30,6 +30,7 @@ RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
ADD conf/hippo4j-logback.xml ${BASE_DIR}/conf/hippo4j-logback.xml ADD conf/hippo4j-logback.xml ${BASE_DIR}/conf/hippo4j-logback.xml
ADD conf/application.properties ${BASE_DIR}/conf/application.properties ADD conf/application.properties ${BASE_DIR}/conf/application.properties
ADD conf/application-h2.properties ${BASE_DIR}/conf/application-h2.properties
ADD target/hippo4j-server.jar ${BASE_DIR}/hippo4j-server.jar ADD target/hippo4j-server.jar ${BASE_DIR}/hippo4j-server.jar
ADD docker-startup.sh ${BASE_DIR}/docker-startup.sh ADD docker-startup.sh ${BASE_DIR}/docker-startup.sh

@ -0,0 +1,9 @@
### Data source customization section
hippo4j.database.dialect=h2
hippo4j.database.init_enable=true
hippo4j.database.init_script=sql-script/h2/hippo4j_manager.sql
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.url=jdbc:h2:file:{your storage address}/h2_hippo4j_test_file;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=false;MODE=MYSQL;
spring.datasource.username=sa
spring.datasource.password=sa

@ -4,6 +4,7 @@
### Server Startup Port ### Server Startup Port
server.port=6691 server.port=6691
spring.profiles.active=mysql
### Server Tomcat ### Server Tomcat
server.tomcat.accesslog.enabled=true server.tomcat.accesslog.enabled=true
@ -23,17 +24,22 @@ hippo4j.core.clean-history-data-enable=true
### Whether to enable authentication. ### Whether to enable authentication.
hippo4j.core.auth.enabled=true hippo4j.core.auth.enabled=true
### Initialize the database dialect class.
hippo4j.database.dialect=mysql
hippo4j.database.init_enable=false
hippo4j.database.init_script=sql-script/mysql/hippo4j_manager.sql
### Use netty to report thread pool monitoring data. The default is http. ### Use netty to report thread pool monitoring data. The default is http.
# hippo4j.core.monitor.report-type=netty # hippo4j.core.monitor.report-type=netty
#*************** Config Module Related Configurations ***************# #*************** Config Module Related Configurations ***************#
### Data source customization section ### Default database
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/hippo4j_manager?characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&serverTimezone=GMT%2B8 spring.datasource.url=jdbc:mysql://localhost:3306/hippo4j_manager?characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&serverTimezone=GMT%2B8
spring.datasource.username=root spring.datasource.username=root
spring.datasource.password=root spring.datasource.password=root
### Hikari Datasource ### Hikari Datasource
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.hikari.pool-name=Hikari spring.datasource.hikari.pool-name=Hikari
spring.datasource.hikari.connectionTimeout=30000 spring.datasource.hikari.connectionTimeout=30000
spring.datasource.hikari.idleTimeout=30000 spring.datasource.hikari.idleTimeout=30000

@ -19,7 +19,8 @@ JAVA_OPT="${JAVA_OPT} --server.max-http-header-size=524288"
JAVA_OPT="${JAVA_OPT} --server.tomcat.basedir=${BASE_DIR}/bin" JAVA_OPT="${JAVA_OPT} --server.tomcat.basedir=${BASE_DIR}/bin"
if [[ "${DATASOURCE_MODE}" == "mysql" ]]; then if [[ "${DATASOURCE_MODE}" == "mysql" ]]; then
JAVA_OPT="${JAVA_OPT} --spring.datasource.url=\"jdbc:mysql://${DATASOURCE_HOST}:${DATASOURCE_PORT}/${DATASOURCE_DB}?characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&serverTimezone=GMT%2B8\" " JAVA_OPT="${JAVA_OPT} --spring.profiles.active=mysql --hippo4j.database.init_enable=false "
JAVA_OPT="${JAVA_OPT} --spring.datasource.url=jdbc:mysql://${DATASOURCE_HOST}:${DATASOURCE_PORT}/${DATASOURCE_DB}?characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&serverTimezone=GMT%2B8 "
JAVA_OPT="${JAVA_OPT} --spring.datasource.username=${DATASOURCE_USERNAME} --spring.datasource.password=${DATASOURCE_PASSWORD} " JAVA_OPT="${JAVA_OPT} --spring.datasource.username=${DATASOURCE_USERNAME} --spring.datasource.password=${DATASOURCE_PASSWORD} "
elif [[ "${DATASOURCE_MODE}" == "h2" ]]; then elif [[ "${DATASOURCE_MODE}" == "h2" ]]; then
JAVA_OPT="${JAVA_OPT} --spring.profiles.active=h2 --spring.datasource.url=jdbc:h2:file:${BASE_DIR}/h2_hippo4j;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=false;MODE=MYSQL" JAVA_OPT="${JAVA_OPT} --spring.profiles.active=h2 --spring.datasource.url=jdbc:h2:file:${BASE_DIR}/h2_hippo4j;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=false;MODE=MYSQL"

@ -4,6 +4,6 @@ hippo4j.database.init_enable=true
hippo4j.database.init_script=sql-script/h2/hippo4j_manager.sql hippo4j.database.init_script=sql-script/h2/hippo4j_manager.sql
spring.datasource.driver-class-name=org.h2.Driver spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.url=jdbc:h2:file:{your storage address}/h2_hippo4j_test_file;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=false;MODE=MYSQL; spring.datasource.url=jdbc:h2:file:${HOME:${HOMEDRIVE}${HOMEPATH}}/h2_hippo4j_test_file;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=false;MODE=MYSQL;
spring.datasource.username=sa spring.datasource.username=sa
spring.datasource.password=sa spring.datasource.password=sa

@ -109,7 +109,7 @@ public class LongPollingService {
@Override @Override
public void run() { public void run() {
try { try {
for (Iterator<ClientLongPolling> iter = allSubs.iterator(); iter.hasNext(); ) { for (Iterator<ClientLongPolling> iter = allSubs.iterator(); iter.hasNext();) {
ClientLongPolling clientSub = iter.next(); ClientLongPolling clientSub = iter.next();
String identity = groupKey + GROUP_KEY_DELIMITER + identify; String identity = groupKey + GROUP_KEY_DELIMITER + identify;
List<String> parseMapForFilter = CollectionUtil.newArrayList(identity); List<String> parseMapForFilter = CollectionUtil.newArrayList(identity);

@ -0,0 +1,32 @@
/*
* 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.event;
import cn.hippo4j.common.toolkit.Assert;
import cn.hippo4j.common.toolkit.StringUtil;
import org.junit.Test;
public final class LocalDataChangeEventTest {
@Test
public void assertGetSingleton() {
LocalDataChangeEvent localDataChangeEvent = new LocalDataChangeEvent("groupKey", "identify");
Assert.isTrue(StringUtil.isNotEmpty(localDataChangeEvent.groupKey));
Assert.isTrue(StringUtil.isNotEmpty(localDataChangeEvent.identify));
}
}

@ -105,10 +105,18 @@ public class DynamicThreadPoolRefreshListener extends AbstractRefreshListener<Ex
} }
} }
/**
* Fail default executor properties.
*
* @param beforeProperties old properties
* @param properties new properties
* @return executor properties
*/
private ExecutorProperties failDefaultExecutorProperties(ExecutorProperties beforeProperties, ExecutorProperties properties) { private ExecutorProperties failDefaultExecutorProperties(ExecutorProperties beforeProperties, ExecutorProperties properties) {
return ExecutorProperties.builder() return ExecutorProperties.builder()
.corePoolSize(Optional.ofNullable(properties.getCorePoolSize()).orElse(beforeProperties.getCorePoolSize())) .corePoolSize(Optional.ofNullable(properties.getCorePoolSize()).orElse(beforeProperties.getCorePoolSize()))
.maximumPoolSize(Optional.ofNullable(properties.getMaximumPoolSize()).orElse(beforeProperties.getMaximumPoolSize())) .maximumPoolSize(Optional.ofNullable(properties.getMaximumPoolSize()).orElse(beforeProperties.getMaximumPoolSize()))
.blockingQueue(properties.getBlockingQueue())
.queueCapacity(Optional.ofNullable(properties.getQueueCapacity()).orElse(beforeProperties.getQueueCapacity())) .queueCapacity(Optional.ofNullable(properties.getQueueCapacity()).orElse(beforeProperties.getQueueCapacity()))
.keepAliveTime(Optional.ofNullable(properties.getKeepAliveTime()).orElse(beforeProperties.getKeepAliveTime())) .keepAliveTime(Optional.ofNullable(properties.getKeepAliveTime()).orElse(beforeProperties.getKeepAliveTime()))
.executeTimeOut(Optional.ofNullable(properties.getExecuteTimeOut()).orElse(beforeProperties.getExecuteTimeOut())) .executeTimeOut(Optional.ofNullable(properties.getExecuteTimeOut()).orElse(beforeProperties.getExecuteTimeOut()))
@ -127,7 +135,6 @@ public class DynamicThreadPoolRefreshListener extends AbstractRefreshListener<Ex
*/ */
private ChangeParameterNotifyRequest buildChangeRequest(ExecutorProperties beforeProperties, ExecutorProperties properties) { private ChangeParameterNotifyRequest buildChangeRequest(ExecutorProperties beforeProperties, ExecutorProperties properties) {
ChangeParameterNotifyRequest changeParameterNotifyRequest = ChangeParameterNotifyRequest.builder() ChangeParameterNotifyRequest changeParameterNotifyRequest = ChangeParameterNotifyRequest.builder()
.blockingQueueName(beforeProperties.getBlockingQueue())
.beforeCorePoolSize(beforeProperties.getCorePoolSize()) .beforeCorePoolSize(beforeProperties.getCorePoolSize())
.beforeMaximumPoolSize(beforeProperties.getMaximumPoolSize()) .beforeMaximumPoolSize(beforeProperties.getMaximumPoolSize())
.beforeAllowsCoreThreadTimeOut(beforeProperties.getAllowCoreThreadTimeOut()) .beforeAllowsCoreThreadTimeOut(beforeProperties.getAllowCoreThreadTimeOut())
@ -135,6 +142,7 @@ public class DynamicThreadPoolRefreshListener extends AbstractRefreshListener<Ex
.beforeQueueCapacity(beforeProperties.getQueueCapacity()) .beforeQueueCapacity(beforeProperties.getQueueCapacity())
.beforeRejectedName(beforeProperties.getRejectedHandler()) .beforeRejectedName(beforeProperties.getRejectedHandler())
.beforeExecuteTimeOut(beforeProperties.getExecuteTimeOut()) .beforeExecuteTimeOut(beforeProperties.getExecuteTimeOut())
.blockingQueueName(properties.getBlockingQueue())
.nowCorePoolSize(Optional.ofNullable(properties.getCorePoolSize()).orElse(beforeProperties.getCorePoolSize())) .nowCorePoolSize(Optional.ofNullable(properties.getCorePoolSize()).orElse(beforeProperties.getCorePoolSize()))
.nowMaximumPoolSize(Optional.ofNullable(properties.getMaximumPoolSize()).orElse(beforeProperties.getMaximumPoolSize())) .nowMaximumPoolSize(Optional.ofNullable(properties.getMaximumPoolSize()).orElse(beforeProperties.getMaximumPoolSize()))
.nowAllowsCoreThreadTimeOut(Optional.ofNullable(properties.getAllowCoreThreadTimeOut()).orElse(beforeProperties.getAllowCoreThreadTimeOut())) .nowAllowsCoreThreadTimeOut(Optional.ofNullable(properties.getAllowCoreThreadTimeOut()).orElse(beforeProperties.getAllowCoreThreadTimeOut()))

@ -204,17 +204,17 @@ public final class DynamicThreadPoolPostProcessor implements BeanPostProcessor {
private ThreadPoolNotifyAlarm buildThreadPoolNotifyAlarm(ExecutorProperties executorProperties) { private ThreadPoolNotifyAlarm buildThreadPoolNotifyAlarm(ExecutorProperties executorProperties) {
DynamicThreadPoolNotifyProperties notify = Optional.ofNullable(executorProperties).map(ExecutorProperties::getNotify).orElse(null); DynamicThreadPoolNotifyProperties notify = Optional.ofNullable(executorProperties).map(ExecutorProperties::getNotify).orElse(null);
boolean isAlarm = Optional.ofNullable(executorProperties.getAlarm()) boolean isAlarm = Optional.ofNullable(executorProperties.getAlarm())
.orElseGet(() -> Optional.ofNullable(configProperties.getDefaultExecutor()).map(each -> each.getAlarm()).orElse(true)); .orElseGet(() -> Optional.ofNullable(configProperties.getDefaultExecutor()).map(ExecutorProperties::getAlarm).orElse(true));
int activeAlarm = Optional.ofNullable(executorProperties.getActiveAlarm()) int activeAlarm = Optional.ofNullable(executorProperties.getActiveAlarm())
.orElseGet(() -> Optional.ofNullable(configProperties.getDefaultExecutor()).map(each -> each.getActiveAlarm()).orElse(80)); .orElseGet(() -> Optional.ofNullable(configProperties.getDefaultExecutor()).map(ExecutorProperties::getActiveAlarm).orElse(80));
int capacityAlarm = Optional.ofNullable(executorProperties.getCapacityAlarm()) int capacityAlarm = Optional.ofNullable(executorProperties.getCapacityAlarm())
.orElseGet(() -> Optional.ofNullable(configProperties.getDefaultExecutor()).map(each -> each.getCapacityAlarm()).orElse(80)); .orElseGet(() -> Optional.ofNullable(configProperties.getDefaultExecutor()).map(ExecutorProperties::getCapacityAlarm).orElse(80));
int interval = Optional.ofNullable(notify) int interval = Optional.ofNullable(notify)
.map(each -> each.getInterval()) .map(DynamicThreadPoolNotifyProperties::getInterval)
.orElseGet(() -> Optional.ofNullable(configProperties.getDefaultExecutor()).map(each -> each.getNotify()).map(each -> each.getInterval()).orElse(5)); .orElseGet(() -> Optional.ofNullable(configProperties.getDefaultExecutor()).map(ExecutorProperties::getNotify).map(DynamicThreadPoolNotifyProperties::getInterval).orElse(5));
String receive = Optional.ofNullable(notify) String receive = Optional.ofNullable(notify)
.map(each -> each.getReceives()) .map(DynamicThreadPoolNotifyProperties::getReceives)
.orElseGet(() -> Optional.ofNullable(configProperties.getDefaultExecutor()).map(each -> each.getNotify()).map(each -> each.getReceives()).orElse("")); .orElseGet(() -> Optional.ofNullable(configProperties.getDefaultExecutor()).map(ExecutorProperties::getNotify).map(DynamicThreadPoolNotifyProperties::getReceives).orElse(""));
ThreadPoolNotifyAlarm threadPoolNotifyAlarm = new ThreadPoolNotifyAlarm(isAlarm, activeAlarm, capacityAlarm); ThreadPoolNotifyAlarm threadPoolNotifyAlarm = new ThreadPoolNotifyAlarm(isAlarm, activeAlarm, capacityAlarm);
threadPoolNotifyAlarm.setInterval(interval); threadPoolNotifyAlarm.setInterval(interval);
threadPoolNotifyAlarm.setReceives(receive); threadPoolNotifyAlarm.setReceives(receive);

@ -53,7 +53,7 @@ public class DynamicThreadPoolSubscribeConfig {
.build(); .build();
public void subscribeConfig(String threadPoolId) { public void subscribeConfig(String threadPoolId) {
subscribeConfig(threadPoolId, config -> threadPoolDynamicRefresh.dynamicRefresh(config)); subscribeConfig(threadPoolId, threadPoolDynamicRefresh::dynamicRefresh);
} }
public void subscribeConfig(String threadPoolId, ThreadPoolSubscribeCallback threadPoolSubscribeCallback) { public void subscribeConfig(String threadPoolId, ThreadPoolSubscribeCallback threadPoolSubscribeCallback) {

@ -130,7 +130,6 @@ public final class DynamicThreadPoolPostProcessor implements BeanPostProcessor {
queryStrMap.put(TP_ID, threadPoolId); queryStrMap.put(TP_ID, threadPoolId);
queryStrMap.put(ITEM_ID, properties.getItemId()); queryStrMap.put(ITEM_ID, properties.getItemId());
queryStrMap.put(NAMESPACE, properties.getNamespace()); queryStrMap.put(NAMESPACE, properties.getNamespace());
boolean isSubscribe = false;
ThreadPoolExecutor newDynamicThreadPoolExecutor = null; ThreadPoolExecutor newDynamicThreadPoolExecutor = null;
ThreadPoolParameterInfo threadPoolParameterInfo = new ThreadPoolParameterInfo(); ThreadPoolParameterInfo threadPoolParameterInfo = new ThreadPoolParameterInfo();
try { try {
@ -167,7 +166,6 @@ public final class DynamicThreadPoolPostProcessor implements BeanPostProcessor {
((DynamicThreadPoolExecutor) newDynamicThreadPoolExecutor).setExecuteTimeOut(executeTimeOut); ((DynamicThreadPoolExecutor) newDynamicThreadPoolExecutor).setExecuteTimeOut(executeTimeOut);
} }
dynamicThreadPoolWrapper.setExecutor(newDynamicThreadPoolExecutor); dynamicThreadPoolWrapper.setExecutor(newDynamicThreadPoolExecutor);
isSubscribe = true;
} }
} else { } else {
// DynamicThreadPool configuration undefined in server // DynamicThreadPool configuration undefined in server
@ -197,8 +195,6 @@ public final class DynamicThreadPoolPostProcessor implements BeanPostProcessor {
if (Objects.isNull(executor)) { if (Objects.isNull(executor)) {
dynamicThreadPoolWrapper.setExecutor(CommonDynamicThreadPool.getInstance(threadPoolId)); dynamicThreadPoolWrapper.setExecutor(CommonDynamicThreadPool.getInstance(threadPoolId));
} }
// Set whether to subscribe to the remote thread pool configuration.
dynamicThreadPoolWrapper.setSubscribeFlag(isSubscribe);
} }
GlobalThreadPoolManage.register(dynamicThreadPoolWrapper.getThreadPoolId(), threadPoolParameterInfo, dynamicThreadPoolWrapper); GlobalThreadPoolManage.register(dynamicThreadPoolWrapper.getThreadPoolId(), threadPoolParameterInfo, dynamicThreadPoolWrapper);
return newDynamicThreadPoolExecutor; return newDynamicThreadPoolExecutor;

@ -0,0 +1,20 @@
#
# 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.
#
# this config is to ignore lombok code in jacoco
config.stopBubbling = true
lombok.addLombokGeneratedAnnotation = true

@ -80,8 +80,10 @@
<skip.maven.gpg.plugin>true</skip.maven.gpg.plugin> <skip.maven.gpg.plugin>true</skip.maven.gpg.plugin>
<skip.spotless.apply>false</skip.spotless.apply> <skip.spotless.apply>false</skip.spotless.apply>
<skip.checkstyle.check>true</skip.checkstyle.check> <skip.checkstyle.check>true</skip.checkstyle.check>
<skip.jacoco.plugin>true</skip.jacoco.plugin>
<maven.javadoc.failOnError>false</maven.javadoc.failOnError> <maven.javadoc.failOnError>false</maven.javadoc.failOnError>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding> <maven.compiler.encoding>UTF-8</maven.compiler.encoding>
<jacoco-maven-plugin.version>0.8.8</jacoco-maven-plugin.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<maven.compiler.plugin.version>3.6.1</maven.compiler.plugin.version> <maven.compiler.plugin.version>3.6.1</maven.compiler.plugin.version>
@ -334,6 +336,28 @@
</execution> </execution>
</executions> </executions>
</plugin> </plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>${jacoco-maven-plugin.version}</version>
<configuration>
<skip>${skip.jacoco.plugin}</skip>
</configuration>
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<goals>
<goal>report</goal>
</goals>
<phase>test</phase>
</execution>
</executions>
</plugin>
</plugins> </plugins>
</build> </build>

Loading…
Cancel
Save