Merge pull request #1 from acmenlt/develop

update new feature
pull/32/head
Jason Lin 4 years ago committed by GitHub
commit d0c816a446
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1,10 +1,10 @@
package cn.hippo4j.auth.filter; package cn.hippo4j.auth.filter;
import cn.hippo4j.auth.toolkit.JwtTokenUtil; import cn.hippo4j.auth.toolkit.JwtTokenUtil;
import cn.hippo4j.common.toolkit.JSONUtil;
import cn.hippo4j.common.toolkit.UserContext; import cn.hippo4j.common.toolkit.UserContext;
import cn.hippo4j.common.web.base.Results; import cn.hippo4j.common.web.base.Results;
import cn.hippo4j.common.web.exception.ServiceException; import cn.hippo4j.common.web.exception.ServiceException;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
@ -50,7 +50,7 @@ public class JWTAuthorizationFilter extends BasicAuthenticationFilter {
// 返回 Json 形式的错误信息 // 返回 Json 形式的错误信息
response.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("UTF-8");
response.setContentType("application/json; charset=utf-8"); response.setContentType("application/json; charset=utf-8");
response.getWriter().write(JSON.toJSONString(Results.failure("-1", ex.getMessage()))); response.getWriter().write(JSONUtil.toJSONString(Results.failure("-1", ex.getMessage())));
response.getWriter().flush(); response.getWriter().flush();
return; return;
} }

@ -21,11 +21,6 @@
<artifactId>spring-boot-starter</artifactId> <artifactId>spring-boot-starter</artifactId>
</dependency> </dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
<dependency> <dependency>
<groupId>org.projectlombok</groupId> <groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId> <artifactId>lombok</artifactId>
@ -35,6 +30,11 @@
<groupId>cn.hutool</groupId> <groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId> <artifactId>hutool-all</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-json</artifactId>
</dependency>
</dependencies> </dependencies>
<build> <build>

@ -0,0 +1,41 @@
package cn.hippo4j.common.api;
import java.util.List;
/**
* Json facade.
*
* @author chen.ma
* @date 2021/12/13 20:01
*/
public interface JsonFacade {
/**
* To JSON string.
*
* @param object
* @return
*/
String toJSONString(Object object);
/**
* Parse object.
*
* @param text
* @param clazz
* @param <T>
* @return
*/
<T> T parseObject(String text, Class<T> clazz);
/**
* Parse array.
*
* @param text
* @param clazz
* @param <T>
* @return
*/
<T> List<T> parseArray(String text, Class<T> clazz);
}

@ -0,0 +1,57 @@
package cn.hippo4j.common.api.impl;
import cn.hippo4j.common.api.JsonFacade;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.type.CollectionType;
import lombok.SneakyThrows;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
/**
* Jackson util.
*
* @author chen.ma
* @date 2021/12/13 20:02
*/
public class JacksonHandler implements JsonFacade {
private static ObjectMapper MAPPER = new ObjectMapper();
static {
MAPPER.enable(JsonGenerator.Feature.IGNORE_UNKNOWN);
String dateTimeFormat = "yyyy-MM-dd HH:mm:ss";
MAPPER.setDateFormat(new SimpleDateFormat(dateTimeFormat));
MAPPER.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
MAPPER.setSerializationInclusion(JsonInclude.Include.NON_NULL);
MAPPER.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
MAPPER.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
}
@Override
@SneakyThrows
public String toJSONString(Object object) {
return MAPPER.writeValueAsString(object);
}
@Override
@SneakyThrows
public <T> T parseObject(String text, Class<T> clazz) {
JavaType javaType = MAPPER.getTypeFactory().constructType(clazz);
return MAPPER.readValue(text, javaType);
}
@Override
@SneakyThrows
public <T> List<T> parseArray(String text, Class<T> clazz) {
CollectionType collectionType = MAPPER.getTypeFactory().constructCollectionType(ArrayList.class, clazz);
return MAPPER.readValue(text, collectionType);
}
}

@ -1,7 +1,6 @@
package cn.hippo4j.common.toolkit; package cn.hippo4j.common.toolkit;
import cn.hippo4j.common.constant.Constants; import cn.hippo4j.common.constant.Constants;
import com.alibaba.fastjson.JSON;
import cn.hippo4j.common.model.PoolParameter; import cn.hippo4j.common.model.PoolParameter;
import cn.hippo4j.common.model.PoolParameterInfo; import cn.hippo4j.common.model.PoolParameterInfo;
@ -27,7 +26,7 @@ public class ContentUtil {
.setCapacityAlarm(parameter.getCapacityAlarm()) .setCapacityAlarm(parameter.getCapacityAlarm())
.setLivenessAlarm(parameter.getLivenessAlarm()) .setLivenessAlarm(parameter.getLivenessAlarm())
.setRejectedType(parameter.getRejectedType()); .setRejectedType(parameter.getRejectedType());
return JSON.toJSONString(poolInfo); return JSONUtil.toJSONString(poolInfo);
} }
public static String getGroupKey(PoolParameter parameter) { public static String getGroupKey(PoolParameter parameter) {

@ -0,0 +1,47 @@
package cn.hippo4j.common.toolkit;
import cn.hippo4j.common.api.JsonFacade;
import cn.hippo4j.common.config.ApplicationContextHolder;
import cn.hutool.core.util.StrUtil;
import java.util.List;
/**
* JSON util.
*
* @author chen.ma
* @date 2021/12/13 20:27
*/
public class JSONUtil {
private static JsonFacade jsonFacade;
static {
JSONUtil.jsonFacade = ApplicationContextHolder.getBean(JsonFacade.class);
}
public static String toJSONString(Object object) {
if (object == null) {
return null;
}
return jsonFacade.toJSONString(object);
}
public static <T> T parseObject(String text, Class<T> clazz) {
if (StrUtil.isBlank(text)) {
return null;
}
return jsonFacade.parseObject(text, clazz);
}
public static <T> List<T> parseArray(String text, Class<T> clazz) {
if (StrUtil.isBlank(text)) {
return null;
}
return jsonFacade.parseArray(text, clazz);
}
}

@ -51,11 +51,6 @@
<artifactId>hippo4j-common</artifactId> <artifactId>hippo4j-common</artifactId>
</dependency> </dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
<dependency> <dependency>
<groupId>com.github.dozermapper</groupId> <groupId>com.github.dozermapper</groupId>
<artifactId>dozer-core</artifactId> <artifactId>dozer-core</artifactId>

@ -1,5 +1,7 @@
package cn.hippo4j.config.config; package cn.hippo4j.config.config;
import cn.hippo4j.common.api.JsonFacade;
import cn.hippo4j.common.api.impl.JacksonHandler;
import cn.hippo4j.common.config.ApplicationContextHolder; import cn.hippo4j.common.config.ApplicationContextHolder;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
@ -13,6 +15,11 @@ import org.springframework.context.annotation.Configuration;
@Configuration @Configuration
public class CommonConfig { public class CommonConfig {
@Bean
public JsonFacade jacksonHandler() {
return new JacksonHandler();
}
@Bean @Bean
public ApplicationContextHolder simpleApplicationContextHolder() { public ApplicationContextHolder simpleApplicationContextHolder() {
return new ApplicationContextHolder(); return new ApplicationContextHolder();

@ -34,6 +34,23 @@ public interface HisRunDataMapper extends BaseMapper<HisRunDataInfo> {
"limit 8") "limit 8")
List<ThreadPoolTaskRanking> queryThreadPoolTaskSumRanking(@Param("startTime") Long startTime, @Param("endTime") Long endTime); List<ThreadPoolTaskRanking> queryThreadPoolTaskSumRanking(@Param("startTime") Long startTime, @Param("endTime") Long endTime);
/**
* Query thread pool task sum ranking.
*
* @param startTime
* @param endTime
* @return
*/
@Select("SELECT " +
"tenant_id, item_id, tp_id, max(queue_size) as max_queue_size, max(reject_count) as max_reject_count, max(completed_task_count) as max_completed_task_count " +
"FROM his_run_data " +
"where timestamp between #{startTime} and #{endTime} " +
"group by tenant_id, item_id, tp_id " +
"order by max_completed_task_count desc " +
"limit 4")
List<ThreadPoolTaskRanking> queryThreadPoolMaxRanking(@Param("startTime") Long startTime, @Param("endTime") Long endTime);
@Data @Data
class ThreadPoolTaskRanking { class ThreadPoolTaskRanking {
@ -57,5 +74,15 @@ public interface HisRunDataMapper extends BaseMapper<HisRunDataInfo> {
*/ */
private Long maxCompletedTaskCount; private Long maxCompletedTaskCount;
/**
*
*/
private Long maxQueueSize;
/**
*
*/
private Long maxRejectCount;
} }
} }

@ -1,12 +1,12 @@
package cn.hippo4j.config.model; package cn.hippo4j.config.model;
import com.alibaba.fastjson.JSON; import cn.hippo4j.common.model.PoolParameter;
import com.alibaba.fastjson.annotation.JSONField; import cn.hippo4j.common.toolkit.JSONUtil;
import com.baomidou.mybatisplus.annotation.FieldFill; import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableLogic; import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import cn.hippo4j.common.model.PoolParameter; import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data; import lombok.Data;
import java.util.Date; import java.util.Date;
@ -26,21 +26,21 @@ public class ConfigAllInfo extends ConfigInfo implements PoolParameter {
/** /**
* desc * desc
*/ */
@JSONField(serialize = false) @JsonIgnore
@TableField(exist = false, fill = FieldFill.UPDATE) @TableField(exist = false, fill = FieldFill.UPDATE)
private String desc; private String desc;
/** /**
* gmtCreate * gmtCreate
*/ */
@JSONField(serialize = false) @JsonIgnore
@TableField(fill = FieldFill.INSERT) @TableField(fill = FieldFill.INSERT)
private Date gmtCreate; private Date gmtCreate;
/** /**
* gmtModified * gmtModified
*/ */
@JSONField(serialize = false) @JsonIgnore
@TableField(fill = FieldFill.INSERT_UPDATE) @TableField(fill = FieldFill.INSERT_UPDATE)
private Date gmtModified; private Date gmtModified;
@ -48,13 +48,13 @@ public class ConfigAllInfo extends ConfigInfo implements PoolParameter {
* delFlag * delFlag
*/ */
@TableLogic @TableLogic
@JSONField(serialize = false) @JsonIgnore
@TableField(fill = FieldFill.INSERT) @TableField(fill = FieldFill.INSERT)
private Integer delFlag; private Integer delFlag;
@Override @Override
public String toString() { public String toString() {
return JSON.toJSONString(this); return JSONUtil.toJSONString(this);
} }
} }

@ -1,8 +1,8 @@
package cn.hippo4j.config.model; package cn.hippo4j.config.model;
import com.alibaba.fastjson.annotation.JSONField;
import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data; import lombok.Data;
import java.io.Serializable; import java.io.Serializable;
@ -87,13 +87,13 @@ public class ConfigInfoBase implements Serializable {
/** /**
* MD5 * MD5
*/ */
@JSONField(serialize = false) @JsonIgnore
private String md5; private String md5;
/** /**
* content * content
*/ */
@JSONField(serialize = false) @JsonIgnore
private String content; private String content;
} }

@ -1,6 +1,6 @@
package cn.hippo4j.config.model.biz.tenant; package cn.hippo4j.config.model.biz.tenant;
import com.alibaba.fastjson.JSON; import cn.hippo4j.common.toolkit.JSONUtil;
import lombok.Data; import lombok.Data;
/** /**
@ -39,7 +39,7 @@ public class TenantUpdateReqDTO {
@Override @Override
public String toString() { public String toString() {
return JSON.toJSONString(this); return JSONUtil.toJSONString(this);
} }
} }

@ -2,9 +2,8 @@ package cn.hippo4j.config.monitor;
import cn.hippo4j.common.monitor.MessageTypeEnum; import cn.hippo4j.common.monitor.MessageTypeEnum;
import cn.hippo4j.common.monitor.RuntimeMessage; import cn.hippo4j.common.monitor.RuntimeMessage;
import cn.hippo4j.common.toolkit.JSONUtil;
import cn.hippo4j.config.service.biz.HisRunDataService; import cn.hippo4j.config.service.biz.HisRunDataService;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@ -29,7 +28,7 @@ public class RuntimeDataResolver extends AbstractMonitorDataExecuteStrategy<Runt
@Override @Override
public void execute(RuntimeMessage message) { public void execute(RuntimeMessage message) {
log.info("[{}] Perform monitoring data persistence. content :: {}", this.getClass().getName(), JSON.toJSONString(message, SerializerFeature.PrettyFormat)); log.info("[{}] Perform monitoring data persistence. content :: {}", this.getClass().getName(), JSONUtil.toJSONString(message));
hisRunDataService.save(message); hisRunDataService.save(message);
} }

@ -1,16 +1,16 @@
package cn.hippo4j.config.service; package cn.hippo4j.config.service;
import cn.hippo4j.config.notify.NotifyCenter;
import cn.hutool.core.collection.CollUtil;
import cn.hippo4j.config.service.biz.ConfigService;
import cn.hippo4j.common.config.ApplicationContextHolder; import cn.hippo4j.common.config.ApplicationContextHolder;
import cn.hippo4j.common.constant.Constants; import cn.hippo4j.common.constant.Constants;
import cn.hippo4j.common.toolkit.JSONUtil;
import cn.hippo4j.common.toolkit.Md5Util; import cn.hippo4j.common.toolkit.Md5Util;
import cn.hippo4j.config.event.LocalDataChangeEvent; import cn.hippo4j.config.event.LocalDataChangeEvent;
import cn.hippo4j.config.model.CacheItem; import cn.hippo4j.config.model.CacheItem;
import cn.hippo4j.config.model.ConfigAllInfo; 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.hippo4j.config.toolkit.MapUtil;
import com.alibaba.fastjson.JSON; import cn.hutool.core.collection.CollUtil;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
@ -20,6 +20,7 @@ import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
/** /**
* Config cache service. * Config cache service.
@ -30,20 +31,20 @@ import java.util.concurrent.ConcurrentHashMap;
@Slf4j @Slf4j
public class ConfigCacheService { public class ConfigCacheService {
private static ConfigService configService = null; private static ConfigService CONFIG_SERVICE = null;
/** /**
* TODO: remove * TODO: remove
* <p> * <p>
* key: message-produce+dynamic-threadpool-example+prescription+192.168.20.227:8088 * key: message-produce+dynamic-threadpool-example+prescription+192.168.20.227:8088_xxx
* val: * val:
* key: 192.168.20.227:8088 * key: 192.168.20.227:8088_xxx
* val: {@link CacheItem} * val: {@link CacheItem}
*/ */
private static final ConcurrentHashMap<String, Map<String, CacheItem>> CACHE = new ConcurrentHashMap(); private static final ConcurrentHashMap<String, Map<String, CacheItem>> CLIENT_CONFIG_CACHE = new ConcurrentHashMap();
public static boolean isUpdateData(String groupKey, String md5, String ip) { public static boolean isUpdateData(String groupKey, String md5, String clientIdentify) {
String contentMd5 = ConfigCacheService.getContentMd5IsNullPut(groupKey, ip); String contentMd5 = ConfigCacheService.getContentMd5IsNullPut(groupKey, clientIdentify);
return Objects.equals(contentMd5, md5); return Objects.equals(contentMd5, md5);
} }
@ -51,38 +52,38 @@ public class ConfigCacheService {
* Get Md5. * Get Md5.
* *
* @param groupKey * @param groupKey
* @param ip * @param clientIdentify
* @return * @return
*/ */
private synchronized static String getContentMd5IsNullPut(String groupKey, String ip) { private synchronized static String getContentMd5IsNullPut(String groupKey, String clientIdentify) {
Map<String, CacheItem> cacheItemMap = Optional.ofNullable(CACHE.get(groupKey)).orElse(Maps.newHashMap()); Map<String, CacheItem> cacheItemMap = Optional.ofNullable(CLIENT_CONFIG_CACHE.get(groupKey)).orElse(Maps.newHashMap());
CacheItem cacheItem = null; CacheItem cacheItem = null;
if (CollUtil.isNotEmpty(cacheItemMap) && (cacheItem = cacheItemMap.get(ip)) != null) { if (CollUtil.isNotEmpty(cacheItemMap) && (cacheItem = cacheItemMap.get(clientIdentify)) != null) {
return cacheItem.md5; return cacheItem.md5;
} }
if (configService == null) { if (CONFIG_SERVICE == null) {
configService = ApplicationContextHolder.getBean(ConfigService.class); CONFIG_SERVICE = ApplicationContextHolder.getBean(ConfigService.class);
} }
String[] params = groupKey.split("\\+"); String[] params = groupKey.split("\\+");
ConfigAllInfo config = configService.findConfigRecentInfo(params); ConfigAllInfo config = CONFIG_SERVICE.findConfigRecentInfo(params);
if (config != null && !StringUtils.isEmpty(config.getTpId())) { if (config != null && !StringUtils.isEmpty(config.getTpId())) {
cacheItem = new CacheItem(groupKey, config); cacheItem = new CacheItem(groupKey, config);
cacheItemMap.put(ip, cacheItem); cacheItemMap.put(clientIdentify, cacheItem);
CACHE.put(groupKey, cacheItemMap); CLIENT_CONFIG_CACHE.put(groupKey, cacheItemMap);
} }
return (cacheItem != null) ? cacheItem.md5 : Constants.NULL; return (cacheItem != null) ? cacheItem.md5 : Constants.NULL;
} }
public static String getContentMd5(String groupKey) { public static String getContentMd5(String groupKey) {
if (configService == null) { if (CONFIG_SERVICE == null) {
configService = ApplicationContextHolder.getBean(ConfigService.class); CONFIG_SERVICE = ApplicationContextHolder.getBean(ConfigService.class);
} }
String[] params = groupKey.split("\\+"); String[] params = groupKey.split("\\+");
ConfigAllInfo config = configService.findConfigRecentInfo(params); ConfigAllInfo config = CONFIG_SERVICE.findConfigRecentInfo(params);
if (config == null || StringUtils.isEmpty(config.getTpId())) { if (config == null || StringUtils.isEmpty(config.getTpId())) {
String errorMessage = String.format("config is null. tpId :: %s, itemId :: %s, tenantId :: %s", params[0], params[1], params[2]); String errorMessage = String.format("config is null. tpId :: %s, itemId :: %s, tenantId :: %s", params[0], params[1], params[2]);
throw new RuntimeException(errorMessage); throw new RuntimeException(errorMessage);
@ -91,40 +92,46 @@ public class ConfigCacheService {
return Md5Util.getTpContentMd5(config); return Md5Util.getTpContentMd5(config);
} }
public static void updateMd5(String groupKey, String ip, String md5) { public static void updateMd5(String groupKey, String identify, String md5) {
CacheItem cache = makeSure(groupKey, ip); CacheItem cache = makeSure(groupKey, identify);
if (cache.md5 == null || !cache.md5.equals(md5)) { if (cache.md5 == null || !cache.md5.equals(md5)) {
cache.md5 = md5; cache.md5 = md5;
String[] params = groupKey.split("\\+"); String[] params = groupKey.split("\\+");
ConfigAllInfo config = configService.findConfigRecentInfo(params); ConfigAllInfo config = CONFIG_SERVICE.findConfigRecentInfo(params);
cache.configAllInfo = config; cache.configAllInfo = config;
cache.lastModifiedTs = System.currentTimeMillis(); cache.lastModifiedTs = System.currentTimeMillis();
NotifyCenter.publishEvent(new LocalDataChangeEvent(ip, groupKey)); NotifyCenter.publishEvent(new LocalDataChangeEvent(identify, groupKey));
} }
} }
public synchronized static CacheItem makeSure(String groupKey, String ip) { public synchronized static CacheItem makeSure(String groupKey, String ip) {
Map<String, CacheItem> ipCacheItemMap = CACHE.get(groupKey); Map<String, CacheItem> ipCacheItemMap = CLIENT_CONFIG_CACHE.get(groupKey);
CacheItem item = ipCacheItemMap.get(ip); CacheItem item;
if (null != item) { if (ipCacheItemMap != null && (item = ipCacheItemMap.get(ip)) != null) {
return item; return item;
} }
CacheItem tmp = new CacheItem(groupKey); CacheItem tmp = new CacheItem(groupKey);
Map<String, CacheItem> cacheItemMap = Maps.newHashMap(); Map<String, CacheItem> cacheItemMap = Maps.newHashMap();
cacheItemMap.put(ip, tmp); cacheItemMap.put(ip, tmp);
CACHE.putIfAbsent(groupKey, cacheItemMap); CLIENT_CONFIG_CACHE.putIfAbsent(groupKey, cacheItemMap);
return tmp; return tmp;
} }
public static Map<String, CacheItem> getContent(String identification) { public static Map<String, CacheItem> getContent(String identification) {
List<String> identificationList = MapUtil.parseMapForFilter(CACHE, identification); List<String> identificationList = MapUtil.parseMapForFilter(CLIENT_CONFIG_CACHE, identification);
Map<String, CacheItem> returnStrCacheItemMap = Maps.newHashMap(); Map<String, CacheItem> returnStrCacheItemMap = Maps.newHashMap();
identificationList.forEach(each -> returnStrCacheItemMap.putAll(CACHE.get(each))); identificationList.forEach(each -> returnStrCacheItemMap.putAll(CLIENT_CONFIG_CACHE.get(each)));
return returnStrCacheItemMap; return returnStrCacheItemMap;
} }
public static synchronized Integer getTotal() {
AtomicInteger total = new AtomicInteger();
CLIENT_CONFIG_CACHE.forEach((key, val) -> total.addAndGet(val.values().size()));
return total.get();
}
/** /**
* Remove config cache. * Remove config cache.
* *
@ -132,10 +139,10 @@ public class ConfigCacheService {
*/ */
public synchronized static void removeConfigCache(String groupKey) { public synchronized static void removeConfigCache(String groupKey) {
// 模糊搜索 // 模糊搜索
List<String> identificationList = MapUtil.parseMapForFilter(CACHE, groupKey); List<String> identificationList = MapUtil.parseMapForFilter(CLIENT_CONFIG_CACHE, groupKey);
for (String cacheMapKey : identificationList) { for (String cacheMapKey : identificationList) {
Map<String, CacheItem> removeCacheItem = CACHE.remove(cacheMapKey); Map<String, CacheItem> removeCacheItem = CLIENT_CONFIG_CACHE.remove(cacheMapKey);
log.info("Remove invalidated config cache. config info :: {}", JSON.toJSONString(removeCacheItem)); log.info("Remove invalidated config cache. config info :: {}", JSONUtil.toJSONString(removeCacheItem));
} }
} }

@ -1,21 +1,22 @@
package cn.hippo4j.config.service; package cn.hippo4j.config.service;
import cn.hippo4j.common.toolkit.JSONUtil;
import cn.hippo4j.common.toolkit.Md5Util;
import cn.hippo4j.common.web.base.Results;
import cn.hippo4j.config.event.Event;
import cn.hippo4j.config.event.LocalDataChangeEvent;
import cn.hippo4j.config.notify.NotifyCenter; import cn.hippo4j.config.notify.NotifyCenter;
import cn.hippo4j.config.toolkit.Md5ConfigUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import cn.hippo4j.config.notify.listener.Subscriber; import cn.hippo4j.config.notify.listener.Subscriber;
import cn.hippo4j.config.toolkit.ConfigExecutor; import cn.hippo4j.config.toolkit.ConfigExecutor;
import cn.hippo4j.config.toolkit.MapUtil; import cn.hippo4j.config.toolkit.MapUtil;
import cn.hippo4j.config.toolkit.Md5ConfigUtil;
import cn.hippo4j.config.toolkit.RequestUtil; import cn.hippo4j.config.toolkit.RequestUtil;
import cn.hippo4j.common.toolkit.Md5Util; import cn.hutool.core.collection.CollUtil;
import cn.hippo4j.common.web.base.Results; import cn.hutool.core.util.StrUtil;
import cn.hippo4j.config.event.Event;
import cn.hippo4j.config.event.LocalDataChangeEvent;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import javax.servlet.AsyncContext; import javax.servlet.AsyncContext;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
@ -113,8 +114,8 @@ public class LongPollingService {
parseMapForFilter.forEach(each -> { parseMapForFilter.forEach(each -> {
if (clientSub.clientMd5Map.containsKey(each)) { if (clientSub.clientMd5Map.containsKey(each)) {
getRetainIps().put(clientSub.ip, System.currentTimeMillis()); getRetainIps().put(clientSub.clientIdentify, System.currentTimeMillis());
ConfigCacheService.updateMd5(each, clientSub.ip, ConfigCacheService.getContentMd5(identity)); ConfigCacheService.updateMd5(each, clientSub.clientIdentify, ConfigCacheService.getContentMd5(each));
iter.remove(); iter.remove();
clientSub.sendResponse(Arrays.asList(groupKey)); clientSub.sendResponse(Arrays.asList(groupKey));
} }
@ -126,18 +127,14 @@ public class LongPollingService {
} }
} }
public static boolean isSupportLongPolling(HttpServletRequest req) { /**
return null != req.getHeader(LONG_POLLING_HEADER); * Add long polling client.
} *
* @param req
private static boolean isFixedPolling() { * @param rsp
return SwitchService.getSwitchBoolean(SwitchService.FIXED_POLLING, false); * @param clientMd5Map
} * @param probeRequestSize
*/
private static int getFixedPollingInterval() {
return SwitchService.getSwitchInteger(SwitchService.FIXED_POLLING_INTERVAL, FIXED_POLLING_INTERVAL_MS);
}
public void addLongPollingClient(HttpServletRequest req, HttpServletResponse rsp, Map<String, String> clientMd5Map, public void addLongPollingClient(HttpServletRequest req, HttpServletResponse rsp, Map<String, String> clientMd5Map,
int probeRequestSize) { int probeRequestSize) {
String str = req.getHeader(LONG_POLLING_HEADER); String str = req.getHeader(LONG_POLLING_HEADER);
@ -159,14 +156,17 @@ public class LongPollingService {
} }
} }
String ip = RequestUtil.getRemoteIp(req); String clientIdentify = RequestUtil.getClientIdentify(req);
final AsyncContext asyncContext = req.startAsync(); final AsyncContext asyncContext = req.startAsync();
asyncContext.setTimeout(0L); asyncContext.setTimeout(0L);
ConfigExecutor.executeLongPolling(new ClientLongPolling(asyncContext, clientMd5Map, ip, probeRequestSize, timeout - delayTime, appName)); ConfigExecutor.executeLongPolling(new ClientLongPolling(asyncContext, clientMd5Map, clientIdentify, probeRequestSize, timeout - delayTime, appName));
} }
/**
* Regularly check the configuration for changes.
*/
class ClientLongPolling implements Runnable { class ClientLongPolling implements Runnable {
final AsyncContext asyncContext; final AsyncContext asyncContext;
@ -175,7 +175,7 @@ public class LongPollingService {
final long createTime; final long createTime;
final String ip; final String clientIdentify;
final String appName; final String appName;
@ -185,10 +185,10 @@ public class LongPollingService {
Future<?> asyncTimeoutFuture; Future<?> asyncTimeoutFuture;
public ClientLongPolling(AsyncContext asyncContext, Map<String, String> clientMd5Map, String ip, int probeRequestSize, long timeout, String appName) { public ClientLongPolling(AsyncContext asyncContext, Map<String, String> clientMd5Map, String clientIdentify, int probeRequestSize, long timeout, String appName) {
this.asyncContext = asyncContext; this.asyncContext = asyncContext;
this.clientMd5Map = clientMd5Map; this.clientMd5Map = clientMd5Map;
this.ip = ip; this.clientIdentify = clientIdentify;
this.probeRequestSize = probeRequestSize; this.probeRequestSize = probeRequestSize;
this.timeoutTime = timeout; this.timeoutTime = timeout;
this.appName = appName; this.appName = appName;
@ -199,7 +199,7 @@ public class LongPollingService {
public void run() { public void run() {
asyncTimeoutFuture = ConfigExecutor.scheduleLongPolling(() -> { asyncTimeoutFuture = ConfigExecutor.scheduleLongPolling(() -> {
try { try {
getRetainIps().put(ClientLongPolling.this.ip, System.currentTimeMillis()); getRetainIps().put(ClientLongPolling.this.clientIdentify, System.currentTimeMillis());
allSubs.remove(ClientLongPolling.this); allSubs.remove(ClientLongPolling.this);
if (isFixedPolling()) { if (isFixedPolling()) {
@ -221,6 +221,11 @@ public class LongPollingService {
allSubs.add(this); allSubs.add(this);
} }
/**
* Send response.
*
* @param changedGroups Changed thread pool group key
*/
private void sendResponse(List<String> changedGroups) { private void sendResponse(List<String> changedGroups) {
// Cancel time out task. // Cancel time out task.
if (null != asyncTimeoutFuture) { if (null != asyncTimeoutFuture) {
@ -229,6 +234,11 @@ public class LongPollingService {
generateResponse(changedGroups); generateResponse(changedGroups);
} }
/**
* Generate async response.
*
* @param changedGroups Changed thread pool group key
*/
private void generateResponse(List<String> changedGroups) { private void generateResponse(List<String> changedGroups) {
if (null == changedGroups) { if (null == changedGroups) {
// Tell web container to send http response. // Tell web container to send http response.
@ -239,17 +249,15 @@ public class LongPollingService {
HttpServletResponse response = (HttpServletResponse) asyncContext.getResponse(); HttpServletResponse response = (HttpServletResponse) asyncContext.getResponse();
try { try {
String respStr = Md5Util.compareMd5ResultString(changedGroups); String respStr = buildRespStr(changedGroups);
String resultStr = JSON.toJSONString(Results.success(respStr));
response.setHeader("Pragma", "no-cache"); response.setHeader("Pragma", "no-cache");
response.setDateHeader("Expires", 0); response.setDateHeader("Expires", 0);
response.setHeader("Cache-Control", "no-cache,no-store"); response.setHeader("Cache-Control", "no-cache,no-store");
response.setStatus(HttpServletResponse.SC_OK); response.setStatus(HttpServletResponse.SC_OK);
response.getWriter().println(resultStr); response.getWriter().println(respStr);
asyncContext.complete();
} catch (Exception ex) { } catch (Exception ex) {
log.error(ex.toString(), ex); log.error("Response client failed to return data.", ex);
} finally {
asyncContext.complete(); asyncContext.complete();
} }
} }
@ -260,20 +268,66 @@ public class LongPollingService {
return retainIps; return retainIps;
} }
/**
* Generate sync response.
*
* @param response response
* @param changedGroups Changed thread pool group key
*/
private void generateResponse(HttpServletResponse response, List<String> changedGroups) { private void generateResponse(HttpServletResponse response, List<String> changedGroups) {
if (!CollectionUtils.isEmpty(changedGroups)) { if (CollUtil.isNotEmpty(changedGroups)) {
try { try {
final String changedGroupKeStr = Md5ConfigUtil.compareMd5ResultString(changedGroups); String respStr = buildRespStr(changedGroups);
final String respString = JSON.toJSONString(Results.success(changedGroupKeStr));
response.setHeader("Pragma", "no-cache"); response.setHeader("Pragma", "no-cache");
response.setDateHeader("Expires", 0); response.setDateHeader("Expires", 0);
response.setHeader("Cache-Control", "no-cache,no-store"); response.setHeader("Cache-Control", "no-cache,no-store");
response.setStatus(HttpServletResponse.SC_OK); response.setStatus(HttpServletResponse.SC_OK);
response.getWriter().println(respString); response.getWriter().println(respStr);
} catch (Exception ex) { } catch (Exception ex) {
log.error(ex.toString(), ex); log.error("Response client failed to return data.", ex);
} }
} }
} }
/**
* Build resp str.
*
* @param changedGroups Changed thread pool group key
* @return
*/
@SneakyThrows
private String buildRespStr(List<String> changedGroups) {
String changedGroupStr = Md5Util.compareMd5ResultString(changedGroups);
String respStr = JSONUtil.toJSONString(Results.success(changedGroupStr));
return respStr;
}
/**
* Is support long polling.
*
* @param req
* @return
*/
public static boolean isSupportLongPolling(HttpServletRequest req) {
return null != req.getHeader(LONG_POLLING_HEADER);
}
/**
* Is fixed polling.
*
* @return
*/
private static boolean isFixedPolling() {
return SwitchService.getSwitchBoolean(SwitchService.FIXED_POLLING, false);
}
/**
* Get fixed polling interval.
*
* @return
*/
private static int getFixedPollingInterval() {
return SwitchService.getSwitchInteger(SwitchService.FIXED_POLLING_INTERVAL, FIXED_POLLING_INTERVAL_MS);
}
} }

@ -3,6 +3,7 @@ package cn.hippo4j.config.service.biz.impl;
import cn.hippo4j.common.config.ApplicationContextHolder; import cn.hippo4j.common.config.ApplicationContextHolder;
import cn.hippo4j.common.toolkit.ConditionUtil; import cn.hippo4j.common.toolkit.ConditionUtil;
import cn.hippo4j.common.toolkit.ContentUtil; import cn.hippo4j.common.toolkit.ContentUtil;
import cn.hippo4j.common.toolkit.JSONUtil;
import cn.hippo4j.common.toolkit.Md5Util; import cn.hippo4j.common.toolkit.Md5Util;
import cn.hippo4j.config.event.LocalDataChangeEvent; import cn.hippo4j.config.event.LocalDataChangeEvent;
import cn.hippo4j.config.mapper.ConfigInfoMapper; import cn.hippo4j.config.mapper.ConfigInfoMapper;
@ -15,7 +16,6 @@ import cn.hippo4j.config.service.biz.ConfigService;
import cn.hippo4j.config.toolkit.BeanUtil; import cn.hippo4j.config.toolkit.BeanUtil;
import cn.hippo4j.tools.logrecord.annotation.LogRecord; import cn.hippo4j.tools.logrecord.annotation.LogRecord;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils; import com.baomidou.mybatisplus.core.toolkit.StringUtils;
@ -62,6 +62,9 @@ public class ConfigServiceImpl implements ConfigService {
public ConfigAllInfo findConfigRecentInfo(String... params) { public ConfigAllInfo findConfigRecentInfo(String... params) {
ConfigAllInfo resultConfig; ConfigAllInfo resultConfig;
ConfigAllInfo configInstance = null; ConfigAllInfo configInstance = null;
String instanceId = params[3];
if (StrUtil.isNotBlank(instanceId)) {
LambdaQueryWrapper<ConfigInstanceInfo> instanceQueryWrapper = Wrappers.lambdaQuery(ConfigInstanceInfo.class) LambdaQueryWrapper<ConfigInstanceInfo> instanceQueryWrapper = Wrappers.lambdaQuery(ConfigInstanceInfo.class)
.eq(ConfigInstanceInfo::getInstanceId, params[3]) .eq(ConfigInstanceInfo::getInstanceId, params[3])
.orderByDesc(ConfigInstanceInfo::getGmtCreate) .orderByDesc(ConfigInstanceInfo::getGmtCreate)
@ -70,11 +73,12 @@ public class ConfigServiceImpl implements ConfigService {
ConfigInstanceInfo instanceInfo = configInstanceMapper.selectOne(instanceQueryWrapper); ConfigInstanceInfo instanceInfo = configInstanceMapper.selectOne(instanceQueryWrapper);
if (instanceInfo != null) { if (instanceInfo != null) {
String content = instanceInfo.getContent(); String content = instanceInfo.getContent();
configInstance = JSON.parseObject(content, ConfigAllInfo.class); configInstance = JSONUtil.parseObject(content, ConfigAllInfo.class);
configInstance.setContent(content); configInstance.setContent(content);
configInstance.setGmtCreate(instanceInfo.getGmtCreate()); configInstance.setGmtCreate(instanceInfo.getGmtCreate());
configInstance.setMd5(Md5Util.getTpContentMd5(configInstance)); configInstance.setMd5(Md5Util.getTpContentMd5(configInstance));
} }
}
ConfigAllInfo configAllInfo = findConfigAllInfo(params[0], params[1], params[2]); ConfigAllInfo configAllInfo = findConfigAllInfo(params[0], params[1], params[2]);
if (configAllInfo != null && configInstance == null) { if (configAllInfo != null && configInstance == null) {

@ -50,8 +50,8 @@ public class Md5ConfigUtil {
public static List<String> compareMd5(HttpServletRequest request, Map<String, String> clientMd5Map) { public static List<String> compareMd5(HttpServletRequest request, Map<String, String> clientMd5Map) {
List<String> changedGroupKeys = new ArrayList(); List<String> changedGroupKeys = new ArrayList();
clientMd5Map.forEach((key, val) -> { clientMd5Map.forEach((key, val) -> {
String remoteIp = RequestUtil.getRemoteIp(request); String clientIdentify = RequestUtil.getClientIdentify(request);
boolean isUpdateData = ConfigCacheService.isUpdateData(key, val, remoteIp); boolean isUpdateData = ConfigCacheService.isUpdateData(key, val, clientIdentify);
if (!isUpdateData) { if (!isUpdateData) {
changedGroupKeys.add(key); changedGroupKeys.add(key);
} }

@ -1,6 +1,6 @@
package cn.hippo4j.config.toolkit; package cn.hippo4j.config.toolkit;
import org.springframework.util.StringUtils; import cn.hutool.core.util.StrUtil;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
@ -20,14 +20,9 @@ public class RequestUtil {
private static final String X_FORWARDED_FOR_SPLIT_SYMBOL = ","; private static final String X_FORWARDED_FOR_SPLIT_SYMBOL = ",";
public static String getRemoteIp(HttpServletRequest request) { public static String getClientIdentify(HttpServletRequest request) {
String xForwardedFor = request.getHeader(X_FORWARDED_FOR); String identify = request.getHeader(LONG_PULLING_CLIENT_IDENTIFICATION);
if (!StringUtils.isEmpty(xForwardedFor)) { return StrUtil.isBlank(identify) ? "" : identify;
return xForwardedFor.split(X_FORWARDED_FOR_SPLIT_SYMBOL)[0].trim();
}
String nginxHeader = request.getHeader(X_REAL_IP);
String ipPort = request.getHeader(LONG_PULLING_CLIENT_IDENTIFICATION);
return StringUtils.isEmpty(nginxHeader) ? ipPort : nginxHeader;
} }
} }

@ -28,4 +28,9 @@ public class ChartInfo {
*/ */
private Integer threadPoolCount; private Integer threadPoolCount;
/**
* 线
*/
private Integer threadPoolInstanceCount;
} }

@ -18,13 +18,23 @@ import java.util.List;
public class LineChartInfo { public class LineChartInfo {
/** /**
* completedTaskCounts * oneList
*/ */
private List<Long> completedTaskCounts; private List<Object> oneList;
/** /**
* rejectCounts * twoList
*/ */
private List<Long> rejectCounts; private List<Object> twoList;
/**
* threeList
*/
private List<Object> threeList;
/**
* fourList
*/
private List<Object> fourList;
} }

@ -24,6 +24,7 @@ import com.google.common.collect.Lists;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -62,19 +63,34 @@ public class DashboardServiceImpl implements DashboardService {
ChartInfo chartInfo = new ChartInfo(); ChartInfo chartInfo = new ChartInfo();
chartInfo.setTenantCount(tenantCount) chartInfo.setTenantCount(tenantCount)
.setItemCount(itemCount) .setItemCount(itemCount)
.setThreadPoolCount(threadPoolCount); .setThreadPoolCount(threadPoolCount)
.setThreadPoolInstanceCount(ConfigCacheService.getTotal());
return chartInfo; return chartInfo;
} }
@Override @Override
public LineChartInfo getLineChatInfo() { public LineChartInfo getLineChatInfo() {
Date currentDate = new Date(); Date currentDate = new Date();
DateTime sixtyTime = DateUtil.offsetMinute(currentDate, -60); DateTime startTime = DateUtil.offsetMinute(currentDate, -10);
List<Long> completedTaskCounts = Lists.newArrayList(2000L, 2345L, 5676L, 2357L, 1111L, 11193L); List<HisRunDataMapper.ThreadPoolTaskRanking> threadPoolTaskRankings = hisRunDataMapper.queryThreadPoolMaxRanking(startTime.getTime(), currentDate.getTime());
List<Long> rejectCounts = Lists.newArrayList(1000L, 1345L, 2676L, 1357L, 111L, 11193L);
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);
for (int i = 0; i < threadPoolTaskRankings.size(); i++) {
List<Object> eachList = lists.get(i);
HisRunDataMapper.ThreadPoolTaskRanking taskRanking = threadPoolTaskRankings.get(i);
eachList.add(taskRanking.getTpId());
eachList.add(taskRanking.getMaxQueueSize());
eachList.add(taskRanking.getMaxRejectCount());
eachList.add(taskRanking.getMaxCompletedTaskCount());
}
return new LineChartInfo(completedTaskCounts, rejectCounts); return new LineChartInfo(oneList, twoList, threeList, fourList);
} }
@Override @Override
@ -150,13 +166,13 @@ public class DashboardServiceImpl implements DashboardService {
Lease<InstanceInfo> first = CollUtil.getFirst(leases); Lease<InstanceInfo> first = CollUtil.getFirst(leases);
if (first == null) { if (first == null) {
rankingChartInfo.setInst(0); rankingChartInfo.setInst(0);
} } else {
InstanceInfo holder = first.getHolder(); InstanceInfo holder = first.getHolder();
String itemTenantKey = holder.getGroupKey(); String itemTenantKey = holder.getGroupKey();
String groupKey = getGroupKey(each.getTpId(), itemTenantKey); String groupKey = getGroupKey(each.getTpId(), itemTenantKey);
Map<String, CacheItem> content = ConfigCacheService.getContent(groupKey); Map<String, CacheItem> content = ConfigCacheService.getContent(groupKey);
rankingChartInfo.setInst(content.keySet().size()); rankingChartInfo.setInst(content.keySet().size());
}
String keyTenant = GroupKey.getKeyTenant(each.getTenantId(), each.getItemId(), each.getTpId()); String keyTenant = GroupKey.getKeyTenant(each.getTenantId(), each.getItemId(), each.getTpId());
rankingChartInfo.setGroupKey(keyTenant); rankingChartInfo.setGroupKey(keyTenant);

@ -1 +1 @@
<!DOCTYPE html><html><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge,chrome=1"><meta name=renderer content=webkit><meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"><link rel=icon href=/favicon.ico><title>Hippo4J Web</title><link href=/static/css/chunk-libs.3dfb7769.css rel=stylesheet><link href=/static/css/app.0168504a.css rel=stylesheet></head><body><div id=app></div><script src=/static/js/chunk-elementUI.04171b28.js></script><script src=/static/js/chunk-libs.db6d03e3.js></script><script>(function(e){function n(n){for(var t,r,o=n[0],d=n[1],h=n[2],f=0,i=[];f<o.length;f++)r=o[f],u[r]&&i.push(u[r][0]),u[r]=0;for(t in d)Object.prototype.hasOwnProperty.call(d,t)&&(e[t]=d[t]);l&&l(n);while(i.length)i.shift()();return a.push.apply(a,h||[]),c()}function c(){for(var e,n=0;n<a.length;n++){for(var c=a[n],t=!0,r=1;r<c.length;r++){var o=c[r];0!==u[o]&&(t=!1)}t&&(a.splice(n--,1),e=d(d.s=c[0]))}return e}var t={},r={runtime:0},u={runtime:0},a=[];function o(e){return d.p+"static/js/"+({}[e]||e)+"."+{"chunk-04a4268a":"c9a819e9","chunk-1504cdfc":"b0b92ae3","chunk-16eb7b18":"7b0a0546","chunk-28552c5d":"2951e36a","chunk-2d230fe7":"19def69d","chunk-40409ae7":"92cf2329","chunk-45e73af7":"9c8dabfb","chunk-4934959c":"8cc51c4d","chunk-4b345e33":"68e60a0a","chunk-648295c6":"bdeb6305","chunk-6d7151ac":"d4f2de43","chunk-6f742c38":"2b23a602","chunk-91584750":"a58b5769","chunk-a6de055c":"18988007","chunk-bc53b446":"8898fbcb","chunk-434632c4":"a264a0ed","chunk-e25b23da":"6f239df4"}[e]+".js"}function d(n){if(t[n])return t[n].exports;var c=t[n]={i:n,l:!1,exports:{}};return e[n].call(c.exports,c,c.exports,d),c.l=!0,c.exports}d.e=function(e){var n=[],c={"chunk-1504cdfc":1,"chunk-16eb7b18":1,"chunk-28552c5d":1,"chunk-40409ae7":1,"chunk-45e73af7":1,"chunk-4934959c":1,"chunk-4b345e33":1,"chunk-648295c6":1,"chunk-6d7151ac":1,"chunk-6f742c38":1,"chunk-91584750":1,"chunk-a6de055c":1,"chunk-bc53b446":1,"chunk-434632c4":1,"chunk-e25b23da":1};r[e]?n.push(r[e]):0!==r[e]&&c[e]&&n.push(r[e]=new Promise((function(n,c){for(var t="static/css/"+({}[e]||e)+"."+{"chunk-04a4268a":"31d6cfe0","chunk-1504cdfc":"480b5dcd","chunk-16eb7b18":"9905f991","chunk-28552c5d":"a47aceb4","chunk-2d230fe7":"31d6cfe0","chunk-40409ae7":"340ac3e2","chunk-45e73af7":"13821f5e","chunk-4934959c":"6d24dacd","chunk-4b345e33":"9905f991","chunk-648295c6":"6d24dacd","chunk-6d7151ac":"9905f991","chunk-6f742c38":"c96d4c5f","chunk-91584750":"b043920c","chunk-a6de055c":"9905f991","chunk-bc53b446":"55a106d0","chunk-434632c4":"adc5827d","chunk-e25b23da":"6d24dacd"}[e]+".css",u=d.p+t,a=document.getElementsByTagName("link"),o=0;o<a.length;o++){var h=a[o],f=h.getAttribute("data-href")||h.getAttribute("href");if("stylesheet"===h.rel&&(f===t||f===u))return n()}var i=document.getElementsByTagName("style");for(o=0;o<i.length;o++){h=i[o],f=h.getAttribute("data-href");if(f===t||f===u)return n()}var l=document.createElement("link");l.rel="stylesheet",l.type="text/css",l.onload=n,l.onerror=function(n){var t=n&&n.target&&n.target.src||u,a=new Error("Loading CSS chunk "+e+" failed.\n("+t+")");a.request=t,delete r[e],l.parentNode.removeChild(l),c(a)},l.href=u;var s=document.getElementsByTagName("head")[0];s.appendChild(l)})).then((function(){r[e]=0})));var t=u[e];if(0!==t)if(t)n.push(t[2]);else{var a=new Promise((function(n,c){t=u[e]=[n,c]}));n.push(t[2]=a);var h,f=document.createElement("script");f.charset="utf-8",f.timeout=120,d.nc&&f.setAttribute("nonce",d.nc),f.src=o(e),h=function(n){f.onerror=f.onload=null,clearTimeout(i);var c=u[e];if(0!==c){if(c){var t=n&&("load"===n.type?"missing":n.type),r=n&&n.target&&n.target.src,a=new Error("Loading chunk "+e+" failed.\n("+t+": "+r+")");a.type=t,a.request=r,c[1](a)}u[e]=void 0}};var i=setTimeout((function(){h({type:"timeout",target:f})}),12e4);f.onerror=f.onload=h,document.head.appendChild(f)}return Promise.all(n)},d.m=e,d.c=t,d.d=function(e,n,c){d.o(e,n)||Object.defineProperty(e,n,{enumerable:!0,get:c})},d.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},d.t=function(e,n){if(1&n&&(e=d(e)),8&n)return e;if(4&n&&"object"===typeof e&&e&&e.__esModule)return e;var c=Object.create(null);if(d.r(c),Object.defineProperty(c,"default",{enumerable:!0,value:e}),2&n&&"string"!=typeof e)for(var t in e)d.d(c,t,function(n){return e[n]}.bind(null,t));return c},d.n=function(e){var n=e&&e.__esModule?function(){return e["default"]}:function(){return e};return d.d(n,"a",n),n},d.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},d.p="/",d.oe=function(e){throw console.error(e),e};var h=window["webpackJsonp"]=window["webpackJsonp"]||[],f=h.push.bind(h);h.push=n,h=h.slice();for(var i=0;i<h.length;i++)n(h[i]);var l=f;c()})([]);</script><script src=/static/js/app.176e2bd7.js></script></body></html> <!DOCTYPE html><html><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge,chrome=1"><meta name=renderer content=webkit><meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"><link rel=icon href=/favicon.ico><title>Hippo4J Web</title><link href=/static/css/chunk-libs.3dfb7769.css rel=stylesheet><link href=/static/css/app.be589ad2.css rel=stylesheet></head><body><div id=app></div><script src=/static/js/chunk-elementUI.04171b28.js></script><script src=/static/js/chunk-libs.db6d03e3.js></script><script>(function(e){function n(n){for(var t,r,o=n[0],d=n[1],f=n[2],h=0,i=[];h<o.length;h++)r=o[h],u[r]&&i.push(u[r][0]),u[r]=0;for(t in d)Object.prototype.hasOwnProperty.call(d,t)&&(e[t]=d[t]);l&&l(n);while(i.length)i.shift()();return a.push.apply(a,f||[]),c()}function c(){for(var e,n=0;n<a.length;n++){for(var c=a[n],t=!0,r=1;r<c.length;r++){var o=c[r];0!==u[o]&&(t=!1)}t&&(a.splice(n--,1),e=d(d.s=c[0]))}return e}var t={},r={runtime:0},u={runtime:0},a=[];function o(e){return d.p+"static/js/"+({}[e]||e)+"."+{"chunk-04a4268a":"c9a819e9","chunk-0b915d32":"0d0f8ccd","chunk-1504cdfc":"b0b92ae3","chunk-16eb7b18":"4c458386","chunk-2d230fe7":"19def69d","chunk-45e73af7":"9c8dabfb","chunk-4934959c":"8cc51c4d","chunk-4b345e33":"68e60a0a","chunk-648295c6":"307c430f","chunk-6d7151ac":"bc9d8df9","chunk-6f742c38":"2b23a602","chunk-91584750":"a58b5769","chunk-9b291858":"7e672b56","chunk-a6de055c":"18988007","chunk-bc53b446":"8898fbcb","chunk-434632c4":"a264a0ed","chunk-e25b23da":"90b118ad"}[e]+".js"}function d(n){if(t[n])return t[n].exports;var c=t[n]={i:n,l:!1,exports:{}};return e[n].call(c.exports,c,c.exports,d),c.l=!0,c.exports}d.e=function(e){var n=[],c={"chunk-0b915d32":1,"chunk-1504cdfc":1,"chunk-16eb7b18":1,"chunk-45e73af7":1,"chunk-4934959c":1,"chunk-4b345e33":1,"chunk-648295c6":1,"chunk-6d7151ac":1,"chunk-6f742c38":1,"chunk-91584750":1,"chunk-9b291858":1,"chunk-a6de055c":1,"chunk-bc53b446":1,"chunk-434632c4":1,"chunk-e25b23da":1};r[e]?n.push(r[e]):0!==r[e]&&c[e]&&n.push(r[e]=new Promise((function(n,c){for(var t="static/css/"+({}[e]||e)+"."+{"chunk-04a4268a":"31d6cfe0","chunk-0b915d32":"4bb60f9d","chunk-1504cdfc":"480b5dcd","chunk-16eb7b18":"9905f991","chunk-2d230fe7":"31d6cfe0","chunk-45e73af7":"13821f5e","chunk-4934959c":"6d24dacd","chunk-4b345e33":"9905f991","chunk-648295c6":"6d24dacd","chunk-6d7151ac":"9905f991","chunk-6f742c38":"c96d4c5f","chunk-91584750":"b043920c","chunk-9b291858":"46efeb03","chunk-a6de055c":"9905f991","chunk-bc53b446":"55a106d0","chunk-434632c4":"adc5827d","chunk-e25b23da":"6d24dacd"}[e]+".css",u=d.p+t,a=document.getElementsByTagName("link"),o=0;o<a.length;o++){var f=a[o],h=f.getAttribute("data-href")||f.getAttribute("href");if("stylesheet"===f.rel&&(h===t||h===u))return n()}var i=document.getElementsByTagName("style");for(o=0;o<i.length;o++){f=i[o],h=f.getAttribute("data-href");if(h===t||h===u)return n()}var l=document.createElement("link");l.rel="stylesheet",l.type="text/css",l.onload=n,l.onerror=function(n){var t=n&&n.target&&n.target.src||u,a=new Error("Loading CSS chunk "+e+" failed.\n("+t+")");a.request=t,delete r[e],l.parentNode.removeChild(l),c(a)},l.href=u;var b=document.getElementsByTagName("head")[0];b.appendChild(l)})).then((function(){r[e]=0})));var t=u[e];if(0!==t)if(t)n.push(t[2]);else{var a=new Promise((function(n,c){t=u[e]=[n,c]}));n.push(t[2]=a);var f,h=document.createElement("script");h.charset="utf-8",h.timeout=120,d.nc&&h.setAttribute("nonce",d.nc),h.src=o(e),f=function(n){h.onerror=h.onload=null,clearTimeout(i);var c=u[e];if(0!==c){if(c){var t=n&&("load"===n.type?"missing":n.type),r=n&&n.target&&n.target.src,a=new Error("Loading chunk "+e+" failed.\n("+t+": "+r+")");a.type=t,a.request=r,c[1](a)}u[e]=void 0}};var i=setTimeout((function(){f({type:"timeout",target:h})}),12e4);h.onerror=h.onload=f,document.head.appendChild(h)}return Promise.all(n)},d.m=e,d.c=t,d.d=function(e,n,c){d.o(e,n)||Object.defineProperty(e,n,{enumerable:!0,get:c})},d.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},d.t=function(e,n){if(1&n&&(e=d(e)),8&n)return e;if(4&n&&"object"===typeof e&&e&&e.__esModule)return e;var c=Object.create(null);if(d.r(c),Object.defineProperty(c,"default",{enumerable:!0,value:e}),2&n&&"string"!=typeof e)for(var t in e)d.d(c,t,function(n){return e[n]}.bind(null,t));return c},d.n=function(e){var n=e&&e.__esModule?function(){return e["default"]}:function(){return e};return d.d(n,"a",n),n},d.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},d.p="/",d.oe=function(e){throw console.error(e),e};var f=window["webpackJsonp"]=window["webpackJsonp"]||[],h=f.push.bind(f);f.push=n,f=f.slice();for(var i=0;i<f.length;i++)n(f[i]);var l=h;c()})([]);</script><script src=/static/js/app.e5aa10f1.js></script></body></html>

@ -0,0 +1 @@
.dashboard-editor-container[data-v-1354c5da]{padding:32px;background-color:#f0f2f5;position:relative}.dashboard-editor-container .github-corner[data-v-1354c5da]{position:absolute;top:0;border:0;right:0}.dashboard-editor-container .chart-wrapper[data-v-1354c5da]{background:#fff;padding:16px 16px 0;margin-bottom:32px}@media (max-width:1024px){.chart-wrapper[data-v-1354c5da]{padding:8px}}

@ -1 +0,0 @@
.dashboard-editor-container[data-v-dfb997ca]{padding:32px;background-color:#f0f2f5;position:relative}.dashboard-editor-container .github-corner[data-v-dfb997ca]{position:absolute;top:0;border:0;right:0}.dashboard-editor-container .chart-wrapper[data-v-dfb997ca]{background:#fff;padding:16px 16px 0;margin-bottom:32px}@media (max-width:1024px){.chart-wrapper[data-v-dfb997ca]{padding:8px}}

@ -1 +0,0 @@
.github-corner:hover .octo-arm[data-v-83aa39e4]{-webkit-animation:octocat-wave-data-v-83aa39e4 .56s ease-in-out;animation:octocat-wave-data-v-83aa39e4 .56s ease-in-out}@-webkit-keyframes octocat-wave-data-v-83aa39e4{0%,to{-webkit-transform:rotate(0);transform:rotate(0)}20%,60%{-webkit-transform:rotate(-25deg);transform:rotate(-25deg)}40%,80%{-webkit-transform:rotate(10deg);transform:rotate(10deg)}}@keyframes octocat-wave-data-v-83aa39e4{0%,to{-webkit-transform:rotate(0);transform:rotate(0)}20%,60%{-webkit-transform:rotate(-25deg);transform:rotate(-25deg)}40%,80%{-webkit-transform:rotate(10deg);transform:rotate(10deg)}}@media (max-width:500px){.github-corner:hover .octo-arm[data-v-83aa39e4]{-webkit-animation:none;animation:none}.github-corner .octo-arm[data-v-83aa39e4]{-webkit-animation:octocat-wave-data-v-83aa39e4 .56s ease-in-out;animation:octocat-wave-data-v-83aa39e4 .56s ease-in-out}}.panel-group[data-v-7e3f64a9]{margin-top:18px}.panel-group .card-panel-col[data-v-7e3f64a9]{margin-bottom:32px}.panel-group .card-panel[data-v-7e3f64a9]{height:108px;cursor:pointer;font-size:12px;position:relative;overflow:hidden;color:#666;background:#fff;-webkit-box-shadow:4px 4px 40px rgba(0,0,0,.05);box-shadow:4px 4px 40px rgba(0,0,0,.05);border-color:rgba(0,0,0,.05)}.panel-group .card-panel:hover .card-panel-icon-wrapper[data-v-7e3f64a9]{color:#fff}.panel-group .card-panel:hover .icon-people[data-v-7e3f64a9]{background:#dae8d6}.panel-group .card-panel:hover .icon-message[data-v-7e3f64a9]{background:#36a3f7}.panel-group .card-panel:hover .icon-money[data-v-7e3f64a9]{background:#a0a6f4}.panel-group .card-panel:hover .icon-shopping[data-v-7e3f64a9]{background:#dae8d6}.panel-group .card-panel .icon-people[data-v-7e3f64a9]{color:#40c9c6}.panel-group .card-panel .icon-message[data-v-7e3f64a9]{color:#36a3f7}.panel-group .card-panel .icon-money[data-v-7e3f64a9]{color:#a0a6f4}.panel-group .card-panel .icon-shopping[data-v-7e3f64a9]{color:#34bfa3}.panel-group .card-panel .card-panel-icon-wrapper[data-v-7e3f64a9]{float:left;margin:14px 0 0 14px;padding:16px;-webkit-transition:all .38s ease-out;transition:all .38s ease-out;border-radius:6px}.panel-group .card-panel .card-panel-icon[data-v-7e3f64a9]{float:left;font-size:48px}.panel-group .card-panel .card-panel-description[data-v-7e3f64a9]{float:right;font-weight:700;margin:26px;margin-left:0}.panel-group .card-panel .card-panel-description .card-panel-text[data-v-7e3f64a9]{line-height:18px;color:rgba(0,0,0,.45);font-size:16px;margin-bottom:12px}.panel-group .card-panel .card-panel-description .card-panel-num[data-v-7e3f64a9]{font-size:20px}@media (max-width:550px){.card-panel-description[data-v-7e3f64a9]{display:none}.card-panel-icon-wrapper[data-v-7e3f64a9]{float:none!important;width:100%;height:100%;margin:0!important}.card-panel-icon-wrapper .svg-icon[data-v-7e3f64a9]{display:block;margin:14px auto!important;float:none!important}}.dashboard-editor-container[data-v-2d721620]{padding:32px;background-color:#f0f2f5;position:relative}.dashboard-editor-container .github-corner[data-v-2d721620]{position:absolute;top:0;border:0;right:0}.dashboard-editor-container .chart-wrapper[data-v-2d721620]{background:#fff;padding:16px 16px 0;margin-bottom:32px}@media (max-width:1024px){.chart-wrapper[data-v-2d721620]{padding:8px}}

@ -0,0 +1 @@
.github-corner:hover .octo-arm[data-v-83aa39e4]{-webkit-animation:octocat-wave-data-v-83aa39e4 .56s ease-in-out;animation:octocat-wave-data-v-83aa39e4 .56s ease-in-out}@-webkit-keyframes octocat-wave-data-v-83aa39e4{0%,to{-webkit-transform:rotate(0);transform:rotate(0)}20%,60%{-webkit-transform:rotate(-25deg);transform:rotate(-25deg)}40%,80%{-webkit-transform:rotate(10deg);transform:rotate(10deg)}}@keyframes octocat-wave-data-v-83aa39e4{0%,to{-webkit-transform:rotate(0);transform:rotate(0)}20%,60%{-webkit-transform:rotate(-25deg);transform:rotate(-25deg)}40%,80%{-webkit-transform:rotate(10deg);transform:rotate(10deg)}}@media (max-width:500px){.github-corner:hover .octo-arm[data-v-83aa39e4]{-webkit-animation:none;animation:none}.github-corner .octo-arm[data-v-83aa39e4]{-webkit-animation:octocat-wave-data-v-83aa39e4 .56s ease-in-out;animation:octocat-wave-data-v-83aa39e4 .56s ease-in-out}}.panel-group[data-v-a6bad5ce]{margin-top:18px}.panel-group .card-panel-col[data-v-a6bad5ce]{margin-bottom:32px}.panel-group .card-panel[data-v-a6bad5ce]{height:108px;cursor:pointer;font-size:12px;position:relative;overflow:hidden;color:#666;background:#fff;-webkit-box-shadow:4px 4px 40px rgba(0,0,0,.05);box-shadow:4px 4px 40px rgba(0,0,0,.05);border-color:rgba(0,0,0,.05)}.panel-group .card-panel:hover .card-panel-icon-wrapper[data-v-a6bad5ce]{color:#fff}.panel-group .card-panel:hover .icon-people[data-v-a6bad5ce]{background:#dae8d6}.panel-group .card-panel:hover .icon-message[data-v-a6bad5ce]{background:#36a3f7}.panel-group .card-panel:hover .icon-money[data-v-a6bad5ce]{background:#a0a6f4}.panel-group .card-panel:hover .icon-shopping[data-v-a6bad5ce]{background:#dae8d6}.panel-group .card-panel .icon-people[data-v-a6bad5ce]{color:#40c9c6}.panel-group .card-panel .icon-message[data-v-a6bad5ce]{color:#36a3f7}.panel-group .card-panel .icon-money[data-v-a6bad5ce]{color:#a0a6f4}.panel-group .card-panel .icon-shopping[data-v-a6bad5ce]{color:#34bfa3}.panel-group .card-panel .card-panel-icon-wrapper[data-v-a6bad5ce]{float:left;margin:14px 0 0 14px;padding:16px;-webkit-transition:all .38s ease-out;transition:all .38s ease-out;border-radius:6px}.panel-group .card-panel .card-panel-icon[data-v-a6bad5ce]{float:left;font-size:48px}.panel-group .card-panel .card-panel-description[data-v-a6bad5ce]{float:right;font-weight:700;margin:26px;margin-left:0}.panel-group .card-panel .card-panel-description .card-panel-text[data-v-a6bad5ce]{line-height:18px;color:rgba(0,0,0,.45);font-size:16px;margin-bottom:12px}.panel-group .card-panel .card-panel-description .card-panel-num[data-v-a6bad5ce]{font-size:20px}@media (max-width:550px){.card-panel-description[data-v-a6bad5ce]{display:none}.card-panel-icon-wrapper[data-v-a6bad5ce]{float:none!important;width:100%;height:100%;margin:0!important}.card-panel-icon-wrapper .svg-icon[data-v-a6bad5ce]{display:block;margin:14px auto!important;float:none!important}}.dashboard-editor-container[data-v-0965ed64]{padding:32px;background-color:#f0f2f5;position:relative}.dashboard-editor-container .github-corner[data-v-0965ed64]{position:absolute;top:0;border:0;right:0}.dashboard-editor-container .el-form-item[data-v-0965ed64]{margin-bottom:5px!important;padding-bottom:20px}.dashboard-editor-container .chart-wrapper[data-v-0965ed64]{background:#fff;padding:16px 16px 0;margin-bottom:32px}@media (max-width:1024px){.chart-wrapper[data-v-0965ed64]{padding:8px}}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -36,11 +36,6 @@
<artifactId>logging-interceptor</artifactId> <artifactId>logging-interceptor</artifactId>
</dependency> </dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
<dependency> <dependency>
<groupId>cn.hippo4j</groupId> <groupId>cn.hippo4j</groupId>
<artifactId>hippo4j-common</artifactId> <artifactId>hippo4j-common</artifactId>

@ -1,8 +1,10 @@
package cn.hippo4j.starter.alarm; package cn.hippo4j.starter.alarm;
import cn.hippo4j.common.config.ApplicationContextHolder; import cn.hippo4j.common.config.ApplicationContextHolder;
import cn.hippo4j.common.constant.Constants;
import cn.hippo4j.common.model.PoolParameterInfo; import cn.hippo4j.common.model.PoolParameterInfo;
import cn.hippo4j.common.toolkit.GroupKey; import cn.hippo4j.common.toolkit.GroupKey;
import cn.hippo4j.common.toolkit.JSONUtil;
import cn.hippo4j.common.web.base.Result; import cn.hippo4j.common.web.base.Result;
import cn.hippo4j.starter.config.BootstrapProperties; import cn.hippo4j.starter.config.BootstrapProperties;
import cn.hippo4j.starter.core.DynamicThreadPoolExecutor; import cn.hippo4j.starter.core.DynamicThreadPoolExecutor;
@ -10,7 +12,6 @@ import cn.hippo4j.starter.core.GlobalThreadPoolManage;
import cn.hippo4j.starter.remote.HttpAgent; import cn.hippo4j.starter.remote.HttpAgent;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.google.common.cache.Cache; import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheBuilder;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
@ -51,10 +52,11 @@ public class BaseSendMessageService implements InitializingBean, SendMessageServ
@Override @Override
public void sendAlarmMessage(MessageTypeEnum typeEnum, DynamicThreadPoolExecutor executor) { public void sendAlarmMessage(MessageTypeEnum typeEnum, DynamicThreadPoolExecutor executor) {
String threadPoolId = executor.getThreadPoolId();
String buildKey = StrUtil.builder(executor.getThreadPoolId(), "+", "ALARM").toString(); String buildKey = StrUtil.builder(executor.getThreadPoolId(), "+", "ALARM").toString();
List<NotifyDTO> notifyList = ALARM_NOTIFY_CONFIG.get(buildKey); List<NotifyDTO> notifyList = ALARM_NOTIFY_CONFIG.get(buildKey);
if (CollUtil.isEmpty(notifyList)) { if (CollUtil.isEmpty(notifyList)) {
log.warn("Please configure alarm notification on the server."); log.warn("Please configure alarm notification on the server. key :: [{}]", threadPoolId);
return; return;
} }
@ -62,7 +64,7 @@ public class BaseSendMessageService implements InitializingBean, SendMessageServ
try { try {
SendMessageHandler messageHandler = sendMessageHandlers.get(each.getPlatform()); SendMessageHandler messageHandler = sendMessageHandlers.get(each.getPlatform());
if (messageHandler == null) { if (messageHandler == null) {
log.warn("Please configure alarm notification on the server."); log.warn("Please configure alarm notification on the server. key :: [{}]", threadPoolId);
return; return;
} }
@ -70,17 +72,18 @@ public class BaseSendMessageService implements InitializingBean, SendMessageServ
messageHandler.sendAlarmMessage(each, executor); messageHandler.sendAlarmMessage(each, executor);
} }
} catch (Exception ex) { } catch (Exception ex) {
log.warn("Failed to send thread pool alarm notification.", ex); log.warn("Failed to send thread pool alarm notification. key :: [{}]", threadPoolId, ex);
} }
}); });
} }
@Override @Override
public void sendChangeMessage(PoolParameterInfo parameter) { public void sendChangeMessage(PoolParameterInfo parameter) {
String threadPoolId = parameter.getTpId();
String buildKey = StrUtil.builder(parameter.getTpId(), "+", "CONFIG").toString(); String buildKey = StrUtil.builder(parameter.getTpId(), "+", "CONFIG").toString();
List<NotifyDTO> notifyList = ALARM_NOTIFY_CONFIG.get(buildKey); List<NotifyDTO> notifyList = ALARM_NOTIFY_CONFIG.get(buildKey);
if (CollUtil.isEmpty(notifyList)) { if (CollUtil.isEmpty(notifyList)) {
log.warn("Please configure alarm notification on the server."); log.warn("Please configure alarm notification on the server. key :: [{}]", threadPoolId);
return; return;
} }
@ -88,13 +91,13 @@ public class BaseSendMessageService implements InitializingBean, SendMessageServ
try { try {
SendMessageHandler messageHandler = sendMessageHandlers.get(each.getPlatform()); SendMessageHandler messageHandler = sendMessageHandlers.get(each.getPlatform());
if (messageHandler == null) { if (messageHandler == null) {
log.warn("Please configure alarm notification on the server."); log.warn("Please configure alarm notification on the server. key :: [{}]", threadPoolId);
return; return;
} }
messageHandler.sendChangeMessage(each, parameter); messageHandler.sendChangeMessage(each, parameter);
} catch (Exception ex) { } catch (Exception ex) {
log.warn("Failed to send thread pool change notification.", ex); log.warn("Failed to send thread pool change notification. key :: [{}]", threadPoolId, ex);
} }
}); });
} }
@ -125,8 +128,8 @@ public class BaseSendMessageService implements InitializingBean, SendMessageServ
} }
if (result != null && result.isSuccess() && result.getData() != null) { if (result != null && result.isSuccess() && result.getData() != null) {
String resultDataStr = JSON.toJSONString(result.getData()); String resultDataStr = JSONUtil.toJSONString(result.getData());
List<ThreadPoolNotify> resultData = JSON.parseArray(resultDataStr, ThreadPoolNotify.class); List<ThreadPoolNotify> resultData = JSONUtil.parseArray(resultDataStr, ThreadPoolNotify.class);
resultData.forEach(each -> ALARM_NOTIFY_CONFIG.put(each.getNotifyKey(), each.getNotifyList())); resultData.forEach(each -> ALARM_NOTIFY_CONFIG.put(each.getNotifyKey(), each.getNotifyList()));
ALARM_NOTIFY_CONFIG.forEach((key, val) -> ALARM_NOTIFY_CONFIG.forEach((key, val) ->
@ -135,7 +138,7 @@ public class BaseSendMessageService implements InitializingBean, SendMessageServ
Cache<String, String> cache = CacheBuilder.newBuilder() Cache<String, String> cache = CacheBuilder.newBuilder()
.expireAfterWrite(each.getInterval(), TimeUnit.MINUTES) .expireAfterWrite(each.getInterval(), TimeUnit.MINUTES)
.build(); .build();
AlarmControlHandler.THREAD_POOL_ALARM_CACHE.put(StrUtil.builder(each.getTpId(), "+", each.getPlatform()).toString(), cache); AlarmControlHandler.THREAD_POOL_ALARM_CACHE.put(StrUtil.builder(each.getTpId(), Constants.GROUP_KEY_DELIMITER, each.getPlatform()).toString(), cache);
}) })
); );
} }

@ -2,6 +2,7 @@ package cn.hippo4j.starter.alarm.wechat;
import cn.hippo4j.common.model.InstanceInfo; import cn.hippo4j.common.model.InstanceInfo;
import cn.hippo4j.common.model.PoolParameterInfo; import cn.hippo4j.common.model.PoolParameterInfo;
import cn.hippo4j.common.toolkit.JSONUtil;
import cn.hippo4j.starter.alarm.NotifyDTO; import cn.hippo4j.starter.alarm.NotifyDTO;
import cn.hippo4j.starter.alarm.NotifyPlatformEnum; import cn.hippo4j.starter.alarm.NotifyPlatformEnum;
import cn.hippo4j.starter.alarm.SendMessageHandler; import cn.hippo4j.starter.alarm.SendMessageHandler;
@ -13,7 +14,6 @@ import cn.hippo4j.starter.wrapper.DynamicThreadPoolWrapper;
import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest; import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSON;
import com.google.common.base.Joiner; import com.google.common.base.Joiner;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
@ -155,7 +155,7 @@ public class WeChatSendMessageHandler implements SendMessageHandler {
markdown.setContent(text); markdown.setContent(text);
weChatReq.setMarkdown(markdown); weChatReq.setMarkdown(markdown);
HttpRequest.post(serverUrl).body(JSON.toJSONString(weChatReq)).execute(); HttpRequest.post(serverUrl).body(JSONUtil.toJSONString(weChatReq)).execute();
} catch (Exception ex) { } catch (Exception ex) {
log.error("WeChat failed to send message", ex); log.error("WeChat failed to send message", ex);
} }

@ -1,5 +1,7 @@
package cn.hippo4j.starter.config; package cn.hippo4j.starter.config;
import cn.hippo4j.common.api.JsonFacade;
import cn.hippo4j.common.api.impl.JacksonHandler;
import cn.hippo4j.common.config.ApplicationContextHolder; import cn.hippo4j.common.config.ApplicationContextHolder;
import cn.hippo4j.starter.controller.PoolRunStateController; import cn.hippo4j.starter.controller.PoolRunStateController;
import cn.hippo4j.starter.core.ConfigService; import cn.hippo4j.starter.core.ConfigService;
@ -105,6 +107,11 @@ public class DynamicThreadPoolAutoConfiguration {
return new HttpScheduledHealthCheck(httpAgent); return new HttpScheduledHealthCheck(httpAgent);
} }
@Bean
public JsonFacade jacksonHandler() {
return new JacksonHandler();
}
} }

@ -3,12 +3,12 @@ package cn.hippo4j.starter.core;
import cn.hippo4j.common.model.PoolParameterInfo; import cn.hippo4j.common.model.PoolParameterInfo;
import cn.hippo4j.common.toolkit.ContentUtil; import cn.hippo4j.common.toolkit.ContentUtil;
import cn.hippo4j.common.toolkit.GroupKey; import cn.hippo4j.common.toolkit.GroupKey;
import cn.hippo4j.common.toolkit.JSONUtil;
import cn.hippo4j.common.web.base.Result; import cn.hippo4j.common.web.base.Result;
import cn.hippo4j.starter.remote.HttpAgent; import cn.hippo4j.starter.remote.HttpAgent;
import cn.hippo4j.starter.remote.ServerHealthCheck; import cn.hippo4j.starter.remote.ServerHealthCheck;
import cn.hippo4j.starter.toolkit.thread.ThreadFactoryBuilder; import cn.hippo4j.starter.toolkit.thread.ThreadFactoryBuilder;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import lombok.SneakyThrows; import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
@ -110,7 +110,7 @@ public class ClientWorker {
try { try {
String content = getServerConfig(namespace, itemId, tpId, 3000L); String content = getServerConfig(namespace, itemId, tpId, 3000L);
CacheData cacheData = cacheMap.get(tpId); CacheData cacheData = cacheMap.get(tpId);
String poolContent = ContentUtil.getPoolContent(JSON.parseObject(content, PoolParameterInfo.class)); String poolContent = ContentUtil.getPoolContent(JSONUtil.parseObject(content, PoolParameterInfo.class));
cacheData.setContent(poolContent); cacheData.setContent(poolContent);
} catch (Exception ex) { } catch (Exception ex) {
// ignore // ignore
@ -191,7 +191,7 @@ public class ClientWorker {
Result result = agent.httpGetByConfig(CONFIG_CONTROLLER_PATH, null, params, readTimeout); Result result = agent.httpGetByConfig(CONFIG_CONTROLLER_PATH, null, params, readTimeout);
if (result.isSuccess()) { if (result.isSuccess()) {
return result.getData().toString(); return JSONUtil.toJSONString(result.getData());
} }
log.error("[Sub server] namespace :: {}, itemId :: {}, tpId :: {}, result code :: {}", log.error("[Sub server] namespace :: {}, itemId :: {}, tpId :: {}, result code :: {}",
@ -217,18 +217,16 @@ public class ClientWorker {
String[] keyArr = dataIdAndGroup.split(WORD_SEPARATOR); String[] keyArr = dataIdAndGroup.split(WORD_SEPARATOR);
String dataId = keyArr[0]; String dataId = keyArr[0];
String group = keyArr[1]; String group = keyArr[1];
if (keyArr.length == 2) { if (keyArr.length == 3) {
updateList.add(GroupKey.getKey(dataId, group));
log.info("[{}] [Polling resp] config changed. dataId={}, group={}", dataId, group);
} else if (keyArr.length == 3) {
String tenant = keyArr[2]; String tenant = keyArr[2];
updateList.add(GroupKey.getKeyTenant(dataId, group, tenant)); updateList.add(GroupKey.getKeyTenant(dataId, group, tenant));
log.info("[Polling resp] config changed. dataId={}, group={}, tenant={}", dataId, group, tenant); log.info("Refresh thread pool changed. [{}]", dataId);
} else { } else {
log.error("[{}] [Polling resp] invalid dataIdAndGroup error {}", dataIdAndGroup); log.error("[{}] [Polling resp] invalid dataIdAndGroup error.", dataIdAndGroup);
} }
} }
} }
return updateList; return updateList;
} }
@ -251,7 +249,7 @@ public class ClientWorker {
String serverConfig = null; String serverConfig = null;
try { try {
serverConfig = getServerConfig(namespace, itemId, tpId, 3000L); serverConfig = getServerConfig(namespace, itemId, tpId, 3000L);
PoolParameterInfo poolInfo = JSON.parseObject(serverConfig, PoolParameterInfo.class); PoolParameterInfo poolInfo = JSONUtil.parseObject(serverConfig, PoolParameterInfo.class);
cacheData.setContent(ContentUtil.getPoolContent(poolInfo)); cacheData.setContent(ContentUtil.getPoolContent(poolInfo));
} catch (Exception ex) { } catch (Exception ex) {
log.error("[Cache Data] Error. Service Unavailable :: {}", ex.getMessage()); log.error("[Cache Data] Error. Service Unavailable :: {}", ex.getMessage());

@ -3,6 +3,7 @@ package cn.hippo4j.starter.core;
import cn.hippo4j.common.config.ApplicationContextHolder; import cn.hippo4j.common.config.ApplicationContextHolder;
import cn.hippo4j.common.constant.Constants; import cn.hippo4j.common.constant.Constants;
import cn.hippo4j.common.model.PoolParameterInfo; import cn.hippo4j.common.model.PoolParameterInfo;
import cn.hippo4j.common.toolkit.JSONUtil;
import cn.hippo4j.common.web.base.Result; import cn.hippo4j.common.web.base.Result;
import cn.hippo4j.starter.common.CommonDynamicThreadPool; import cn.hippo4j.starter.common.CommonDynamicThreadPool;
import cn.hippo4j.starter.config.BootstrapProperties; import cn.hippo4j.starter.config.BootstrapProperties;
@ -11,7 +12,6 @@ import cn.hippo4j.starter.toolkit.thread.QueueTypeEnum;
import cn.hippo4j.starter.toolkit.thread.RejectedTypeEnum; import cn.hippo4j.starter.toolkit.thread.RejectedTypeEnum;
import cn.hippo4j.starter.toolkit.thread.ThreadPoolBuilder; import cn.hippo4j.starter.toolkit.thread.ThreadPoolBuilder;
import cn.hippo4j.starter.wrapper.DynamicThreadPoolWrapper; import cn.hippo4j.starter.wrapper.DynamicThreadPoolWrapper;
import com.alibaba.fastjson.JSON;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import lombok.var; import lombok.var;
@ -108,7 +108,9 @@ public final class DynamicThreadPoolPostProcessor implements BeanPostProcessor {
try { try {
result = httpAgent.httpGetByConfig(Constants.CONFIG_CONTROLLER_PATH, null, queryStrMap, 5000L); result = httpAgent.httpGetByConfig(Constants.CONFIG_CONTROLLER_PATH, null, queryStrMap, 5000L);
if (result.isSuccess() && result.getData() != null && (ppi = JSON.toJavaObject((JSON) result.getData(), PoolParameterInfo.class)) != null) { if (result.isSuccess() && result.getData() != null) {
String resultJsonStr = JSONUtil.toJSONString(result.getData());
if ((ppi = JSONUtil.parseObject(resultJsonStr, PoolParameterInfo.class)) != null) {
// 使用相关参数创建线程池 // 使用相关参数创建线程池
BlockingQueue workQueue = QueueTypeEnum.createBlockingQueue(ppi.getQueueType(), ppi.getCapacity()); BlockingQueue workQueue = QueueTypeEnum.createBlockingQueue(ppi.getQueueType(), ppi.getCapacity());
poolExecutor = ThreadPoolBuilder.builder() poolExecutor = ThreadPoolBuilder.builder()
@ -129,6 +131,7 @@ public final class DynamicThreadPoolPostProcessor implements BeanPostProcessor {
dynamicThreadPoolWrap.setExecutor(poolExecutor); dynamicThreadPoolWrap.setExecutor(poolExecutor);
isSubscribe = true; isSubscribe = true;
} }
}
} catch (Exception ex) { } catch (Exception ex) {
poolExecutor = dynamicThreadPoolWrap.getExecutor() != null ? dynamicThreadPoolWrap.getExecutor() : CommonDynamicThreadPool.getInstance(tpId); poolExecutor = dynamicThreadPoolWrap.getExecutor() != null ? dynamicThreadPoolWrap.getExecutor() : CommonDynamicThreadPool.getInstance(tpId);
dynamicThreadPoolWrap.setExecutor(poolExecutor); dynamicThreadPoolWrap.setExecutor(poolExecutor);

@ -1,11 +1,11 @@
package cn.hippo4j.starter.core; package cn.hippo4j.starter.core;
import cn.hippo4j.common.model.PoolParameterInfo;
import cn.hippo4j.common.toolkit.JSONUtil;
import cn.hippo4j.starter.alarm.ThreadPoolAlarmManage;
import cn.hippo4j.starter.toolkit.thread.QueueTypeEnum; import cn.hippo4j.starter.toolkit.thread.QueueTypeEnum;
import cn.hippo4j.starter.toolkit.thread.RejectedTypeEnum; import cn.hippo4j.starter.toolkit.thread.RejectedTypeEnum;
import cn.hippo4j.starter.toolkit.thread.ResizableCapacityLinkedBlockIngQueue; import cn.hippo4j.starter.toolkit.thread.ResizableCapacityLinkedBlockIngQueue;
import com.alibaba.fastjson.JSON;
import cn.hippo4j.common.model.PoolParameterInfo;
import cn.hippo4j.starter.alarm.ThreadPoolAlarmManage;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import java.util.Objects; import java.util.Objects;
@ -22,7 +22,7 @@ import java.util.concurrent.TimeUnit;
public class ThreadPoolDynamicRefresh { public class ThreadPoolDynamicRefresh {
public static void refreshDynamicPool(String content) { public static void refreshDynamicPool(String content) {
PoolParameterInfo parameter = JSON.parseObject(content, PoolParameterInfo.class); PoolParameterInfo parameter = JSONUtil.parseObject(content, PoolParameterInfo.class);
ThreadPoolAlarmManage.sendPoolConfigChange(parameter); ThreadPoolAlarmManage.sendPoolConfigChange(parameter);
ThreadPoolDynamicRefresh.refreshDynamicPool(parameter); ThreadPoolDynamicRefresh.refreshDynamicPool(parameter);
} }

@ -1,6 +1,6 @@
package cn.hippo4j.starter.toolkit; package cn.hippo4j.starter.toolkit;
import com.alibaba.fastjson.JSON; import cn.hippo4j.common.toolkit.JSONUtil;
import lombok.SneakyThrows; import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import okhttp3.*; import okhttp3.*;
@ -63,7 +63,7 @@ public class HttpClientUtil {
*/ */
public <T> T restApiGet(String url, Class<T> clazz) { public <T> T restApiGet(String url, Class<T> clazz) {
String resp = get(url); String resp = get(url);
return JSON.parseObject(resp, clazz); return JSONUtil.parseObject(resp, clazz);
} }
/** /**
@ -77,7 +77,7 @@ public class HttpClientUtil {
@SneakyThrows @SneakyThrows
public <T> T restApiGetHealth(String url, Class<T> clazz) { public <T> T restApiGetHealth(String url, Class<T> clazz) {
String resp = new String(doGet(url), "utf-8"); String resp = new String(doGet(url), "utf-8");
return JSON.parseObject(resp, clazz); return JSONUtil.parseObject(resp, clazz);
} }
/** /**
@ -92,7 +92,7 @@ public class HttpClientUtil {
public <T> T restApiGet(String url, Map<String, String> queryString, Class<T> clazz) { public <T> T restApiGet(String url, Map<String, String> queryString, Class<T> clazz) {
String fullUrl = buildUrl(url, queryString); String fullUrl = buildUrl(url, queryString);
String resp = get(fullUrl); String resp = get(fullUrl);
return JSON.parseObject(resp, clazz); return JSONUtil.parseObject(resp, clazz);
} }
/** /**
@ -121,7 +121,7 @@ public class HttpClientUtil {
*/ */
public <T> T restApiPost(String url, Object body, Class<T> clazz) { public <T> T restApiPost(String url, Object body, Class<T> clazz) {
String resp = restApiPost(url, body); String resp = restApiPost(url, body);
return JSON.parseObject(resp, clazz); return JSONUtil.parseObject(resp, clazz);
} }
/** /**
@ -159,7 +159,7 @@ public class HttpClientUtil {
@SneakyThrows @SneakyThrows
private String doPost(String url, Object body) { private String doPost(String url, Object body) {
String jsonBody = JSON.toJSONString(body); String jsonBody = JSONUtil.toJSONString(body);
RequestBody requestBody = RequestBody.create(jsonMediaType, jsonBody); RequestBody requestBody = RequestBody.create(jsonMediaType, jsonBody);
Request request = new Request.Builder() Request request = new Request.Builder()
.url(url) .url(url)
@ -205,7 +205,7 @@ public class HttpClientUtil {
throw new RuntimeException(msg); throw new RuntimeException(msg);
} }
return JSON.parseObject(resp.body().string(), clazz); return JSONUtil.parseObject(resp.body().string(), clazz);
} }
@SneakyThrows @SneakyThrows
@ -227,7 +227,7 @@ public class HttpClientUtil {
log.error(msg); log.error(msg);
throw new RuntimeException(msg); throw new RuntimeException(msg);
} }
return JSON.parseObject(resp.body().string(), clazz); return JSONUtil.parseObject(resp.body().string(), clazz);
} }
} }

@ -26,7 +26,7 @@
<properties> <properties>
<java.version>1.8</java.version> <java.version>1.8</java.version>
<revision>1.0.0-RC3</revision> <revision>1.0.0-SNAPSHOT</revision>
<dozer.version>6.5.0</dozer.version> <dozer.version>6.5.0</dozer.version>
<guava.version>29.0-jre</guava.version> <guava.version>29.0-jre</guava.version>
@ -38,6 +38,7 @@
<transmittable-thread-local.version>2.12.1</transmittable-thread-local.version> <transmittable-thread-local.version>2.12.1</transmittable-thread-local.version>
<forest.version>1.5.11</forest.version> <forest.version>1.5.11</forest.version>
<jjwt.version>0.9.0</jjwt.version> <jjwt.version>0.9.0</jjwt.version>
<jackson-bom.version>2.11.1</jackson-bom.version>
<dingtalk-sdk.version>1.0.1</dingtalk-sdk.version> <dingtalk-sdk.version>1.0.1</dingtalk-sdk.version>
@ -195,6 +196,13 @@
<artifactId>logback-classic</artifactId> <artifactId>logback-classic</artifactId>
<version>${logback.version}</version> <version>${logback.version}</version>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-json</artifactId>
<version>${spring-boot.version}</version>
<scope>compile</scope>
</dependency>
</dependencies> </dependencies>
</dependencyManagement> </dependencyManagement>

Loading…
Cancel
Save