Simplified DynamicThreadPool usage

pull/872/head
weihu 3 years ago
commit 3aaf0eec7f

@ -13,9 +13,9 @@ sidebar_position: 2
<td align="center" width="26%">联系方式</td> <td align="center" width="26%">联系方式</td>
</tr> </tr>
<tr> <tr>
<td align="center" ><a href="https://github.com/agentart"><img src="https://avatars.githubusercontent.com/u/77398366?v=4?s=64" width="64px;"/></a></td> <td align="center" ><a href="https://github.com/itmachen"><img src="https://avatars.githubusercontent.com/u/77398366?v=4?s=64" width="64px;"/></a></td>
<td align="center" >马称</td> <td align="center" >马称</td>
<td align="center" ><a href="https://github.com/agentart">agentart</a></td> <td align="center" ><a href="https://github.com/itmachen">itmachen</a></td>
<td align="center" ><a href="http://www.xiaomage.info/">小马哥的技术专栏</a></td> <td align="center" ><a href="http://www.xiaomage.info/">小马哥的技术专栏</a></td>
<td align="center" >machen@apache.org</td> <td align="center" >machen@apache.org</td>
</tr> </tr>
@ -54,4 +54,11 @@ sidebar_position: 2
<td align="center" ><a href="https://www.yuque.com/chenghu-08dla/pizig1">pizihao</a></td> <td align="center" ><a href="https://www.yuque.com/chenghu-08dla/pizig1">pizihao</a></td>
<td align="center" >hao3073liu@163.com</td> <td align="center" >hao3073liu@163.com</td>
</tr> </tr>
<tr>
<td align="center"><a href="https://github.com/pizihao"><img src="https://avatars.githubusercontent.com/u/49084314?v=4?s=64" width="64px;"/></a></td>
<td align="center">叶炜</td>
<td align="center" ><a href="https://github.com/shanjianq">shanjianq</a></td>
<td align="center" >-</td>
<td align="center" >17855368071@163.com</td>
</tr>
</table> </table>

@ -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> </dependency>
``` ```
启动类上添加注解 @EnableDynamicThreadPool 启动类上添加注解 `@EnableDynamicThreadPool`
```java ```java
@SpringBootApplication @SpringBootApplication

@ -2,7 +2,7 @@
sidebar_position: 2 sidebar_position: 2
--- ---
# Docker 部署 # Docker部署
## 镜像启动 ## 镜像启动

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

@ -22,6 +22,7 @@ import cn.hippo4j.auth.filter.JWTAuthenticationFilter;
import cn.hippo4j.auth.filter.JWTAuthorizationFilter; import cn.hippo4j.auth.filter.JWTAuthorizationFilter;
import cn.hippo4j.auth.security.JwtTokenManager; import cn.hippo4j.auth.security.JwtTokenManager;
import cn.hippo4j.auth.service.impl.UserDetailsServiceImpl; import cn.hippo4j.auth.service.impl.UserDetailsServiceImpl;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.AuthenticationManager;
@ -50,6 +51,9 @@ import java.util.stream.Stream;
@EnableGlobalMethodSecurity(prePostEnabled = true) @EnableGlobalMethodSecurity(prePostEnabled = true)
public class GlobalSecurityConfig extends WebSecurityConfigurerAdapter { public class GlobalSecurityConfig extends WebSecurityConfigurerAdapter {
@Value("${hippo4j.core.auth.enabled:true}")
private Boolean enableAuthentication;
@Resource @Resource
private UserDetailsService userDetailsService; private UserDetailsService userDetailsService;
@ -93,11 +97,12 @@ public class GlobalSecurityConfig extends WebSecurityConfigurerAdapter {
.authorizeRequests() .authorizeRequests()
.antMatchers("/static/**", "/index.html", "/favicon.ico", "/avatar.jpg").permitAll() .antMatchers("/static/**", "/index.html", "/favicon.ico", "/avatar.jpg").permitAll()
.antMatchers("/doc.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs").anonymous() .antMatchers("/doc.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs").anonymous()
.anyRequest().authenticated()
.and() .and()
.addFilter(new JWTAuthenticationFilter(authenticationManager())) .addFilter(new JWTAuthenticationFilter(authenticationManager()))
.addFilter(new JWTAuthorizationFilter(tokenManager, authenticationManager())) .addFilter(new JWTAuthorizationFilter(tokenManager, authenticationManager()))
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
disableAuthenticationIfNeeded(http);
http.authorizeRequests().anyRequest().authenticated();
} }
@Override @Override
@ -105,4 +110,10 @@ public class GlobalSecurityConfig extends WebSecurityConfigurerAdapter {
String[] ignores = Stream.of("/hippo4j/v1/cs/auth/users/apply/token/**").toArray(String[]::new); String[] ignores = Stream.of("/hippo4j/v1/cs/auth/users/apply/token/**").toArray(String[]::new);
web.ignoring().antMatchers(ignores); web.ignoring().antMatchers(ignores);
} }
private void disableAuthenticationIfNeeded(HttpSecurity http) throws Exception {
if (Boolean.FALSE.equals(enableAuthentication)) {
http.authorizeRequests().antMatchers("/hippo4j/v1/cs/**").permitAll();
}
}
} }

@ -68,6 +68,7 @@ public class JWTAuthenticationFilter extends UsernamePasswordAuthenticationFilte
Authentication authenticate = null; Authentication authenticate = null;
try { try {
LoginUser loginUser = new ObjectMapper().readValue(request.getInputStream(), LoginUser.class); LoginUser loginUser = new ObjectMapper().readValue(request.getInputStream(), LoginUser.class);
request.setAttribute("loginUser", loginUser);
rememberMe.set(loginUser.getRememberMe()); rememberMe.set(loginUser.getRememberMe());
authenticate = authenticationManager.authenticate( authenticate = authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(loginUser.getUsername(), loginUser.getPassword(), new ArrayList())); new UsernamePasswordAuthenticationToken(loginUser.getUsername(), loginUser.getPassword(), new ArrayList()));

@ -20,14 +20,21 @@ package cn.hippo4j.auth.service.impl;
import cn.hippo4j.auth.mapper.UserMapper; import cn.hippo4j.auth.mapper.UserMapper;
import cn.hippo4j.auth.model.UserInfo; import cn.hippo4j.auth.model.UserInfo;
import cn.hippo4j.auth.model.biz.user.JwtUser; import cn.hippo4j.auth.model.biz.user.JwtUser;
import cn.hippo4j.auth.model.biz.user.LoginUser;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Collections; import java.util.Collections;
import java.util.Objects; import java.util.Objects;
import java.util.Set; import java.util.Set;
@ -38,11 +45,18 @@ import java.util.Set;
@Slf4j @Slf4j
public class UserDetailsServiceImpl implements UserDetailsService { public class UserDetailsServiceImpl implements UserDetailsService {
@Value("${hippo4j.core.auth.enabled:true}")
private Boolean enableAuthentication;
@Resource @Resource
private UserMapper userMapper; private UserMapper userMapper;
@Override @Override
public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException { public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
JwtUser anonymous = dealWithAnonymous();
if (!Objects.isNull(anonymous)) {
return anonymous;
}
UserInfo userInfo = userMapper.selectOne(Wrappers.lambdaQuery(UserInfo.class).eq(UserInfo::getUserName, userName)); UserInfo userInfo = userMapper.selectOne(Wrappers.lambdaQuery(UserInfo.class).eq(UserInfo::getUserName, userName));
if (Objects.isNull(userInfo)) { if (Objects.isNull(userInfo)) {
log.warn("User {} not found", userName); log.warn("User {} not found", userName);
@ -56,4 +70,27 @@ public class UserDetailsServiceImpl implements UserDetailsService {
jwtUser.setAuthorities(authorities); jwtUser.setAuthorities(authorities);
return jwtUser; return jwtUser;
} }
private JwtUser dealWithAnonymous() {
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
if (requestAttributes == null) {
return null;
}
HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
LoginUser loginUser = (LoginUser) request.getAttribute("loginUser");
if (Objects.isNull(loginUser)) {
return null;
}
if (Boolean.FALSE.equals(enableAuthentication)) {
JwtUser jwtUser = new JwtUser();
BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
jwtUser.setId(1L);
jwtUser.setUsername("anonymous");
jwtUser.setPassword(bCryptPasswordEncoder.encode(loginUser.getPassword()));
Set<SimpleGrantedAuthority> authorities = Collections.singleton(new SimpleGrantedAuthority("ROLE_ADMIN"));
jwtUser.setAuthorities(authorities);
return jwtUser;
}
return null;
}
} }

@ -0,0 +1,41 @@
/*
* 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.constant;
public class ConfigModifyTypeConstants {
/**
* Thread pool manager change
*/
public static final int THREAD_POOL_MANAGER = 1;
/**
* Thread pool instance change
*/
public static final int THREAD_POOL_INSTANCE = 2;
/**
* Web thread pool change
*/
public static final int WEB_THREAD_POOL = 3;
/**
* Adapter thread pool change
*/
public static final int ADAPTER_THREAD_POOL = 4;
}

@ -62,6 +62,8 @@ public class Constants {
public static final String LISTENER_PATH = CONFIG_CONTROLLER_PATH + "/listener"; public static final String LISTENER_PATH = CONFIG_CONTROLLER_PATH + "/listener";
public static final String VERIFY_PATH = CONFIG_CONTROLLER_PATH + "/verify";
public static final String MONITOR_PATH = BASE_PATH + "/monitor"; public static final String MONITOR_PATH = BASE_PATH + "/monitor";
public static final String REGISTER_ADAPTER_BASE_PATH = BASE_PATH + "/adapter/thread-pool"; public static final String REGISTER_ADAPTER_BASE_PATH = BASE_PATH + "/adapter/thread-pool";

@ -0,0 +1,58 @@
/*
* 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.enums;
public enum VerifyEnum {
/**
* unVerify
*/
TO_VERIFY(0, "待审核"),
/**
* accept
*/
VERIFY_ACCEPT(1, "审核通过"),
/**
* reject
*/
VERIFY_REJECT(2, "审核拒绝"),
/**
* invalid
*/
VERIFY_INVALID(3, "失效");
private final Integer verifyStatus;
private final String desc;
VerifyEnum(Integer verifyStatus, String desc) {
this.verifyStatus = verifyStatus;
this.desc = desc;
}
public String getDesc() {
return this.desc;
}
public Integer getVerifyStatus() {
return this.verifyStatus;
}
}

@ -59,6 +59,12 @@
<artifactId>hippo4j-adapter-base</artifactId> <artifactId>hippo4j-adapter-base</artifactId>
</dependency> </dependency>
<dependency>
<groupId>cn.hippo4j</groupId>
<artifactId>hippo4j-discovery</artifactId>
<version>${version}</version>
</dependency>
<dependency> <dependency>
<groupId>io.netty</groupId> <groupId>io.netty</groupId>
<artifactId>netty-all</artifactId> <artifactId>netty-all</artifactId>
@ -79,5 +85,6 @@
<artifactId>spring-boot-starter-test</artifactId> <artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
</dependencies> </dependencies>
</project> </project>

@ -17,17 +17,22 @@
package cn.hippo4j.config.controller; package cn.hippo4j.config.controller;
import cn.hippo4j.common.constant.ConfigModifyTypeConstants;
import cn.hippo4j.common.constant.Constants; import cn.hippo4j.common.constant.Constants;
import cn.hippo4j.common.model.register.DynamicThreadPoolRegisterWrapper; import cn.hippo4j.common.model.register.DynamicThreadPoolRegisterWrapper;
import cn.hippo4j.common.toolkit.BeanUtil;
import cn.hippo4j.common.toolkit.StringUtil; import cn.hippo4j.common.toolkit.StringUtil;
import cn.hippo4j.common.toolkit.UserContext;
import cn.hippo4j.common.web.base.Result; import cn.hippo4j.common.web.base.Result;
import cn.hippo4j.common.web.base.Results; import cn.hippo4j.common.web.base.Results;
import cn.hippo4j.config.model.ConfigAllInfo; import cn.hippo4j.config.model.ConfigAllInfo;
import cn.hippo4j.config.model.ConfigInfoBase; import cn.hippo4j.config.model.ConfigInfoBase;
import cn.hippo4j.config.model.biz.threadpool.ConfigModifySaveReqDTO;
import cn.hippo4j.config.service.ConfigCacheService; import cn.hippo4j.config.service.ConfigCacheService;
import cn.hippo4j.config.service.ConfigServletInner; import cn.hippo4j.config.service.ConfigServletInner;
import cn.hippo4j.config.service.biz.ConfigService; import cn.hippo4j.config.service.biz.ConfigService;
import cn.hippo4j.config.toolkit.Md5ConfigUtil; import cn.hippo4j.config.toolkit.Md5ConfigUtil;
import cn.hippo4j.config.verify.ConfigModificationVerifyServiceChoose;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.SneakyThrows; import lombok.SneakyThrows;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
@ -50,6 +55,8 @@ public class ConfigController {
private final ConfigServletInner configServletInner; private final ConfigServletInner configServletInner;
private final ConfigModificationVerifyServiceChoose configModificationVerifyServiceChoose;
@GetMapping @GetMapping
public Result<ConfigInfoBase> detailConfigInfo(@RequestParam("tpId") String tpId, public Result<ConfigInfoBase> detailConfigInfo(@RequestParam("tpId") String tpId,
@RequestParam("itemId") String itemId, @RequestParam("itemId") String itemId,
@ -62,7 +69,18 @@ public class ConfigController {
@PostMapping @PostMapping
public Result<Boolean> publishConfig(@RequestParam(value = "identify", required = false) String identify, public Result<Boolean> publishConfig(@RequestParam(value = "identify", required = false) String identify,
@RequestBody ConfigAllInfo config) { @RequestBody ConfigAllInfo config) {
if (UserContext.getUserRole().equals("ROLE_ADMIN")) {
configService.insertOrUpdate(identify, true, config); configService.insertOrUpdate(identify, true, config);
} else {
ConfigModifySaveReqDTO modifySaveReqDTO = BeanUtil.convert(config, ConfigModifySaveReqDTO.class);
modifySaveReqDTO.setCorePoolSize(config.getCoreSize());
modifySaveReqDTO.setMaximumPoolSize(config.getMaxSize());
modifySaveReqDTO.setModifyUser(UserContext.getUserName());
modifySaveReqDTO.setModifyAll(StringUtil.isEmpty(identify) ? true : false);
modifySaveReqDTO.setIdentify(identify);
modifySaveReqDTO.setType(ConfigModifyTypeConstants.THREAD_POOL_INSTANCE);
configModificationVerifyServiceChoose.choose(modifySaveReqDTO.getType()).saveConfigModifyApplication(modifySaveReqDTO);
}
return Results.success(true); return Results.success(true);
} }

@ -0,0 +1,29 @@
/*
* 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.mapper;
import cn.hippo4j.config.model.HisConfigVerifyInfo;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* his config verify info mapper
*/
@Mapper
public interface HisConfigVerifyMapper extends BaseMapper<HisConfigVerifyInfo> {
}

@ -0,0 +1,101 @@
/*
* 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.model;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import java.util.Date;
/**
* His config verify info
*/
@Data
@TableName("his_config_verify")
public class HisConfigVerifyInfo {
@TableId(type = IdType.AUTO)
private Long id;
/**
* Change type
*/
private Integer type;
/**
* Tenant id
*/
private String tenantId;
/**
* Item id
*/
private String itemId;
/**
* Thread pool id
*/
private String tpId;
/**
* Thread pool mark
*/
private String mark;
/**
* Thread pool instance identify
*/
private String identify;
/**
* Config content
*/
private String content;
/**
* Weather modify all thread pool instances
*/
private Boolean modifyAll = false;
/**
* GmtCreate
*/
@TableField(fill = FieldFill.INSERT)
private Date gmtCreate;
/**
* ModifyUserId
*/
private String modifyUser;
/**
* Verify status
*/
private Integer verifyStatus;
/**
* GmtVerify
*/
private Date gmtVerify;
/**
* VerifyUser
*/
private String verifyUser;
}

@ -66,4 +66,9 @@ public class ThreadPoolAdapterReqDTO {
* Client address list * Client address list
*/ */
private List<String> clientAddressList; private List<String> clientAddressList;
/**
* weather Modify all instances
*/
private Boolean modifyAll;
} }

@ -0,0 +1,97 @@
/*
* 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.model.biz.threadpool;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.util.Date;
/**
* Config modify query resp
*/
@Data
public class ConfigModificationQueryRespDTO {
/**
* His_config_verify id
*/
private String id;
/**
* Config modify type
*/
private Integer type;
/**
* Thread pool mark
*/
private String mark;
/**
* Tenant id
*/
private String tenantId;
/**
* Item id
*/
private String itemId;
/**
* Thread pool id
*/
private String tpId;
/**
* Thread pool identify
*/
private String identify;
/**
* Weather modify all instances
*/
private Boolean modifyAll;
/**
* Modify user
*/
private String modifyUser;
/**
* Verify status
*/
private Integer verifyStatus;
/**
* GmtCreate
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date gmtCreate;
/**
* GmtVerify
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date gmtVerify;
/**
* Verify user
*/
private String verifyUser;
}

@ -0,0 +1,124 @@
/*
* 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.model.biz.threadpool;
import lombok.Data;
import javax.validation.constraints.Pattern;
@Data
public class ConfigModifySaveReqDTO {
/**
* Thread pool config change type.
*/
private Integer type;
/**
* Thread pool instance id
*/
private String identify;
/**
* Weather modify all instances
*/
private Boolean modifyAll = false;
/**
* Tenant Id
*/
@Pattern(regexp = "^((?!\\+).)*$", message = "租户、项目、线程池 ID 包含+号")
private String tenantId;
/**
* Thread pool id
*/
@Pattern(regexp = "^((?!\\+).)*$", message = "租户、项目、线程池 ID 包含+号")
private String tpId;
/**
* Item id
*/
@Pattern(regexp = "^((?!\\+).)*$", message = "租户、项目、线程池 ID 包含+号")
private String itemId;
/**
* Thread pool mark
*/
private String mark;
/**
* Core pool size
*/
private Integer corePoolSize;
/**
* Maximum pool size
*/
private Integer maximumPoolSize;
/**
* Queue type
*/
private Integer queueType;
/**
* Capacity
*/
private Integer capacity;
/**
* Keep alive time
*/
private Integer keepAliveTime;
/**
* Execute time out
*/
private Long executeTimeOut;
/**
* Is alarm
*/
private Integer isAlarm;
/**
* Capacity alarm
*/
private Integer capacityAlarm;
/**
* Liveness alarm
*/
private Integer livenessAlarm;
/**
* Rejected type
*/
private Integer rejectedType;
/**
* Allow core thread timeout
*/
private Integer allowCoreThreadTimeOut;
/**
* ModifyUser
*/
private String modifyUser;
}

@ -0,0 +1,138 @@
/*
* 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.model.biz.threadpool;
import com.fasterxml.jackson.annotation.JsonAlias;
import lombok.Data;
import java.util.List;
/**
* Config modify verify dto
*/
@Data
public class ConfigModifyVerifyReqDTO {
/**
* His config verify id
*/
private String id;
/**
* Config verify type
*/
private Integer type;
/**
* Tenant id
*/
private String tenantId;
/**
* Item id
*/
private String itemId;
/**
* Instance identify
*/
private String identify;
/**
* Adapter thread pool mark
*/
private String mark;
/**
* Adapter thread pool key
*/
private String threadPoolKey;
/**
* Thread pool id
*/
@JsonAlias("threadPoolId")
private String tpId;
/**
* Weather modify all instances
*/
private Boolean modifyAll;
/**
* Weather accept config modification
*/
private Boolean accept;
/**
* Core pool size
*/
private Integer corePoolSize;
/**
* Maximum pool size
*/
private Integer maximumPoolSize;
/**
* Queue type
*/
private Integer queueType;
/**
* Capacity
*/
private Integer capacity;
/**
* Keep alive time
*/
private Integer keepAliveTime;
/**
* Execute time out
*/
private Long executeTimeOut;
/**
* Rejected type
*/
private Integer rejectedType;
/**
* Is alarm
*/
private Integer isAlarm;
/**
* Capacity alarm
*/
private Integer capacityAlarm;
/**
* Liveness alarm
*/
@JsonAlias("activeAlarm")
private Integer livenessAlarm;
/**
* Allow core thread timeout
*/
private Integer allowCoreThreadTimeOut;
}

@ -0,0 +1,45 @@
/*
* 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.service.biz;
import cn.hippo4j.common.model.ThreadPoolParameterInfo;
import cn.hippo4j.config.model.biz.threadpool.ConfigModificationQueryRespDTO;
import cn.hippo4j.config.model.biz.threadpool.ThreadPoolQueryReqDTO;
import com.baomidou.mybatisplus.core.metadata.IPage;
/**
* Config modification application query service.
*/
public interface ConfigModificationQueryService {
/**
* Query config modification application page.
*
* @param reqDTO
* @return
*/
IPage<ConfigModificationQueryRespDTO> queryApplicationPage(ThreadPoolQueryReqDTO reqDTO);
/**
* Query config modification detail by application id.
*
* @param id
* @return
*/
ThreadPoolParameterInfo queryApplicationDetail(Long id);
}

@ -0,0 +1,55 @@
/*
* 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.service.biz;
import cn.hippo4j.config.model.biz.threadpool.ConfigModifySaveReqDTO;
import cn.hippo4j.config.model.biz.threadpool.ConfigModifyVerifyReqDTO;
/**
* Config modification verify service.
*/
public interface ConfigModificationVerifyService {
/**
* Get type.
*
* @return
*/
Integer type();
/**
* Save config change application.
*
* @param reqDTO
*/
void saveConfigModifyApplication(ConfigModifySaveReqDTO reqDTO);
/**
* Reject config modification.
*
* @param reqDTO
*/
void rejectModification(ConfigModifyVerifyReqDTO reqDTO);
/**
* Accept config modification.
*
* @param reqDTO
*/
void acceptModification(ConfigModifyVerifyReqDTO reqDTO);
}

@ -0,0 +1,114 @@
/*
* 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.service.biz.impl;
import cn.hippo4j.common.enums.VerifyEnum;
import cn.hippo4j.common.model.InstanceInfo;
import cn.hippo4j.common.toolkit.BeanUtil;
import cn.hippo4j.common.toolkit.ConditionUtil;
import cn.hippo4j.common.toolkit.JSONUtil;
import cn.hippo4j.common.toolkit.UserContext;
import cn.hippo4j.config.mapper.HisConfigVerifyMapper;
import cn.hippo4j.config.model.HisConfigVerifyInfo;
import cn.hippo4j.config.model.biz.threadpool.ConfigModifySaveReqDTO;
import cn.hippo4j.config.model.biz.threadpool.ConfigModifyVerifyReqDTO;
import cn.hippo4j.config.service.biz.ConfigModificationVerifyService;
import cn.hippo4j.discovery.core.BaseInstanceRegistry;
import cn.hippo4j.discovery.core.Lease;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* Abstract config modification verify service.
*/
public abstract class AbstractConfigModificationVerifyService implements ConfigModificationVerifyService {
@Resource
protected HisConfigVerifyMapper hisConfigVerifyMapper;
@Resource
private BaseInstanceRegistry baseInstanceRegistry;
@Override
public void saveConfigModifyApplication(ConfigModifySaveReqDTO reqDTO) {
HisConfigVerifyInfo hisConfigVerifyInfo = BeanUtil.convert(reqDTO, HisConfigVerifyInfo.class);
hisConfigVerifyInfo.setContent(JSONUtil.toJSONString(reqDTO));
hisConfigVerifyInfo.setVerifyStatus(VerifyEnum.TO_VERIFY.getVerifyStatus());
hisConfigVerifyMapper.insert(hisConfigVerifyInfo);
}
@Override
public void rejectModification(ConfigModifyVerifyReqDTO reqDTO) {
LambdaUpdateWrapper<HisConfigVerifyInfo> updateWrapper = new LambdaUpdateWrapper<HisConfigVerifyInfo>()
.eq(HisConfigVerifyInfo::getId, Long.parseLong(reqDTO.getId()))
.set(HisConfigVerifyInfo::getVerifyStatus, VerifyEnum.VERIFY_REJECT.getVerifyStatus())
.set(HisConfigVerifyInfo::getGmtVerify, new Date())
.set(HisConfigVerifyInfo::getVerifyUser, UserContext.getUserName());
hisConfigVerifyMapper.update(null, updateWrapper);
}
public void acceptModification(ConfigModifyVerifyReqDTO reqDTO) {
updateThreadPoolParameter(reqDTO);
LambdaUpdateWrapper<HisConfigVerifyInfo> updateWrapper = new LambdaUpdateWrapper<HisConfigVerifyInfo>()
.eq(HisConfigVerifyInfo::getId, Long.parseLong(reqDTO.getId()))
.set(HisConfigVerifyInfo::getVerifyStatus, VerifyEnum.VERIFY_ACCEPT.getVerifyStatus())
.set(HisConfigVerifyInfo::getGmtVerify, new Date())
.set(HisConfigVerifyInfo::getVerifyUser, UserContext.getUserName());
hisConfigVerifyMapper.update(null, updateWrapper);
Date gmtVerify = hisConfigVerifyMapper.selectById(reqDTO.getId()).getGmtVerify();
LambdaUpdateWrapper<HisConfigVerifyInfo> invalidUpdateWrapper = new LambdaUpdateWrapper<HisConfigVerifyInfo>()
.eq(HisConfigVerifyInfo::getType, reqDTO.getType())
.eq(reqDTO.getTenantId() != null, HisConfigVerifyInfo::getTenantId, reqDTO.getTenantId())
.eq(reqDTO.getItemId() != null, HisConfigVerifyInfo::getItemId, reqDTO.getItemId())
.eq(reqDTO.getTpId() != null, HisConfigVerifyInfo::getTpId, reqDTO.getTpId())
.and(reqDTO.getIdentify() != null, wrapper -> wrapper.eq(HisConfigVerifyInfo::getIdentify, reqDTO.getIdentify()).or().eq(HisConfigVerifyInfo::getModifyAll, true))
.lt(HisConfigVerifyInfo::getGmtVerify, gmtVerify)
.set(HisConfigVerifyInfo::getVerifyStatus, VerifyEnum.VERIFY_INVALID.getVerifyStatus());
hisConfigVerifyMapper.update(null, invalidUpdateWrapper);
}
/**
* Get client address.
*
* @param reqDTO
* @return
*/
protected List<String> getClientAddress(ConfigModifyVerifyReqDTO reqDTO) {
List<String> clientAddressList = new ArrayList<>();
List<Lease<InstanceInfo>> leases = baseInstanceRegistry.listInstance(reqDTO.getItemId());
ConditionUtil
.condition(reqDTO.getModifyAll(),
() -> leases.forEach(lease -> clientAddressList.add(lease.getHolder().getCallBackUrl())),
() -> clientAddressList.add(
leases.stream()
.filter(lease -> lease.getHolder().getIdentify().equals(reqDTO.getIdentify())).findAny().orElseThrow(() -> new RuntimeException("该线程池实例不存在")).getHolder()
.getCallBackUrl()));
return clientAddressList;
}
/**
* Update thread pool parameter.
*
* @param reqDTO
*/
protected abstract void updateThreadPoolParameter(ConfigModifyVerifyReqDTO reqDTO);
}

@ -0,0 +1,52 @@
/*
* 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.service.biz.impl;
import cn.hippo4j.common.constant.ConfigModifyTypeConstants;
import cn.hippo4j.common.toolkit.JSONUtil;
import cn.hippo4j.config.model.biz.threadpool.ConfigModifyVerifyReqDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
/**
* Adapter thread pool config modification verify service impl.
*/
@Slf4j
@Service
public class AdapterThreadPoolConfigModificationVerifyServiceImpl extends AbstractConfigModificationVerifyService {
private final RestTemplate restTemplate = new RestTemplate();
@Override
public Integer type() {
return ConfigModifyTypeConstants.ADAPTER_THREAD_POOL;
}
@Override
protected void updateThreadPoolParameter(ConfigModifyVerifyReqDTO reqDTO) {
for (String each : getClientAddress(reqDTO)) {
String urlString = new StringBuilder()
.append("http://")
.append(each)
.append("/adapter/thread-pool/update")
.toString();
restTemplate.postForObject(urlString, JSONUtil.toJSONString(reqDTO), Object.class);
}
}
}

@ -0,0 +1,62 @@
/*
* 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.service.biz.impl;
import cn.hippo4j.common.model.ThreadPoolParameterInfo;
import cn.hippo4j.common.toolkit.BeanUtil;
import cn.hippo4j.common.toolkit.JSONUtil;
import cn.hippo4j.config.mapper.HisConfigVerifyMapper;
import cn.hippo4j.config.model.HisConfigVerifyInfo;
import cn.hippo4j.config.model.biz.threadpool.ConfigModificationQueryRespDTO;
import cn.hippo4j.config.model.biz.threadpool.ThreadPoolQueryReqDTO;
import cn.hippo4j.config.service.biz.ConfigModificationQueryService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/**
* Config modification query service impl
*/
@Service
public class ConfigModificationQueryServiceImpl implements ConfigModificationQueryService {
@Resource
private HisConfigVerifyMapper hisConfigVerifyMapper;
@Override
public IPage<ConfigModificationQueryRespDTO> queryApplicationPage(ThreadPoolQueryReqDTO reqDTO) {
LambdaQueryWrapper<HisConfigVerifyInfo> wrapper = Wrappers.lambdaQuery(HisConfigVerifyInfo.class)
.eq(!StringUtils.isBlank(reqDTO.getTenantId()), HisConfigVerifyInfo::getTenantId, reqDTO.getTenantId())
.eq(!StringUtils.isBlank(reqDTO.getItemId()), HisConfigVerifyInfo::getItemId, reqDTO.getItemId())
.orderByDesc(HisConfigVerifyInfo::getGmtCreate);
return hisConfigVerifyMapper.selectPage(reqDTO, wrapper).convert(each -> BeanUtil.convert(each, ConfigModificationQueryRespDTO.class));
}
@Override
public ThreadPoolParameterInfo queryApplicationDetail(Long id) {
HisConfigVerifyInfo hisConfigVerifyInfo = hisConfigVerifyMapper.selectById(id);
ThreadPoolParameterInfo poolParameterInfo = JSONUtil.parseObject(hisConfigVerifyInfo.getContent(), ThreadPoolParameterInfo.class);
poolParameterInfo.setCorePoolSize(poolParameterInfo.corePoolSizeAdapt());
poolParameterInfo.setMaximumPoolSize(poolParameterInfo.maximumPoolSizeAdapt());
return poolParameterInfo;
}
}

@ -0,0 +1,53 @@
/*
* 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.service.biz.impl;
import cn.hippo4j.common.constant.ConfigModifyTypeConstants;
import cn.hippo4j.common.toolkit.BeanUtil;
import cn.hippo4j.config.model.ConfigAllInfo;
import cn.hippo4j.config.model.biz.threadpool.ConfigModifyVerifyReqDTO;
import cn.hippo4j.config.service.biz.ConfigService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/**
* Thread pool instance config modification verify service impl.
*/
@Slf4j
@Service
public class ThreadPoolInstanceConfigModificationVerifyServiceImpl extends AbstractConfigModificationVerifyService {
@Resource
private ConfigService configService;
@Override
public Integer type() {
return ConfigModifyTypeConstants.THREAD_POOL_INSTANCE;
}
@Override
protected void updateThreadPoolParameter(ConfigModifyVerifyReqDTO reqDTO) {
ConfigAllInfo config = BeanUtil.convert(reqDTO, ConfigAllInfo.class);
config.setCoreSize(reqDTO.getCorePoolSize());
config.setMaxSize(reqDTO.getMaximumPoolSize());
configService.insertOrUpdate(reqDTO.getIdentify(), true, config);
}
}

@ -0,0 +1,53 @@
/*
* 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.service.biz.impl;
import cn.hippo4j.common.constant.ConfigModifyTypeConstants;
import cn.hippo4j.common.toolkit.BeanUtil;
import cn.hippo4j.config.model.biz.threadpool.ConfigModifyVerifyReqDTO;
import cn.hippo4j.config.model.biz.threadpool.ThreadPoolSaveOrUpdateReqDTO;
import cn.hippo4j.config.service.biz.ThreadPoolService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/**
* Thread pool manager config modification verify service impl.
*/
@Slf4j
@Service
public class ThreadPoolManageConfigModificationVerifyServiceImpl extends AbstractConfigModificationVerifyService {
@Resource
private ThreadPoolService threadPoolService;
@Override
public Integer type() {
return ConfigModifyTypeConstants.THREAD_POOL_MANAGER;
}
@Override
public void updateThreadPoolParameter(ConfigModifyVerifyReqDTO reqDTO) {
ThreadPoolSaveOrUpdateReqDTO saveOrUpdateReqDTO = BeanUtil.convert(reqDTO, ThreadPoolSaveOrUpdateReqDTO.class);
saveOrUpdateReqDTO.setCoreSize(reqDTO.getCorePoolSize());
saveOrUpdateReqDTO.setMaxSize(reqDTO.getMaximumPoolSize());
threadPoolService.saveOrUpdateThreadPoolConfig(null, saveOrUpdateReqDTO);
}
}

@ -17,20 +17,19 @@
package cn.hippo4j.config.service.biz.impl; package cn.hippo4j.config.service.biz.impl;
import cn.hippo4j.common.constant.ConfigModifyTypeConstants;
import cn.hippo4j.common.enums.DelEnum; import cn.hippo4j.common.enums.DelEnum;
import cn.hippo4j.common.toolkit.BeanUtil;
import cn.hippo4j.common.toolkit.JSONUtil; import cn.hippo4j.common.toolkit.JSONUtil;
import cn.hippo4j.common.toolkit.UserContext; import cn.hippo4j.common.toolkit.UserContext;
import cn.hippo4j.config.mapper.ConfigInfoMapper; import cn.hippo4j.config.mapper.ConfigInfoMapper;
import cn.hippo4j.config.model.ConfigAllInfo; import cn.hippo4j.config.model.ConfigAllInfo;
import cn.hippo4j.config.model.LogRecordInfo; import cn.hippo4j.config.model.LogRecordInfo;
import cn.hippo4j.config.model.biz.threadpool.ThreadPoolDelReqDTO; import cn.hippo4j.config.model.biz.threadpool.*;
import cn.hippo4j.config.model.biz.threadpool.ThreadPoolQueryReqDTO;
import cn.hippo4j.config.model.biz.threadpool.ThreadPoolRespDTO;
import cn.hippo4j.config.model.biz.threadpool.ThreadPoolSaveOrUpdateReqDTO;
import cn.hippo4j.config.service.biz.ConfigService; import cn.hippo4j.config.service.biz.ConfigService;
import cn.hippo4j.config.service.biz.OperationLogService; import cn.hippo4j.config.service.biz.OperationLogService;
import cn.hippo4j.config.service.biz.ThreadPoolService; import cn.hippo4j.config.service.biz.ThreadPoolService;
import cn.hippo4j.common.toolkit.BeanUtil; import cn.hippo4j.config.verify.ConfigModificationVerifyServiceChoose;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils; import com.baomidou.mybatisplus.core.toolkit.StringUtils;
@ -55,6 +54,8 @@ public class ThreadPoolServiceImpl implements ThreadPoolService {
private final OperationLogService operationLogService; private final OperationLogService operationLogService;
private final ConfigModificationVerifyServiceChoose configModificationVerifyServiceChoose;
@Override @Override
public IPage<ThreadPoolRespDTO> queryThreadPoolPage(ThreadPoolQueryReqDTO reqDTO) { public IPage<ThreadPoolRespDTO> queryThreadPoolPage(ThreadPoolQueryReqDTO reqDTO) {
LambdaQueryWrapper<ConfigAllInfo> wrapper = Wrappers.lambdaQuery(ConfigAllInfo.class) LambdaQueryWrapper<ConfigAllInfo> wrapper = Wrappers.lambdaQuery(ConfigAllInfo.class)
@ -82,10 +83,22 @@ public class ThreadPoolServiceImpl implements ThreadPoolService {
@Override @Override
public void saveOrUpdateThreadPoolConfig(String identify, ThreadPoolSaveOrUpdateReqDTO reqDTO) { public void saveOrUpdateThreadPoolConfig(String identify, ThreadPoolSaveOrUpdateReqDTO reqDTO) {
// TODO to optimize the Role of judgment
if (UserContext.getUserRole().equals("ROLE_ADMIN")) {
ConfigAllInfo configAllInfo = BeanUtil.convert(reqDTO, ConfigAllInfo.class); ConfigAllInfo configAllInfo = BeanUtil.convert(reqDTO, ConfigAllInfo.class);
Long executeTimeOut = Objects.equals(configAllInfo.getExecuteTimeOut(), 0L) ? null : configAllInfo.getExecuteTimeOut(); Long executeTimeOut = Objects.equals(configAllInfo.getExecuteTimeOut(), 0L) ? null : configAllInfo.getExecuteTimeOut();
configAllInfo.setExecuteTimeOut(executeTimeOut); configAllInfo.setExecuteTimeOut(executeTimeOut);
configService.insertOrUpdate(identify, false, configAllInfo); configService.insertOrUpdate(identify, false, configAllInfo);
} else {
ConfigModifySaveReqDTO modifySaveReqDTO = BeanUtil.convert(reqDTO, ConfigModifySaveReqDTO.class);
modifySaveReqDTO.setCorePoolSize(reqDTO.getCoreSize());
modifySaveReqDTO.setMaximumPoolSize(reqDTO.getMaxSize());
modifySaveReqDTO.setModifyUser(UserContext.getUserName());
modifySaveReqDTO.setModifyAll(false);
modifySaveReqDTO.setType(ConfigModifyTypeConstants.THREAD_POOL_MANAGER);
configModificationVerifyServiceChoose.choose(modifySaveReqDTO.getType()).saveConfigModifyApplication(modifySaveReqDTO);
}
} }
@Override @Override

@ -0,0 +1,52 @@
/*
* 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.service.biz.impl;
import cn.hippo4j.common.constant.ConfigModifyTypeConstants;
import cn.hippo4j.common.toolkit.JSONUtil;
import cn.hippo4j.config.model.biz.threadpool.ConfigModifyVerifyReqDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
/**
* Web thread pool config modification verify service impl.
*/
@Slf4j
@Service
public class WebThreadPoolConfigModificationVerifyServiceImpl extends AbstractConfigModificationVerifyService {
private final RestTemplate restTemplate = new RestTemplate();
@Override
public Integer type() {
return ConfigModifyTypeConstants.WEB_THREAD_POOL;
}
@Override
protected void updateThreadPoolParameter(ConfigModifyVerifyReqDTO reqDTO) {
for (String each : getClientAddress(reqDTO)) {
String urlString = new StringBuilder()
.append("http://")
.append(each)
.append("/web/update/pool")
.toString();
restTemplate.postForObject(urlString, JSONUtil.toJSONString(reqDTO), Object.class);
}
}
}

@ -0,0 +1,57 @@
/*
* 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.verify;
import cn.hippo4j.common.config.ApplicationContextHolder;
import cn.hippo4j.common.constant.ConfigModifyTypeConstants;
import cn.hippo4j.config.service.biz.ConfigModificationVerifyService;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
/**
* Config change verify service choose
*/
@Component
public class ConfigModificationVerifyServiceChoose implements CommandLineRunner {
/**
* Storage config change verify service container.
*/
private Map<Integer, ConfigModificationVerifyService> configChangeVerifyServiceChooseMap = new HashMap<>();
/**
* Choose by type.
*
* @param type {@link ConfigModifyTypeConstants}
* @return
*/
public ConfigModificationVerifyService choose(Integer type) {
ConfigModificationVerifyService verifyService = configChangeVerifyServiceChooseMap.get(type);
return verifyService;
}
@Override
public void run(String... args) throws Exception {
Map<String, ConfigModificationVerifyService> configChangeVerifyServiceMap =
ApplicationContextHolder.getBeansOfType(ConfigModificationVerifyService.class);
configChangeVerifyServiceMap.values().forEach(each -> configChangeVerifyServiceChooseMap.put(each.type(), each));
}
}

@ -0,0 +1,64 @@
/*
* 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.console.controller;
import cn.hippo4j.common.constant.Constants;
import cn.hippo4j.common.model.ThreadPoolParameterInfo;
import cn.hippo4j.common.toolkit.ConditionUtil;
import cn.hippo4j.common.web.base.Result;
import cn.hippo4j.common.web.base.Results;
import cn.hippo4j.config.model.biz.threadpool.ConfigModificationQueryRespDTO;
import cn.hippo4j.config.model.biz.threadpool.ConfigModifyVerifyReqDTO;
import cn.hippo4j.config.model.biz.threadpool.ThreadPoolQueryReqDTO;
import cn.hippo4j.config.service.biz.ConfigModificationQueryService;
import cn.hippo4j.config.service.biz.ConfigModificationVerifyService;
import cn.hippo4j.config.verify.ConfigModificationVerifyServiceChoose;
import com.baomidou.mybatisplus.core.metadata.IPage;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.*;
@RestController
@AllArgsConstructor
@RequestMapping(Constants.VERIFY_PATH)
public class ConfigVerifyController {
private final ConfigModificationVerifyServiceChoose serviceChoose;
private final ConfigModificationQueryService queryService;
@PostMapping
public Result<Void> verifyConfigModification(@RequestBody ConfigModifyVerifyReqDTO reqDTO) {
ConfigModificationVerifyService modifyVerifyService = serviceChoose.choose(reqDTO.getType());
ConditionUtil
.condition(reqDTO.getAccept(),
() -> modifyVerifyService.acceptModification(reqDTO),
() -> modifyVerifyService.rejectModification(reqDTO));
return Results.success();
}
@PostMapping("/query/application/page")
public Result<IPage<ConfigModificationQueryRespDTO>> modificationApplicationPage(@RequestBody ThreadPoolQueryReqDTO reqDTO) {
return Results.success(queryService.queryApplicationPage(reqDTO));
}
@GetMapping("/query/application/detail")
public Result<ThreadPoolParameterInfo> modificationApplicationDetail(@RequestParam("id") String id) {
return Results.success(queryService.queryApplicationDetail(Long.parseLong(id)));
}
}

@ -17,12 +17,17 @@
package cn.hippo4j.console.controller; package cn.hippo4j.console.controller;
import cn.hippo4j.common.constant.ConfigModifyTypeConstants;
import cn.hippo4j.common.toolkit.BeanUtil;
import cn.hippo4j.common.toolkit.JSONUtil; import cn.hippo4j.common.toolkit.JSONUtil;
import cn.hippo4j.common.toolkit.UserContext;
import cn.hippo4j.common.web.base.Result; import cn.hippo4j.common.web.base.Result;
import cn.hippo4j.common.web.base.Results; import cn.hippo4j.common.web.base.Results;
import cn.hippo4j.config.model.biz.adapter.ThreadPoolAdapterReqDTO; import cn.hippo4j.config.model.biz.adapter.ThreadPoolAdapterReqDTO;
import cn.hippo4j.config.model.biz.adapter.ThreadPoolAdapterRespDTO; import cn.hippo4j.config.model.biz.adapter.ThreadPoolAdapterRespDTO;
import cn.hippo4j.config.model.biz.threadpool.ConfigModifySaveReqDTO;
import cn.hippo4j.config.service.ThreadPoolAdapterService; import cn.hippo4j.config.service.ThreadPoolAdapterService;
import cn.hippo4j.config.verify.ConfigModificationVerifyServiceChoose;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
@ -30,11 +35,9 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate; import org.springframework.web.client.RestTemplate;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import static cn.hippo4j.common.constant.Constants.HTTP_EXECUTE_TIMEOUT;
import static cn.hippo4j.common.constant.Constants.REGISTER_ADAPTER_BASE_PATH; import static cn.hippo4j.common.constant.Constants.REGISTER_ADAPTER_BASE_PATH;
/** /**
@ -46,6 +49,8 @@ public class ThreadPoolAdapterController {
private final ThreadPoolAdapterService threadPoolAdapterService; private final ThreadPoolAdapterService threadPoolAdapterService;
private final ConfigModificationVerifyServiceChoose configModificationVerifyServiceChoose;
private final RestTemplate restTemplate = new RestTemplate(); private final RestTemplate restTemplate = new RestTemplate();
@GetMapping(REGISTER_ADAPTER_BASE_PATH + "/query") @GetMapping(REGISTER_ADAPTER_BASE_PATH + "/query")
@ -62,6 +67,7 @@ public class ThreadPoolAdapterController {
@PostMapping(REGISTER_ADAPTER_BASE_PATH + "/update") @PostMapping(REGISTER_ADAPTER_BASE_PATH + "/update")
public Result<Void> updateAdapterThreadPool(@RequestBody ThreadPoolAdapterReqDTO requestParameter) { public Result<Void> updateAdapterThreadPool(@RequestBody ThreadPoolAdapterReqDTO requestParameter) {
if (UserContext.getUserRole().equals("ROLE_ADMIN")) {
for (String each : requestParameter.getClientAddressList()) { for (String each : requestParameter.getClientAddressList()) {
String urlString = new StringBuilder() String urlString = new StringBuilder()
.append("http://") .append("http://")
@ -70,6 +76,15 @@ public class ThreadPoolAdapterController {
.toString(); .toString();
restTemplate.postForObject(urlString, JSONUtil.toJSONString(requestParameter), Object.class); restTemplate.postForObject(urlString, JSONUtil.toJSONString(requestParameter), Object.class);
} }
} else {
ConfigModifySaveReqDTO modifySaveReqDTO = BeanUtil.convert(requestParameter, ConfigModifySaveReqDTO.class);
modifySaveReqDTO.setModifyUser(UserContext.getUserName());
modifySaveReqDTO.setTenantId(requestParameter.getTenant());
modifySaveReqDTO.setItemId(requestParameter.getItem());
modifySaveReqDTO.setTpId(requestParameter.getThreadPoolKey());
modifySaveReqDTO.setType(ConfigModifyTypeConstants.ADAPTER_THREAD_POOL);
configModificationVerifyServiceChoose.choose(modifySaveReqDTO.getType()).saveConfigModifyApplication(modifySaveReqDTO);
}
return Results.success(); return Results.success();
} }

@ -17,22 +17,18 @@
package cn.hippo4j.console.controller; package cn.hippo4j.console.controller;
import cn.hippo4j.common.constant.ConfigModifyTypeConstants;
import cn.hippo4j.common.constant.Constants; import cn.hippo4j.common.constant.Constants;
import cn.hippo4j.common.model.InstanceInfo; import cn.hippo4j.common.model.InstanceInfo;
import cn.hippo4j.common.toolkit.CollectionUtil; import cn.hippo4j.common.toolkit.*;
import cn.hippo4j.common.toolkit.JSONUtil;
import cn.hippo4j.common.toolkit.StringUtil;
import cn.hippo4j.common.web.base.Result; import cn.hippo4j.common.web.base.Result;
import cn.hippo4j.common.web.base.Results; import cn.hippo4j.common.web.base.Results;
import cn.hippo4j.common.web.exception.ErrorCodeEnum; import cn.hippo4j.common.web.exception.ErrorCodeEnum;
import cn.hippo4j.config.model.CacheItem; import cn.hippo4j.config.model.CacheItem;
import cn.hippo4j.config.model.biz.threadpool.ThreadPoolDelReqDTO; import cn.hippo4j.config.model.biz.threadpool.*;
import cn.hippo4j.config.model.biz.threadpool.ThreadPoolQueryReqDTO;
import cn.hippo4j.config.model.biz.threadpool.ThreadPoolRespDTO;
import cn.hippo4j.config.model.biz.threadpool.ThreadPoolSaveOrUpdateReqDTO;
import cn.hippo4j.config.service.ConfigCacheService; import cn.hippo4j.config.service.ConfigCacheService;
import cn.hippo4j.config.service.biz.ThreadPoolService; import cn.hippo4j.config.service.biz.ThreadPoolService;
import cn.hippo4j.common.toolkit.BeanUtil; import cn.hippo4j.config.verify.ConfigModificationVerifyServiceChoose;
import cn.hippo4j.console.model.ThreadPoolInstanceInfo; import cn.hippo4j.console.model.ThreadPoolInstanceInfo;
import cn.hippo4j.console.model.WebThreadPoolReqDTO; import cn.hippo4j.console.model.WebThreadPoolReqDTO;
import cn.hippo4j.console.model.WebThreadPoolRespDTO; import cn.hippo4j.console.model.WebThreadPoolRespDTO;
@ -44,13 +40,12 @@ import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate; import org.springframework.web.client.RestTemplate;
import java.util.HashMap;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static cn.hippo4j.common.constant.Constants.HTTP_EXECUTE_TIMEOUT;
import static cn.hippo4j.common.toolkit.ContentUtil.getGroupKey; import static cn.hippo4j.common.toolkit.ContentUtil.getGroupKey;
/** /**
@ -65,6 +60,8 @@ public class ThreadPoolController {
private final BaseInstanceRegistry baseInstanceRegistry; private final BaseInstanceRegistry baseInstanceRegistry;
private final ConfigModificationVerifyServiceChoose configModificationVerifyServiceChoose;
private final RestTemplate restTemplate = new RestTemplate(); private final RestTemplate restTemplate = new RestTemplate();
@PostMapping("/query/page") @PostMapping("/query/page")
@ -157,6 +154,8 @@ public class ThreadPoolController {
continue; continue;
} }
WebThreadPoolRespDTO result = BeanUtil.convert(data, WebThreadPoolRespDTO.class); WebThreadPoolRespDTO result = BeanUtil.convert(data, WebThreadPoolRespDTO.class);
result.setItemId(itemId);
result.setTenantId(each.getHolder().getGroupKey().split("[+]")[1]);
result.setActive(each.getHolder().getActive()); result.setActive(each.getHolder().getActive());
result.setIdentify(each.getHolder().getIdentify()); result.setIdentify(each.getHolder().getIdentify());
result.setClientAddress(each.getHolder().getCallBackUrl()); result.setClientAddress(each.getHolder().getCallBackUrl());
@ -191,6 +190,7 @@ public class ThreadPoolController {
@PostMapping("/web/update/pool") @PostMapping("/web/update/pool")
public Result<Void> updateWebThreadPool(@RequestBody WebThreadPoolReqDTO requestParam) { public Result<Void> updateWebThreadPool(@RequestBody WebThreadPoolReqDTO requestParam) {
if (UserContext.getUserRole().equals("ROLE_ADMIN")) {
for (String each : requestParam.getClientAddressList()) { for (String each : requestParam.getClientAddressList()) {
String urlString = new StringBuilder() String urlString = new StringBuilder()
.append("http://") .append("http://")
@ -199,6 +199,12 @@ public class ThreadPoolController {
.toString(); .toString();
restTemplate.postForObject(urlString, JSONUtil.toJSONString(requestParam), Object.class); restTemplate.postForObject(urlString, JSONUtil.toJSONString(requestParam), Object.class);
} }
} else {
ConfigModifySaveReqDTO modifySaveReqDTO = BeanUtil.convert(requestParam, ConfigModifySaveReqDTO.class);
modifySaveReqDTO.setModifyUser(UserContext.getUserName());
modifySaveReqDTO.setType(ConfigModifyTypeConstants.WEB_THREAD_POOL);
configModificationVerifyServiceChoose.choose(modifySaveReqDTO.getType()).saveConfigModifyApplication(modifySaveReqDTO);
}
return Results.success(); return Results.success();
} }
@ -215,9 +221,9 @@ public class ThreadPoolController {
String groupKey = getGroupKey(tpId, itemTenantKey); String groupKey = getGroupKey(tpId, itemTenantKey);
Map<String, CacheItem> content = ConfigCacheService.getContent(groupKey); Map<String, CacheItem> content = ConfigCacheService.getContent(groupKey);
Map<String, String> activeMap = Map<String, String> activeMap =
leases.stream().map(Lease::getHolder).filter(each -> StringUtil.isNotBlank(each.getActive())) leases.stream().map(each -> each.getHolder()).filter(each -> StringUtil.isNotBlank(each.getActive()))
.collect(Collectors.toMap(InstanceInfo::getIdentify, InstanceInfo::getActive)); .collect(Collectors.toMap(InstanceInfo::getIdentify, InstanceInfo::getActive));
Map<String, String> clientBasePathMap = leases.stream().map(Lease::getHolder) Map<String, String> clientBasePathMap = leases.stream().map(each -> each.getHolder())
.filter(each -> StringUtil.isNotBlank(each.getClientBasePath())) .filter(each -> StringUtil.isNotBlank(each.getClientBasePath()))
.collect(Collectors.toMap(InstanceInfo::getIdentify, InstanceInfo::getClientBasePath)); .collect(Collectors.toMap(InstanceInfo::getIdentify, InstanceInfo::getClientBasePath));
List<ThreadPoolInstanceInfo> returnThreadPool = new ArrayList<>(); List<ThreadPoolInstanceInfo> returnThreadPool = new ArrayList<>();
@ -232,4 +238,5 @@ public class ThreadPoolController {
}); });
return Results.success(returnThreadPool); return Results.success(returnThreadPool);
} }
} }

@ -27,6 +27,21 @@ import java.util.List;
@Data @Data
public class WebThreadPoolReqDTO { public class WebThreadPoolReqDTO {
/**
* Thread-pool id
*/
private String tenantId;
/**
* Item id
*/
private String itemId;
/**
* thread pool instance id
*/
private String identify;
/** /**
* Core pool size * Core pool size
*/ */
@ -42,6 +57,11 @@ public class WebThreadPoolReqDTO {
*/ */
private Integer keepAliveTime; private Integer keepAliveTime;
/**
* weather modify all instances
*/
private Boolean modifyAll;
/** /**
* Client address list * Client address list
*/ */

@ -25,6 +25,16 @@ import lombok.Data;
@Data @Data
public class WebThreadPoolRespDTO { public class WebThreadPoolRespDTO {
/**
* thread pool tenant id
*/
private String tenantId;
/**
* item id
*/
private String itemId;
/** /**
* Active * Active
*/ */

@ -42,18 +42,6 @@ public class BeforeCheckConfiguration {
ConfigurableEnvironment environment) { ConfigurableEnvironment environment) {
boolean checkFlag = properties != null && Objects.equals(bootstrapPropertiesClassName, properties.getClass().getName()) && properties.getEnable(); boolean checkFlag = properties != null && Objects.equals(bootstrapPropertiesClassName, properties.getClass().getName()) && properties.getEnable();
if (checkFlag) { if (checkFlag) {
String username = properties.getUsername();
if (StringUtil.isBlank(username)) {
throw new ConfigEmptyException(
"Web server failed to start. The dynamic thread pool username is empty.",
"Please check whether the [spring.dynamic.thread-pool.username] configuration is empty or an empty string.");
}
String password = properties.getPassword();
if (StringUtil.isBlank(password)) {
throw new ConfigEmptyException(
"Web server failed to start. The dynamic thread pool password is empty.",
"Please check whether the [spring.dynamic.thread-pool.password] configuration is empty or an empty string.");
}
String namespace = properties.getNamespace(); String namespace = properties.getNamespace();
if (StringUtil.isBlank(namespace)) { if (StringUtil.isBlank(namespace)) {
throw new ConfigEmptyException( throw new ConfigEmptyException(

@ -231,7 +231,7 @@ public class ThreadPoolBuilder implements Builder<ThreadPoolExecutor> {
* @param threadPoolId threadPoolId * @param threadPoolId threadPoolId
* @return ThreadPoolExecutor * @return ThreadPoolExecutor
*/ */
public static ThreadPoolExecutor builderDynamicPoolById(String threadPoolId) { public static ThreadPoolExecutor buildDynamicPoolById(String threadPoolId) {
return ThreadPoolBuilder.builder() return ThreadPoolBuilder.builder()
.threadFactory(threadPoolId) .threadFactory(threadPoolId)
.threadPoolId(threadPoolId) .threadPoolId(threadPoolId)

@ -35,6 +35,6 @@ public class ThreadPoolConfig {
@SpringDynamicThreadPool @SpringDynamicThreadPool
public ThreadPoolExecutor messageConsumeDynamicExecutor() { public ThreadPoolExecutor messageConsumeDynamicExecutor() {
String threadPoolId = "message-consume"; String threadPoolId = "message-consume";
return ThreadPoolBuilder.builderDynamicPoolById(threadPoolId); return ThreadPoolBuilder.buildDynamicPoolById(threadPoolId);
} }
} }

@ -65,7 +65,7 @@ public class DynamicThreadPoolConfig {
*/ */
@SpringDynamicThreadPool @SpringDynamicThreadPool
public ThreadPoolExecutor messageProduceDynamicThreadPool() { public ThreadPoolExecutor messageProduceDynamicThreadPool() {
return ThreadPoolBuilder.builderDynamicPoolById(MESSAGE_PRODUCE); return ThreadPoolBuilder.buildDynamicPoolById(MESSAGE_PRODUCE);
} }
/** /**

@ -15,8 +15,8 @@ spring.dynamic.thread-pool.server-addr=http://localhost:6691
# spring.dynamic.thread-pool.netty-server-port=8899 # spring.dynamic.thread-pool.netty-server-port=8899
spring.dynamic.thread-pool.namespace=prescription spring.dynamic.thread-pool.namespace=prescription
spring.dynamic.thread-pool.item-id=dynamic-threadpool-example spring.dynamic.thread-pool.item-id=dynamic-threadpool-example
spring.dynamic.thread-pool.username=admin #spring.dynamic.thread-pool.username=admin
spring.dynamic.thread-pool.password=123456 #spring.dynamic.thread-pool.password=123456
# Enable server and micrometer monitoring at the same time # Enable server and micrometer monitoring at the same time
spring.dynamic.thread-pool.collect-type=server,micrometer spring.dynamic.thread-pool.collect-type=server,micrometer

@ -20,6 +20,9 @@ tenant=hippo4j
hippo4j.core.clean-history-data-period=30 hippo4j.core.clean-history-data-period=30
hippo4j.core.clean-history-data-enable=true hippo4j.core.clean-history-data-enable=true
### Whether to enable authentication.
hippo4j.core.auth.enabled=false
### Use netty to report thread pool monitoring data. The default is http. ### Use netty to report thread pool monitoring data. The default is http.
# hippo4j.core.monitor.report-type=netty # hippo4j.core.monitor.report-type=netty

@ -208,6 +208,29 @@ CREATE TABLE `notify` (
UNIQUE KEY `uk_notify_biz_key` (`tenant_id`,`item_id`,`tp_id`,`platform`,`type`,`del_flag`) USING BTREE UNIQUE KEY `uk_notify_biz_key` (`tenant_id`,`item_id`,`tp_id`,`platform`,`type`,`del_flag`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='通知表'; ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='通知表';
-- ----------------------------
-- Table structure for his_config_verify
-- ----------------------------
DROP TABLE IF EXISTS `his_config_verify`;
CREATE TABLE `his_config_verify` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`type` int NULL DEFAULT NULL COMMENT '变更类型',
`mark` varchar(128) DEFAULT NULL COMMENT '框架线程池类型',
`tenant_id` varchar(128) DEFAULT NULL COMMENT '租户ID',
`item_id` varchar(128) DEFAULT NULL COMMENT '项目ID',
`tp_id` varchar(256) DEFAULT NULL COMMENT '线程池ID',
`identify` varchar(64) DEFAULT NULL COMMENT '线程池唯一标识',
`content` longtext NULL COMMENT '参数变更内容',
`modify_all` tinyint(1) NULL DEFAULT NULL COMMENT '是否全部修改',
`gmt_create` datetime NULL DEFAULT NULL COMMENT '参数变更时间',
`modify_user` varchar(128) DEFAULT NULL COMMENT '修改人',
`verify_status` tinyint(1) NULL DEFAULT NULL COMMENT '审核状态 0:待审核 1审核通过 2审核拒绝',
`gmt_verify` datetime NULL DEFAULT NULL COMMENT '审核时间',
`verify_user` varchar(128) DEFAULT NULL COMMENT '审核人',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET=utf8mb4 COMMENT = '参数变更审核记录表';
/* Init SQL */ /* Init SQL */
INSERT IGNORE INTO `tenant` (`id`, `tenant_id`, `tenant_name`, `tenant_desc`, `owner`, `gmt_create`, `gmt_modified`, `del_flag`) VALUES ('1', 'prescription', '处方组', '负责维护处方服务, 包括不限于电子处方等业务', '谢良辰', '2021-10-24 13:42:11', '2021-10-24 13:42:11', '0'); INSERT IGNORE INTO `tenant` (`id`, `tenant_id`, `tenant_name`, `tenant_desc`, `owner`, `gmt_create`, `gmt_modified`, `del_flag`) VALUES ('1', 'prescription', '处方组', '负责维护处方服务, 包括不限于电子处方等业务', '谢良辰', '2021-10-24 13:42:11', '2021-10-24 13:42:11', '0');

@ -15,3 +15,23 @@ ALTER TABLE inst_config Modify COLUMN tp_id varchar(256) COMMENT '线程池ID';
ALTER TABLE his_run_data Modify COLUMN tp_id varchar(256) COMMENT '线程池ID'; ALTER TABLE his_run_data Modify COLUMN tp_id varchar(256) COMMENT '线程池ID';
ALTER TABLE notify Modify COLUMN tp_id varchar(256) COMMENT '线程池ID'; ALTER TABLE notify Modify COLUMN tp_id varchar(256) COMMENT '线程池ID';
DROP TABLE IF EXISTS `his_config_verify`;
CREATE TABLE `his_config_verify` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`type` int NULL DEFAULT NULL COMMENT '变更类型',
`mark` varchar(128) DEFAULT NULL COMMENT '框架线程池类型',
`tenant_id` varchar(128) DEFAULT NULL COMMENT '租户ID',
`item_id` varchar(128) DEFAULT NULL COMMENT '项目ID',
`tp_id` varchar(256) DEFAULT NULL COMMENT '线程池ID',
`identify` varchar(64) DEFAULT NULL COMMENT '线程池唯一标识',
`content` longtext DEFAULT NULL COMMENT '参数变更内容',
`modify_all` tinyint(1) NULL DEFAULT NULL COMMENT '是否全部修改',
`gmt_create` datetime NULL DEFAULT NULL COMMENT '参数变更时间',
`modify_user` varchar(128) DEFAULT NULL COMMENT '修改人',
`verify_status` tinyint(1) NULL DEFAULT NULL COMMENT '审核状态 0:待审核 1审核通过 2审核拒绝',
`gmt_verify` datetime NULL DEFAULT NULL COMMENT '审核时间',
`verify_user` varchar(128) DEFAULT NULL COMMENT '审核人',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET=utf8mb4 COMMENT = '参数变更审核记录表';

@ -21,6 +21,9 @@ tenant=hippo4j
hippo4j.core.clean-history-data-period=30 hippo4j.core.clean-history-data-period=30
hippo4j.core.clean-history-data-enable=true hippo4j.core.clean-history-data-enable=true
### Whether to enable authentication.
hippo4j.core.auth.enabled=false
### Initialize the database dialect class. ### Initialize the database dialect class.
hippo4j.database.dialect=mysql hippo4j.database.dialect=mysql
hippo4j.database.init_enable=true hippo4j.database.init_enable=true

@ -144,6 +144,24 @@ CREATE TABLE IF NOT EXISTS `notify` (
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
); );
CREATE TABLE IF NOT EXISTS `his_config_verify` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`type` int NULL DEFAULT NULL COMMENT '变更类型',
`mark` varchar(128) DEFAULT NULL COMMENT '框架线程池类型',
`tenant_id` varchar(128) DEFAULT NULL COMMENT '租户ID',
`item_id` varchar(128) DEFAULT NULL COMMENT '项目ID',
`tp_id` varchar(256) DEFAULT NULL COMMENT '线程池ID',
`identify` varchar(64) DEFAULT NULL COMMENT '线程池唯一标识',
`content` longtext COMMENT '参数变更内容',
`modify_all` tinyint(1) COMMENT '是否全部修改',
`gmt_create` datetime COMMENT '参数变更时间',
`modify_user` varchar(128) DEFAULT NULL COMMENT '修改人',
`verify_status` tinyint(1) COMMENT '审核状态 0:待审核 1审核通过 2审核拒绝',
`gmt_verify` datetime COMMENT '审核时间',
`verify_user` varchar(128) DEFAULT NULL COMMENT '审核人',
PRIMARY KEY (`id`) USING BTREE
);
INSERT INTO `tenant` (`id`, `tenant_id`, `tenant_name`, `tenant_desc`, `owner`, `gmt_create`, `gmt_modified`, `del_flag`) VALUES ('1', 'prescription', '处方组', '负责维护处方服务, 包括不限于电子处方等业务', '谢良辰', '2021-10-24 13:42:11', '2021-10-24 13:42:11', '0'); INSERT INTO `tenant` (`id`, `tenant_id`, `tenant_name`, `tenant_desc`, `owner`, `gmt_create`, `gmt_modified`, `del_flag`) VALUES ('1', 'prescription', '处方组', '负责维护处方服务, 包括不限于电子处方等业务', '谢良辰', '2021-10-24 13:42:11', '2021-10-24 13:42:11', '0');
INSERT INTO `item` (`id`, `tenant_id`, `item_id`, `item_name`, `item_desc`, `owner`, `gmt_create`, `gmt_modified`, `del_flag`) VALUES ('1', 'prescription', 'dynamic-threadpool-example', '动态线程池示例项目', '动态线程池示例项目,对应 Hippo 项目的 example 模块', '马称', '2021-10-24 16:11:00', '2021-10-24 16:11:00', '0'); INSERT INTO `item` (`id`, `tenant_id`, `item_id`, `item_name`, `item_desc`, `owner`, `gmt_create`, `gmt_modified`, `del_flag`) VALUES ('1', 'prescription', 'dynamic-threadpool-example', '动态线程池示例项目', '动态线程池示例项目,对应 Hippo 项目的 example 模块', '马称', '2021-10-24 16:11:00', '2021-10-24 16:11:00', '0');

@ -198,6 +198,28 @@ CREATE TABLE IF NOT EXISTS `notify` (
UNIQUE KEY `uk_notify_biz_key` (`tenant_id`,`item_id`,`tp_id`,`platform`,`type`,`del_flag`) USING BTREE UNIQUE KEY `uk_notify_biz_key` (`tenant_id`,`item_id`,`tp_id`,`platform`,`type`,`del_flag`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='通知表'; ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='通知表';
-- ----------------------------
-- Table structure for his_config_verify
-- ----------------------------
DROP TABLE IF EXISTS `his_config_verify`;
CREATE TABLE `his_config_verify` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`type` int NULL DEFAULT NULL COMMENT '变更类型',
`mark` varchar(128) DEFAULT NULL COMMENT '框架线程池类型',
`tenant_id` varchar(128) DEFAULT NULL COMMENT '租户ID',
`item_id` varchar(128) DEFAULT NULL COMMENT '项目ID',
`tp_id` varchar(256) DEFAULT NULL COMMENT '线程池ID',
`identify` varchar(64) DEFAULT NULL COMMENT '线程池唯一标识',
`content` longtext NULL COMMENT '参数变更内容',
`modify_all` tinyint(1) NULL DEFAULT NULL COMMENT '是否全部修改',
`gmt_create` datetime NULL DEFAULT NULL COMMENT '参数变更时间',
`modify_user` varchar(128) DEFAULT NULL COMMENT '修改人',
`verify_status` tinyint(1) NULL DEFAULT NULL COMMENT '审核状态 0:待审核 1审核通过 2审核拒绝',
`gmt_verify` datetime NULL DEFAULT NULL COMMENT '审核时间',
`verify_user` varchar(128) DEFAULT NULL COMMENT '审核人',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET=utf8mb4 COMMENT = '参数变更审核记录表';
/* Init SQL */ /* Init SQL */
INSERT IGNORE INTO `tenant` (`id`, `tenant_id`, `tenant_name`, `tenant_desc`, `owner`, `gmt_create`, `gmt_modified`, `del_flag`) VALUES ('1', 'prescription', '处方组', '负责维护处方服务, 包括不限于电子处方等业务', '谢良辰', '2021-10-24 13:42:11', '2021-10-24 13:42:11', '0'); INSERT IGNORE INTO `tenant` (`id`, `tenant_id`, `tenant_name`, `tenant_desc`, `owner`, `gmt_create`, `gmt_modified`, `del_flag`) VALUES ('1', 'prescription', '处方组', '负责维护处方服务, 包括不限于电子处方等业务', '谢良辰', '2021-10-24 13:42:11', '2021-10-24 13:42:11', '0');

@ -44,7 +44,7 @@ public class HttpScheduledHealthCheck extends AbstractHealthCheck {
healthStatus = true; healthStatus = true;
} }
} catch (Throwable ex) { } catch (Throwable ex) {
log.error("Failed to periodically check the health status of the server.", ex.getMessage()); log.error("Failed to periodically check the health status of the server. message: {}", ex.getMessage());
} }
return healthStatus; return healthStatus;
} }

Loading…
Cancel
Save