The abstract thread pool dynamically changes the kernel layer (#1320)

pull/1321/head
magestack 1 year ago committed by GitHub
parent bf9572f261
commit d1362fab6e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -37,7 +37,6 @@ public class DynamicThreadPoolChangeHandlerSpring2x extends AbstractDynamicThrea
super(context);
}
@Override
protected BootstrapConfigProperties bindProperties(Map<Object, Object> configInfo, ApplicationContext applicationContext) {
BootstrapConfigProperties bindableBootstrapConfigProperties = new BootstrapConfigProperties();
ConfigurationPropertySource sources = new MapConfigurationPropertySource(configInfo);

@ -37,14 +37,21 @@
<dependency>
<groupId>cn.hippo4j</groupId>
<artifactId>hippo4j-threadpool-config-spring-boot-starter</artifactId>
<artifactId>hippo4j-threadpool-dynamic-api</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>cn.hippo4j</groupId>
<artifactId>hippo4j-threadpool-dynamic-api</artifactId>
<artifactId>hippo4j-threadpool-core</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>cn.hippo4j</groupId>
<artifactId>hippo4j-threadpool-dynamic-mode-config</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>

@ -21,18 +21,16 @@ import cn.hippo4j.agent.core.registry.AgentThreadPoolExecutorHolder;
import cn.hippo4j.agent.core.registry.AgentThreadPoolInstanceRegistry;
import cn.hippo4j.agent.core.util.ThreadPoolPropertyKey;
import cn.hippo4j.agent.plugin.spring.common.conf.SpringBootConfig;
import cn.hippo4j.common.model.executor.ExecutorProperties;
import cn.hippo4j.common.executor.support.BlockingQueueTypeEnum;
import cn.hippo4j.common.executor.support.RejectedPolicyTypeEnum;
import cn.hippo4j.common.executor.support.ResizableCapacityLinkedBlockingQueue;
import cn.hippo4j.common.model.executor.ExecutorProperties;
import cn.hippo4j.common.toolkit.CollectionUtil;
import cn.hippo4j.common.toolkit.ThreadPoolExecutorUtil;
import cn.hippo4j.config.springboot.starter.config.BootstrapConfigProperties;
import cn.hippo4j.config.springboot.starter.parser.ConfigFileTypeEnum;
import cn.hippo4j.config.springboot.starter.parser.ConfigParserHandler;
import cn.hippo4j.core.executor.DynamicThreadPoolExecutor;
import cn.hippo4j.message.request.ChangeParameterNotifyRequest;
import cn.hippo4j.threadpool.dynamic.api.ThreadPoolDynamicRefresh;
import cn.hippo4j.threadpool.dynamic.mode.config.parser.ConfigFileTypeEnum;
import cn.hippo4j.threadpool.dynamic.mode.config.parser.ConfigParserHandler;
import com.ctrip.framework.apollo.ConfigChangeListener;
import com.ctrip.framework.apollo.ConfigFile;
import com.ctrip.framework.apollo.ConfigService;
@ -43,19 +41,12 @@ import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Properties;
import java.util.*;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import static cn.hippo4j.agent.core.conf.Constants.SPRING_BOOT_CONFIG_PREFIX;
import static cn.hippo4j.common.constant.ChangeThreadPoolConstants.CHANGE_DELIMITER;
import static cn.hippo4j.common.constant.ChangeThreadPoolConstants.CHANGE_THREAD_POOL_TEXT;
/**
* Abstract dynamic thread poo change handler spring
@ -93,8 +84,6 @@ public abstract class AbstractDynamicThreadPoolChangeHandlerSpring implements Th
LOGGER.info("[Hippo4j-Agent] Dynamic thread pool refresher, add apollo listener success. namespace: {}", namespace);
}
protected abstract BootstrapConfigProperties bindProperties(Map<Object, Object> configInfo, ApplicationContext applicationContext);
private void dynamicRefresh(String configContent, Map<String, Object> newValueChangeMap, ApplicationContext context) {
try {
String configFileType = SpringBootConfig.Spring.Dynamic.Thread_Pool.CONFIG_FILE_TYPE;
@ -104,34 +93,24 @@ public abstract class AbstractDynamicThreadPoolChangeHandlerSpring implements Th
if (CollectionUtil.isNotEmpty(newValueChangeMap)) {
Optional.ofNullable(afterConfigMap).ifPresent(each -> each.putAll(newValueChangeMap));
}
BootstrapConfigProperties afterConfigProperties = bindProperties(afterConfigMap, context);
List<ExecutorProperties> executors = afterConfigProperties.getExecutors();
for (ExecutorProperties afterProperties : executors) {
String threadPoolId = afterProperties.getThreadPoolId();
AgentThreadPoolExecutorHolder holder = AgentThreadPoolInstanceRegistry.getInstance().getHolder(threadPoolId);
if (holder.isEmpty() || holder.getExecutor() == null) {
continue;
}
ExecutorProperties beforeProperties = convert(holder.getProperties());
if (!checkConsistency(threadPoolId, beforeProperties, afterProperties)) {
continue;
}
dynamicRefreshPool(beforeProperties, afterProperties);
holder.setProperties(failDefaultExecutorProperties(beforeProperties, afterProperties)); // do refresh.
ChangeParameterNotifyRequest changeRequest = buildChangeRequest(beforeProperties, afterProperties);
LOGGER.info(CHANGE_THREAD_POOL_TEXT,
threadPoolId,
String.format(CHANGE_DELIMITER, beforeProperties.getCorePoolSize(), changeRequest.getNowCorePoolSize()),
String.format(CHANGE_DELIMITER, beforeProperties.getMaximumPoolSize(), changeRequest.getNowMaximumPoolSize()),
String.format(CHANGE_DELIMITER, beforeProperties.getQueueCapacity(), changeRequest.getNowQueueCapacity()),
String.format(CHANGE_DELIMITER, beforeProperties.getKeepAliveTime(), changeRequest.getNowKeepAliveTime()),
String.format(CHANGE_DELIMITER, beforeProperties.getExecuteTimeOut(), changeRequest.getNowExecuteTimeOut()),
String.format(CHANGE_DELIMITER, beforeProperties.getRejectedHandler(), changeRequest.getNowRejectedName()),
String.format(CHANGE_DELIMITER, beforeProperties.getAllowCoreThreadTimeOut(), changeRequest.getNowAllowsCoreThreadTimeOut()));
}
// TODO
/*
* BootstrapConfigProperties afterConfigProperties = bindProperties(afterConfigMap, context);
*
* List<ExecutorProperties> executors = afterConfigProperties.getExecutors(); for (ExecutorProperties afterProperties : executors) { String threadPoolId =
* afterProperties.getThreadPoolId(); AgentThreadPoolExecutorHolder holder = AgentThreadPoolInstanceRegistry.getInstance().getHolder(threadPoolId); if (holder.isEmpty() ||
* holder.getExecutor() == null) { continue; } ExecutorProperties beforeProperties = convert(holder.getProperties());
*
* if (!checkConsistency(threadPoolId, beforeProperties, afterProperties)) { continue; }
*
* dynamicRefreshPool(beforeProperties, afterProperties); holder.setProperties(failDefaultExecutorProperties(beforeProperties, afterProperties)); // do refresh.
* ChangeParameterNotifyRequest changeRequest = buildChangeRequest(beforeProperties, afterProperties); LOGGER.info(CHANGE_THREAD_POOL_TEXT, threadPoolId, String.format(CHANGE_DELIMITER,
* beforeProperties.getCorePoolSize(), changeRequest.getNowCorePoolSize()), String.format(CHANGE_DELIMITER, beforeProperties.getMaximumPoolSize(), changeRequest.getNowMaximumPoolSize()),
* String.format(CHANGE_DELIMITER, beforeProperties.getQueueCapacity(), changeRequest.getNowQueueCapacity()), String.format(CHANGE_DELIMITER, beforeProperties.getKeepAliveTime(),
* changeRequest.getNowKeepAliveTime()), String.format(CHANGE_DELIMITER, beforeProperties.getExecuteTimeOut(), changeRequest.getNowExecuteTimeOut()), String.format(CHANGE_DELIMITER,
* beforeProperties.getRejectedHandler(), changeRequest.getNowRejectedName()), String.format(CHANGE_DELIMITER, beforeProperties.getAllowCoreThreadTimeOut(),
* changeRequest.getNowAllowsCoreThreadTimeOut())); }
*/
} catch (Exception ex) {
LOGGER.error("[Hippo4j-Agent] config mode dynamic refresh failed.", ex);
}
@ -183,7 +162,7 @@ public abstract class AbstractDynamicThreadPoolChangeHandlerSpring implements Th
* Fail default executor properties.
*
* @param beforeProperties old properties
* @param afterProperties new properties
* @param afterProperties new properties
* @return executor properties
*/
private Properties failDefaultExecutorProperties(ExecutorProperties beforeProperties, ExecutorProperties afterProperties) {
@ -236,27 +215,20 @@ public abstract class AbstractDynamicThreadPoolChangeHandlerSpring implements Th
* @param afterProperties new properties
* @return instance
*/
private ChangeParameterNotifyRequest buildChangeRequest(ExecutorProperties beforeProperties, ExecutorProperties afterProperties) {
ChangeParameterNotifyRequest changeParameterNotifyRequest = ChangeParameterNotifyRequest.builder()
.beforeCorePoolSize(beforeProperties.getCorePoolSize())
.beforeMaximumPoolSize(beforeProperties.getMaximumPoolSize())
.beforeAllowsCoreThreadTimeOut(beforeProperties.getAllowCoreThreadTimeOut())
.beforeKeepAliveTime(beforeProperties.getKeepAliveTime())
.beforeQueueCapacity(beforeProperties.getQueueCapacity())
.beforeRejectedName(beforeProperties.getRejectedHandler())
.beforeExecuteTimeOut(beforeProperties.getExecuteTimeOut())
.blockingQueueName(afterProperties.getBlockingQueue())
.nowCorePoolSize(Optional.ofNullable(afterProperties.getCorePoolSize()).orElse(beforeProperties.getCorePoolSize()))
.nowMaximumPoolSize(Optional.ofNullable(afterProperties.getMaximumPoolSize()).orElse(beforeProperties.getMaximumPoolSize()))
.nowAllowsCoreThreadTimeOut(Optional.ofNullable(afterProperties.getAllowCoreThreadTimeOut()).orElse(beforeProperties.getAllowCoreThreadTimeOut()))
.nowKeepAliveTime(Optional.ofNullable(afterProperties.getKeepAliveTime()).orElse(beforeProperties.getKeepAliveTime()))
.nowQueueCapacity(Optional.ofNullable(afterProperties.getQueueCapacity()).orElse(beforeProperties.getQueueCapacity()))
.nowRejectedName(Optional.ofNullable(afterProperties.getRejectedHandler()).orElse(beforeProperties.getRejectedHandler()))
.nowExecuteTimeOut(Optional.ofNullable(afterProperties.getExecuteTimeOut()).orElse(beforeProperties.getExecuteTimeOut()))
.build();
changeParameterNotifyRequest.setThreadPoolId(beforeProperties.getThreadPoolId());
return changeParameterNotifyRequest;
}
/*
* private ChangeParameterNotifyRequest buildChangeRequest(ExecutorProperties beforeProperties, ExecutorProperties afterProperties) { ChangeParameterNotifyRequest changeParameterNotifyRequest =
* ChangeParameterNotifyRequest.builder() .beforeCorePoolSize(beforeProperties.getCorePoolSize()) .beforeMaximumPoolSize(beforeProperties.getMaximumPoolSize())
* .beforeAllowsCoreThreadTimeOut(beforeProperties.getAllowCoreThreadTimeOut()) .beforeKeepAliveTime(beforeProperties.getKeepAliveTime()) .beforeQueueCapacity(beforeProperties.getQueueCapacity())
* .beforeRejectedName(beforeProperties.getRejectedHandler()) .beforeExecuteTimeOut(beforeProperties.getExecuteTimeOut()) .blockingQueueName(afterProperties.getBlockingQueue())
* .nowCorePoolSize(Optional.ofNullable(afterProperties.getCorePoolSize()).orElse(beforeProperties.getCorePoolSize()))
* .nowMaximumPoolSize(Optional.ofNullable(afterProperties.getMaximumPoolSize()).orElse(beforeProperties.getMaximumPoolSize()))
* .nowAllowsCoreThreadTimeOut(Optional.ofNullable(afterProperties.getAllowCoreThreadTimeOut()).orElse(beforeProperties.getAllowCoreThreadTimeOut()))
* .nowKeepAliveTime(Optional.ofNullable(afterProperties.getKeepAliveTime()).orElse(beforeProperties.getKeepAliveTime()))
* .nowQueueCapacity(Optional.ofNullable(afterProperties.getQueueCapacity()).orElse(beforeProperties.getQueueCapacity()))
* .nowRejectedName(Optional.ofNullable(afterProperties.getRejectedHandler()).orElse(beforeProperties.getRejectedHandler()))
* .nowExecuteTimeOut(Optional.ofNullable(afterProperties.getExecuteTimeOut()).orElse(beforeProperties.getExecuteTimeOut())) .build();
* changeParameterNotifyRequest.setThreadPoolId(beforeProperties.getThreadPoolId()); return changeParameterNotifyRequest; }
*/
/**
* Check consistency.

@ -24,8 +24,6 @@ import cn.hippo4j.common.constant.Constants;
import cn.hippo4j.common.executor.support.BlockingQueueTypeEnum;
import cn.hippo4j.common.executor.support.RejectedPolicyTypeEnum;
import cn.hippo4j.common.toolkit.BooleanUtil;
import cn.hippo4j.core.executor.DynamicThreadPool;
import cn.hippo4j.core.executor.DynamicThreadPoolExecutor;
import cn.hippo4j.core.executor.support.adpter.DynamicThreadPoolAdapterChoose;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -101,9 +99,7 @@ public class SpringThreadPoolRegisterSupport {
properties.put(ThreadPoolPropertyKey.THREAD_NAME_PREFIX, threadPoolId);
properties.put(ThreadPoolPropertyKey.REJECTED_HANDLER, RejectedPolicyTypeEnum.getRejectedPolicyTypeEnumByName(executor.getRejectedExecutionHandler().getClass().getSimpleName()).getName());
properties.put(ThreadPoolPropertyKey.EXECUTE_TIME_OUT, Constants.EXECUTE_TIME_OUT);
// register executor.
AgentThreadPoolInstanceRegistry.getInstance().putHolder(threadPoolId, executor, properties);
}
}

@ -1,5 +1,21 @@
package cn.hippo4j.common.toolkit;
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.hippo4j.common.toolkit;
import org.junit.Assert;
import org.junit.Test;
@ -10,7 +26,7 @@ import org.junit.Test;
public class ClassUtilTest {
@Test
public void testGetClassLoader(){
public void testGetClassLoader() {
ClassLoader expectedClassLoader = Thread.currentThread().getContextClassLoader();
ClassLoader actualClassLoader = ClassUtil.getClassLoader(ClassUtilTest.class);
Assert.assertEquals(expectedClassLoader, actualClassLoader);

@ -15,7 +15,7 @@
* limitations under the License.
*/
package cn.hippo4j.core.config;
package cn.hippo4j.threadpool.dynamic.api;
/**
* Bootstrap properties interface.

@ -38,6 +38,15 @@ public interface ThreadPoolDynamicRefresh {
default void dynamicRefresh(String content) {
}
/**
* Dynamic refresh of configuration center data changes.
*
* @param configFileType config file type
* @param content changed data
*/
default void dynamicRefresh(String configFileType, String content) {
}
/**
* Dynamic refresh.
*
@ -46,4 +55,14 @@ public interface ThreadPoolDynamicRefresh {
*/
default void dynamicRefresh(String content, Map<String, Object> newValueChangeMap) {
}
/**
* Dynamic refresh.
*
* @param configFileType config file type
* @param content changed data
* @param newValueChangeMap new value change map
*/
default void dynamicRefresh(String configFileType, String content, Map<String, Object> newValueChangeMap) {
}
}

@ -10,4 +10,12 @@
</parent>
<artifactId>hippo4j-threadpool-dynamic-mode-config</artifactId>
<dependencies>
<dependency>
<groupId>cn.hippo4j</groupId>
<artifactId>hippo4j-threadpool-dynamic-api</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>

@ -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.threadpool.dynamic.mode.config.parser;
/**
* Abstract config parser
*/
public abstract class AbstractConfigParser implements ConfigParser {
@Override
public boolean supports(ConfigFileTypeEnum type) {
return getConfigFileTypes().contains(type);
}
}

@ -0,0 +1,72 @@
/*
* 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.threadpool.dynamic.mode.config.parser;
import lombok.Getter;
/**
* Config file type enum
*/
@Getter
public enum ConfigFileTypeEnum {
/**
* PROPERTIES
*/
PROPERTIES("properties"),
/**
* XML
*/
XML("xml"),
/**
* JSON
*/
JSON("json"),
/**
* YML
*/
YML("yml"),
/**
* YAML
*/
YAML("yaml"),
/**
* TXT
*/
TXT("txt");
private final String value;
ConfigFileTypeEnum(String value) {
this.value = value;
}
public static ConfigFileTypeEnum of(String value) {
for (ConfigFileTypeEnum typeEnum : ConfigFileTypeEnum.values()) {
if (typeEnum.value.equals(value)) {
return typeEnum;
}
}
return PROPERTIES;
}
}

@ -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.threadpool.dynamic.mode.config.parser;
import java.io.IOException;
import java.util.List;
import java.util.Map;
/**
* Config parser.
*/
public interface ConfigParser {
/**
* Supports.
*
* @param type
* @return
*/
boolean supports(ConfigFileTypeEnum type);
/**
* Do parse.
*
* @param content
* @return
* @throws IOException
*/
Map<Object, Object> doParse(String content) throws IOException;
/**
* Get config file types.
*
* @return
*/
List<ConfigFileTypeEnum> getConfigFileTypes();
}

@ -0,0 +1,63 @@
/*
* 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.threadpool.dynamic.mode.config.parser;
import java.io.IOException;
import java.util.*;
/**
* Config parser handler.
*/
public final class ConfigParserHandler {
private static final List<ConfigParser> PARSERS = new ArrayList<>();
private ConfigParserHandler() {
ServiceLoader<ConfigParser> loader = ServiceLoader.load(ConfigParser.class);
for (ConfigParser configParser : loader) {
PARSERS.add(configParser);
}
PARSERS.add(new PropertiesConfigParser());
PARSERS.add(new YamlConfigParser());
}
public Map<Object, Object> parseConfig(String content, String type) throws IOException {
return parseConfig(content, ConfigFileTypeEnum.of(type));
}
public Map<Object, Object> parseConfig(String content, ConfigFileTypeEnum type) throws IOException {
for (ConfigParser parser : PARSERS) {
if (parser.supports(type)) {
return parser.doParse(content);
}
}
return Collections.emptyMap();
}
public static ConfigParserHandler getInstance() {
return ConfigParserHandlerHolder.INSTANCE;
}
/**
* Config Parser Handler Holder
*/
private static class ConfigParserHandlerHolder {
private static final ConfigParserHandler INSTANCE = new ConfigParserHandler();
}
}

@ -0,0 +1,44 @@
/*
* 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.threadpool.dynamic.mode.config.parser;
import cn.hippo4j.common.toolkit.CollectionUtil;
import java.io.IOException;
import java.io.StringReader;
import java.util.List;
import java.util.Map;
import java.util.Properties;
/**
* Properties config parser.
*/
public class PropertiesConfigParser extends AbstractConfigParser {
@Override
public Map<Object, Object> doParse(String content) throws IOException {
Properties properties = new Properties();
properties.load(new StringReader(content));
return properties;
}
@Override
public List<ConfigFileTypeEnum> getConfigFileTypes() {
return CollectionUtil.newArrayList(ConfigFileTypeEnum.PROPERTIES);
}
}

@ -0,0 +1,40 @@
/*
* 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.threadpool.dynamic.mode.config.parser;
import cn.hippo4j.common.toolkit.CollectionUtil;
import java.util.List;
import java.util.Map;
/**
* Yaml config parser.
*/
public class YamlConfigParser extends AbstractConfigParser {
@Override
public Map<Object, Object> doParse(String content) {
// TODO
return null;
}
@Override
public List<ConfigFileTypeEnum> getConfigFileTypes() {
return CollectionUtil.newArrayList(ConfigFileTypeEnum.YML, ConfigFileTypeEnum.YAML);
}
}

@ -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.threadpool.dynamic.mode.config.refresher;
import cn.hippo4j.common.toolkit.CollectionUtil;
import cn.hippo4j.threadpool.dynamic.api.ThreadPoolDynamicRefresh;
import cn.hippo4j.threadpool.dynamic.mode.config.parser.ConfigParserHandler;
import lombok.extern.slf4j.Slf4j;
import java.util.Map;
import java.util.Optional;
/**
* Abstract config thread-pool dynamic refresh.
*/
@Slf4j
public abstract class AbstractConfigThreadPoolDynamicRefresh implements ThreadPoolDynamicRefresh {
@Override
public void dynamicRefresh(String configFileType, String configContent) {
dynamicRefresh(configFileType, configContent, null);
}
@Override
public void dynamicRefresh(String configFileType, String configContent, Map<String, Object> newValueChangeMap) {
try {
Map<Object, Object> configInfo = ConfigParserHandler.getInstance().parseConfig(configContent, configFileType);
if (CollectionUtil.isNotEmpty(newValueChangeMap)) {
Optional.ofNullable(configInfo).ifPresent(each -> each.putAll(newValueChangeMap));
}
// BootstrapConfigProperties binderCoreProperties = bootstrapConfigPropertiesBinderAdapt.bootstrapCorePropertiesBinder(configInfo, bootstrapConfigProperties);
// publishDynamicThreadPoolEvent(binderCoreProperties);
} catch (Exception ex) {
log.error("Hippo4j config mode dynamic refresh failed.", ex);
}
}
}

@ -15,16 +15,16 @@
* limitations under the License.
*/
package cn.hippo4j.config.springboot.starter.refresher;
package cn.hippo4j.threadpool.dynamic.mode.config.refresher;
import cn.hippo4j.config.springboot.starter.config.BootstrapConfigProperties;
import cn.hippo4j.threadpool.dynamic.api.BootstrapPropertiesInterface;
import java.util.Map;
/**
* Bootstrap config properties binder adapt.
*/
public interface BootstrapConfigPropertiesBinderAdapt {
public interface BootstrapConfigPropertiesBinderAdapter {
/**
* Bootstrap core properties binder.
@ -33,5 +33,5 @@ public interface BootstrapConfigPropertiesBinderAdapt {
* @param bootstrapConfigProperties bootstrap config properties
* @return
*/
BootstrapConfigProperties bootstrapCorePropertiesBinder(Map<Object, Object> configInfo, BootstrapConfigProperties bootstrapConfigProperties);
BootstrapPropertiesInterface bootstrapCorePropertiesBinder(Map<Object, Object> configInfo, BootstrapPropertiesInterface bootstrapConfigProperties);
}

@ -17,8 +17,8 @@
package cn.hippo4j.config.springboot1x.starter.config;
import cn.hippo4j.config.springboot.starter.refresher.BootstrapConfigPropertiesBinderAdapt;
import cn.hippo4j.config.springboot1x.starter.refresher.SpringBoot1xBootstrapConfigPropertiesBinderAdapt;
import cn.hippo4j.threadpool.dynamic.mode.config.refresher.BootstrapConfigPropertiesBinderAdapter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.bind.RelaxedDataBinder;
import org.springframework.context.annotation.Bean;
@ -30,7 +30,7 @@ public class ConfigHandlerAutoConfiguration {
@Bean
@ConditionalOnClass(RelaxedDataBinder.class)
public BootstrapConfigPropertiesBinderAdapt bootstrapConfigPropertiesBinderAdapt() {
public BootstrapConfigPropertiesBinderAdapter bootstrapConfigPropertiesBinderAdapter() {
return new SpringBoot1xBootstrapConfigPropertiesBinderAdapt();
}
}

@ -18,7 +18,8 @@
package cn.hippo4j.config.springboot1x.starter.refresher;
import cn.hippo4j.config.springboot.starter.config.BootstrapConfigProperties;
import cn.hippo4j.config.springboot.starter.refresher.BootstrapConfigPropertiesBinderAdapt;
import cn.hippo4j.threadpool.dynamic.api.BootstrapPropertiesInterface;
import cn.hippo4j.threadpool.dynamic.mode.config.refresher.BootstrapConfigPropertiesBinderAdapter;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
@ -40,7 +41,7 @@ import java.util.Set;
/**
* Bootstrap core properties binder adapt.
*/
public class SpringBoot1xBootstrapConfigPropertiesBinderAdapt implements ApplicationContextAware, BootstrapConfigPropertiesBinderAdapt {
public class SpringBoot1xBootstrapConfigPropertiesBinderAdapt implements ApplicationContextAware, BootstrapConfigPropertiesBinderAdapter {
private ApplicationContext applicationContext;
@ -52,7 +53,7 @@ public class SpringBoot1xBootstrapConfigPropertiesBinderAdapt implements Applica
* @return
*/
@Override
public BootstrapConfigProperties bootstrapCorePropertiesBinder(Map<Object, Object> configInfo, BootstrapConfigProperties bootstrapConfigProperties) {
public BootstrapPropertiesInterface bootstrapCorePropertiesBinder(Map<Object, Object> configInfo, BootstrapPropertiesInterface bootstrapConfigProperties) {
BootstrapConfigProperties bindableCoreProperties = new BootstrapConfigProperties();
RelaxedNames relaxedNames = new RelaxedNames(BootstrapConfigProperties.PREFIX);
Set<String> names = getNames(bindableCoreProperties, relaxedNames);

@ -133,5 +133,10 @@
<artifactId>hippo4j-threadpool-dynamic-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>cn.hippo4j</groupId>
<artifactId>hippo4j-threadpool-dynamic-mode-config</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>

@ -19,7 +19,7 @@ package cn.hippo4j.config.springboot.starter.config;
import cn.hippo4j.common.model.executor.ExecutorProperties;
import cn.hippo4j.config.springboot.starter.parser.ConfigFileTypeEnum;
import cn.hippo4j.core.config.BootstrapPropertiesInterface;
import cn.hippo4j.threadpool.dynamic.api.BootstrapPropertiesInterface;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;

@ -17,15 +17,8 @@
package cn.hippo4j.config.springboot.starter.config;
import cn.hippo4j.config.springboot.starter.refresher.ApolloRefresherHandler;
import cn.hippo4j.config.springboot.starter.refresher.BootstrapConfigPropertiesBinderAdapt;
import cn.hippo4j.config.springboot.starter.refresher.ConsulRefresherHandler;
import cn.hippo4j.config.springboot.starter.refresher.DefaultBootstrapConfigPropertiesBinderAdapt;
import cn.hippo4j.config.springboot.starter.refresher.EtcdRefresherHandler;
import cn.hippo4j.config.springboot.starter.refresher.NacosCloudRefresherHandler;
import cn.hippo4j.config.springboot.starter.refresher.NacosRefresherHandler;
import cn.hippo4j.config.springboot.starter.refresher.PolarisRefresherHandler;
import cn.hippo4j.config.springboot.starter.refresher.ZookeeperRefresherHandler;
import cn.hippo4j.config.springboot.starter.refresher.*;
import cn.hippo4j.threadpool.dynamic.mode.config.refresher.BootstrapConfigPropertiesBinderAdapter;
import com.alibaba.cloud.nacos.NacosConfigProperties;
import com.alibaba.nacos.api.config.ConfigService;
import com.tencent.polaris.configuration.api.core.ConfigFileService;
@ -64,7 +57,7 @@ public class ConfigHandlerConfiguration {
@Bean
@ConditionalOnMissingBean
public BootstrapConfigPropertiesBinderAdapt bootstrapConfigPropertiesBinderAdapt() {
public BootstrapConfigPropertiesBinderAdapter bootstrapConfigPropertiesBinderAdapter() {
return new DefaultBootstrapConfigPropertiesBinderAdapt();
}

@ -17,52 +17,56 @@
package cn.hippo4j.config.springboot.starter.refresher;
import cn.hippo4j.core.config.ApplicationContextHolder;
import cn.hippo4j.common.toolkit.CollectionUtil;
import cn.hippo4j.config.springboot.starter.config.BootstrapConfigProperties;
import cn.hippo4j.config.springboot.starter.parser.ConfigParserHandler;
import cn.hippo4j.config.springboot.starter.refresher.event.Hippo4jConfigDynamicRefreshEvent;
import cn.hippo4j.core.config.ApplicationContextHolder;
import cn.hippo4j.core.executor.support.ThreadPoolBuilder;
import cn.hippo4j.threadpool.dynamic.api.BootstrapPropertiesInterface;
import cn.hippo4j.threadpool.dynamic.api.ThreadPoolDynamicRefresh;
import cn.hippo4j.threadpool.dynamic.mode.config.refresher.BootstrapConfigPropertiesBinderAdapter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ExecutorService;
/**
* Abstract core thread-pool dynamic refresh.
* Abstract config thread-pool dynamic refresh.
*/
@Slf4j
public abstract class AbstractConfigThreadPoolDynamicRefresh implements ThreadPoolDynamicRefresh, InitializingBean, ApplicationRunner {
private final BootstrapConfigPropertiesBinderAdapt bootstrapConfigPropertiesBinderAdapt;
protected BootstrapConfigProperties bootstrapConfigProperties;
private final BootstrapConfigPropertiesBinderAdapter bootstrapConfigPropertiesBinderAdapter;
protected BootstrapPropertiesInterface bootstrapConfigProperties;
protected final ExecutorService dynamicRefreshExecutorService = ThreadPoolBuilder.builder().singlePool("client.dynamic.refresh").build();
public AbstractConfigThreadPoolDynamicRefresh() {
bootstrapConfigProperties = ApplicationContextHolder.getBean(BootstrapConfigProperties.class);
bootstrapConfigPropertiesBinderAdapt = ApplicationContextHolder.getBean(BootstrapConfigPropertiesBinderAdapt.class);
bootstrapConfigProperties = ApplicationContextHolder.getBean(BootstrapPropertiesInterface.class);
bootstrapConfigPropertiesBinderAdapter = ApplicationContextHolder.getBean(BootstrapConfigPropertiesBinderAdapter.class);
}
@Override
public void dynamicRefresh(String configContent) {
dynamicRefresh(configContent, null);
dynamicRefresh(configContent, new HashMap<>());
}
@Override
public void dynamicRefresh(String configContent, Map<String, Object> newValueChangeMap) {
try {
Map<Object, Object> configInfo = ConfigParserHandler.getInstance().parseConfig(configContent, bootstrapConfigProperties.getConfigFileType());
BootstrapConfigProperties actualBootstrapConfigProperties = (BootstrapConfigProperties) bootstrapConfigProperties;
Map<Object, Object> configInfo = ConfigParserHandler.getInstance().parseConfig(configContent, actualBootstrapConfigProperties.getConfigFileType());
if (CollectionUtil.isNotEmpty(newValueChangeMap)) {
Optional.ofNullable(configInfo).ifPresent(each -> each.putAll(newValueChangeMap));
}
BootstrapConfigProperties binderCoreProperties = bootstrapConfigPropertiesBinderAdapt.bootstrapCorePropertiesBinder(configInfo, bootstrapConfigProperties);
publishDynamicThreadPoolEvent(binderCoreProperties);
BootstrapPropertiesInterface binderCoreProperties = bootstrapConfigPropertiesBinderAdapter.bootstrapCorePropertiesBinder(configInfo, bootstrapConfigProperties);
publishDynamicThreadPoolEvent((BootstrapConfigProperties) binderCoreProperties);
} catch (Exception ex) {
log.error("Hippo4j config mode dynamic refresh failed.", ex);
}
@ -84,7 +88,7 @@ public abstract class AbstractConfigThreadPoolDynamicRefresh implements ThreadPo
@Override
public void run(ApplicationArguments args) {
try {
publishDynamicThreadPoolEvent(bootstrapConfigProperties);
publishDynamicThreadPoolEvent((BootstrapConfigProperties) bootstrapConfigProperties);
} catch (Exception ex) {
log.error("Hippo4j failed to initialize update configuration.", ex);
}

@ -45,10 +45,11 @@ public class ApolloRefresherHandler extends AbstractConfigThreadPoolDynamicRefre
public void registerListener() {
String[] apolloNamespaces = this.namespace.split(",");
this.namespace = apolloNamespaces[0];
Config config = ConfigService.getConfig(String.format("%s.%s", namespace, bootstrapConfigProperties.getConfigFileType().getValue()));
BootstrapConfigProperties actualBootstrapConfigProperties = (BootstrapConfigProperties) bootstrapConfigProperties;
Config config = ConfigService.getConfig(String.format("%s.%s", namespace, actualBootstrapConfigProperties.getConfigFileType().getValue()));
ConfigChangeListener configChangeListener = configChangeEvent -> {
String namespace = this.namespace.replaceAll("." + bootstrapConfigProperties.getConfigFileType().getValue(), "");
ConfigFileFormat configFileFormat = ConfigFileFormat.fromString(bootstrapConfigProperties.getConfigFileType().getValue());
String namespace = this.namespace.replaceAll("." + actualBootstrapConfigProperties.getConfigFileType().getValue(), "");
ConfigFileFormat configFileFormat = ConfigFileFormat.fromString(actualBootstrapConfigProperties.getConfigFileType().getValue());
ConfigFile configFile = ConfigService.getConfigFile(namespace, configFileFormat);
Map<String, Object> newChangeValueMap = new HashMap<>();
configChangeEvent.changedKeys().stream().filter(each -> each.contains(BootstrapConfigProperties.PREFIX)).forEach(each -> {

@ -18,6 +18,8 @@
package cn.hippo4j.config.springboot.starter.refresher;
import cn.hippo4j.config.springboot.starter.config.BootstrapConfigProperties;
import cn.hippo4j.threadpool.dynamic.api.BootstrapPropertiesInterface;
import cn.hippo4j.threadpool.dynamic.mode.config.refresher.BootstrapConfigPropertiesBinderAdapter;
import org.springframework.boot.context.properties.bind.Bindable;
import org.springframework.boot.context.properties.bind.Binder;
import org.springframework.boot.context.properties.source.ConfigurationPropertySource;
@ -28,7 +30,7 @@ import java.util.Map;
/**
* Bootstrap core properties binder adapt.
*/
public class DefaultBootstrapConfigPropertiesBinderAdapt implements BootstrapConfigPropertiesBinderAdapt {
public class DefaultBootstrapConfigPropertiesBinderAdapt implements BootstrapConfigPropertiesBinderAdapter {
/**
* Bootstrap core properties binder.
@ -38,7 +40,7 @@ public class DefaultBootstrapConfigPropertiesBinderAdapt implements BootstrapCon
* @return
*/
@Override
public BootstrapConfigProperties bootstrapCorePropertiesBinder(Map<Object, Object> configInfo, BootstrapConfigProperties bootstrapConfigProperties) {
public BootstrapPropertiesInterface bootstrapCorePropertiesBinder(Map<Object, Object> configInfo, BootstrapPropertiesInterface bootstrapConfigProperties) {
ConfigurationPropertySource sources = new MapConfigurationPropertySource(configInfo);
Binder binder = new Binder(sources);
return binder.bind(BootstrapConfigProperties.PREFIX, Bindable.ofInstance(bootstrapConfigProperties)).get();

@ -19,6 +19,7 @@ package cn.hippo4j.config.springboot.starter.refresher;
import cn.hippo4j.common.toolkit.JSONUtil;
import cn.hippo4j.common.toolkit.StringUtil;
import cn.hippo4j.config.springboot.starter.config.BootstrapConfigProperties;
import io.etcd.jetcd.ByteSequence;
import io.etcd.jetcd.Client;
import io.etcd.jetcd.ClientBuilder;
@ -59,7 +60,8 @@ public class EtcdRefresherHandler extends AbstractConfigThreadPoolDynamicRefresh
@SneakyThrows(value = {InterruptedException.class, ExecutionException.class})
@Override
public void registerListener() {
Map<String, String> etcd = bootstrapConfigProperties.getEtcd();
BootstrapConfigProperties actualBootstrapConfigProperties = (BootstrapConfigProperties) bootstrapConfigProperties;
Map<String, String> etcd = actualBootstrapConfigProperties.getEtcd();
String key = etcd.get(KEY);
Charset charset = StringUtil.isBlank(etcd.get(CHARSET)) ? StandardCharsets.UTF_8 : Charset.forName(etcd.get(CHARSET));
initClient(etcd, charset);

@ -17,6 +17,7 @@
package cn.hippo4j.config.springboot.starter.refresher;
import cn.hippo4j.config.springboot.starter.config.BootstrapConfigProperties;
import cn.hippo4j.core.config.ApplicationContextHolder;
import com.alibaba.cloud.nacos.NacosConfigProperties;
import com.alibaba.nacos.api.config.ConfigService;
@ -47,7 +48,8 @@ public class NacosCloudRefresherHandler extends AbstractConfigThreadPoolDynamicR
@SneakyThrows(NacosException.class)
@Override
public void registerListener() {
Map<String, String> nacosConfig = bootstrapConfigProperties.getNacos();
BootstrapConfigProperties actualBootstrapConfigProperties = (BootstrapConfigProperties) bootstrapConfigProperties;
Map<String, String> nacosConfig = actualBootstrapConfigProperties.getNacos();
configService.addListener(nacosConfig.get(DATA_ID),
nacosConfig.get(GROUP), new Listener() {

@ -17,6 +17,7 @@
package cn.hippo4j.config.springboot.starter.refresher;
import cn.hippo4j.config.springboot.starter.config.BootstrapConfigProperties;
import com.alibaba.nacos.api.annotation.NacosInjected;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.listener.Listener;
@ -47,8 +48,8 @@ public class NacosRefresherHandler extends AbstractConfigThreadPoolDynamicRefres
@SneakyThrows(NacosException.class)
@Override
public void registerListener() {
Map<String, String> nacosConfig = bootstrapConfigProperties.getNacos();
BootstrapConfigProperties actualBootstrapConfigProperties = (BootstrapConfigProperties) bootstrapConfigProperties;
Map<String, String> nacosConfig = actualBootstrapConfigProperties.getNacos();
configService.addListener(nacosConfig.get(DATA_ID), nacosConfig.get(GROUP),
new Listener() {

@ -17,6 +17,7 @@
package cn.hippo4j.config.springboot.starter.refresher;
import cn.hippo4j.config.springboot.starter.config.BootstrapConfigProperties;
import cn.hippo4j.message.service.GlobalNotifyAlarmManage;
import cn.hippo4j.message.service.ThreadPoolNotifyAlarm;
import lombok.extern.slf4j.Slf4j;
@ -57,7 +58,8 @@ public class ZookeeperRefresherHandler extends AbstractConfigThreadPoolDynamicRe
@Override
public void registerListener() {
Map<String, String> zkConfigs = bootstrapConfigProperties.getZookeeper();
BootstrapConfigProperties actualBootstrapConfigProperties = (BootstrapConfigProperties) bootstrapConfigProperties;
Map<String, String> zkConfigs = actualBootstrapConfigProperties.getZookeeper();
curatorFramework = CuratorFrameworkFactory.newClient(zkConfigs.get(ZK_CONNECT_STR),
new ExponentialBackoffRetry(BASE_SLEEP_TIME_MS, MAX_RETRIES));
String nodePath = ZKPaths.makePath(ZKPaths.makePath(zkConfigs.get(ROOT_NODE),
@ -134,7 +136,8 @@ public class ZookeeperRefresherHandler extends AbstractConfigThreadPoolDynamicRe
* Register notify alarm manage.
*/
public void registerNotifyAlarmManage() {
bootstrapConfigProperties.getExecutors().forEach(executorProperties -> {
BootstrapConfigProperties actualBootstrapConfigProperties = (BootstrapConfigProperties) bootstrapConfigProperties;
actualBootstrapConfigProperties.getExecutors().forEach(executorProperties -> {
ThreadPoolNotifyAlarm threadPoolNotifyAlarm = new ThreadPoolNotifyAlarm(
executorProperties.getAlarm(),
executorProperties.getCapacityAlarm(),

@ -18,7 +18,7 @@
package cn.hippo4j.springboot.starter.config;
import cn.hippo4j.common.constant.Constants;
import cn.hippo4j.core.config.BootstrapPropertiesInterface;
import cn.hippo4j.threadpool.dynamic.api.BootstrapPropertiesInterface;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;

@ -19,6 +19,11 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>cn.hippo4j</groupId>
<artifactId>hippo4j-threadpool-dynamic-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>

@ -18,8 +18,8 @@
package cn.hippo4j.core.enable;
import cn.hippo4j.common.toolkit.StringUtil;
import cn.hippo4j.core.config.BootstrapPropertiesInterface;
import cn.hippo4j.core.config.ConfigEmptyException;
import cn.hippo4j.threadpool.dynamic.api.BootstrapPropertiesInterface;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
@ -40,6 +40,7 @@ public class BeforeCheckConfiguration {
@Bean
public BeforeCheckConfiguration.BeforeCheck dynamicThreadPoolBeforeCheckBean(@Autowired(required = false) BootstrapPropertiesInterface properties,
ConfigurableEnvironment environment) {
// TODO test
boolean checkFlag = properties != null && Objects.equals(bootstrapPropertiesClassName, properties.getClass().getName()) && properties.getEnable();
if (checkFlag) {
String namespace = properties.getNamespace();

@ -18,7 +18,7 @@
package cn.hippo4j.core.executor.handler;
import cn.hippo4j.common.toolkit.StringUtil;
import cn.hippo4j.core.config.BootstrapPropertiesInterface;
import cn.hippo4j.threadpool.dynamic.api.BootstrapPropertiesInterface;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.ansi.AnsiColor;

@ -24,6 +24,7 @@ import lombok.Data;
*/
@Data
public class LoginUser {
/**
* encode key reverse
*/

@ -1,3 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.hippo4j.auth.toolkit;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
@ -30,15 +47,15 @@ public class AESUtil {
* @return byte[]
*/
public static byte[] encrypt(byte[] data, byte[] key) throws GeneralSecurityException {
SecretKeySpec sKeySpec = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance(AES_GCM_CIPHER);
cipher.init(Cipher.ENCRYPT_MODE, sKeySpec);
byte[] iv = cipher.getIV();
byte[] encryptData = cipher.doFinal(data);
byte[] message = new byte[12 + data.length + 16];
System.arraycopy(iv, 0, message, 0, 12);
System.arraycopy(encryptData, 0, message, 12, encryptData.length);
return message;
SecretKeySpec sKeySpec = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance(AES_GCM_CIPHER);
cipher.init(Cipher.ENCRYPT_MODE, sKeySpec);
byte[] iv = cipher.getIV();
byte[] encryptData = cipher.doFinal(data);
byte[] message = new byte[12 + data.length + 16];
System.arraycopy(iv, 0, message, 0, 12);
System.arraycopy(encryptData, 0, message, 12, encryptData.length);
return message;
}
/**
@ -48,12 +65,12 @@ public class AESUtil {
* @param key Decryption key
* @return byte[]
*/
public static byte[] decrypt(byte[] data, byte[] key) throws GeneralSecurityException{
GCMParameterSpec iv = new GCMParameterSpec(128, data, 0, 12);
Cipher cipher = Cipher.getInstance(AES_GCM_CIPHER);
SecretKey key2 = new SecretKeySpec(key, "AES");
cipher.init(Cipher.DECRYPT_MODE, key2, iv);
return cipher.doFinal(data, 12, data.length - 12);
public static byte[] decrypt(byte[] data, byte[] key) throws GeneralSecurityException {
GCMParameterSpec iv = new GCMParameterSpec(128, data, 0, 12);
Cipher cipher = Cipher.getInstance(AES_GCM_CIPHER);
SecretKey key2 = new SecretKeySpec(key, "AES");
cipher.init(Cipher.DECRYPT_MODE, key2, iv);
return cipher.doFinal(data, 12, data.length - 12);
}
/**

Loading…
Cancel
Save