Merge remote-tracking branch 'upstream/develop' into config_change_verify

# Conflicts:
#	hippo4j-config/src/main/java/cn/hippo4j/config/controller/ConfigController.java
#	hippo4j-config/src/main/java/cn/hippo4j/config/service/biz/impl/ThreadPoolServiceImpl.java
#	hippo4j-console/src/main/java/cn/hippo4j/console/controller/ThreadPoolAdapterController.java
#	hippo4j-console/src/main/java/cn/hippo4j/console/controller/ThreadPoolController.java
pull/776/head
yewei 3 years ago
commit eb0ad2bc6f

@ -28,7 +28,7 @@ Hippo-4J 通过对 JDK 线程池增强,以及扩展三方框架底层线程池
提供以下功能支持:
- 全局管控 - 管理应用线程池实例
- 全局管控 - 管理应用线程池实例
- 动态变更 - 应用运行时动态变更线程池参数,包括不限于:核心、最大线程数、阻塞队列容量、拒绝策略等。
- 通知报警 - 内置四种报警通知策略,线程池活跃度、容量水位、拒绝策略以及任务执行时间超长。
@ -36,7 +36,7 @@ Hippo-4J 通过对 JDK 线程池增强,以及扩展三方框架底层线程池
- 功能扩展 - 支持线程池任务传递上下文;项目关闭时,支持等待线程池在指定时间内完成任务。
- 多种模式 - 内置两种使用模式:[依赖配置中心](https://hippo4j.cn/docs/user_docs/getting_started/config/hippo4j-config-start) 和 [无中间件依赖](https://hippo4j.cn/docs/user_docs/getting_started/server/hippo4j-server-start)。
- 容器管理 - Tomcat、Jetty、Undertow 容器线程池运行时查看和线程数变更。
- 中间件适配 - Dubbo、Hystrix、RocketMQ、RabbitMQ 等消费线程池运行时数据查看和线程数变更。
- 中间件适配 - Dubbo、Hystrix、Polaris、RabbitMQ、RocketMQ 等消费线程池运行时数据查看和线程数变更。
## 快速开始
@ -115,15 +115,15 @@ Hippo-4J 通过对 JDK 线程池增强,以及扩展三方框架底层线程池
</a>
</td>
<td align="center">
<a href="https://github.com/xqxyxchy">
<img src="https://avatars.githubusercontent.com/u/21134578?v=4" width="50;" alt="xqxyxchy"/>
<a href="https://github.com/Gdk666">
<img src="https://avatars.githubusercontent.com/u/22442067?v=4" width="50;" alt="Gdk666"/>
<br />
<sub><b>Null</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/Gdk666">
<img src="https://avatars.githubusercontent.com/u/22442067?v=4" width="50;" alt="Gdk666"/>
<a href="https://github.com/xqxyxchy">
<img src="https://avatars.githubusercontent.com/u/21134578?v=4" width="50;" alt="xqxyxchy"/>
<br />
<sub><b>Null</b></sub>
</a>
@ -151,17 +151,17 @@ Hippo-4J 通过对 JDK 线程池增强,以及扩展三方框架底层线程池
</a>
</td>
<td align="center">
<a href="https://github.com/liulinfei121">
<img src="https://avatars.githubusercontent.com/u/57127515?v=4" width="50;" alt="liulinfei121"/>
<a href="https://github.com/road2master">
<img src="https://avatars.githubusercontent.com/u/53806703?v=4" width="50;" alt="road2master"/>
<br />
<sub><b>Null</b></sub>
<sub><b>Lijx</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/road2master">
<img src="https://avatars.githubusercontent.com/u/53806703?v=4" width="50;" alt="road2master"/>
<a href="https://github.com/liulinfei121">
<img src="https://avatars.githubusercontent.com/u/57127515?v=4" width="50;" alt="liulinfei121"/>
<br />
<sub><b>Lijx</b></sub>
<sub><b>Null</b></sub>
</a>
</td>
<td align="center">
@ -242,21 +242,28 @@ Hippo-4J 通过对 JDK 线程池增强,以及扩展三方框架底层线程池
<sub><b>Serenity</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/baymax55">
<img src="https://avatars.githubusercontent.com/u/35788491?v=4" width="50;" alt="baymax55"/>
<br />
<sub><b>Baymax55</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/gewuwo">
<img src="https://avatars.githubusercontent.com/u/97213587?v=4" width="50;" alt="gewuwo"/>
<br />
<sub><b>格悟沃</b></sub>
</a>
</td>
</td></tr>
<tr>
<td align="center">
<a href="https://github.com/hushtian">
<img src="https://avatars.githubusercontent.com/u/55479601?v=4" width="50;" alt="hushtian"/>
<br />
<sub><b>Null</b></sub>
</a>
</td></tr>
<tr>
</td>
<td align="center">
<a href="https://github.com/jinlingmei">
<img src="https://avatars.githubusercontent.com/u/24669082?v=4" width="50;" alt="jinlingmei"/>
@ -312,15 +319,15 @@ Hippo-4J 通过对 JDK 线程池增强,以及扩展三方框架底层线程池
<br />
<sub><b>Null</b></sub>
</a>
</td>
</td></tr>
<tr>
<td align="center">
<a href="https://github.com/onesimplecoder">
<img src="https://avatars.githubusercontent.com/u/30288465?v=4" width="50;" alt="onesimplecoder"/>
<br />
<sub><b>Alic</b></sub>
</a>
</td></tr>
<tr>
</td>
<td align="center">
<a href="https://github.com/CalebZYC">
<img src="https://avatars.githubusercontent.com/u/42887532?v=4" width="50;" alt="CalebZYC"/>
@ -376,21 +383,14 @@ Hippo-4J 通过对 JDK 线程池增强,以及扩展三方框架底层线程池
<br />
<sub><b>WuLang</b></sub>
</a>
</td>
</td></tr>
<tr>
<td align="center">
<a href="https://github.com/alexhaoxuan">
<img src="https://avatars.githubusercontent.com/u/46749051?v=4" width="50;" alt="alexhaoxuan"/>
<br />
<sub><b>Alexli</b></sub>
</a>
</td></tr>
<tr>
<td align="center">
<a href="https://github.com/baymax55">
<img src="https://avatars.githubusercontent.com/u/35788491?v=4" width="50;" alt="baymax55"/>
<br />
<sub><b>Baymax55</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/qizhongju">

@ -0,0 +1,130 @@
<?xml version="1.0"?>
<!--
~ 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.
-->
<!DOCTYPE module PUBLIC
"-//Puppy Crawl//DTD Check Configuration 1.3//EN"
"http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
<module name="Checker">
<module name="NewlineAtEndOfFile"/>
<module name="RegexpSingleline">
<property name="format" value="printStackTrace"/>
<property name="message" value="Prohibit invoking printStackTrace in source code !"/>
</module>
<module name="TreeWalker">
<module name="AvoidStarImport">
<property name="excludes" value="java.io,java.net,java.lang.Math"/>
<property name="allowClassImports" value="false"/>
<property name="allowStaticMemberImports" value="true"/>
</module>
<module name="IllegalImport"/>
<module name="RedundantImport"/>
<module name="UnusedImports"/>
<module name="JavadocType">
<property name="allowUnknownTags" value="true"/>
<property name="allowMissingParamTags" value="true"/>
<message key="javadoc.missing" value="Class Comments: Missing Javadoc Comments"/>
</module>
<!-- Do not scan method annotations for now -->
<!--<module name="JavadocMethod">
<property name="tokens" value="METHOD_DEF"/>
<property name="allowMissingPropertyJavadoc" value="true"/>
<message key="javadoc.missing" value="Method Comments: Missing Javadoc Comments"/>
</module>-->
<module name="LocalFinalVariableName"/>
<module name="LocalVariableName"/>
<module name="PackageName">
<property name="format" value="^[a-z]+(\.[a-z][a-z0-9]*)*$" />
</module>
<module name="StaticVariableName"/>
<module name="TypeName"/>
<module name="MemberName"/>
<module name="MethodName"/>
<module name="ParameterName "/>
<module name="ConstantName"/>
<module name="ArrayTypeStyle"/>
<module name="UpperEll"/>
<module name="LineLength">
<property name="max" value="200"/>
</module>
<module name="MethodLength">
<property name="tokens" value="METHOD_DEF"/>
<property name="max" value="150"/>
</module>
<module name="ParameterNumber">
<property name="max" value="5"/>
<property name="ignoreOverriddenMethods" value="true"/>
<property name="tokens" value="METHOD_DEF"/>
</module>
<module name="MethodParamPad"/>
<module name="TypecastParenPad"/>
<module name="NoWhitespaceAfter"/>
<module name="NoWhitespaceBefore"/>
<module name="OperatorWrap"/>
<module name="ParenPad"/>
<module name="WhitespaceAfter"/>
<module name="WhitespaceAround"/>
<module name="ModifierOrder"/>
<module name="RedundantModifier"/>
<module name="AvoidNestedBlocks"/>
<module name="EmptyBlock"/>
<module name="LeftCurly"/>
<module name="NeedBraces"/>
<module name="RightCurly"/>
<module name="EmptyStatement"/>
<module name="EqualsHashCode"/>
<module name="IllegalInstantiation"/>
<module name="InnerAssignment"/>
<module name="MagicNumber">
<property name="ignoreNumbers" value="0, 1, 2"/>
<property name="ignoreAnnotation" value="true"/>
<property name="ignoreHashCodeMethod" value="true"/>
<property name="ignoreFieldDeclaration" value="true"/>
</module>
<module name="MissingSwitchDefault"/>
<module name="SimplifyBooleanExpression"/>
<module name="SimplifyBooleanReturn"/>
<module name="FinalClass"/>
<module name="InterfaceIsType"/>
<module name="VisibilityModifier">
<property name="packageAllowed" value="true"/>
<property name="protectedAllowed" value="true"/>
</module>
<module name="StringLiteralEquality"/>
<module name="NestedForDepth">
<property name="max" value="3"/>
</module>
<module name="NestedIfDepth">
<property name="max" value="4"/>
</module>
<module name="UncommentedMain">
<property name="excludedClasses" value=".*Application$"/>
</module>
<module name="Regexp">
<property name="format" value="System\.out\.println"/>
<property name="illegalPattern" value="true"/>
</module>
<module name="ReturnCount">
<property name="max" value="4"/>
</module>
<module name="NestedTryDepth ">
<property name="max" value="4"/>
</module>
<module name="SuperFinalize"/>
<module name="SuperClone"/>
</module>
</module>

@ -0,0 +1,28 @@
<?xml version="1.0"?>
<!--
~ 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.
-->
<!DOCTYPE suppressions PUBLIC
"-//Puppy Crawl//DTD Suppressions 1.1//EN"
"http://www.puppycrawl.com/dtds/suppressions_1_1.dtd">
<suppressions>
<suppress checks="MagicNumber" files="ResizableCapacityLinkedBlockingQueue.java"/>
<suppress checks="InnerAssignment" files="ResizableCapacityLinkedBlockingQueue.java"/>
<suppress checks="StaticVariableName" files="ApplicationContextHolder.java"/>
<suppress checks="StaticVariableName" files="JacksonHandler.java"/>
<suppress checks="MagicNumber" files="ByteConvertUtil.java"/>
</suppressions>

@ -18,6 +18,7 @@
* limitations under the License.
*/
-->
<profiles version="13">
<profile kind="CodeFormatterProfile" name="'Hippo4j Current'" version="13">
<setting id="org.eclipse.jdt.core.compiler.source" value="1.8"/>

@ -1,7 +0,0 @@
---
sidebar_position: 2
---
# 阻塞队列自定义
同拒绝策略自定义。

@ -0,0 +1,45 @@
---
sidebar_position: 4
---
# 参数默认配置
曾有多名小伙伴反馈说,项目中线程池一多,配置文件中配置就显得很臃肿。为此 hippo4j-config 开发出了动态线程池默认配置。
```yaml
spring:
dynamic:
thread-pool:
default-executor:
core-pool-size: 4
maximum-pool-size: 6
blocking-queue: ResizableCapacityLinkedBlockingQueue
queue-capacity: 1024
execute-time-out: 1000
keep-alive-time: 9999
rejected-handler: AbortPolicy
active-alarm: 90
capacity-alarm: 85
alarm: true
allow-core-thread-time-out: true
notify:
interval: 5
receives: chen.ma
executors:
- thread-pool-id: message-produce
- thread-pool-id: message-consume
core-pool-size: 80
maximum-pool-size: 100
execute-time-out: 1000
notify:
interval: 6
receives: chen.ma
```
`spring.dynamic.thread-pool.executors` 层级下,仅需要配置 `thread-pool-id`,其余配置从 `spring.dynamic.thread-pool.default-executor` 读取。
如果 `spring.dynamic.thread-pool.executors` 下配置和 `spring.dynamic.thread-pool.default-executor` 冲突,以前者为主。
通过该自定义配置方式,可减少大量重复线程池参数配置项,提高核心配置简洁度。
提示:`spring.dynamic.thread-pool.default-executor` 层级下参数,不提供动态刷新功能。

@ -1,5 +1,5 @@
---
sidebar_position: 2
sidebar_position: 3
---
# 线程池监控

@ -0,0 +1,80 @@
---
sidebar_position: 3
---
# 个性化配置
以下所述特性自 hippo4j-config v1.4.2 及以上版本提供,由 hippo4j 核心开发者 [@pizihao](https://github.com/pizihao) 完成相应功能开发。
## 需求背景
**1容器及三方框架线程池自定义启用**
最初设计容器线程池和三方框架线程池的动态变更是和启动无关的。也就是说,启动时不会根据配置文件中相关参数去修改两者对应的线程池配置。
这么设计的初衷是因为,不想让 hippo4j 过多的去介入框架原有的功能。因为容器和三方框架都支持线程池参数的自定义。
也就造成,可能你在配置中心配置了对应的容器和三方框架线程池参数,启动时是无效的。但当修改配置文件任一配置,容器和三方框架线程池配置将生效。
为了更好的用户体验,决定加入启用标识来控制:是否在项目初始化启动时,对容器和三方框架线程池参数进行修改。
**2客户端集群个性化配置**
大家都知道hippo4j-config 是依赖配置中心做线程池配置动态变更。这种模式有一种缺点:改动配置文件后,所有客户端都会变更。
有些小伙伴希望 hippo4j-config 能够像 hippo4j-server 一样,能够针对单独的客户端进行配置变更。
## 容器及三方框架线程池自定义启用
容器及三方框架线程池添加启用配置,为了保持统一,动态线程池配置中也有该参数配置。配置项默认开启。
```yaml
spring:
dynamic:
thread-pool:
tomcat:
enable: true
executors:
- thread-pool-id: message-consume
enable: false
adapter-executors:
- threadPoolKey: 'input'
enable: true
```
## 客户端集群个性化配置
分别在动态线程池、容器线程池以及三方框架线程池配置下增加 `nodes` 配置节点,通过该配置可匹配需要变更的节点。
```yaml
spring:
dynamic:
thread-pool:
tomcat:
nodes: 192.168.1.5:*,192.168.1.6:8080
executors:
- thread-pool-id: message-consume
nodes: 192.168.1.5:*
adapter-executors:
- threadPoolKey: 'input'
nodes: 192.168.1.5:*
```
来一段代码方法中的注释,大家就基本明白如何使用了。
```java
/**
* Matching nodes<br>
* nodes is ip + port.Get 'nodes' in the new Properties,Compare this with the ip + port of Application.<br>
* support prefix pattern matching. e.g: <br>
* <ul>
* <li>192.168.1.5:* -- Matches all ports of 192.168.1.5</li>
* <li>192.168.1.*:2009 -- Matches 2009 port of 192.168.1.*</li>
* <li>* -- all</li>
* <li>empty -- all</li>
* </ul>
* The format of ip + port is ip : port.
*/
```
`nodes` 可与 `enable` 同时使用。如此,基于配置中心的动态线程池实现方式,将能够更方便的支持个性化需求。

@ -16,7 +16,7 @@ Nacos、Apollo、Zookeeper、ETCD 配置中心任选其一。
</dependency>
```
启动类上添加注解 @EnableDynamicThreadPool
启动类上添加注解 `@EnableDynamicThreadPool`
```java
@SpringBootApplication

@ -4,11 +4,6 @@ sidebar_position: 1
# 加群沟通
扫码添加微信,备注:`hippo4j`,邀您加入群聊。
对于这个项目,是否有什么不一样看法,欢迎在 Issue 一起沟通交流;或者添加小编微信进交流群。
![](https://images-machen.oss-cn-beijing.aliyuncs.com/64E583A0-B1DD-49A3-9AEC-8D246E9D5C12.PNG?x-oss-process=image/resize,h_500,w_800)
![](https://images-machen.oss-cn-beijing.aliyuncs.com/185774220-c11951f9-e130-4d60-8204-afb5c51d4401.png)

@ -44,7 +44,7 @@ sidebar_position: 3
> 更聪明问题X.org 6.8.1 的鼠标指针,在某牌显卡 MV1005 芯片组环境下 - 会变形。
### <a name="使用清晰、正确、精准且合乎语法的语句">使用清晰、正确、精准且合乎语法的语句</a>
### 使用清晰、正确、精准且合乎语法的语句
我们从经验中发现,粗心的提问者通常也会粗心地写程序与思考(我敢打包票)。回答粗心大意者的问题很不值得,我们宁愿把时间耗在别处。

@ -22,12 +22,12 @@ import cn.hippo4j.adapter.base.ThreadPoolAdapterParameter;
import cn.hippo4j.adapter.base.ThreadPoolAdapterState;
import com.alibaba.dubbo.common.extension.ExtensionLoader;
import com.alibaba.dubbo.common.store.DataStore;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.event.ApplicationStartedEvent;
import org.springframework.context.ApplicationListener;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
@ -41,7 +41,7 @@ import static cn.hippo4j.common.constant.ChangeThreadPoolConstants.CHANGE_DELIMI
@Slf4j
public class AlibabaDubboThreadPoolAdapter implements ThreadPoolAdapter, ApplicationListener<ApplicationStartedEvent> {
private final Map<String, ThreadPoolExecutor> DUBBO_PROTOCOL_EXECUTOR = Maps.newHashMap();
private final Map<String, ThreadPoolExecutor> DUBBO_PROTOCOL_EXECUTOR = new HashMap<>();
@Override
public String mark() {

@ -18,10 +18,10 @@
package cn.hippo4j.adapter.base;
import cn.hippo4j.common.config.ApplicationContextHolder;
import com.google.common.collect.Maps;
import org.springframework.beans.factory.InitializingBean;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* Thread-pool adapter bean container.
@ -31,7 +31,7 @@ public class ThreadPoolAdapterBeanContainer implements InitializingBean {
/**
* Store three-party thread pool framework bean instances.
*/
public static final Map<String, ThreadPoolAdapter> THREAD_POOL_ADAPTER_BEAN_CONTAINER = Maps.newConcurrentMap();
public static final Map<String, ThreadPoolAdapter> THREAD_POOL_ADAPTER_BEAN_CONTAINER = new ConcurrentHashMap<>();
@Override
public void afterPropertiesSet() throws Exception {

@ -21,7 +21,6 @@ import cn.hippo4j.adapter.base.ThreadPoolAdapter;
import cn.hippo4j.adapter.base.ThreadPoolAdapterParameter;
import cn.hippo4j.adapter.base.ThreadPoolAdapterState;
import cn.hippo4j.common.toolkit.ReflectUtil;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.common.Version;
import org.apache.dubbo.common.extension.ExtensionLoader;
@ -31,6 +30,7 @@ import org.springframework.boot.context.event.ApplicationStartedEvent;
import org.springframework.context.ApplicationListener;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentMap;
@ -45,7 +45,7 @@ import static cn.hippo4j.common.constant.ChangeThreadPoolConstants.CHANGE_DELIMI
@Slf4j
public class DubboThreadPoolAdapter implements ThreadPoolAdapter, ApplicationListener<ApplicationStartedEvent> {
private final Map<String, ThreadPoolExecutor> DUBBO_PROTOCOL_EXECUTOR = Maps.newHashMap();
private final Map<String, ThreadPoolExecutor> DUBBO_PROTOCOL_EXECUTOR = new HashMap<>();
@Override
public String mark() {

@ -20,8 +20,6 @@ package cn.hippo4j.adapter.hystrix;
import cn.hippo4j.adapter.base.*;
import cn.hippo4j.common.config.ApplicationContextHolder;
import cn.hippo4j.common.toolkit.CollectionUtil;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.netflix.hystrix.HystrixThreadPool;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.event.ApplicationStartedEvent;
@ -29,6 +27,7 @@ import org.springframework.context.ApplicationListener;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@ -49,7 +48,7 @@ public class HystrixThreadPoolAdapter implements ThreadPoolAdapter, ApplicationL
private static final String THREAD_POOLS_FIELD = "threadPools";
private final Map<String, ThreadPoolExecutor> HYSTRIX_CONSUME_EXECUTOR = Maps.newHashMap();
private final Map<String, ThreadPoolExecutor> HYSTRIX_CONSUME_EXECUTOR = new HashMap<>();
private ThreadPoolAdapterScheduler threadPoolAdapterScheduler;
@ -112,7 +111,7 @@ public class HystrixThreadPoolAdapter implements ThreadPoolAdapter, ApplicationL
// Periodically refresh registration.
ThreadPoolAdapterRegisterAction threadPoolAdapterRegisterAction = ApplicationContextHolder.getBean(ThreadPoolAdapterRegisterAction.class);
Map<String, ? extends HystrixThreadPoolAdapter> beansOfType = ApplicationContextHolder.getBeansOfType(this.getClass());
Map<String, ThreadPoolAdapter> map = Maps.newHashMap(beansOfType);
Map<String, ThreadPoolAdapter> map = new HashMap<>(beansOfType);
ThreadPoolAdapterRegisterTask threadPoolAdapterRegisterTask = new ThreadPoolAdapterRegisterTask(scheduler, taskIntervalSeconds, map, threadPoolAdapterRegisterAction);
scheduler.schedule(threadPoolAdapterRegisterTask, threadPoolAdapterScheduler.getTaskIntervalSeconds(), TimeUnit.SECONDS);
}
@ -207,7 +206,7 @@ public class HystrixThreadPoolAdapter implements ThreadPoolAdapter, ApplicationL
ThreadPoolAdapterRegisterAction threadPoolAdapterRegisterAction;
private List<ThreadPoolAdapterCacheConfig> cacheConfigList = Lists.newArrayList();
private List<ThreadPoolAdapterCacheConfig> cacheConfigList = new ArrayList<>();
public ThreadPoolAdapterRegisterTask(ScheduledExecutorService scheduler, int taskIntervalSeconds,
Map<String, ThreadPoolAdapter> threadPoolAdapterMap,

@ -17,7 +17,7 @@
package cn.hippo4j.adapter.hystrix;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import cn.hippo4j.common.design.builder.ThreadFactoryBuilder;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.ScheduledExecutorService;
@ -36,8 +36,8 @@ public class ThreadPoolAdapterScheduler {
public ThreadPoolAdapterScheduler() {
scheduler = new ScheduledThreadPoolExecutor(2,
new ThreadFactoryBuilder()
.setNameFormat("threadPoolAdapter")
.setDaemon(true)
.prefix("threadPoolAdapter")
.daemon(true)
.build());
}

@ -21,17 +21,13 @@ import cn.hippo4j.adapter.base.ThreadPoolAdapter;
import cn.hippo4j.adapter.base.ThreadPoolAdapterParameter;
import cn.hippo4j.adapter.base.ThreadPoolAdapterState;
import cn.hippo4j.common.toolkit.ReflectUtil;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.connection.AbstractConnectionFactory;
import org.springframework.boot.context.event.ApplicationStartedEvent;
import org.springframework.context.ApplicationListener;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
@ -50,7 +46,7 @@ public class RabbitMQThreadPoolAdapter implements ThreadPoolAdapter, Application
private final Map<String, AbstractConnectionFactory> abstractConnectionFactoryMap;
private final Map<String, ThreadPoolExecutor> RABBITMQ_THREAD_POOL_TASK_EXECUTOR = Maps.newHashMap();
private final Map<String, ThreadPoolExecutor> RABBITMQ_THREAD_POOL_TASK_EXECUTOR = new HashMap<>();
@Override
public String mark() {
@ -71,7 +67,7 @@ public class RabbitMQThreadPoolAdapter implements ThreadPoolAdapter, Application
@Override
public List<ThreadPoolAdapterState> getThreadPoolStates() {
List<ThreadPoolAdapterState> adapterStateList = Lists.newArrayList();
List<ThreadPoolAdapterState> adapterStateList = new ArrayList<>();
RABBITMQ_THREAD_POOL_TASK_EXECUTOR.forEach(
(key, val) -> adapterStateList.add(getThreadPoolState(key)));
return adapterStateList;

@ -22,14 +22,15 @@ import cn.hippo4j.adapter.base.ThreadPoolAdapterParameter;
import cn.hippo4j.adapter.base.ThreadPoolAdapterState;
import cn.hippo4j.common.config.ApplicationContextHolder;
import cn.hippo4j.common.toolkit.ReflectUtil;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.impl.consumer.ConsumeMessageService;
import org.apache.rocketmq.spring.support.DefaultRocketMQListenerContainer;
import org.springframework.boot.context.event.ApplicationStartedEvent;
import org.springframework.context.ApplicationListener;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ThreadPoolExecutor;
@ -42,7 +43,7 @@ import static cn.hippo4j.common.constant.ChangeThreadPoolConstants.CHANGE_DELIMI
@Slf4j
public class RocketMQThreadPoolAdapter implements ThreadPoolAdapter, ApplicationListener<ApplicationStartedEvent> {
private final Map<String, ThreadPoolExecutor> ROCKET_MQ_CONSUME_EXECUTOR = Maps.newHashMap();
private final Map<String, ThreadPoolExecutor> ROCKET_MQ_CONSUME_EXECUTOR = new HashMap<>();
@Override
public String mark() {
@ -65,7 +66,7 @@ public class RocketMQThreadPoolAdapter implements ThreadPoolAdapter, Application
@Override
public List<ThreadPoolAdapterState> getThreadPoolStates() {
List<ThreadPoolAdapterState> adapterStateList = Lists.newArrayList();
List<ThreadPoolAdapterState> adapterStateList = new ArrayList<>();
ROCKET_MQ_CONSUME_EXECUTOR.forEach(
(key, val) -> adapterStateList.add(getThreadPoolState(key)));
return adapterStateList;

@ -23,8 +23,6 @@ import cn.hippo4j.adapter.base.ThreadPoolAdapterState;
import cn.hippo4j.common.config.ApplicationContextHolder;
import cn.hippo4j.common.toolkit.CollectionUtil;
import cn.hippo4j.common.toolkit.ReflectUtil;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer;
import org.springframework.amqp.rabbit.listener.DirectMessageListenerContainer;
@ -36,10 +34,7 @@ import org.springframework.cloud.stream.binding.InputBindingLifecycle;
import org.springframework.context.ApplicationListener;
import org.springframework.integration.amqp.inbound.AmqpInboundChannelAdapter;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.*;
import static cn.hippo4j.common.constant.ChangeThreadPoolConstants.CHANGE_DELIMITER;
@ -49,7 +44,7 @@ import static cn.hippo4j.common.constant.ChangeThreadPoolConstants.CHANGE_DELIMI
@Slf4j
public class SpringCloudStreamRabbitMQThreadPoolAdapter implements ThreadPoolAdapter, ApplicationListener<ApplicationStartedEvent> {
private final Map<String, AbstractMessageListenerContainer> ROCKET_MQ_SPRING_CLOUD_STREAM_CONSUME_EXECUTOR = Maps.newHashMap();
private final Map<String, AbstractMessageListenerContainer> ROCKET_MQ_SPRING_CLOUD_STREAM_CONSUME_EXECUTOR = new HashMap<>();
@Override
public String mark() {
@ -84,7 +79,7 @@ public class SpringCloudStreamRabbitMQThreadPoolAdapter implements ThreadPoolAda
@Override
public List<ThreadPoolAdapterState> getThreadPoolStates() {
List<ThreadPoolAdapterState> adapterStateList = Lists.newArrayList();
List<ThreadPoolAdapterState> adapterStateList = new ArrayList<>();
ROCKET_MQ_SPRING_CLOUD_STREAM_CONSUME_EXECUTOR.forEach(
(key, val) -> adapterStateList.add(getThreadPoolState(key)));
return adapterStateList;

@ -25,8 +25,6 @@ import cn.hippo4j.common.toolkit.CollectionUtil;
import cn.hippo4j.common.toolkit.ReflectUtil;
import com.alibaba.cloud.stream.binder.rocketmq.consuming.RocketMQListenerBindingContainer;
import com.alibaba.cloud.stream.binder.rocketmq.integration.RocketMQInboundChannelAdapter;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.impl.consumer.ConsumeMessageConcurrentlyService;
@ -37,10 +35,7 @@ import org.springframework.cloud.stream.binder.DefaultBinding;
import org.springframework.cloud.stream.binding.InputBindingLifecycle;
import org.springframework.context.ApplicationListener;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.*;
import java.util.concurrent.ThreadPoolExecutor;
import static cn.hippo4j.common.constant.ChangeThreadPoolConstants.CHANGE_DELIMITER;
@ -51,7 +46,7 @@ import static cn.hippo4j.common.constant.ChangeThreadPoolConstants.CHANGE_DELIMI
@Slf4j
public class SpringCloudStreamRocketMQThreadPoolAdapter implements ThreadPoolAdapter, ApplicationListener<ApplicationStartedEvent> {
private final Map<String, ThreadPoolExecutor> ROCKET_MQ_SPRING_CLOUD_STREAM_CONSUME_EXECUTOR = Maps.newHashMap();
private final Map<String, ThreadPoolExecutor> ROCKET_MQ_SPRING_CLOUD_STREAM_CONSUME_EXECUTOR = new HashMap<>();
@Override
public String mark() {
@ -74,7 +69,7 @@ public class SpringCloudStreamRocketMQThreadPoolAdapter implements ThreadPoolAda
@Override
public List<ThreadPoolAdapterState> getThreadPoolStates() {
List<ThreadPoolAdapterState> adapterStateList = Lists.newArrayList();
List<ThreadPoolAdapterState> adapterStateList = new ArrayList<>();
ROCKET_MQ_SPRING_CLOUD_STREAM_CONSUME_EXECUTOR.forEach(
(key, val) -> adapterStateList.add(getThreadPoolState(key)));
return adapterStateList;

@ -24,12 +24,13 @@ import cn.hippo4j.common.model.ThreadPoolParameterInfo;
import cn.hippo4j.common.model.ThreadPoolRunStateInfo;
import cn.hippo4j.common.toolkit.CalculateUtil;
import cn.hippo4j.core.executor.state.AbstractThreadPoolRuntime;
import cn.hutool.core.date.DateUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.web.embedded.tomcat.TomcatWebServer;
import org.springframework.boot.web.server.WebServer;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executor;
@ -138,7 +139,7 @@ public class TomcatWebThreadPoolHandler extends AbstractWebThreadPoolService {
runStateInfo.setQueueRemainingCapacity(remainingCapacity);
runStateInfo.setLargestPoolSize(largestPoolSize);
runStateInfo.setCompletedTaskCount(completedTaskCount);
runStateInfo.setClientLastRefreshTime(DateUtil.formatDateTime(new Date()));
runStateInfo.setClientLastRefreshTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
runStateInfo.setTimestamp(System.currentTimeMillis());
String rejectedExecutionHandlerName = executor instanceof ThreadPoolExecutor ? ((ThreadPoolExecutor) executor).getRejectedExecutionHandler().getClass().getSimpleName()
: tomcatThreadPoolExecutor.getRejectedExecutionHandler().getClass().getSimpleName();

@ -17,6 +17,13 @@
package cn.hippo4j.adapter.web;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Objects;
import java.util.concurrent.Executor;
import cn.hippo4j.common.constant.ChangeThreadPoolConstants;
import cn.hippo4j.common.model.ThreadPoolBaseInfo;
import cn.hippo4j.common.model.ThreadPoolParameter;
@ -24,20 +31,14 @@ import cn.hippo4j.common.model.ThreadPoolParameterInfo;
import cn.hippo4j.common.model.ThreadPoolRunStateInfo;
import cn.hippo4j.common.toolkit.CalculateUtil;
import cn.hippo4j.core.executor.DynamicThreadPoolExecutor;
import cn.hutool.core.date.DateUtil;
import io.undertow.Undertow;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.web.embedded.undertow.UndertowServletWebServer;
import org.springframework.boot.web.server.WebServer;
import org.springframework.util.ReflectionUtils;
import org.xnio.Options;
import org.xnio.XnioWorker;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.Objects;
import java.util.concurrent.Executor;
import org.springframework.boot.web.embedded.undertow.UndertowServletWebServer;
import org.springframework.boot.web.server.WebServer;
import org.springframework.util.ReflectionUtils;
/**
* Undertow web thread pool handler.
@ -128,7 +129,7 @@ public class UndertowWebThreadPoolHandler extends AbstractWebThreadPoolService {
? ((DynamicThreadPoolExecutor) fieldObject).getRejectCountNum()
: -1L;
stateInfo.setRejectCount(rejectCount);
stateInfo.setClientLastRefreshTime(DateUtil.formatDateTime(new Date()));
stateInfo.setClientLastRefreshTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
stateInfo.setTimestamp(System.currentTimeMillis());
return stateInfo;
}

@ -20,10 +20,12 @@ package cn.hippo4j.adapter.web;
import cn.hippo4j.common.model.ThreadPoolRunStateInfo;
import cn.hippo4j.common.toolkit.ByteConvertUtil;
import cn.hippo4j.core.executor.state.AbstractThreadPoolRuntime;
import cn.hutool.core.util.StrUtil;
import cn.hutool.system.RuntimeInfo;
import lombok.extern.slf4j.Slf4j;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryUsage;
/**
* Web thread pool run state handler.
*/
@ -32,16 +34,20 @@ public class WebThreadPoolRunStateHandler extends AbstractThreadPoolRuntime {
@Override
public ThreadPoolRunStateInfo supplement(ThreadPoolRunStateInfo poolRunStateInfo) {
RuntimeInfo runtimeInfo = new RuntimeInfo();
String memoryProportion = StrUtil.builder(
"已分配: ",
ByteConvertUtil.getPrintSize(runtimeInfo.getTotalMemory()),
" / 最大可用: ",
ByteConvertUtil.getPrintSize(runtimeInfo.getMaxMemory())).toString();
MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
MemoryUsage heapMemoryUsage = memoryMXBean.getHeapMemoryUsage();
long used = heapMemoryUsage.getUsed();
long max = heapMemoryUsage.getMax();
String memoryProportion = new StringBuilder()
.append("已分配: ")
.append(ByteConvertUtil.getPrintSize(used))
.append(" / 最大可用: ")
.append(ByteConvertUtil.getPrintSize(max))
.toString();
poolRunStateInfo.setCurrentLoad(poolRunStateInfo.getCurrentLoad() + "%");
poolRunStateInfo.setPeakLoad(poolRunStateInfo.getPeakLoad() + "%");
poolRunStateInfo.setMemoryProportion(memoryProportion);
poolRunStateInfo.setFreeMemory(ByteConvertUtil.getPrintSize(runtimeInfo.getFreeMemory()));
poolRunStateInfo.setFreeMemory(ByteConvertUtil.getPrintSize(Math.subtractExact(max, used)));
return poolRunStateInfo;
}
}

@ -46,11 +46,6 @@
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>

@ -21,8 +21,8 @@ import cn.hippo4j.auth.model.biz.user.JwtUser;
import cn.hippo4j.auth.model.biz.user.LoginUser;
import cn.hippo4j.auth.toolkit.JwtTokenUtil;
import cn.hippo4j.auth.toolkit.ReturnT;
import cn.hippo4j.common.toolkit.JSONUtil;
import cn.hippo4j.common.web.base.Results;
import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.AuthenticationManager;
@ -34,7 +34,6 @@ import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@ -100,7 +99,7 @@ public class JWTAuthenticationFilter extends UsernamePasswordAuthenticationFilte
Map<String, Object> maps = new HashMap(MAP_INITIAL_CAPACITY);
maps.put("data", JwtTokenUtil.TOKEN_PREFIX + token);
maps.put("roles", role.split(SPLIT_COMMA));
response.getWriter().write(JSONUtil.toJsonStr(Results.success(maps)));
response.getWriter().write(JSONUtil.toJSONString(Results.success(maps)));
} finally {
rememberMe.remove();
}
@ -109,6 +108,6 @@ public class JWTAuthenticationFilter extends UsernamePasswordAuthenticationFilte
@Override
protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException {
response.setCharacterEncoding("UTF-8");
response.getWriter().write(JSONUtil.toJsonStr(new ReturnT(-1, "Server Error")));
response.getWriter().write(JSONUtil.toJSONString(new ReturnT(-1, "Server Error")));
}
}

@ -20,10 +20,10 @@ package cn.hippo4j.auth.filter;
import cn.hippo4j.auth.security.JwtTokenManager;
import cn.hippo4j.auth.toolkit.JwtTokenUtil;
import cn.hippo4j.common.toolkit.JSONUtil;
import cn.hippo4j.common.toolkit.StringUtil;
import cn.hippo4j.common.toolkit.UserContext;
import cn.hippo4j.common.web.base.Results;
import cn.hippo4j.common.web.exception.ServiceException;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
@ -61,7 +61,7 @@ public class JWTAuthorizationFilter extends BasicAuthenticationFilter {
FilterChain chain) throws IOException, ServletException {
// Token when verifying client interaction.
String accessToken = request.getParameter(ACCESS_TOKEN);
if (StrUtil.isNotBlank(accessToken)) {
if (StringUtil.isNotBlank(accessToken)) {
tokenManager.validateToken(accessToken);
Authentication authentication = this.tokenManager.getAuthentication(accessToken);
SecurityContextHolder.getContext().setAuthentication(authentication);
@ -85,7 +85,7 @@ public class JWTAuthorizationFilter extends BasicAuthenticationFilter {
String resultStatus = "-1";
if (ex instanceof ServiceException) {
ServiceException serviceException = (ServiceException) ex;
resultStatus = serviceException.errorCode.getCode();
resultStatus = serviceException.getErrorCode().getCode();
}
response.getWriter().write(JSONUtil.toJSONString(Results.failure(resultStatus, ex.getMessage())));
response.getWriter().flush();

@ -17,7 +17,7 @@
package cn.hippo4j.auth.security;
import cn.hutool.core.util.StrUtil;
import cn.hippo4j.common.toolkit.StringUtil;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
@ -64,7 +64,7 @@ public class JwtTokenManager {
Claims claims = Jwts.parser().setSigningKey(SECRET).parseClaimsJws(token).getBody();
List<GrantedAuthority> authorities = AuthorityUtils
.commaSeparatedStringToAuthorityList((String) claims.get(AUTHORITIES_KEY));
User principal = new User(claims.getSubject(), StrUtil.EMPTY, authorities);
return new UsernamePasswordAuthenticationToken(principal, StrUtil.EMPTY, authorities);
User principal = new User(claims.getSubject(), StringUtil.EMPTY, authorities);
return new UsernamePasswordAuthenticationToken(principal, StringUtil.EMPTY, authorities);
}
}

@ -21,8 +21,8 @@ import cn.hippo4j.auth.mapper.PermissionMapper;
import cn.hippo4j.auth.model.biz.permission.PermissionQueryPageReqDTO;
import cn.hippo4j.auth.model.biz.permission.PermissionRespDTO;
import cn.hippo4j.auth.service.PermissionService;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import cn.hippo4j.common.toolkit.BeanUtil;
import cn.hippo4j.common.toolkit.StringUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
@ -44,8 +44,7 @@ public class PermissionServiceImpl implements PermissionService {
public IPage<PermissionRespDTO> listPermission(int pageNo, int pageSize) {
PermissionQueryPageReqDTO queryPage = new PermissionQueryPageReqDTO(pageNo, pageSize);
IPage<PermissionInfo> selectPage = permissionMapper.selectPage(queryPage, null);
return selectPage.convert(each -> BeanUtil.toBean(each, PermissionRespDTO.class));
return selectPage.convert(each -> BeanUtil.convert(each, PermissionRespDTO.class));
}
@Override
@ -68,9 +67,9 @@ public class PermissionServiceImpl implements PermissionService {
@Override
public void deletePermission(String role, String resource, String action) {
LambdaUpdateWrapper<PermissionInfo> updateWrapper = Wrappers.lambdaUpdate(PermissionInfo.class)
.eq(StrUtil.isNotBlank(role), PermissionInfo::getRole, role)
.eq(StrUtil.isNotBlank(resource), PermissionInfo::getResource, resource)
.eq(StrUtil.isNotBlank(action), PermissionInfo::getAction, action);
.eq(StringUtil.isNotBlank(role), PermissionInfo::getRole, role)
.eq(StringUtil.isNotBlank(resource), PermissionInfo::getResource, resource)
.eq(StringUtil.isNotBlank(action), PermissionInfo::getAction, action);
permissionMapper.delete(updateWrapper);
}
}

@ -22,9 +22,9 @@ import cn.hippo4j.auth.model.biz.role.RoleQueryPageReqDTO;
import cn.hippo4j.auth.model.biz.role.RoleRespDTO;
import cn.hippo4j.auth.service.PermissionService;
import cn.hippo4j.auth.service.RoleService;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hippo4j.common.toolkit.BeanUtil;
import cn.hippo4j.common.toolkit.CollectionUtil;
import cn.hippo4j.common.toolkit.StringUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
@ -51,7 +51,7 @@ public class RoleServiceImpl implements RoleService {
public IPage<RoleRespDTO> listRole(int pageNo, int pageSize) {
RoleQueryPageReqDTO queryPage = new RoleQueryPageReqDTO(pageNo, pageSize);
IPage<RoleInfo> selectPage = roleMapper.selectPage(queryPage, null);
return selectPage.convert(each -> BeanUtil.toBean(each, RoleRespDTO.class));
return selectPage.convert(each -> BeanUtil.convert(each, RoleRespDTO.class));
}
@Override
@ -70,14 +70,14 @@ public class RoleServiceImpl implements RoleService {
@Override
public void deleteRole(String role, String userName) {
List<String> roleStrList = CollUtil.toList(role);
if (StrUtil.isBlank(role)) {
List<String> roleStrList = CollectionUtil.toList(role);
if (StringUtil.isBlank(role)) {
LambdaQueryWrapper<RoleInfo> queryWrapper = Wrappers.lambdaQuery(RoleInfo.class).eq(RoleInfo::getUserName, userName);
roleStrList = roleMapper.selectList(queryWrapper).stream().map(RoleInfo::getRole).collect(Collectors.toList());
}
LambdaUpdateWrapper<RoleInfo> updateWrapper = Wrappers.lambdaUpdate(RoleInfo.class)
.eq(StrUtil.isNotBlank(role), RoleInfo::getRole, role)
.eq(StrUtil.isNotBlank(userName), RoleInfo::getUserName, userName);
.eq(StringUtil.isNotBlank(role), RoleInfo::getRole, role)
.eq(StringUtil.isNotBlank(userName), RoleInfo::getUserName, userName);
roleMapper.delete(updateWrapper);
roleStrList.forEach(each -> permissionService.deletePermission(each, "", ""));
}

@ -24,10 +24,9 @@ import cn.hippo4j.auth.model.biz.user.UserReqDTO;
import cn.hippo4j.auth.model.biz.user.UserRespDTO;
import cn.hippo4j.auth.service.RoleService;
import cn.hippo4j.auth.service.UserService;
import cn.hippo4j.common.toolkit.BeanUtil;
import cn.hippo4j.common.toolkit.StringUtil;
import cn.hippo4j.common.web.exception.ServiceException;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
@ -59,7 +58,7 @@ public class UserServiceImpl implements UserService {
LambdaQueryWrapper<UserInfo> queryWrapper = Wrappers.lambdaQuery(UserInfo.class)
.eq(StringUtil.isNotBlank(reqDTO.getUserName()), UserInfo::getUserName, reqDTO.getUserName());
IPage<UserInfo> selectPage = userMapper.selectPage(reqDTO, queryWrapper);
return selectPage.convert(each -> BeanUtil.toBean(each, UserRespDTO.class));
return selectPage.convert(each -> BeanUtil.convert(each, UserRespDTO.class));
}
@Override
@ -71,16 +70,16 @@ public class UserServiceImpl implements UserService {
throw new RuntimeException("用户名重复");
}
reqDTO.setPassword(bCryptPasswordEncoder.encode(reqDTO.getPassword()));
UserInfo insertUser = BeanUtil.toBean(reqDTO, UserInfo.class);
UserInfo insertUser = BeanUtil.convert(reqDTO, UserInfo.class);
userMapper.insert(insertUser);
}
@Override
public void updateUser(UserReqDTO reqDTO) {
if (StrUtil.isNotBlank(reqDTO.getPassword())) {
if (StringUtil.isNotBlank(reqDTO.getPassword())) {
reqDTO.setPassword(bCryptPasswordEncoder.encode(reqDTO.getPassword()));
}
UserInfo updateUser = BeanUtil.toBean(reqDTO, UserInfo.class);
UserInfo updateUser = BeanUtil.convert(reqDTO, UserInfo.class);
LambdaUpdateWrapper<UserInfo> updateWrapper = Wrappers.lambdaUpdate(UserInfo.class)
.eq(UserInfo::getUserName, reqDTO.getUserName());
userMapper.update(updateUser, updateWrapper);
@ -108,7 +107,7 @@ public class UserServiceImpl implements UserService {
Wrapper queryWrapper = Wrappers.lambdaQuery(UserInfo.class).eq(UserInfo::getUserName, reqDTO.getUserName());
UserInfo userInfo = userMapper.selectOne(queryWrapper);
UserRespDTO respUser = Optional.ofNullable(userInfo)
.map(each -> BeanUtil.toBean(each, UserRespDTO.class))
.map(each -> BeanUtil.convert(each, UserRespDTO.class))
.orElseThrow(() -> new ServiceException("查询无此用户, 可以尝试清空缓存或退出登录."));
return respUser;
}

@ -62,19 +62,19 @@
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<groupId>com.github.dozermapper</groupId>
<artifactId>dozer-core</artifactId>
</dependency>
</dependencies>

@ -32,6 +32,9 @@ public interface ClientCloseHookExecute {
*/
void closeHook(ClientCloseHookReq req);
/**
* Client close hook req.
*/
@Data
@Accessors(chain = true)
class ClientCloseHookReq {

@ -25,14 +25,14 @@ public class ChangeThreadPoolConstants {
/**
* Dynamic thread pool parameter change text
*/
public static final String CHANGE_THREAD_POOL_TEXT = "[{}] Dynamic thread pool change parameter." +
"\n corePoolSize: {}" +
"\n maximumPoolSize: {}" +
"\n capacity: {}" +
"\n keepAliveTime: {}" +
"\n executeTimeOut: {}" +
"\n rejectedType: {}" +
"\n allowCoreThreadTimeOut: {}";
public static final String CHANGE_THREAD_POOL_TEXT = "[{}] Dynamic thread pool change parameter."
+ "\n corePoolSize: {}"
+ "\n maximumPoolSize: {}"
+ "\n capacity: {}"
+ "\n keepAliveTime: {}"
+ "\n executeTimeOut: {}"
+ "\n rejectedType: {}"
+ "\n allowCoreThreadTimeOut: {}";
/**
* Dynamic thread pool parameter change separator

@ -15,9 +15,7 @@
* limitations under the License.
*/
package cn.hippo4j.core.executor.support;
import cn.hippo4j.common.design.builder.Builder;
package cn.hippo4j.common.design.builder;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;

@ -64,12 +64,10 @@ public class AbstractSubjectCenter {
log.warn("Register observer. A string whose subject or observer is empty or empty.");
return;
}
List<Observer> observers = OBSERVERS_MAP.get(subject);
if (CollectionUtil.isEmpty(observers)) {
observers = new ArrayList();
}
observers.add(observer);
OBSERVERS_MAP.put(subject, observers);
}
@ -90,12 +88,11 @@ public class AbstractSubjectCenter {
* @param observer
*/
public static void remove(String subject, Observer observer) {
List<Observer> observers;
if (StringUtil.isBlank(subject) || CollectionUtil.isEmpty((observers = OBSERVERS_MAP.get(subject))) || observer == null) {
List<Observer> observers = OBSERVERS_MAP.get(subject);
if (StringUtil.isBlank(subject) || CollectionUtil.isEmpty(observers) || observer == null) {
log.warn("Remove observer. A string whose subject or observer is empty or empty.");
return;
}
observers.remove(observer);
}
@ -121,7 +118,6 @@ public class AbstractSubjectCenter {
log.warn("Under the subject, there is no observer group.");
return;
}
observers.parallelStream().forEach(each -> {
try {
each.accept(observerMessage);
@ -131,6 +127,9 @@ public class AbstractSubjectCenter {
});
}
/**
* Subject type.
*/
public enum SubjectType {
/**

@ -26,6 +26,9 @@ import java.util.concurrent.ThreadFactory;
*/
public class ExecutorFactory {
/**
* Thread pool management tool.
*/
public static final class Managed {
private static final String DEFAULT_NAMESPACE = "dynamic.thread-pool";

@ -32,7 +32,7 @@ public class ThreadPoolManager {
private Map<String, Map<String, Set<ExecutorService>>> resourcesManager;
private Map<String, Object> lockers = new ConcurrentHashMap(8);
private Map<String, Object> lockers = new ConcurrentHashMap();
private static final ThreadPoolManager INSTANCE = new ThreadPoolManager();
@ -47,7 +47,7 @@ public class ThreadPoolManager {
}
private void init() {
resourcesManager = new ConcurrentHashMap(8);
resourcesManager = new ConcurrentHashMap();
}
public void register(String tenantId, String group, ExecutorService executor) {
@ -60,7 +60,7 @@ public class ThreadPoolManager {
synchronized (monitor) {
Map<String, Set<ExecutorService>> map = resourcesManager.get(tenantId);
if (map == null) {
map = new HashMap(8);
map = new HashMap();
map.put(group, new HashSet());
map.get(group).add(executor);
resourcesManager.put(tenantId, map);

@ -24,7 +24,13 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.*;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.LinkedTransferQueue;
import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.SynchronousQueue;
import java.util.stream.Stream;
/**
@ -78,6 +84,8 @@ public enum BlockingQueueTypeEnum {
this.name = name;
}
private static final int DEFAULT_CAPACITY = 1024;
static {
DynamicThreadPoolServiceLoader.register(CustomBlockingQueue.class);
}
@ -105,7 +113,7 @@ public enum BlockingQueueTypeEnum {
.orElseGet(() -> {
int temCapacity = capacity;
if (capacity == null || capacity <= 0) {
temCapacity = 1024;
temCapacity = DEFAULT_CAPACITY;
}
return new LinkedBlockingQueue(temCapacity);
}));

@ -50,7 +50,7 @@ public enum RejectedPolicyTypeEnum {
@Getter
private String name;
public RejectedExecutionHandler rejectedHandler;
private RejectedExecutionHandler rejectedHandler;
RejectedPolicyTypeEnum(Integer type, String name, RejectedExecutionHandler rejectedHandler) {
this.type = type;

@ -17,11 +17,15 @@
package cn.hippo4j.common.executor.support;
import java.util.AbstractQueue;
import java.util.Collection;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.*;
import java.util.concurrent.locks.*;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
/**
* A clone of {@linkplain java.util.concurrent.LinkedBlockingQueue}
@ -229,9 +233,10 @@ public class ResizableCapacityLinkedBlockingQueue<E> extends AbstractQueue<E>
*/
public ResizableCapacityLinkedBlockingQueue(Collection<? extends E> c) {
this(Integer.MAX_VALUE);
for (Iterator<? extends E> it = c.iterator(); it.hasNext();)
for (Iterator<? extends E> it = c.iterator(); it.hasNext();) {
add(it.next());
}
}
// this doc comment is overridden to remove the reference to collections
// greater in size than Integer.MAX_VALUE
@ -698,6 +703,9 @@ public class ResizableCapacityLinkedBlockingQueue<E> extends AbstractQueue<E>
return new Itr();
}
/**
* Itr.
*/
private class Itr implements Iterator<E> {
/*

@ -113,6 +113,9 @@ public class InstanceInfo {
this.actionType = actionType;
}
/**
* Instance status.
*/
public enum InstanceStatus {
/**
@ -153,6 +156,9 @@ public class InstanceInfo {
}
}
/**
* Action type.
*/
public enum ActionType {
/**
* ADDED
@ -170,6 +176,9 @@ public class InstanceInfo {
DELETED
}
/**
* Instance renew.
*/
@Data
@Accessors(chain = true)
public static class InstanceRenew {

@ -17,7 +17,10 @@
package cn.hippo4j.common.model.register.notify;
import lombok.*;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* Dynamic thread-pool register core notify parameter.

@ -18,7 +18,11 @@
package cn.hippo4j.common.spi;
import java.lang.reflect.InvocationTargetException;
import java.util.*;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
import java.util.Map;
import java.util.ServiceLoader;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
@ -86,7 +90,8 @@ public class DynamicThreadPoolServiceLoader {
private static Object newServiceInstance(final Class<?> clazz) {
try {
return clazz.getDeclaredConstructor().newInstance();
} catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
} catch (InstantiationException | IllegalAccessException | InvocationTargetException
| NoSuchMethodException e) {
throw new ServiceLoaderInstantiationException(clazz, e);
}
}

@ -91,6 +91,16 @@ public class Assert {
}
}
public static void notBlank(String str, String message) {
if (StringUtil.isBlank(str)) {
throw new IllegalArgumentException(message);
}
}
public static void notBlank(String str) {
notBlank(str, "[Assertion failed] - this string must not be blank");
}
public static void hasText(String text, String message) {
if (!StringUtils.hasText(text)) {
throw new IllegalArgumentException(message);

@ -0,0 +1,152 @@
/*
* 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.common.toolkit;
import cn.hippo4j.common.web.exception.IllegalException;
import com.github.dozermapper.core.DozerBeanMapperBuilder;
import com.github.dozermapper.core.Mapper;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.springframework.beans.BeanUtils;
import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.*;
/**
* Bean util.
*/
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class BeanUtil {
protected static Mapper BEAN_MAPPER_BUILDER;
static {
BEAN_MAPPER_BUILDER = DozerBeanMapperBuilder.buildDefault();
}
public static <T, S> T convert(S source, Class<T> clazz) {
return Optional.ofNullable(source)
.map(each -> BEAN_MAPPER_BUILDER.map(each, clazz))
.orElse(null);
}
public static <T, S> T convert(S source, T target) {
Optional.ofNullable(source)
.ifPresent(each -> BEAN_MAPPER_BUILDER.map(each, target));
return target;
}
public static <T, S> List<T> convert(List<S> sources, Class<T> clazz) {
return Optional.ofNullable(sources)
.map(each -> {
List<T> targetList = new ArrayList<T>(each.size());
each.forEach(item -> targetList.add(BEAN_MAPPER_BUILDER.map(item, clazz)));
return targetList;
})
.orElse(null);
}
public static <T, S> Set<T> convert(Set<S> sources, Class<T> clazz) {
return Optional.ofNullable(sources)
.map(each -> {
Set<T> targetSize = new HashSet<T>(each.size());
each.forEach(item -> targetSize.add(BEAN_MAPPER_BUILDER.map(item, clazz)));
return targetSize;
})
.orElse(null);
}
public static <T> T mapToBean(Map<String, Object> map, Class<T> clazz, boolean toCamelCase) {
if (clazz == null) {
return null;
}
try {
T newInstance = clazz.newInstance();
return mapToBean(map, newInstance, toCamelCase);
} catch (InstantiationException | IllegalAccessException e) {
throw new IllegalException("do not create instance for " + clazz.getName(), e);
}
}
/**
* map to bean
*
* @param map map
* @param bean obj bean
* @param toCamelCase format to camel case
* @param <T> bean type
* @return T
*/
public static <T> T mapToBean(Map<String, Object> map, T bean, boolean toCamelCase) {
if (bean == null) {
return null;
}
if (map.isEmpty()) {
return bean;
}
Class<?> clazz = bean.getClass();
map.forEach((s, o) -> {
String name = toCamelCase ? StringUtil.toCamelCase(s, StringUtil.UNDERLINE) : s;
Method method = setter(clazz, name);
if (method != null) {
ReflectUtil.invoke(bean, method, o);
}
});
return bean;
}
/**
* getter for properties
*
* @param o obj
* @param propertiesName name
* @return Method for get
*/
public static Method getter(Class<?> o, String propertiesName) {
if (o == null) {
return null;
}
try {
PropertyDescriptor descriptor = new PropertyDescriptor(propertiesName, o);
return descriptor.getReadMethod();
} catch (IntrospectionException e) {
throw new IllegalException("not find getter for" + propertiesName + "in" + o.getName(), e);
}
}
/**
* setter for properties
*
* @param o obj
* @param propertiesName name
* @return Method for set
*/
public static Method setter(Class<?> o, String propertiesName) {
if (o == null) {
return null;
}
try {
PropertyDescriptor descriptor = new PropertyDescriptor(propertiesName, o);
return descriptor.getWriteMethod();
} catch (IntrospectionException e) {
throw new IllegalException("not find setter for" + propertiesName + "in" + o.getName(), e);
}
}
}

@ -17,8 +17,6 @@
package cn.hippo4j.common.toolkit;
import cn.hutool.core.util.StrUtil;
import java.util.HashSet;
import java.util.Set;
@ -42,7 +40,7 @@ public class BooleanUtil {
* @return
*/
public static boolean toBoolean(String valueStr) {
if (StrUtil.isNotBlank(valueStr)) {
if (StringUtil.isNotBlank(valueStr)) {
valueStr = valueStr.trim().toLowerCase();
return TREE_SET.contains(valueStr);
}

@ -24,9 +24,11 @@ import java.text.DecimalFormat;
*/
public class ByteConvertUtil {
public static final Integer KB_SIZE = 2 << 9;
public static final Integer MB_SIZE = 2 << 19;
public static final Integer GB_SIZE = 2 << 29;
public static final int KB_SIZE = 2 << 9;
public static final int MB_SIZE = 2 << 19;
public static final int GB_SIZE = 2 << 29;
public static String getPrintSize(long size) {
DecimalFormat df = new DecimalFormat("#.00");

@ -25,7 +25,9 @@ package cn.hippo4j.common.toolkit;
*/
public class CalculateUtil {
private static final int PERCENTAGE = 100;
public static int divide(int num1, int num2) {
return ((int) (Double.parseDouble(num1 + "") / Double.parseDouble(num2 + "") * 100));
return ((int) (Double.parseDouble(num1 + "") / Double.parseDouble(num2 + "") * PERCENTAGE));
}
}

@ -17,10 +17,8 @@
package cn.hippo4j.common.toolkit;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.stream.Collectors;
/**
* Collection util.
@ -35,11 +33,12 @@ public class CollectionUtil {
* @return
*/
public static <T> T getFirst(Iterable<T> iterable) {
Iterator<T> iterator;
if (iterable != null && (iterator = iterable.iterator()) != null && iterator.hasNext()) {
if (iterable != null) {
Iterator<T> iterator = iterable.iterator();
if (iterator != null && iterator.hasNext()) {
return iterator.next();
}
}
return null;
}
@ -90,7 +89,7 @@ public class CollectionUtil {
* @return
*/
public static boolean isEmpty(Iterator<?> iterator) {
return null == iterator || false == iterator.hasNext();
return null == iterator || !iterator.hasNext();
}
/**
@ -122,4 +121,57 @@ public class CollectionUtil {
public static boolean isNotEmpty(Collection<?> collection) {
return !isEmpty(collection);
}
/**
* to list
*
* @param ts elements
* @param <T> type
* @return List
*/
public static <T> List<T> toList(T... ts) {
if (ts == null || ts.length == 0) {
return new ArrayList<>();
}
return Arrays.stream(ts)
.collect(Collectors.toList());
}
/**
* reference google guava
*
* @param elements
* @return
*/
@SafeVarargs
public static <E> ArrayList<E> newArrayList(E... elements) {
Objects.requireNonNull(elements);
// Avoid integer overflow when a large array is passed in
int capacity = computeArrayListCapacity(elements.length);
ArrayList<E> list = new ArrayList<>(capacity);
Collections.addAll(list, elements);
return list;
}
private static int computeArrayListCapacity(int arraySize) {
checkNonnegative(arraySize);
// TODO(kevinb): Figure out the right behavior, and document it
return saturatedCast(5L + arraySize + (arraySize / 10));
}
private static void checkNonnegative(int value) {
if (value < 0) {
throw new IllegalArgumentException("arraySize cannot be negative but was: " + value);
}
}
private static int saturatedCast(long value) {
if (value > Integer.MAX_VALUE) {
return Integer.MAX_VALUE;
}
if (value < Integer.MIN_VALUE) {
return Integer.MIN_VALUE;
}
return (int) value;
}
}

@ -0,0 +1,76 @@
/*
* 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.common.toolkit;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.util.Date;
import java.util.SimpleTimeZone;
import java.util.TimeZone;
/**
* date and time util
*/
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class DateUtil {
/**
* get time zone for this JVM
*/
private static final TimeZone TIME_ZONE = TimeZone.getDefault();
public static final String NORM_DATE_PATTERN = "yyyy-MM-dd";
public static final String NORM_TIME_PATTERN = "HH:mm:ss";
public static final String NORM_DATETIME_PATTERN = "yyyy-MM-dd HH:mm:ss";
/**
* Returns the number of milliseconds since January 1, 1970, 00:00:00 GMT
* represented by this <tt>Date</tt> object.
*
* @return the number of milliseconds since January 1, 1970, 00:00:00 GMT
* represented by this date.
*/
public static long getTime(LocalDateTime date) {
return getTime(date, TIME_ZONE.toZoneId());
}
public static long getTime(LocalDateTime date, ZoneId zoneId) {
return date.atZone(zoneId).toInstant().toEpochMilli();
}
/**
* modify format to date
*
* @param date date
* @param normTimePattern PATTERN
* @return String
*/
public static String format(Date date, String normTimePattern) {
SimpleDateFormat zoneFormat = new SimpleDateFormat(normTimePattern);
return zoneFormat.format(date);
}
}

@ -17,18 +17,23 @@
package cn.hippo4j.common.toolkit;
import cn.hippo4j.common.web.exception.IllegalException;
import lombok.SneakyThrows;
import org.springframework.core.io.ClassPathResource;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.*;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
/**
* File util;
*/
public class FileUtil {
private static final int ERROR_CODE = -1;
@SneakyThrows
public static String readUtf8String(String path) {
String resultReadStr;
@ -38,7 +43,7 @@ public class FileUtil {
BufferedInputStream bis = new BufferedInputStream(inputStream);
ByteArrayOutputStream buf = new ByteArrayOutputStream()) {
int result = bis.read();
while (result != -1) {
while (result != ERROR_CODE) {
buf.write((byte) result);
result = bis.read();
}
@ -46,4 +51,38 @@ public class FileUtil {
}
return resultReadStr;
}
public static List<String> readLines(String path, Charset charset) {
List<String> strList = new ArrayList<>();
InputStreamReader inputStreamReader = null;
BufferedReader bufferedReader = null;
ClassPathResource classPathResource = new ClassPathResource(path);
try {
inputStreamReader = new InputStreamReader(classPathResource.getInputStream(), charset);
bufferedReader = new BufferedReader(inputStreamReader);
String line;
while ((line = bufferedReader.readLine()) != null) {
strList.add(line);
}
} catch (IOException e) {
e.printStackTrace();
throw new IllegalException("file read error");
} finally {
if (inputStreamReader != null) {
try {
inputStreamReader.close();
} catch (IOException e) {
throw new IllegalException("file read error");
}
}
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException e) {
throw new IllegalException("file read error");
}
}
}
return strList;
}
}

@ -0,0 +1,85 @@
/*
* 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.common.toolkit;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import java.util.UUID;
/**
* id and uuid util{@link UUID}
*/
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class IdUtil {
/**
* get a random UUID
*
* @return UUID
*/
public static String randomUUID() {
return toString(UUID.randomUUID(), false);
}
/**
* get a simple random UUID
*
* @return a simple UUID
*/
public static String simpleUUID() {
return toString(UUID.randomUUID(), true);
}
/**
* toString
*
* @param uuid UUID
* @return UUID String
*/
public static String toString(UUID uuid, boolean isSimple) {
long mostSigBits = uuid.getMostSignificantBits();
long leastSigBits = uuid.getLeastSignificantBits();
if (isSimple) {
return (digits(mostSigBits >> 32, 8) +
digits(mostSigBits >> 16, 4) +
digits(mostSigBits, 4) +
digits(leastSigBits >> 48, 4) +
digits(leastSigBits, 12));
} else {
return (digits(mostSigBits >> 32, 8) + "-" +
digits(mostSigBits >> 16, 4) + "-" +
digits(mostSigBits, 4) + "-" +
digits(leastSigBits >> 48, 4) + "-" +
digits(leastSigBits, 12));
}
}
/**
* Returns val represented by the specified number of hex digits. <br>
* {@link UUID#digits(long, int)}
*
* @param val value
* @param digits position
* @return hex value
*/
private static String digits(long val, int digits) {
long hi = 1L << (digits * 4);
return Long.toHexString(hi | (val & (hi - 1))).substring(1);
}
}

@ -0,0 +1,88 @@
/*
* 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.common.toolkit;
import java.io.IOException;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Objects;
/**
* reference google guava
*/
public class Joiner {
private final String separator;
private Joiner(String separator) {
this.separator = Objects.requireNonNull(separator);
}
/**
* Returns a joiner which automatically places {@code separator} between consecutive elements.
*/
public static Joiner on(String separator) {
return new Joiner(separator);
}
/**
* Returns a string containing the string representation of each of {@code parts}, using the
* previously configured separator between each.
*/
public final String join(Object[] parts) {
return join(Arrays.asList(parts));
}
public final String join(Iterable<?> parts) {
return join(parts.iterator());
}
/**
* Returns a string containing the string representation of each of {@code parts}, using the
* previously configured separator between each.
*/
public final String join(Iterator<?> parts) {
return appendTo(new StringBuilder(), parts).toString();
}
public final StringBuilder appendTo(StringBuilder builder, Iterator<?> parts) {
try {
appendTo((Appendable) builder, parts);
} catch (IOException impossible) {
throw new AssertionError(impossible);
}
return builder;
}
public <A extends Appendable> A appendTo(A appendable, Iterator<?> parts) throws IOException {
Objects.requireNonNull(appendable);
if (parts.hasNext()) {
appendable.append(toString(parts.next()));
while (parts.hasNext()) {
appendable.append(separator);
appendable.append(toString(parts.next()));
}
}
return appendable;
}
CharSequence toString(Object part) {
Objects.requireNonNull(part);
return (part instanceof CharSequence) ? (CharSequence) part : part.toString();
}
}

@ -33,6 +33,16 @@ public class Md5Util {
private static final char[] DIGITS_LOWER = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
private static final char XF0 = 0xF0;
private static final char XF = 0x0F;
private static final int DATA_ID_GROUP_ID_THREE_LEN = 3;
private static final int DATA_ID_GROUP_ID_FOUR_LEN = 4;
private static final int DISPLACEMENT = 4;
private static final ThreadLocal<MessageDigest> MESSAGE_DIGEST_LOCAL = ThreadLocal.withInitial(() -> {
try {
return MessageDigest.getInstance("MD5");
@ -65,8 +75,8 @@ public class Md5Util {
int l = bytes.length;
char[] out = new char[l << 1];
for (int i = 0, j = 0; i < l; i++) {
out[j++] = DIGITS_LOWER[(0xF0 & bytes[i]) >>> 4];
out[j++] = DIGITS_LOWER[0x0F & bytes[i]];
out[j++] = DIGITS_LOWER[(XF0 & bytes[i]) >>> DISPLACEMENT];
out[j++] = DIGITS_LOWER[XF & bytes[i]];
}
return new String(out);
}
@ -86,12 +96,12 @@ public class Md5Util {
sb.append(Constants.WORD_SEPARATOR);
sb.append(dataIdGroupId[1]);
// if have tenant, then set it
if (dataIdGroupId.length == 3) {
if (dataIdGroupId.length == DATA_ID_GROUP_ID_THREE_LEN) {
if (StringUtil.isNotBlank(dataIdGroupId[2])) {
sb.append(Constants.WORD_SEPARATOR);
sb.append(dataIdGroupId[2]);
}
} else if (dataIdGroupId.length == 4) {
} else if (dataIdGroupId.length == DATA_ID_GROUP_ID_FOUR_LEN) {
if (StringUtil.isNotBlank(dataIdGroupId[2])) {
sb.append(Constants.WORD_SEPARATOR);
sb.append(dataIdGroupId[2]);

@ -41,7 +41,7 @@ public class MessageConvert {
MessageWrapper wrapper = new MessageWrapper();
wrapper.setResponseClass(message.getClass());
wrapper.setMessageType(message.getMessageType());
List<Map<String, Object>> messageMapList = new ArrayList();
List<Map<String, Object>> messageMapList = new ArrayList<>();
List<Message> messages = message.getMessages();
messages.forEach(each -> {
String eachVal = JSONUtil.toJSONString(each);

@ -17,22 +17,27 @@
package cn.hippo4j.common.toolkit;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.exceptions.UtilException;
import cn.hutool.core.util.ClassUtil;
import cn.hippo4j.common.web.exception.IllegalException;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ThreadPoolExecutor;
/**
* Reflect util.
*/
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class ReflectUtil {
private static final Map<Class<?>, Field[]> FIELDS_CACHE = new ConcurrentHashMap();
private static final Map<Class<?>, Field[]> FIELDS_CACHE = new ConcurrentHashMap<>();
public static Object getFieldValue(Object obj, String fieldName) {
if (null == obj || StringUtil.isBlank(fieldName)) {
@ -55,13 +60,13 @@ public class ReflectUtil {
result = field.get(obj);
} catch (IllegalAccessException e) {
String exceptionMsg = String.format("IllegalAccess for %s.%s", field.getDeclaringClass(), field.getName());
throw new RuntimeException(exceptionMsg, e);
throw new IllegalException(exceptionMsg, e);
}
return result;
}
public static <T extends AccessibleObject> T setAccessible(T accessibleObject) {
if (null != accessibleObject && false == accessibleObject.isAccessible()) {
if (null != accessibleObject && !accessibleObject.isAccessible()) {
accessibleObject.setAccessible(true);
}
return accessibleObject;
@ -69,7 +74,7 @@ public class ReflectUtil {
public static Field getField(Class<?> beanClass, String name) throws SecurityException {
final Field[] fields = getFields(beanClass);
return ArrayUtil.firstMatch((field) -> name.equals(getFieldName(field)), fields);
return ArrayUtil.firstMatch(field -> name.equals(getFieldName(field)), fields);
}
public static Field[] getFields(Class<?> beanClass) throws SecurityException {
@ -109,32 +114,137 @@ public class ReflectUtil {
return field.getName();
}
public static void setFieldValue(Object obj, String fieldName, Object value) throws UtilException {
cn.hutool.core.lang.Assert.notNull(obj);
cn.hutool.core.lang.Assert.notBlank(fieldName);
public static void setFieldValue(Object obj, String fieldName, Object value) throws IllegalException {
Assert.notNull(obj);
Assert.notBlank(fieldName);
final Field field = getField((obj instanceof Class) ? (Class<?>) obj : obj.getClass(), fieldName);
cn.hutool.core.lang.Assert.notNull(field, "Field [{}] is not exist in [{}]", fieldName, obj.getClass().getName());
Assert.notNull(field, "Field [" + fieldName + "] is not exist in [" + obj.getClass().getName() + "]");
setFieldValue(obj, field, value);
}
public static void setFieldValue(Object obj, Field field, Object value) throws UtilException {
cn.hutool.core.lang.Assert.notNull(field, "Field in [{}] not exist !", obj);
public static void setFieldValue(Object obj, Field field, Object value) throws IllegalException {
Assert.notNull(field, "Field in [" + obj + "] not exist !");
final Class<?> fieldType = field.getType();
if (null != value) {
if (false == fieldType.isAssignableFrom(value.getClass())) {
final Object targetValue = Convert.convert(fieldType, value);
if (!fieldType.isAssignableFrom(value.getClass())) {
final Object targetValue = cast(fieldType, value);
if (null != targetValue) {
value = targetValue;
}
}
} else {
value = ClassUtil.getDefaultValue(fieldType);
value = getDefaultValue(fieldType);
}
setAccessible(field);
try {
field.set(obj instanceof Class ? null : obj, value);
} catch (IllegalAccessException e) {
throw new UtilException(e, "IllegalAccess for {}.{}", obj, field.getName());
throw new IllegalException("IllegalAccess for " + obj + "." + field.getName(), e);
}
}
/**
* find the method associated with the method name<br>
* if find multiple, return the first, parameter is equivocal
*
* @param clazz the class
* @param methodName retrieves the method name
* @return find method
*/
public static Method getMethodByName(Class<?> clazz, String methodName) {
if (Objects.nonNull(clazz) && Objects.nonNull(methodName)) {
Method method = Arrays.stream(clazz.getMethods())
.filter(m -> Objects.equals(m.getName(), methodName))
.findFirst().orElse(null);
if (method != null) {
return method;
}
return Arrays.stream(clazz.getDeclaredMethods())
.filter(m -> Objects.equals(m.getName(), methodName))
.findFirst().orElse(null);
}
return null;
}
/**
* find the method associated with the method name
*
* @param clazz the class
* @param methodName retrieves the method name
* @param arguments matched parameters class
* @return find method
*/
public static Method getMethodByName(Class<?> clazz, String methodName, Class<?>... arguments) {
try {
if (Objects.nonNull(clazz) && Objects.nonNull(methodName)) {
return clazz.getMethod(methodName, arguments);
}
} catch (NoSuchMethodException e) {
throw new IllegalException(e);
}
return null;
}
/**
* Cast the value to the type <br>
* If a ClassCastException occurs, return null
*
* @param clazz Cast class
* @param value The cast value
* @return The value after the cast is completed
*/
public static Object cast(Class<?> clazz, Object value) {
try {
return clazz.cast(value);
} catch (ClassCastException e) {
return null;
}
}
/**
* the default value is obtained if it is a primitive type, and NULL if it is not
*
* @param clazz clazz
* @return default value
*/
public static Object getDefaultValue(Class<?> clazz) {
if (Objects.isNull(clazz) || !clazz.isPrimitive()) {
return null;
}
if (long.class.isAssignableFrom(clazz)) {
return 0L;
} else if (int.class.isAssignableFrom(clazz)) {
return 0;
} else if (short.class.isAssignableFrom(clazz)) {
return (short) 0;
} else if (char.class.isAssignableFrom(clazz)) {
return (char) 0;
} else if (byte.class.isAssignableFrom(clazz)) {
return (byte) 0;
} else if (double.class.isAssignableFrom(clazz)) {
return 0D;
} else if (float.class.isAssignableFrom(clazz)) {
return 0f;
} else if (boolean.class.isAssignableFrom(clazz)) {
return false;
}
return null;
}
/**
* invoke
*
* @param obj the obj
* @param method the method
* @param arguments parameters
* @return result for zhe method
*/
@SuppressWarnings("unchecked")
public static <T> T invoke(Object obj, Method method, Object... arguments) {
try {
return (T) method.invoke(obj, arguments);
} catch (IllegalAccessException | InvocationTargetException e) {
throw new IllegalException(e);
}
}
}

@ -29,7 +29,7 @@ import java.util.function.Supplier;
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class Singleton {
private static final ConcurrentHashMap<String, Object> SINGLE_OBJECT_POOL = new ConcurrentHashMap();
private static final ConcurrentHashMap<String, Object> SINGLE_OBJECT_POOL = new ConcurrentHashMap<>();
/**
* Get a singleton object by key.
@ -55,9 +55,12 @@ public final class Singleton {
*/
public static <T> T get(String key, Supplier<T> supplier) {
Object result = SINGLE_OBJECT_POOL.get(key);
if (result == null && (result = supplier.get()) != null) {
if (result == null) {
result = supplier.get();
if (result != null) {
SINGLE_OBJECT_POOL.put(key, result);
}
}
return result != null ? (T) result : null;
}

@ -17,6 +17,9 @@
package cn.hippo4j.common.toolkit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* String util.
*/
@ -63,14 +66,17 @@ public class StringUtil {
* @return
*/
public static boolean isBlank(CharSequence str) {
int length;
if ((str == null) || ((length = str.length()) == 0)) {
if ((str == null)) {
return true;
}
int length = str.length();
if (length == 0) {
return true;
}
for (int i = 0; i < length; i++) {
char c = str.charAt(i);
boolean charNotBlank = Character.isWhitespace(c) || Character.isSpaceChar(c) || c == '\ufeff' || c == '\u202a';
if (charNotBlank == false) {
if (!charNotBlank) {
return false;
}
}
@ -104,7 +110,7 @@ public class StringUtil {
* @return
*/
public static boolean isNotBlank(CharSequence str) {
return isBlank(str) == false;
return !isBlank(str);
}
/**
@ -114,7 +120,7 @@ public class StringUtil {
* @return
*/
public static boolean isAllNotEmpty(CharSequence... args) {
return false == hasEmpty(args);
return !hasEmpty(args);
}
/**
@ -188,4 +194,85 @@ public class StringUtil {
}
return sb.toString();
}
/**
* to camel case
*
* @param str CharSequence
* @param symbol symbol
* @return toCamelCase String
*/
public static String toCamelCase(CharSequence str, char symbol) {
if (null == str || str.length() == 0) {
return null;
}
int length = str.length();
StringBuilder sb = new StringBuilder(length);
boolean upperCase = false;
for (int i = 0; i < length; ++i) {
char c = str.charAt(i);
if (c == symbol) {
upperCase = true;
} else if (upperCase) {
sb.append(Character.toUpperCase(c));
upperCase = false;
} else {
sb.append(c);
}
}
return sb.toString();
}
/**
* Replace a portion of the string, replacing all found
*
* @param str A string to operate on
* @param searchStr The replaced string
* @param replaceStr The replaced string
* @return Replace the result
*/
public static String replace(String str, String searchStr, String replaceStr) {
return Pattern
.compile(searchStr, Pattern.LITERAL)
.matcher(str)
.replaceAll(Matcher.quoteReplacement(replaceStr));
}
/**
* Tests if this string starts with the specified prefix.
*
* @param str this str
* @param prefix the suffix
* @return Whether the prefix exists
*/
public static boolean startWith(String str, String prefix) {
if (isEmpty(str)) {
return false;
}
return str.startsWith(prefix);
}
/**
* get the string before the delimiter
*
* @param str string
* @param symbol separator
* @return String
*/
public static String subBefore(String str, String symbol) {
if (isEmpty(str) || symbol == null) {
return str;
}
if (symbol.isEmpty()) {
return EMPTY;
}
int pos = str.indexOf(symbol);
if (-1 == pos) {
return str;
}
if (0 == pos) {
return EMPTY;
}
return str.substring(0, pos);
}
}

@ -28,7 +28,7 @@ import java.util.Optional;
*/
public class UserContext {
private static final ThreadLocal<User> USER_THREAD_LOCAL = new ThreadLocal();
private static final ThreadLocal<User> USER_THREAD_LOCAL = new ThreadLocal<>();
public static void setUserInfo(String username, String userRole) {
USER_THREAD_LOCAL.set(new User(username, userRole));
@ -46,6 +46,9 @@ public class UserContext {
USER_THREAD_LOCAL.remove();
}
/**
* User info.
*/
@Data
@NoArgsConstructor
@AllArgsConstructor

@ -25,7 +25,7 @@ import lombok.Getter;
public class AbstractException extends RuntimeException {
@Getter
public final ErrorCode errorCode;
private final ErrorCode errorCode;
public AbstractException(String message, Throwable throwable, ErrorCode errorCode) {
super(message, throwable);

@ -0,0 +1,47 @@
/*
* 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.common.web.exception;
/**
* A generic exception to handle illegal operations
*/
public class IllegalException extends RuntimeException {
private static final long serialVersionUID = 8247610319171014183L;
public IllegalException() {
super();
}
public IllegalException(String message) {
super(message);
}
public IllegalException(Throwable e) {
super(e.getMessage(), e);
}
public IllegalException(String message, Throwable throwable) {
super(message, throwable);
}
public IllegalException(String message, Throwable throwable, boolean enableSuppression, boolean writableStackTrace) {
super(message, throwable, enableSuppression, writableStackTrace);
}
}

@ -59,9 +59,9 @@ public class ServiceException extends AbstractException {
@Override
public String toString() {
return "ServiceException{" +
"code='" + errorCode.getCode() + "'," +
"message='" + errorCode.getMessage() + "'" +
'}';
return "ServiceException{"
+ "code='" + getErrorCode().getCode() + "',"
+ "message='" + getErrorCode().getMessage() + "'"
+ '}';
}
}

@ -18,9 +18,10 @@
package cn.hippo4j.common.function;
import cn.hippo4j.common.toolkit.Assert;
import java.math.BigDecimal;
import org.junit.Test;
import java.math.BigDecimal;
public final class MatcherFunctionTest {
public static <T> boolean matchTest(Matcher<T> matcher, T value) {

@ -17,5 +17,18 @@
package cn.hippo4j.common.function;
public final class NoArgsConsumerTest {
import cn.hippo4j.common.toolkit.Assert;
import org.junit.jupiter.api.Test;
import java.util.concurrent.atomic.AtomicBoolean;
final class NoArgsConsumerTest {
@Test
void accept() {
AtomicBoolean checkValue = new AtomicBoolean(false);
NoArgsConsumer noArgsConsumer = () -> checkValue.set(true);
noArgsConsumer.accept();
Assert.isTrue(checkValue.get());
}
}

@ -18,8 +18,8 @@
package cn.hippo4j.common.toolkit;
import cn.hippo4j.common.function.Matcher;
import com.google.common.base.Strings;
import org.junit.Test;
import org.springframework.util.StringUtils;
public class ArrayUtilTest {
@ -39,11 +39,11 @@ public class ArrayUtilTest {
public void assertFirstMatch() {
Matcher<String> matcher = (str) -> "1".equalsIgnoreCase(str);
String[] array = new String[0];
Assert.isTrue(Strings.isNullOrEmpty(ArrayUtil.firstMatch(matcher, array)));
Assert.isTrue(StringUtils.isEmpty(ArrayUtil.firstMatch(matcher, array)));
array = new String[]{"0"};
Assert.isTrue(Strings.isNullOrEmpty(ArrayUtil.firstMatch(matcher, array)));
Assert.isTrue(StringUtils.isEmpty(ArrayUtil.firstMatch(matcher, array)));
array = new String[]{"1"};
Assert.isTrue(!Strings.isNullOrEmpty(ArrayUtil.firstMatch(matcher, array)));
Assert.isTrue(!StringUtils.isEmpty(ArrayUtil.firstMatch(matcher, array)));
}
@Test

@ -15,21 +15,16 @@
* limitations under the License.
*/
package cn.hippo4j.config.toolkit;
package cn.hippo4j.common.toolkit;
import cn.hippo4j.common.toolkit.Assert;
import com.github.dozermapper.core.converters.ConversionException;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import lombok.*;
import org.junit.Assert;
import org.junit.Test;
import java.lang.reflect.Method;
import java.util.*;
/**
* BeanUtil Test
*/
public class BeanUtilTest {
@Test
@ -41,47 +36,47 @@ public class BeanUtilTest {
person.setAddress("hippo4j.cn");
person.setSize(999);
final Map<?, ?> convert = BeanUtil.convert(person, Map.class);
Assert.isTrue(Objects.equals("Hippo4j", convert.get("name")));
Assert.isTrue(Objects.equals(1, convert.get("age")));
Assert.isTrue(Objects.equals("hippo4j.cn", convert.get("address")));
Assert.isTrue(Objects.equals(999, convert.get("size")));
Assert.assertEquals("Hippo4j", convert.get("name"));
Assert.assertEquals(1, convert.get("age"));
Assert.assertEquals("hippo4j.cn", convert.get("address"));
Assert.assertEquals(999, convert.get("size"));
}
@Test
public void mapToBeanConvertTest() {
// 测试MapToBean
final HashMap<String, Object> map = Maps.newHashMap();
final HashMap<String, Object> map = new HashMap<>();
map.put("name", "Hippo4j");
map.put("age", 1);
map.put("address", "hippo4j.cn");
map.put("size", 999);
final Person person = BeanUtil.convert(map, Person.class);
Assert.isTrue(Objects.equals("Hippo4j", person.getName()));
Assert.isTrue(Objects.equals(1, person.getAge()));
Assert.isTrue(Objects.equals("hippo4j.cn", person.getAddress()));
Assert.isTrue(Objects.equals(999, person.getSize()));
Assert.assertEquals("Hippo4j", person.getName());
Assert.assertEquals(1, person.getAge());
Assert.assertEquals("hippo4j.cn", person.getAddress());
Assert.assertEquals(999, (int) person.getSize());
}
@Test
public void ListToListConvertTest() {
final List<Person> list = Lists.newArrayList();
final List<Person> list = new ArrayList<>();
list.add(Person.builder().name("one").age(1).build());
list.add(Person.builder().name("two").age(2).build());
list.add(Person.builder().name("three").age(3).build());
final List<PersonVo> persons = BeanUtil.convert(list, PersonVo.class);
Assert.isTrue(Objects.equals(list.size(), persons.size()));
Assert.assertEquals(list.size(), persons.size());
}
@Test
public void SetToSetConvertTest() {
final Set<Person> sets = Sets.newHashSet();
final Set<Person> sets = new HashSet<>();
sets.add(Person.builder().name("one").age(1).build());
sets.add(Person.builder().name("two").age(2).build());
sets.add(Person.builder().name("three").age(3).build());
final Set<PersonVo> persons = BeanUtil.convert(sets, PersonVo.class);
Assert.isTrue(Objects.equals(sets.size(), persons.size()));
Assert.assertEquals(sets.size(), persons.size());
}
@Test
@ -91,10 +86,10 @@ public class BeanUtilTest {
person.setName("Hippo4j");
final Map<?, ?> convert = BeanUtil.convert(person, Map.class);
Assert.isTrue(Objects.equals("Hippo4j", convert.get("name")));
Assert.assertEquals("Hippo4j", convert.get("name"));
// static属性应被忽略
Assert.isTrue(!convert.containsKey("STATIC_NAME"));
Assert.assertFalse(convert.containsKey("STATIC_NAME"));
}
/**
@ -109,6 +104,28 @@ public class BeanUtilTest {
// -----------------------------------------------------------------------------------------------------------------
@Test
public void testMapToBean() {
Map<String, Object> map = new HashMap<>();
map.put("name", "Test");
map.put("status_code", 12);
Customer customer = BeanUtil.mapToBean(map, Customer.class, true);
Assert.assertEquals("Test", customer.getName());
Assert.assertEquals(Integer.valueOf(12), customer.getStatusCode());
}
@Test
public void testGetter() {
Method name = BeanUtil.getter(Customer.class, "name");
Assert.assertEquals("getName", name.getName());
}
@Test
public void testSetter() {
Method name = BeanUtil.setter(Customer.class, "name");
Assert.assertEquals("setName", name.getName());
}
@Getter
@Setter
@Builder
@ -130,4 +147,20 @@ public class BeanUtilTest {
private String name;
private int age;
}
@Getter
@Setter
static class Customer {
String name;
Integer statusCode;
}
@Getter
@Setter
static class PreCustomer {
String name;
Integer statusCode;
}
}

@ -17,19 +17,20 @@
package cn.hippo4j.common.toolkit;
import org.junit.Assert;
import org.junit.Test;
public class BooleanUtilTest {
@Test
public void assertToBoolean() {
Assert.isTrue(BooleanUtil.toBoolean("true"));
Assert.isTrue(BooleanUtil.toBoolean("yes"));
Assert.isTrue(BooleanUtil.toBoolean("1"));
Assert.assertTrue(BooleanUtil.toBoolean("true"));
Assert.assertTrue(BooleanUtil.toBoolean("yes"));
Assert.assertTrue(BooleanUtil.toBoolean("1"));
}
@Test
public void assertIsTrue() {
Assert.isTrue(BooleanUtil.isTrue(true));
Assert.assertTrue(BooleanUtil.isTrue(true));
}
}

@ -17,10 +17,10 @@
package cn.hippo4j.common.toolkit;
import com.google.common.collect.Maps;
import org.assertj.core.util.Lists;
import org.junit.Test;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@ -44,7 +44,7 @@ public class CollectionUtilTest {
Assert.isTrue(!CollectionUtil.isEmpty(list));
Map map = null;
Assert.isTrue(CollectionUtil.isEmpty(map));
map = Maps.newHashMap();
map = new HashMap<>();
Assert.isTrue(CollectionUtil.isEmpty(map));
map.put("key", "value");
Assert.isTrue(!CollectionUtil.isEmpty(map));
@ -66,7 +66,7 @@ public class CollectionUtilTest {
Assert.isTrue(CollectionUtil.isNotEmpty(list));
Map map = null;
Assert.isTrue(!CollectionUtil.isNotEmpty(map));
map = Maps.newHashMap();
map = new HashMap<>();
Assert.isTrue(!CollectionUtil.isNotEmpty(map));
map.put("key", "value");
Assert.isTrue(CollectionUtil.isNotEmpty(map));

@ -18,6 +18,10 @@
package cn.hippo4j.common.toolkit;
import org.junit.Test;
import org.junit.Assert;
import java.nio.charset.StandardCharsets;
import java.util.List;
public class FileUtilTest {
@ -25,7 +29,7 @@ public class FileUtilTest {
public void assertReadUtf8String() {
String testFilePath = "test/test_utf8.txt";
String contentByFileUtil = FileUtil.readUtf8String(testFilePath);
Assert.notEmpty(contentByFileUtil);
Assert.assertFalse(contentByFileUtil.isEmpty());
}
@Test
@ -36,6 +40,13 @@ public class FileUtilTest {
"empty line next" + linebreaks;
String testFilePath = "test/test_utf8.txt";
String contentByFileUtil = FileUtil.readUtf8String(testFilePath);
Assert.isTrue(testText.equals(contentByFileUtil));
Assert.assertTrue(testText.equals(contentByFileUtil));
}
@Test
public void assertReadLines() {
String testFilePath = "test/test_utf8.txt";
List<String> readLines = FileUtil.readLines(testFilePath, StandardCharsets.UTF_8);
Assert.assertEquals(3, readLines.size());
}
}

@ -17,14 +17,8 @@
package cn.hippo4j.common.toolkit;
import org.checkerframework.checker.units.qual.A;
import org.junit.Test;
import java.util.Arrays;
import java.util.List;
import static org.junit.Assert.*;
public class GroupKeyTest {
@Test

@ -0,0 +1,37 @@
/*
* 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.common.toolkit;
import org.junit.Assert;
import org.junit.Test;
public class IdUtilTest {
@Test
public void randomUUIDTest() {
String randomUUID = IdUtil.randomUUID();
Assert.assertNotNull(randomUUID);
}
@Test
public void simpleUUIDTest() {
String simpleUUID = IdUtil.simpleUUID();
Assert.assertNotNull(simpleUUID);
Assert.assertFalse(simpleUUID.contains("-"));
}
}

@ -18,10 +18,13 @@
package cn.hippo4j.common.toolkit;
import lombok.Getter;
import lombok.Setter;
import org.junit.Test;
import org.junit.Assert;
import java.lang.reflect.Field;
import java.util.Objects;
import java.lang.reflect.Method;
import java.util.concurrent.ThreadPoolExecutor;
public class ReflectUtilTest {
@ -29,10 +32,10 @@ public class ReflectUtilTest {
public void getFieldValueTest() {
TestSubClass testSubClass = new TestSubClass();
Object privateField = ReflectUtil.getFieldValue(testSubClass, "privateField");
Assert.isTrue(Objects.equals("privateField", privateField));
Assert.assertEquals("privateField", privateField);
Object field = ReflectUtil.getFieldValue(testSubClass, "field");
Assert.isTrue(Objects.equals("field", field));
Assert.assertEquals("field", field);
}
@ -42,57 +45,106 @@ public class ReflectUtilTest {
Field privateField = ReflectUtil.getField(TestSubClass.class, "privateField");
Object privateFieldVal = ReflectUtil.getFieldValue(testSubClass, privateField);
Assert.isTrue(Objects.equals("privateField", privateFieldVal));
Assert.assertEquals("privateField", privateFieldVal);
}
@Test
public void getFieldTest() {
Field privateField = ReflectUtil.getField(TestSubClass.class, "privateField");
Assert.notNull(privateField);
Assert.assertNotNull(privateField);
Field field = ReflectUtil.getField(TestSubClass.class, "field");
Assert.notNull(field);
Assert.assertNotNull(field);
}
@Test
public void getFieldsTest() {
Field[] fields = ReflectUtil.getFields(TestSubClass.class);
Assert.isTrue(Objects.equals(4, fields.length));
Assert.assertEquals(4, fields.length);
}
@Test
public void getFieldsDirectlyTest() {
Field[] fields = ReflectUtil.getFieldsDirectly(TestSubClass.class, false);
Assert.isTrue(Objects.equals(2, fields.length));
Assert.assertEquals(2, fields.length);
fields = ReflectUtil.getFieldsDirectly(TestSubClass.class, true);
Assert.isTrue(Objects.equals(4, fields.length));
Assert.assertEquals(4, fields.length);
}
@Test
public void getFieldNameTest() {
Field privateField = ReflectUtil.getField(TestSubClass.class, "privateField");
String fieldName = ReflectUtil.getFieldName(privateField);
Assert.notNull(fieldName);
Assert.assertNotNull(fieldName);
Field subField = ReflectUtil.getField(TestSubClass.class, "subField");
String subfieldName = ReflectUtil.getFieldName(subField);
Assert.notNull(subfieldName);
Assert.assertNotNull(subfieldName);
}
@Test
public void setFieldValueTest() {
TestClass testClass = new TestClass();
ReflectUtil.setFieldValue(testClass, "field", "fieldVal");
Assert.isTrue(Objects.equals("fieldVal", testClass.getField()));
Assert.assertEquals("fieldVal", testClass.getField());
Field privateField = ReflectUtil.getField(TestSubClass.class, "privateField");
ReflectUtil.setFieldValue(testClass, privateField, "privateFieldVal");
Assert.isTrue(Objects.equals("privateFieldVal", testClass.getPrivateField()));
Assert.assertEquals("privateFieldVal", testClass.getPrivateField());
}
@Test
public void castTest() {
TestClass testClass = new TestSubClass();
Object cast = ReflectUtil.cast(TestSubClass.class, testClass);
Assert.assertTrue(cast instanceof TestSubClass);
}
@Test
public void getDefaultValueTest() {
Object defaultValue = ReflectUtil.getDefaultValue(Long.class);
Assert.assertNull(defaultValue);
Object primitiveValueLong = ReflectUtil.getDefaultValue(long.class);
Assert.assertEquals(0L, primitiveValueLong);
Object primitiveValueInt = ReflectUtil.getDefaultValue(int.class);
Assert.assertEquals(0, primitiveValueInt);
Object primitiveValueFloat = ReflectUtil.getDefaultValue(float.class);
Assert.assertEquals(0f, primitiveValueFloat);
Object primitiveValueShort = ReflectUtil.getDefaultValue(short.class);
Assert.assertEquals((short) 0, primitiveValueShort);
Object primitiveValueChar = ReflectUtil.getDefaultValue(char.class);
Assert.assertEquals((char) 0, primitiveValueChar);
Object primitiveValueDouble = ReflectUtil.getDefaultValue(double.class);
Assert.assertEquals(0D, primitiveValueDouble);
Object primitiveValueBoolean = ReflectUtil.getDefaultValue(boolean.class);
Assert.assertEquals(false, primitiveValueBoolean);
}
@Test
public void getMethodByNameTest() {
// private method
Method runStateLessThan = ReflectUtil.getMethodByName(ThreadPoolExecutor.class, "runStateLessThan");
Assert.assertNotNull(runStateLessThan);
// public method
Method field = ReflectUtil.getMethodByName(TestClass.class, "setPrivateField");
Assert.assertNotNull(field);
// parameters
Method privateField = ReflectUtil.getMethodByName(TestClass.class, "setPrivateField", String.class);
Assert.assertNotNull(privateField);
}
@Test
public void invokeTest() {
TestClass testClass = new TestClass();
Method method = ReflectUtil.getMethodByName(TestClass.class, "getPrivateField");
String invoke = ReflectUtil.invoke(testClass, method);
Assert.assertEquals(invoke, "privateField");
}
@Getter
@Setter
static class TestClass {
private String privateField;

@ -90,4 +90,11 @@ public class StringUtilTest {
String s = StringUtil.toSymbolCase(string, StringUtil.UNDERLINE);
Assert.isTrue(Objects.equals(s, "str"));
}
@Test
public void toCamelCase() {
String string = "str_str";
String s = StringUtil.toCamelCase(string, StringUtil.UNDERLINE);
Assert.isTrue(Objects.equals(s, "strStr"));
}
}

@ -18,8 +18,7 @@
package cn.hippo4j.common.toolkit;
import org.junit.Test;
import static org.junit.Assert.assertTrue;
import org.junit.Assert;
public class ThreadUtilTest {
@ -32,11 +31,11 @@ public class ThreadUtilTest {
final Thread result = ThreadUtil.newThread(runnable, "name", false);
// Verify the results
Assert.notNull(result);
Assert.assertNotNull(result);
}
@Test
public void testSleep() {
assertTrue(ThreadUtil.sleep(0L));
Assert.assertTrue(ThreadUtil.sleep(0L));
}
}

@ -17,11 +17,8 @@
package cn.hippo4j.common.toolkit;
import cn.hutool.core.util.ReflectUtil;
import org.junit.jupiter.api.Test;
import java.lang.reflect.Field;
public class UserContextTest {
private static final String USERNAME = "test";

@ -15,6 +15,12 @@
</properties>
<dependencies>
<dependency>
<groupId>cn.hippo4j</groupId>
<artifactId>hippo4j-common</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
@ -43,22 +49,6 @@
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
</dependency>
<dependency>
<groupId>cn.hippo4j</groupId>
<artifactId>hippo4j-common</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>com.github.dozermapper</groupId>
<artifactId>dozer-core</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
@ -86,6 +76,11 @@
<artifactId>netty-all</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>

@ -20,10 +20,10 @@ package cn.hippo4j.config.monitor;
import cn.hippo4j.common.config.ApplicationContextHolder;
import cn.hippo4j.common.monitor.Message;
import cn.hippo4j.common.monitor.MessageTypeEnum;
import com.google.common.collect.Maps;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
/**
@ -35,7 +35,7 @@ public class QueryMonitorExecuteChoose implements CommandLineRunner {
/**
* Storage monitoring data execution container.
*/
private Map<String, AbstractMonitorDataExecuteStrategy> monitorDataExecuteStrategyChooseMap = Maps.newHashMap();
private Map<String, AbstractMonitorDataExecuteStrategy> monitorDataExecuteStrategyChooseMap = new HashMap<>();
/**
* Choose by {@link cn.hippo4j.common.monitor.MessageTypeEnum}.

@ -18,11 +18,10 @@
package cn.hippo4j.config.monitor;
import cn.hippo4j.common.executor.ExecutorFactory;
import cn.hippo4j.common.toolkit.DateUtil;
import cn.hippo4j.config.config.ServerBootstrapProperties;
import cn.hippo4j.config.model.HisRunDataInfo;
import cn.hippo4j.config.service.biz.HisRunDataService;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.NonNull;
@ -30,6 +29,7 @@ import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
@ -53,10 +53,9 @@ public class TimeCleanHistoryDataTask implements Runnable, InitializingBean {
@Override
public void run() {
Date currentDate = new Date();
DateTime offsetMinuteDateTime = DateUtil.offsetMinute(currentDate, -properties.getCleanHistoryDataPeriod());
LocalDateTime offsetMinuteDateTime = LocalDateTime.now().plusMinutes(-properties.getCleanHistoryDataPeriod());
LambdaQueryWrapper<HisRunDataInfo> queryWrapper = Wrappers.lambdaQuery(HisRunDataInfo.class)
.le(HisRunDataInfo::getTimestamp, offsetMinuteDateTime.getTime());
.le(HisRunDataInfo::getTimestamp, DateUtil.getTime(offsetMinuteDateTime));
hisRunDataService.remove(queryWrapper);
}

@ -18,11 +18,13 @@
package cn.hippo4j.config.notify;
import cn.hippo4j.config.event.AbstractEvent;
import cn.hutool.core.collection.ConcurrentHashSet;
import cn.hippo4j.config.notify.listener.AbstractSubscriber;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executor;
@ -34,7 +36,7 @@ import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
@Slf4j
public class DefaultPublisher extends Thread implements EventPublisher {
protected final ConcurrentHashSet<AbstractSubscriber> subscribers = new ConcurrentHashSet();
protected final Set<AbstractSubscriber> subscribers = Collections.synchronizedSet(new HashSet<>());
private BlockingQueue<AbstractEvent> queue;

@ -18,10 +18,11 @@
package cn.hippo4j.config.notify;
import cn.hippo4j.config.event.AbstractEvent;
import cn.hutool.core.collection.ConcurrentHashSet;
import cn.hippo4j.config.notify.listener.AbstractSubscriber;
import cn.hippo4j.config.event.AbstractSlowEvent;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
@ -35,7 +36,7 @@ public class DefaultSharePublisher extends DefaultPublisher {
private final Map<Class<? extends AbstractSlowEvent>, Set<AbstractSubscriber>> subMappings = new ConcurrentHashMap();
protected final ConcurrentHashSet<AbstractSubscriber> subscribers = new ConcurrentHashSet();
protected final Set<AbstractSubscriber> subscribers = Collections.synchronizedSet(new HashSet<>());
private final Lock lock = new ReentrantLock();
@ -46,7 +47,7 @@ public class DefaultSharePublisher extends DefaultPublisher {
try {
Set<AbstractSubscriber> sets = subMappings.get(subSlowEventType);
if (sets == null) {
Set<AbstractSubscriber> newSet = new ConcurrentHashSet();
Set<AbstractSubscriber> newSet = Collections.synchronizedSet(new HashSet<>());
newSet.add(subscriber);
subMappings.put(subSlowEventType, newSet);
return;

@ -24,18 +24,15 @@ import cn.hippo4j.common.design.observer.Observer;
import cn.hippo4j.common.design.observer.ObserverMessage;
import cn.hippo4j.common.toolkit.CollectionUtil;
import cn.hippo4j.common.toolkit.JSONUtil;
import cn.hippo4j.common.toolkit.Joiner;
import cn.hippo4j.common.toolkit.Md5Util;
import cn.hippo4j.common.toolkit.StringUtil;
import cn.hippo4j.config.event.LocalDataChangeEvent;
import cn.hippo4j.config.model.CacheItem;
import cn.hippo4j.config.model.ConfigAllInfo;
import cn.hippo4j.config.notify.NotifyCenter;
import cn.hippo4j.config.service.biz.ConfigService;
import cn.hippo4j.config.toolkit.MapUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;
@ -79,9 +76,9 @@ public class ConfigCacheService {
* @return
*/
private synchronized static String getContentMd5IsNullPut(String groupKey, String clientIdentify) {
Map<String, CacheItem> cacheItemMap = Optional.ofNullable(CLIENT_CONFIG_CACHE.get(groupKey)).orElse(Maps.newHashMap());
Map<String, CacheItem> cacheItemMap = Optional.ofNullable(CLIENT_CONFIG_CACHE.get(groupKey)).orElse(new HashMap<>());
CacheItem cacheItem = null;
if (CollUtil.isNotEmpty(cacheItemMap) && (cacheItem = cacheItemMap.get(clientIdentify)) != null) {
if (CollectionUtil.isNotEmpty(cacheItemMap) && (cacheItem = cacheItemMap.get(clientIdentify)) != null) {
return cacheItem.md5;
}
if (CONFIG_SERVICE == null) {
@ -89,7 +86,7 @@ public class ConfigCacheService {
}
String[] params = groupKey.split(GROUP_KEY_DELIMITER_TRANSLATION);
ConfigAllInfo config = CONFIG_SERVICE.findConfigRecentInfo(params);
if (config != null && StrUtil.isNotBlank(config.getTpId())) {
if (config != null && StringUtil.isNotBlank(config.getTpId())) {
cacheItem = new CacheItem(groupKey, config);
cacheItemMap.put(clientIdentify, cacheItem);
CLIENT_CONFIG_CACHE.put(groupKey, cacheItemMap);
@ -129,7 +126,7 @@ public class ConfigCacheService {
return item;
}
CacheItem tmp = new CacheItem(groupKey);
Map<String, CacheItem> cacheItemMap = Maps.newHashMap();
Map<String, CacheItem> cacheItemMap = new HashMap<>();
cacheItemMap.put(ip, tmp);
CLIENT_CONFIG_CACHE.putIfAbsent(groupKey, cacheItemMap);
return tmp;
@ -137,7 +134,7 @@ public class ConfigCacheService {
public static Map<String, CacheItem> getContent(String identification) {
List<String> identificationList = MapUtil.parseMapForFilter(CLIENT_CONFIG_CACHE, identification);
Map<String, CacheItem> returnStrCacheItemMap = Maps.newHashMap();
Map<String, CacheItem> returnStrCacheItemMap = new HashMap<>();
identificationList.forEach(each -> returnStrCacheItemMap.putAll(CLIENT_CONFIG_CACHE.get(each)));
return returnStrCacheItemMap;
}
@ -150,13 +147,13 @@ public class ConfigCacheService {
public static List<String> getIdentifyList(String tenantId, String itemId, String threadPoolId) {
List<String> identifyList = null;
String buildKey = Joiner.on(GROUP_KEY_DELIMITER).join(Lists.newArrayList(threadPoolId, itemId, tenantId));
String buildKey = Joiner.on(GROUP_KEY_DELIMITER).join(CollectionUtil.newArrayList(threadPoolId, itemId, tenantId));
List<String> keys = MapUtil.parseMapForFilter(CLIENT_CONFIG_CACHE, buildKey);
if (CollectionUtil.isNotEmpty(keys)) {
identifyList = new ArrayList(keys.size());
identifyList = new ArrayList<>(keys.size());
for (String each : keys) {
String[] keyArray = each.split(GROUP_KEY_DELIMITER_TRANSLATION);
if (keyArray != null && keyArray.length > 2) {
if (keyArray.length > 2) {
identifyList.add(keyArray[3]);
}
}

@ -17,9 +17,8 @@
package cn.hippo4j.config.service;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import lombok.NonNull;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
@ -36,20 +35,21 @@ import static cn.hippo4j.common.constant.Constants.WEIGHT_CONFIGS;
@RequiredArgsConstructor
public class ConfigServletInner {
@NonNull
private final LongPollingService longPollingService;
private final Cache<String, Long> deWeightCache = CacheBuilder.newBuilder()
.maximumSize(1024)
private static final int CLIENT_IDENTIFY_MAXIMUM_SIZE = 16384;
private final Cache<String, Long> deWeightCache = Caffeine.newBuilder()
.maximumSize(CLIENT_IDENTIFY_MAXIMUM_SIZE)
.build();
/**
* Poll configuration.
*
* @param request
* @param response
* @param clientMd5Map
* @param probeRequestSize
* @param request http servlet request
* @param response http servlet response
* @param clientMd5Map client md5 map
* @param probeRequestSize probe request size
* @return
*/
public String doPollingConfig(HttpServletRequest request, HttpServletResponse response, Map<String, String> clientMd5Map, int probeRequestSize) {
@ -66,7 +66,7 @@ public class ConfigServletInner {
* When a user proposes to deploy in the company environment, the same request will be called repeatedly.
* This problem belongs to an extremely individual scenario. Since it cannot be reproduced, so first solve the problem in this way.
*
* @param request
* @param request http servlet request
* @return
*/
private boolean weightVerification(HttpServletRequest request) {

@ -17,8 +17,10 @@
package cn.hippo4j.config.service;
import cn.hippo4j.common.toolkit.CollectionUtil;
import cn.hippo4j.common.toolkit.JSONUtil;
import cn.hippo4j.common.toolkit.Md5Util;
import cn.hippo4j.common.toolkit.StringUtil;
import cn.hippo4j.common.web.base.Results;
import cn.hippo4j.config.event.AbstractEvent;
import cn.hippo4j.config.event.LocalDataChangeEvent;
@ -28,9 +30,6 @@ import cn.hippo4j.config.toolkit.ConfigExecutor;
import cn.hippo4j.config.toolkit.MapUtil;
import cn.hippo4j.config.toolkit.Md5ConfigUtil;
import cn.hippo4j.config.toolkit.RequestUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.google.common.collect.Lists;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@ -117,8 +116,8 @@ public class LongPollingService {
for (Iterator<ClientLongPolling> iter = allSubs.iterator(); iter.hasNext();) {
ClientLongPolling clientSub = iter.next();
String identity = groupKey + GROUP_KEY_DELIMITER + identify;
List<String> parseMapForFilter = Lists.newArrayList(identity);
if (StrUtil.isBlank(identify)) {
List<String> parseMapForFilter = CollectionUtil.newArrayList(identity);
if (StringUtil.isBlank(identify)) {
parseMapForFilter = MapUtil.parseMapForFilter(clientSub.clientMd5Map, groupKey);
}
parseMapForFilter.forEach(each -> {
@ -274,7 +273,7 @@ public class LongPollingService {
* @param changedGroups Changed thread pool group key
*/
private void generateResponse(HttpServletResponse response, List<String> changedGroups) {
if (CollUtil.isNotEmpty(changedGroups)) {
if (CollectionUtil.isNotEmpty(changedGroups)) {
try {
String respStr = buildRespStr(changedGroups);
response.setHeader("Pragma", "no-cache");

@ -28,15 +28,14 @@ import cn.hippo4j.common.toolkit.StringUtil;
import cn.hippo4j.common.web.base.Result;
import cn.hippo4j.config.model.biz.adapter.ThreadPoolAdapterReqDTO;
import cn.hippo4j.config.model.biz.adapter.ThreadPoolAdapterRespDTO;
import cn.hutool.core.text.StrBuilder;
import cn.hutool.http.HttpUtil;
import com.fasterxml.jackson.core.type.TypeReference;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
import static cn.hippo4j.common.constant.Constants.HTTP_EXECUTE_TIMEOUT;
@ -52,7 +51,7 @@ public class ThreadPoolAdapterService {
/**
* Map<mark, Map<tenantItem, Map<threadPoolKey, List<ThreadPoolAdapterState>>>>
*/
private static final Map<String, Map<String, Map<String, List<ThreadPoolAdapterState>>>> THREAD_POOL_ADAPTER_MAP = Maps.newConcurrentMap();
private static final Map<String, Map<String, Map<String, List<ThreadPoolAdapterState>>>> THREAD_POOL_ADAPTER_MAP = new ConcurrentHashMap<>();
static {
AbstractSubjectCenter.register(AbstractSubjectCenter.SubjectType.CLEAR_CONFIG_CACHE, new ClearThreadPoolAdapterCache());
@ -64,19 +63,19 @@ public class ThreadPoolAdapterService {
String mark = each.getMark();
Map<String, Map<String, List<ThreadPoolAdapterState>>> actual = THREAD_POOL_ADAPTER_MAP.get(mark);
if (CollectionUtil.isEmpty(actual)) {
actual = Maps.newHashMap();
actual = new HashMap<>();
THREAD_POOL_ADAPTER_MAP.put(mark, actual);
}
Map<String, List<ThreadPoolAdapterState>> tenantItemMap = actual.get(each.getTenantItemKey());
if (CollectionUtil.isEmpty(tenantItemMap)) {
tenantItemMap = Maps.newHashMap();
tenantItemMap = new HashMap<>();
actual.put(each.getTenantItemKey(), tenantItemMap);
}
List<ThreadPoolAdapterState> threadPoolAdapterStates = each.getThreadPoolAdapterStates();
for (ThreadPoolAdapterState adapterState : threadPoolAdapterStates) {
List<ThreadPoolAdapterState> adapterStateList = tenantItemMap.get(adapterState.getThreadPoolKey());
if (CollectionUtil.isEmpty(adapterStateList)) {
adapterStateList = Lists.newArrayList();
adapterStateList = new ArrayList<>();
tenantItemMap.put(adapterState.getThreadPoolKey(), adapterStateList);
}
Optional<ThreadPoolAdapterState> first = adapterStateList.stream().filter(state -> Objects.equals(state.getClientAddress(), each.getClientAddress())).findFirst();
@ -95,16 +94,22 @@ public class ThreadPoolAdapterService {
List<ThreadPoolAdapterState> actual = Optional.ofNullable(THREAD_POOL_ADAPTER_MAP.get(requestParameter.getMark()))
.map(each -> each.get(requestParameter.getTenant() + IDENTIFY_SLICER_SYMBOL + requestParameter.getItem()))
.map(each -> each.get(requestParameter.getThreadPoolKey()))
.orElse(Lists.newArrayList());
.orElse(new ArrayList<>());
List<String> addressList = actual.stream().map(ThreadPoolAdapterState::getClientAddress).collect(Collectors.toList());
List<ThreadPoolAdapterRespDTO> result = new ArrayList<>(addressList.size());
addressList.forEach(each -> {
String urlString = StrBuilder.create("http://", each, "/adapter/thread-pool/info").toString();
Map<String, Object> param = Maps.newHashMap();
String urlString = new StringBuilder()
.append("http://")
.append(each)
.append("/adapter/thread-pool/info")
.toString();
Map<String, Object> param = new HashMap<>();
param.put("mark", requestParameter.getMark());
param.put("threadPoolKey", requestParameter.getThreadPoolKey());
try {
String resultStr = HttpUtil.get(urlString, param, HTTP_EXECUTE_TIMEOUT);
RestTemplate template = new RestTemplate();
String resultStr = template.getForObject(urlString, String.class, param);
if (StringUtil.isNotBlank(resultStr)) {
Result<ThreadPoolAdapterRespDTO> restResult = JSONUtil.parseObject(resultStr, new TypeReference<Result<ThreadPoolAdapterRespDTO>>() {
});

@ -27,18 +27,19 @@ import cn.hippo4j.common.web.exception.ServiceException;
import cn.hippo4j.config.event.LocalDataChangeEvent;
import cn.hippo4j.config.mapper.ConfigInfoMapper;
import cn.hippo4j.config.mapper.ConfigInstanceMapper;
import cn.hippo4j.config.model.*;
import cn.hippo4j.config.model.ConfigAllInfo;
import cn.hippo4j.config.model.ConfigInfoBase;
import cn.hippo4j.config.model.ConfigInstanceInfo;
import cn.hippo4j.config.model.LogRecordInfo;
import cn.hippo4j.config.model.biz.notify.NotifyReqDTO;
import cn.hippo4j.config.service.ConfigCacheService;
import cn.hippo4j.config.service.ConfigChangePublisher;
import cn.hippo4j.config.service.biz.*;
import cn.hippo4j.config.toolkit.BeanUtil;
import cn.hutool.core.util.StrUtil;
import cn.hippo4j.common.toolkit.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import com.google.common.collect.Lists;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@ -70,9 +71,9 @@ public class ConfigServiceImpl implements ConfigService {
@Override
public ConfigAllInfo findConfigAllInfo(String tpId, String itemId, String tenantId) {
LambdaQueryWrapper<ConfigAllInfo> wrapper = Wrappers.lambdaQuery(ConfigAllInfo.class)
.eq(StrUtil.isNotBlank(tpId), ConfigAllInfo::getTpId, tpId)
.eq(StrUtil.isNotBlank(itemId), ConfigAllInfo::getItemId, itemId)
.eq(StrUtil.isNotBlank(tenantId), ConfigAllInfo::getTenantId, tenantId);
.eq(StringUtil.isNotBlank(tpId), ConfigAllInfo::getTpId, tpId)
.eq(StringUtil.isNotBlank(itemId), ConfigAllInfo::getItemId, itemId)
.eq(StringUtil.isNotBlank(tenantId), ConfigAllInfo::getTenantId, tenantId);
ConfigAllInfo configAllInfo = configInfoMapper.selectOne(wrapper);
return configAllInfo;
}
@ -82,7 +83,7 @@ public class ConfigServiceImpl implements ConfigService {
ConfigAllInfo resultConfig;
ConfigAllInfo configInstance = null;
String instanceId = params[3];
if (StrUtil.isNotBlank(instanceId)) {
if (StringUtil.isNotBlank(instanceId)) {
LambdaQueryWrapper<ConfigInstanceInfo> instanceQueryWrapper = Wrappers.lambdaQuery(ConfigInstanceInfo.class)
.eq(ConfigInstanceInfo::getTpId, params[0])
.eq(ConfigInstanceInfo::getItemId, params[1])
@ -152,7 +153,8 @@ public class ConfigServiceImpl implements ConfigService {
}
DynamicThreadPoolRegisterServerNotifyParameter serverNotifyParameter = registerWrapper.getDynamicThreadPoolRegisterServerNotifyParameter();
if (serverNotifyParameter != null) {
ArrayList<String> notifyTypes = Lists.newArrayList("CONFIG", "ALARM");
ArrayList<String> notifyTypes = new ArrayList<>();
Collections.addAll(notifyTypes, "CONFIG", "ALARM");
notifyTypes.forEach(each -> {
NotifyReqDTO notifyReqDTO = new NotifyReqDTO();
notifyReqDTO.setType(each)

@ -20,6 +20,7 @@ package cn.hippo4j.config.service.biz.impl;
import cn.hippo4j.common.monitor.Message;
import cn.hippo4j.common.monitor.MessageWrapper;
import cn.hippo4j.common.monitor.RuntimeMessage;
import cn.hippo4j.common.toolkit.DateUtil;
import cn.hippo4j.common.toolkit.GroupKey;
import cn.hippo4j.common.toolkit.MessageConvert;
import cn.hippo4j.common.web.base.Result;
@ -32,21 +33,20 @@ import cn.hippo4j.config.model.biz.monitor.MonitorQueryReqDTO;
import cn.hippo4j.config.model.biz.monitor.MonitorRespDTO;
import cn.hippo4j.config.monitor.QueryMonitorExecuteChoose;
import cn.hippo4j.config.service.biz.HisRunDataService;
import cn.hippo4j.config.toolkit.BeanUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hippo4j.common.toolkit.BeanUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import lombok.AllArgsConstructor;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import static cn.hutool.core.date.DatePattern.NORM_TIME_PATTERN;
import static cn.hippo4j.common.toolkit.DateUtil.NORM_TIME_PATTERN;
/**
* His run data service impl.
@ -63,15 +63,15 @@ public class HisRunDataServiceImpl extends ServiceImpl<HisRunDataMapper, HisRunD
@Override
public List<MonitorRespDTO> query(MonitorQueryReqDTO reqDTO) {
Date currentDate = new Date();
DateTime dateTime = DateUtil.offsetMinute(currentDate, -properties.getCleanHistoryDataPeriod());
long startTime = dateTime.getTime();
LocalDateTime currentDate = LocalDateTime.now();
LocalDateTime dateTime = currentDate.plusMinutes(-properties.getCleanHistoryDataPeriod());
long startTime = DateUtil.getTime(dateTime);
List<HisRunDataInfo> hisRunDataInfos = this.lambdaQuery()
.eq(HisRunDataInfo::getTenantId, reqDTO.getTenantId())
.eq(HisRunDataInfo::getItemId, reqDTO.getItemId())
.eq(HisRunDataInfo::getTpId, reqDTO.getTpId())
.eq(HisRunDataInfo::getInstanceId, reqDTO.getInstanceId())
.between(HisRunDataInfo::getTimestamp, startTime, currentDate.getTime())
.between(HisRunDataInfo::getTimestamp, startTime, DateUtil.getTime(currentDate))
.orderByAsc(HisRunDataInfo::getTimestamp)
.list();
return BeanUtil.convert(hisRunDataInfos, MonitorRespDTO.class);
@ -79,26 +79,26 @@ public class HisRunDataServiceImpl extends ServiceImpl<HisRunDataMapper, HisRunD
@Override
public MonitorActiveRespDTO queryInfoThreadPoolMonitor(MonitorQueryReqDTO reqDTO) {
Date currentDate = new Date();
DateTime dateTime = DateUtil.offsetMinute(currentDate, -properties.getCleanHistoryDataPeriod());
long startTime = dateTime.getTime();
LocalDateTime currentDate = LocalDateTime.now();
LocalDateTime dateTime = currentDate.plusMinutes(-properties.getCleanHistoryDataPeriod());
long startTime = DateUtil.getTime(dateTime);
List<HisRunDataInfo> hisRunDataInfos = this.lambdaQuery()
.eq(HisRunDataInfo::getTenantId, reqDTO.getTenantId())
.eq(HisRunDataInfo::getItemId, reqDTO.getItemId())
.eq(HisRunDataInfo::getTpId, reqDTO.getTpId())
.eq(HisRunDataInfo::getInstanceId, reqDTO.getInstanceId())
.between(HisRunDataInfo::getTimestamp, startTime, currentDate.getTime())
.between(HisRunDataInfo::getTimestamp, startTime, DateUtil.getTime(currentDate))
.orderByAsc(HisRunDataInfo::getTimestamp)
.list();
List<String> times = Lists.newArrayList();
List<Long> poolSizeList = Lists.newArrayList();
List<Long> activeSizeList = Lists.newArrayList();
List<Long> queueCapacityList = Lists.newArrayList();
List<Long> queueSizeList = Lists.newArrayList();
List<Long> completedTaskCountList = Lists.newArrayList();
List<Long> rejectCountList = Lists.newArrayList();
List<Long> queueRemainingCapacityList = Lists.newArrayList();
List<Long> currentLoadList = Lists.newArrayList();
List<String> times = new ArrayList<>();
List<Long> poolSizeList = new ArrayList<>();
List<Long> activeSizeList = new ArrayList<>();
List<Long> queueCapacityList = new ArrayList<>();
List<Long> queueSizeList = new ArrayList<>();
List<Long> completedTaskCountList = new ArrayList<>();
List<Long> rejectCountList = new ArrayList<>();
List<Long> queueRemainingCapacityList = new ArrayList<>();
List<Long> currentLoadList = new ArrayList<>();
long countTemp = 0L;
AtomicBoolean firstFlag = new AtomicBoolean(Boolean.TRUE);
for (HisRunDataInfo each : hisRunDataInfos) {
@ -127,16 +127,16 @@ public class HisRunDataServiceImpl extends ServiceImpl<HisRunDataMapper, HisRunD
@Override
public MonitorRespDTO queryThreadPoolLastTaskCount(MonitorQueryReqDTO reqDTO) {
Date currentDate = new Date();
DateTime dateTime = DateUtil.offsetMinute(currentDate, -properties.getCleanHistoryDataPeriod());
long startTime = dateTime.getTime();
LocalDateTime currentDate = LocalDateTime.now();
LocalDateTime dateTime = currentDate.plusMinutes(-properties.getCleanHistoryDataPeriod());
long startTime = DateUtil.getTime(dateTime);
HisRunDataInfo hisRunDataInfo = this.lambdaQuery()
.eq(HisRunDataInfo::getTenantId, reqDTO.getTenantId())
.eq(HisRunDataInfo::getItemId, reqDTO.getItemId())
.eq(HisRunDataInfo::getTpId, reqDTO.getTpId())
.eq(HisRunDataInfo::getInstanceId, reqDTO.getInstanceId())
.orderByDesc(HisRunDataInfo::getTimestamp)
.between(HisRunDataInfo::getTimestamp, startTime, currentDate.getTime())
.between(HisRunDataInfo::getTimestamp, startTime, DateUtil.getTime(currentDate))
.last("LIMIT 1")
.one();
return BeanUtil.convert(hisRunDataInfo, MonitorRespDTO.class);
@ -146,7 +146,7 @@ public class HisRunDataServiceImpl extends ServiceImpl<HisRunDataMapper, HisRunD
@Transactional(rollbackFor = Exception.class)
public void save(Message message) {
List<RuntimeMessage> runtimeMessages = message.getMessages();
List<HisRunDataInfo> hisRunDataInfos = Lists.newArrayList();
List<HisRunDataInfo> hisRunDataInfos = new ArrayList<>();
runtimeMessages.forEach(each -> {
HisRunDataInfo hisRunDataInfo = BeanUtil.convert(each, HisRunDataInfo.class);
String[] parseKey = GroupKey.parseKey(each.getGroupKey());

@ -28,7 +28,7 @@ import cn.hippo4j.config.model.biz.item.ItemUpdateReqDTO;
import cn.hippo4j.config.model.biz.threadpool.ThreadPoolRespDTO;
import cn.hippo4j.config.service.biz.ItemService;
import cn.hippo4j.config.service.biz.ThreadPoolService;
import cn.hippo4j.config.toolkit.BeanUtil;
import cn.hippo4j.common.toolkit.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;

@ -18,7 +18,10 @@
package cn.hippo4j.config.service.biz.impl;
import cn.hippo4j.common.enums.EnableEnum;
import cn.hippo4j.common.toolkit.CollectionUtil;
import cn.hippo4j.common.toolkit.BooleanUtil;
import cn.hippo4j.common.toolkit.GroupKey;
import cn.hippo4j.common.toolkit.StringUtil;
import cn.hippo4j.common.web.exception.ServiceException;
import cn.hippo4j.config.mapper.NotifyInfoMapper;
import cn.hippo4j.config.model.NotifyInfo;
@ -27,19 +30,16 @@ import cn.hippo4j.config.model.biz.notify.NotifyQueryReqDTO;
import cn.hippo4j.config.model.biz.notify.NotifyReqDTO;
import cn.hippo4j.config.model.biz.notify.NotifyRespDTO;
import cn.hippo4j.config.service.biz.NotifyService;
import cn.hippo4j.config.toolkit.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hippo4j.common.toolkit.BooleanUtil;
import cn.hutool.core.util.StrUtil;
import cn.hippo4j.common.toolkit.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Lists;
import lombok.AllArgsConstructor;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
@ -54,16 +54,16 @@ public class NotifyServiceImpl implements NotifyService {
@Override
public List<NotifyListRespDTO> listNotifyConfig(NotifyQueryReqDTO reqDTO) {
List<NotifyListRespDTO> notifyListRespList = Lists.newArrayList();
List<NotifyListRespDTO> notifyListRespList = new ArrayList<>();
reqDTO.getGroupKeys().forEach(each -> {
String[] parseKey = GroupKey.parseKey(each);
List<NotifyInfo> notifyInfos = listNotifyCommon("CONFIG", parseKey);
if (CollUtil.isNotEmpty(notifyInfos)) {
notifyListRespList.add(new NotifyListRespDTO(StrUtil.builder(parseKey[0], "+", "CONFIG").toString(), notifyInfos));
if (CollectionUtil.isNotEmpty(notifyInfos)) {
notifyListRespList.add(new NotifyListRespDTO(parseKey[0] + "+" + "CONFIG", notifyInfos));
}
List<NotifyInfo> alarmInfos = listNotifyCommon("ALARM", parseKey);
if (CollUtil.isNotEmpty(alarmInfos)) {
notifyListRespList.add(new NotifyListRespDTO(StrUtil.builder(parseKey[0], "+", "ALARM").toString(), alarmInfos));
if (CollectionUtil.isNotEmpty(alarmInfos)) {
notifyListRespList.add(new NotifyListRespDTO(parseKey[0] + "+" + "ALARM", alarmInfos));
}
});
return notifyListRespList;
@ -72,9 +72,9 @@ public class NotifyServiceImpl implements NotifyService {
@Override
public IPage<NotifyRespDTO> queryPage(NotifyQueryReqDTO reqDTO) {
LambdaQueryWrapper<NotifyInfo> queryWrapper = Wrappers.lambdaQuery(NotifyInfo.class)
.eq(StrUtil.isNotBlank(reqDTO.getTenantId()), NotifyInfo::getTenantId, reqDTO.getTenantId())
.eq(StrUtil.isNotBlank(reqDTO.getItemId()), NotifyInfo::getItemId, reqDTO.getItemId())
.eq(StrUtil.isNotBlank(reqDTO.getTpId()), NotifyInfo::getTpId, reqDTO.getTpId())
.eq(StringUtil.isNotBlank(reqDTO.getTenantId()), NotifyInfo::getTenantId, reqDTO.getTenantId())
.eq(StringUtil.isNotBlank(reqDTO.getItemId()), NotifyInfo::getItemId, reqDTO.getItemId())
.eq(StringUtil.isNotBlank(reqDTO.getTpId()), NotifyInfo::getTpId, reqDTO.getTpId())
.orderByDesc(NotifyInfo::getGmtCreate);
IPage<NotifyInfo> resultPage = notifyInfoMapper.selectPage(reqDTO, queryWrapper);
return resultPage.convert(each -> {
@ -93,7 +93,7 @@ public class NotifyServiceImpl implements NotifyService {
if (BooleanUtil.isTrue(requestParam.getAlarmType())) {
existNotify("ALARM", requestParam);
}
List<NotifyInfo> notifyInfos = Lists.newArrayList();
List<NotifyInfo> notifyInfos = new ArrayList<>();
if (BooleanUtil.isTrue(requestParam.getAlarmType())) {
NotifyInfo alarmNotifyInfo = BeanUtil.convert(requestParam, NotifyInfo.class);
alarmNotifyInfo.setType("ALARM");
@ -173,7 +173,7 @@ public class NotifyServiceImpl implements NotifyService {
.eq(NotifyInfo::getPlatform, requestParam.getPlatform())
.eq(NotifyInfo::getType, type);
List<NotifyInfo> existNotifyInfos = notifyInfoMapper.selectList(queryWrapper);
if (CollUtil.isNotEmpty(existNotifyInfos)) {
if (CollectionUtil.isNotEmpty(existNotifyInfos)) {
throw new ServiceException(String.format("%s 新增通知报警配置重复", type));
}
}

@ -17,13 +17,13 @@
package cn.hippo4j.config.service.biz.impl;
import cn.hippo4j.common.toolkit.StringUtil;
import cn.hippo4j.config.mapper.OperationLogMapper;
import cn.hippo4j.config.model.LogRecordInfo;
import cn.hippo4j.config.model.biz.log.LogRecordQueryReqDTO;
import cn.hippo4j.config.model.biz.log.LogRecordRespDTO;
import cn.hippo4j.config.service.biz.OperationLogService;
import cn.hippo4j.config.toolkit.BeanUtil;
import cn.hutool.core.util.StrUtil;
import cn.hippo4j.common.toolkit.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
@ -42,9 +42,9 @@ public class OperationLogServiceImpl implements OperationLogService {
@Override
public IPage<LogRecordRespDTO> queryPage(LogRecordQueryReqDTO pageQuery) {
LambdaQueryWrapper<LogRecordInfo> queryWrapper = Wrappers.lambdaQuery(LogRecordInfo.class)
.eq(StrUtil.isNotBlank(pageQuery.getBizNo()), LogRecordInfo::getBizNo, pageQuery.getBizNo())
.eq(StrUtil.isNotBlank(pageQuery.getCategory()), LogRecordInfo::getCategory, pageQuery.getCategory())
.eq(StrUtil.isNotBlank(pageQuery.getOperator()), LogRecordInfo::getOperator, pageQuery.getOperator())
.eq(StringUtil.isNotBlank(pageQuery.getBizNo()), LogRecordInfo::getBizNo, pageQuery.getBizNo())
.eq(StringUtil.isNotBlank(pageQuery.getCategory()), LogRecordInfo::getCategory, pageQuery.getCategory())
.eq(StringUtil.isNotBlank(pageQuery.getOperator()), LogRecordInfo::getOperator, pageQuery.getOperator())
.orderByDesc(LogRecordInfo::getCreateTime);
IPage<LogRecordInfo> selectPage = operationLogMapper.selectPage(pageQuery, queryWrapper);
return selectPage.convert(each -> BeanUtil.convert(each, LogRecordRespDTO.class));

@ -29,7 +29,7 @@ import cn.hippo4j.config.model.biz.tenant.TenantSaveReqDTO;
import cn.hippo4j.config.model.biz.tenant.TenantUpdateReqDTO;
import cn.hippo4j.config.service.biz.ItemService;
import cn.hippo4j.config.service.biz.TenantService;
import cn.hippo4j.config.toolkit.BeanUtil;
import cn.hippo4j.common.toolkit.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;

@ -19,8 +19,8 @@ package cn.hippo4j.config.service.handler;
import cn.hippo4j.common.api.ClientCloseHookExecute;
import cn.hippo4j.common.toolkit.JSONUtil;
import cn.hippo4j.common.toolkit.StringUtil;
import cn.hippo4j.config.service.ConfigCacheService;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@ -36,7 +36,7 @@ public class ClientCloseHookRemoveConfigCache implements ClientCloseHookExecute
log.info("Remove Config Cache, Execute client hook function. Request: {}", JSONUtil.toJSONString(requestParam));
try {
String groupKey = requestParam.getGroupKey();
if (StrUtil.isNotBlank(groupKey)) {
if (StringUtil.isNotBlank(groupKey)) {
ConfigCacheService.removeConfigCache(groupKey);
}
} catch (Exception ex) {

@ -1,67 +0,0 @@
/*
* 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.toolkit;
import com.github.dozermapper.core.DozerBeanMapperBuilder;
import com.github.dozermapper.core.Mapper;
import java.util.*;
/**
* Bean util.
*/
public class BeanUtil {
private BeanUtil() {
}
protected static Mapper BEAN_MAPPER_BUILDER;
static {
BEAN_MAPPER_BUILDER = DozerBeanMapperBuilder.buildDefault();
}
public static <T, S> T convert(S source, Class<T> clazz) {
return Optional.ofNullable(source)
.map(each -> BEAN_MAPPER_BUILDER.map(each, clazz))
.orElse(null);
}
public static <T, S> List<T> convert(List<S> sources, Class<T> clazz) {
return Optional.ofNullable(sources)
.map(each -> {
List<T> targetList = new ArrayList<T>(each.size());
each.stream()
.forEach(item -> targetList.add(BEAN_MAPPER_BUILDER.map(item, clazz)));
return targetList;
})
.orElse(null);
}
public static <T, S> Set<T> convert(Set<S> sources, Class<T> clazz) {
return Optional.ofNullable(sources)
.map(each -> {
Set<T> targetSize = new HashSet<T>(each.size());
each.stream()
.forEach(item -> targetSize.add(BEAN_MAPPER_BUILDER.map(item, clazz)));
return targetSize;
})
.orElse(null);
}
}

@ -17,9 +17,9 @@
package cn.hippo4j.config.toolkit;
import cn.hutool.core.collection.CollUtil;
import com.google.common.collect.Lists;
import cn.hippo4j.common.toolkit.CollectionUtil;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@ -53,8 +53,8 @@ public class MapUtil {
* @return
*/
public static List<String> parseMapForFilter(Map<String, ?> sourceMap, String filters) {
List<String> resultList = Lists.newArrayList();
if (CollUtil.isEmpty(sourceMap)) {
List<String> resultList = new ArrayList<>();
if (CollectionUtil.isEmpty(sourceMap)) {
return resultList;
}
sourceMap.forEach((key, val) -> {

@ -17,7 +17,7 @@
package cn.hippo4j.config.toolkit;
import cn.hutool.core.util.StrUtil;
import cn.hippo4j.common.toolkit.StringUtil;
import javax.servlet.http.HttpServletRequest;
@ -36,6 +36,6 @@ public class RequestUtil {
public static String getClientIdentify(HttpServletRequest request) {
String identify = request.getHeader(LONG_PULLING_CLIENT_IDENTIFICATION);
return StrUtil.isBlank(identify) ? "" : identify;
return StringUtil.isBlank(identify) ? "" : identify;
}
}

@ -18,7 +18,6 @@
package cn.hippo4j.config.toolkit;
import cn.hippo4j.common.toolkit.Assert;
import cn.hutool.core.lang.caller.CallerUtil;
import org.junit.Test;
import java.util.Objects;

@ -18,7 +18,7 @@
package cn.hippo4j.config.toolkit;
import cn.hippo4j.common.toolkit.Assert;
import cn.hutool.core.util.StrUtil;
import cn.hippo4j.common.toolkit.StringUtil;
import org.junit.Test;
/**
@ -29,7 +29,7 @@ public class EnvUtilTest {
@Test
public void getHippo4JHomeTest() {
String hippo4JHome = EnvUtil.getHippo4JHome();
Assert.isTrue(StrUtil.isNotBlank(hippo4JHome));
Assert.isTrue(StringUtil.isNotBlank(hippo4JHome));
}
@Test

@ -18,8 +18,7 @@
package cn.hippo4j.config.toolkit;
import cn.hippo4j.common.toolkit.Assert;
import cn.hutool.core.collection.CollectionUtil;
import com.google.common.collect.ImmutableMap;
import cn.hippo4j.common.toolkit.CollectionUtil;
import org.junit.Test;
import java.util.HashMap;
@ -35,14 +34,20 @@ public class MapUtilTest {
@Test
public void parseMapForFilterRetIsEmptyTest() {
Map<String, Object> map = ImmutableMap.of("abc", "123", "bcd", "456", "cde", "789");
HashMap<String, Object> map = new HashMap<>();
map.put("abc", "123");
map.put("bcd", "456");
map.put("cde", "789");
List<String> ret = MapUtil.parseMapForFilter(map, "x");
Assert.isTrue(CollectionUtil.isEmpty(ret));
}
@Test
public void parseMapForFilterRetIsNotEmptyTest() {
Map<String, Object> map = ImmutableMap.of("abc", "123", "bcd", "456", "cde", "789");
HashMap<String, Object> map = new HashMap<>();
map.put("abc", "123");
map.put("bcd", "456");
map.put("cde", "789");
List<String> ret = MapUtil.parseMapForFilter(map, "b");
Assert.isTrue(CollectionUtil.isNotEmpty(ret));
}

@ -17,8 +17,76 @@
package cn.hippo4j.config.toolkit;
import cn.hippo4j.common.toolkit.Assert;
import cn.hippo4j.common.toolkit.StringUtil;
import cn.hippo4j.config.model.ConfigAllInfo;
import org.assertj.core.util.Lists;
import org.junit.Test;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Objects;
/**
* Md5ConfigUtil Test
*/
public class Md5ConfigUtilTest {
@Test
public void getKeyTest() {
String key = Md5ConfigUtil.getKey("DataId", "Group");
Assert.isTrue(Objects.equals("DataId+Group", key));
}
@Test
public void getKeySpecialTest() {
String key = Md5ConfigUtil.getKey("DataId+", "Group");
Assert.isTrue(Objects.equals("DataId%2B+Group", key));
String key1 = Md5ConfigUtil.getKey("DataId%", "Group");
Assert.isTrue(Objects.equals("DataId%25+Group", key1));
}
@Test
public void getKeyTenantIdentifyTest() {
String key = Md5ConfigUtil.getKey("DataId", "Group", "Tenant", "Identify");
Assert.isTrue(Objects.equals("DataId+Group+Tenant+Identify", key));
}
@Test
public void getKeyTenantIdentifySpecialTest() {
String key = Md5ConfigUtil.getKey("DataId+", "Group+", "Tenant+", "Identify");
Assert.isTrue(Objects.equals("DataId%2B+Group%2B+Tenant%2B+Identify", key));
}
@Test
public void compareMd5ResultStringEmptyTest() {
String key = null;
try {
key = Md5ConfigUtil.compareMd5ResultString(new ArrayList<>());
} catch (IOException ignored) {
}
Assert.isTrue(Objects.equals(StringUtil.EMPTY, key));
}
@Test
public void compareMd5ResultStringTest() {
String key = null;
try {
key = Md5ConfigUtil.compareMd5ResultString(Lists.newArrayList("DataId+Group"));
} catch (IOException ignored) {
}
Assert.isTrue(Objects.equals("DataId%02Group%01", key));
}
@Test
public void getClientMd5MapTest() {
ConfigAllInfo configAllInfo = new ConfigAllInfo();
configAllInfo.setDesc("hippo4j config");
String tpContentMd5 = Md5ConfigUtil.getTpContentMd5(configAllInfo);
Assert.isTrue(StringUtil.isNotEmpty(tpContentMd5));
}
}

@ -37,10 +37,6 @@
<artifactId>hibernate-validator</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
</dependency>
</dependencies>
<build>

@ -19,6 +19,8 @@ package cn.hippo4j.console.service.impl;
import cn.hippo4j.common.enums.DelEnum;
import cn.hippo4j.common.model.InstanceInfo;
import cn.hippo4j.common.toolkit.CollectionUtil;
import cn.hippo4j.common.toolkit.DateUtil;
import cn.hippo4j.common.toolkit.GroupKey;
import cn.hippo4j.config.mapper.ConfigInfoMapper;
import cn.hippo4j.config.mapper.HisRunDataMapper;
@ -30,20 +32,13 @@ import cn.hippo4j.console.model.*;
import cn.hippo4j.console.service.DashboardService;
import cn.hippo4j.discovery.core.BaseInstanceRegistry;
import cn.hippo4j.discovery.core.Lease;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Dict;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Lists;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;
import static cn.hippo4j.common.toolkit.ContentUtil.getGroupKey;
@ -80,14 +75,16 @@ public class DashboardServiceImpl implements DashboardService {
@Override
public LineChartInfo getLineChatInfo() {
Date currentDate = new Date();
DateTime startTime = DateUtil.offsetMinute(currentDate, -10);
List<HisRunDataMapper.ThreadPoolTaskRanking> threadPoolTaskRankings = hisRunDataMapper.queryThreadPoolMaxRanking(startTime.getTime(), currentDate.getTime());
List<Object> oneList = Lists.newArrayList();
List<Object> twoList = Lists.newArrayList();
List<Object> threeList = Lists.newArrayList();
List<Object> fourList = Lists.newArrayList();
ArrayList<List<Object>> lists = Lists.newArrayList(oneList, twoList, threeList, fourList);
LocalDateTime currentDate = LocalDateTime.now();
LocalDateTime startDate = currentDate.plusMinutes(-10);
long currentTime = DateUtil.getTime(currentDate);
long startTime = DateUtil.getTime(startDate);
List<HisRunDataMapper.ThreadPoolTaskRanking> threadPoolTaskRankings = hisRunDataMapper.queryThreadPoolMaxRanking(startTime, currentTime);
List<Object> oneList = new ArrayList<>();
List<Object> twoList = new ArrayList<>();
List<Object> threeList = new ArrayList<>();
List<Object> fourList = new ArrayList<>();
ArrayList<List<Object>> lists = CollectionUtil.newArrayList(oneList, twoList, threeList, fourList);
for (int i = 0; i < threadPoolTaskRankings.size(); i++) {
List<Object> eachList = lists.get(i);
HisRunDataMapper.ThreadPoolTaskRanking taskRanking = threadPoolTaskRankings.get(i);
@ -101,7 +98,7 @@ public class DashboardServiceImpl implements DashboardService {
@Override
public TenantChart getTenantChart() {
List<Map<String, Object>> tenantChartList = Lists.newArrayList();
List<Map<String, Object>> tenantChartList = new ArrayList<>();
List<TenantInfo> tenantInfos = tenantInfoMapper.selectList(Wrappers.lambdaQuery(TenantInfo.class).eq(TenantInfo::getDelFlag, DelEnum.NORMAL.getIntCode()));
for (TenantInfo tenant : tenantInfos) {
int tenantThreadPoolNum = 0;
@ -115,10 +112,12 @@ public class DashboardServiceImpl implements DashboardService {
Integer threadPoolCount = configInfoMapper.selectCount(threadPoolQueryWrapper);
tenantThreadPoolNum += threadPoolCount;
}
Dict dict = Dict.create().set("name", tenant.getTenantId()).set("value", tenantThreadPoolNum);
Map<String, Object> dict = new LinkedHashMap<>();
dict.put("name", tenant.getTenantId());
dict.put("value", tenantThreadPoolNum);
tenantChartList.add(dict);
}
List resultTenantChartList = tenantChartList.stream()
List<Map<String, Object>> resultTenantChartList = tenantChartList.stream()
.sorted((one, two) -> (int) two.get("value") - (int) one.get("value"))
.limit(5)
.collect(Collectors.toList());
@ -129,19 +128,21 @@ public class DashboardServiceImpl implements DashboardService {
public PieChartInfo getPieChart() {
LambdaQueryWrapper<ItemInfo> itemQueryWrapper = Wrappers.lambdaQuery(ItemInfo.class).eq(ItemInfo::getDelFlag, DelEnum.NORMAL.getIntCode()).select(ItemInfo::getItemId);
List<Object> itemNameList = itemInfoMapper.selectObjs(itemQueryWrapper);
List<Map<String, Object>> pieDataList = Lists.newArrayList();
List<Map<String, Object>> pieDataList = new ArrayList<>();
for (Object each : itemNameList) {
LambdaQueryWrapper<ConfigAllInfo> threadPoolQueryWrapper = Wrappers.lambdaQuery(ConfigAllInfo.class)
.eq(ConfigInfoBase::getItemId, each)
.eq(ConfigAllInfo::getDelFlag, DelEnum.NORMAL.getIntCode());
Integer threadPoolCount = configInfoMapper.selectCount(threadPoolQueryWrapper);
if (threadPoolCount != null) {
Dict dict = Dict.create().set("name", each).set("value", threadPoolCount);
Map<String, Object> dict = new LinkedHashMap<>();
dict.put("name", each);
dict.put("value", threadPoolCount);
pieDataList.add(dict);
}
}
pieDataList.sort((one, two) -> (int) two.get("value") - (int) one.get("value"));
List<String> resultItemIds = Lists.newArrayList();
List<String> resultItemIds = new ArrayList<>();
List<Map<String, Object>> resultPieDataList = pieDataList.stream()
.limit(5)
.map(each -> {
@ -154,15 +155,17 @@ public class DashboardServiceImpl implements DashboardService {
@Override
public RankingChart getRankingChart() {
Date currentDate = new Date();
DateTime tenTime = DateUtil.offsetMinute(currentDate, -10);
List<RankingChart.RankingChartInfo> resultList = Lists.newArrayList();
List<HisRunDataMapper.ThreadPoolTaskRanking> threadPoolTaskRankings = hisRunDataMapper.queryThreadPoolTaskSumRanking(tenTime.getTime(), currentDate.getTime());
LocalDateTime currentDate = LocalDateTime.now();
LocalDateTime startDate = currentDate.plusMinutes(-10);
long currentTime = DateUtil.getTime(currentDate);
long startTime = DateUtil.getTime(startDate);
List<RankingChart.RankingChartInfo> resultList = new ArrayList<>();
List<HisRunDataMapper.ThreadPoolTaskRanking> threadPoolTaskRankings = hisRunDataMapper.queryThreadPoolTaskSumRanking(startTime, currentTime);
threadPoolTaskRankings.forEach(each -> {
RankingChart.RankingChartInfo rankingChartInfo = new RankingChart.RankingChartInfo();
rankingChartInfo.setMaxCompletedTaskCount(each.getMaxCompletedTaskCount());
List<Lease<InstanceInfo>> leases = baseInstanceRegistry.listInstance(each.getItemId());
Lease<InstanceInfo> first = CollUtil.getFirst(leases);
Lease<InstanceInfo> first = CollectionUtil.getFirst(leases);
if (first == null) {
rankingChartInfo.setInst(0);
} else {

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save