mirror of https://github.com/longtai-cn/hippo4j
parent
be122d5d11
commit
9800d6c011
@ -0,0 +1,87 @@
|
|||||||
|
/*
|
||||||
|
* 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.agent.plugin.apollo;
|
||||||
|
|
||||||
|
import cn.hippo4j.agent.plugin.spring.common.conf.SpringBootConfig;
|
||||||
|
import cn.hippo4j.agent.plugin.spring.common.toolkit.SpringPropertyBinder;
|
||||||
|
import cn.hippo4j.common.logging.api.ILog;
|
||||||
|
import cn.hippo4j.common.logging.api.LogManager;
|
||||||
|
import cn.hippo4j.threadpool.dynamic.mode.config.properties.BootstrapConfigProperties;
|
||||||
|
import cn.hippo4j.threadpool.dynamic.mode.config.refresher.AbstractConfigThreadPoolDynamicRefresh;
|
||||||
|
import com.ctrip.framework.apollo.Config;
|
||||||
|
import com.ctrip.framework.apollo.ConfigChangeListener;
|
||||||
|
import com.ctrip.framework.apollo.ConfigFile;
|
||||||
|
import com.ctrip.framework.apollo.ConfigService;
|
||||||
|
import com.ctrip.framework.apollo.core.enums.ConfigFileFormat;
|
||||||
|
import com.ctrip.framework.apollo.model.ConfigChange;
|
||||||
|
import org.springframework.boot.context.properties.bind.Binder;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static cn.hippo4j.agent.core.conf.Constants.SPRING_BOOT_CONFIG_PREFIX;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dynamic thread pool change handler
|
||||||
|
*/
|
||||||
|
public class ApolloDynamicThreadPoolChangeHandler extends AbstractConfigThreadPoolDynamicRefresh {
|
||||||
|
|
||||||
|
private static final ILog LOGGER = LogManager.getLogger(ApolloDynamicThreadPoolChangeHandler.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a listener with Apollo to monitor for changes in the thread pool configuration.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void registerListener() {
|
||||||
|
List<String> apolloNamespaces = SpringBootConfig.Spring.Dynamic.Thread_Pool.Apollo.NAMESPACE;
|
||||||
|
String namespace = apolloNamespaces.get(0);
|
||||||
|
String configFileType = SpringBootConfig.Spring.Dynamic.Thread_Pool.CONFIG_FILE_TYPE;
|
||||||
|
Config config = ConfigService.getConfig(String.format("%s.%s", namespace, configFileType));
|
||||||
|
ConfigChangeListener configChangeListener = configChangeEvent -> {
|
||||||
|
String replacedNamespace = namespace.replaceAll("." + configFileType, "");
|
||||||
|
ConfigFileFormat configFileFormat = ConfigFileFormat.fromString(configFileType);
|
||||||
|
ConfigFile configFile = ConfigService.getConfigFile(replacedNamespace, configFileFormat);
|
||||||
|
Map<String, Object> newChangeValueMap = new HashMap<>();
|
||||||
|
configChangeEvent.changedKeys().stream().filter(each -> each.contains(SPRING_BOOT_CONFIG_PREFIX)).forEach(each -> {
|
||||||
|
ConfigChange change = configChangeEvent.getChange(each);
|
||||||
|
String newValue = change.getNewValue();
|
||||||
|
newChangeValueMap.put(each, newValue);
|
||||||
|
});
|
||||||
|
dynamicRefresh(configFileType, configFile.getContent(), newChangeValueMap);
|
||||||
|
};
|
||||||
|
config.addChangeListener(configChangeListener);
|
||||||
|
LOGGER.info("[Hippo4j-Agent] Dynamic thread pool refresher, add apollo listener success. namespace: {}", namespace);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds and binds the {@link BootstrapConfigProperties} from the given configuration map.
|
||||||
|
* <p>
|
||||||
|
* This method uses Spring's {@link Binder} to bind the configuration values to an instance
|
||||||
|
* of {@link BootstrapConfigProperties}, which can then be used to configure the thread pool
|
||||||
|
* dynamically.
|
||||||
|
*
|
||||||
|
* @param configInfo the configuration map containing properties to bind.
|
||||||
|
* @return the bound {@link BootstrapConfigProperties} instance.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public BootstrapConfigProperties buildBootstrapProperties(Map<Object, Object> configInfo) {
|
||||||
|
BootstrapConfigProperties bindableBootstrapConfigProperties = SpringPropertyBinder.bindProperties(configInfo, BootstrapConfigProperties.PREFIX, BootstrapConfigProperties.class);
|
||||||
|
return bindableBootstrapConfigProperties;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package cn.hippo4j.agent.plugin.apollo.interceptor;
|
||||||
|
|
||||||
|
import cn.hippo4j.agent.core.plugin.interceptor.enhance.EnhancedInstance;
|
||||||
|
import cn.hippo4j.agent.core.plugin.interceptor.enhance.InstanceConstructorInterceptor;
|
||||||
|
import cn.hippo4j.agent.plugin.apollo.listeners.ApolloConfigPropertiesLoaderCompletedListener;
|
||||||
|
import cn.hippo4j.common.extension.design.AbstractSubjectCenter;
|
||||||
|
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default config constructor interceptor
|
||||||
|
*/
|
||||||
|
public class ApolloConfigConstructorInterceptor implements InstanceConstructorInterceptor {
|
||||||
|
|
||||||
|
private static final AtomicBoolean isExecuted = new AtomicBoolean(false);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onConstruct(EnhancedInstance objInst, Object[] allArguments) throws Throwable {
|
||||||
|
|
||||||
|
// This logic will only be executed once
|
||||||
|
if (isExecuted.compareAndSet(false, true)) {
|
||||||
|
// The Apollo plugin triggers before the Spring configuration plug-in.
|
||||||
|
// This means that when the Apollo plug-in executes, Spring's Environment is not yet ready,
|
||||||
|
// so the configuration cannot be read
|
||||||
|
// After listening to the AGENT_SPRING_PROPERTIES_LOADER_COMPLETED event, register the listener for Apollo
|
||||||
|
AbstractSubjectCenter.register(AbstractSubjectCenter.SubjectType.AGENT_SPRING_PROPERTIES_LOADER_COMPLETED,
|
||||||
|
new ApolloConfigPropertiesLoaderCompletedListener());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* 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.agent.plugin.apollo.listeners;
|
||||||
|
|
||||||
|
import cn.hippo4j.agent.plugin.apollo.ApolloDynamicThreadPoolChangeHandler;
|
||||||
|
import cn.hippo4j.common.extension.design.Observer;
|
||||||
|
import cn.hippo4j.common.extension.design.ObserverMessage;
|
||||||
|
import cn.hippo4j.threadpool.dynamic.api.ThreadPoolDynamicRefresh;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apollo Config Properties Loader Completed Listener
|
||||||
|
*/
|
||||||
|
public class ApolloConfigPropertiesLoaderCompletedListener implements Observer<String> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(ObserverMessage<String> observerMessage) {
|
||||||
|
ThreadPoolDynamicRefresh dynamicRefresh = new ApolloDynamicThreadPoolChangeHandler();
|
||||||
|
dynamicRefresh.registerListener();
|
||||||
|
}
|
||||||
|
}
|
@ -1,71 +0,0 @@
|
|||||||
/*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
|
||||||
* this work for additional information regarding copyright ownership.
|
|
||||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
|
||||||
* (the "License"); you may not use this file except in compliance with
|
|
||||||
* the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package cn.hippo4j.agent.plugin.spring.boot.v1;
|
|
||||||
|
|
||||||
import cn.hippo4j.common.toolkit.MapUtil;
|
|
||||||
import cn.hippo4j.threadpool.dynamic.mode.config.properties.BootstrapConfigProperties;
|
|
||||||
import cn.hippo4j.threadpool.dynamic.mode.config.refresher.AbstractConfigThreadPoolDynamicRefresh;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import org.springframework.beans.PropertyValues;
|
|
||||||
import org.springframework.beans.support.ResourceEditorRegistrar;
|
|
||||||
import org.springframework.boot.bind.CustomPropertyNamePatternsMatcher;
|
|
||||||
import org.springframework.boot.bind.RelaxedDataBinder;
|
|
||||||
import org.springframework.boot.bind.RelaxedNames;
|
|
||||||
import org.springframework.context.ConfigurableApplicationContext;
|
|
||||||
import org.springframework.core.env.MapPropertySource;
|
|
||||||
import org.springframework.core.env.MutablePropertySources;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import static cn.hippo4j.config.springboot1x.starter.refresher.SpringBoot1xBootstrapConfigPropertiesBinderAdapter.getNames;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Dynamic thread pool change handler spring 1x
|
|
||||||
*/
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
public class DynamicThreadPoolChangeHandlerSpring1x extends AbstractConfigThreadPoolDynamicRefresh {
|
|
||||||
|
|
||||||
private final ConfigurableApplicationContext applicationContext;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BootstrapConfigProperties buildBootstrapProperties(Map<Object, Object> configInfo) {
|
|
||||||
BootstrapConfigProperties bindableCoreProperties = new BootstrapConfigProperties();
|
|
||||||
if (MapUtil.isEmpty(configInfo)) {
|
|
||||||
return bindableCoreProperties;
|
|
||||||
}
|
|
||||||
RelaxedNames relaxedNames = new RelaxedNames(BootstrapConfigProperties.PREFIX);
|
|
||||||
Set<String> names = getNames(bindableCoreProperties, relaxedNames);
|
|
||||||
Map<String, Object> stringConfigInfo = new HashMap<>(configInfo.size());
|
|
||||||
configInfo.forEach((key, value) -> stringConfigInfo.put(key.toString(), value));
|
|
||||||
MapPropertySource test = new MapPropertySource("Hippo4j", stringConfigInfo);
|
|
||||||
MutablePropertySources propertySources = new MutablePropertySources();
|
|
||||||
propertySources.addFirst(test);
|
|
||||||
PropertyValues propertyValues = CustomPropertyNamePatternsMatcher.getPropertySourcesPropertyValues(names, propertySources);
|
|
||||||
RelaxedDataBinder dataBinder = new RelaxedDataBinder(bindableCoreProperties, BootstrapConfigProperties.PREFIX);
|
|
||||||
dataBinder.setAutoGrowCollectionLimit(Integer.MAX_VALUE);
|
|
||||||
dataBinder.setIgnoreNestedProperties(false);
|
|
||||||
dataBinder.setIgnoreInvalidFields(false);
|
|
||||||
dataBinder.setIgnoreUnknownFields(true);
|
|
||||||
ResourceEditorRegistrar resourceEditorRegistrar = new ResourceEditorRegistrar(applicationContext, applicationContext.getEnvironment());
|
|
||||||
resourceEditorRegistrar.registerCustomEditors(dataBinder);
|
|
||||||
dataBinder.bind(propertyValues);
|
|
||||||
return bindableCoreProperties;
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,83 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>cn.hippo4j</groupId>
|
||||||
|
<artifactId>hippo4j-threadpool-agent-example</artifactId>
|
||||||
|
<version>2.0.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>hippo4j-threadpool-agent-config-apollo-spring-boot-1x</artifactId>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.deploy.skip>true</maven.deploy.skip>
|
||||||
|
<spring-boot.version>1.5.22.RELEASE</spring-boot.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.hippo4j</groupId>
|
||||||
|
<artifactId>hippo4j-agent-example-core</artifactId>
|
||||||
|
<version>${revision}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.ctrip.framework.apollo</groupId>
|
||||||
|
<artifactId>apollo-client</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.slf4j</groupId>
|
||||||
|
<artifactId>slf4j-api</artifactId>
|
||||||
|
<version>1.7.21</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-context</artifactId>
|
||||||
|
<version>1.3.6.RELEASE</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<dependencyManagement>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-dependencies</artifactId>
|
||||||
|
<version>${spring-boot.version}</version>
|
||||||
|
<type>pom</type>
|
||||||
|
<scope>import</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</dependencyManagement>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<finalName>${project.artifactId}</finalName>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>repackage</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
15
agent/hippo4j-agent-plugin/apollo-plugin/src/main/java/cn/hippo4j/agent/plugin/apollo/interceptor/DefaultConfigConstructorInterceptor.java → examples/threadpool-example/agent/config-apollo-spring-boot-1x/src/main/java/cn/hippo4j/example/agent/config/apollo/v1/AgentConfigApolloSpringBoot1xExampleApplication.java
15
agent/hippo4j-agent-plugin/apollo-plugin/src/main/java/cn/hippo4j/agent/plugin/apollo/interceptor/DefaultConfigConstructorInterceptor.java → examples/threadpool-example/agent/config-apollo-spring-boot-1x/src/main/java/cn/hippo4j/example/agent/config/apollo/v1/AgentConfigApolloSpringBoot1xExampleApplication.java
Loading…
Reference in new issue