Commit e8c4d608 authored by biao.dong's avatar biao.dong

Initial commit

parents
/mvnw text eol=lf
*.cmd text eol=crlf
Readme.md
target/
.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.quantgroup</groupId>
<artifactId>eos-config-loader</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<name>eos-config-loader</name>
<description>eos-config-loader</description>
<properties>
<java.version>17</java.version>
<spring.boot.version>3.4.9</spring.boot.version>
<spring.version>6.2.10</spring.version>
</properties>
<dependencies>
<!-- 只用于编译,不传递给使用方 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
<version>${spring.boot.version}</version>
<optional>true</optional>
</dependency>
<!-- 只用于编译,不传递给使用方 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>${spring.boot.version}</version>
<optional>true</optional>
</dependency>
<!-- 只用于编译,不传递给使用方 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
<optional>true</optional>
</dependency>
<!-- RestTemplate / ResponseEntity -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<plugins>
<!-- Java 17 编译 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
package com.quantgroup.eos.configuration;
import java.util.ArrayList;
import java.util.Collections;
import org.springframework.boot.context.config.ConfigData;
import org.springframework.boot.context.config.ConfigDataLoader;
import org.springframework.boot.context.config.ConfigDataLoaderContext;
import org.springframework.boot.logging.DeferredLog;
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.log.LogMessage;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
/**
* 测试环境 通过Spring Boot Config Data Loader 模式来加载配置 测试环境 mysql、redis 等服务地址及端口号
* 获取 eos 配置信息 API :
* 如:<a href="http://eos.quantgroups.com/api/apollo/env_vars?namespace=yxm">...</a>
* 此类配置信息加载完成后,交由 spring 管理
*/
public class EosConfigDataLoader implements ConfigDataLoader<EosConfigDataResource> {
private static final String NAMESPACE = "NAMESPACE";
private static final String ENV = "env";
private static final String ENV_DEV = "dev";
private static final String EOS_SERVER_HOST = "EOS_SERVER_HOST";
@Override
public ConfigData load(ConfigDataLoaderContext context, EosConfigDataResource resource) {
DeferredLog logger = context.getBootstrapContext().get(DeferredLog.class);
String env = System.getProperty(ENV);
String namespace = System.getProperty(NAMESPACE);
logger.info(LogMessage.of(() -> "Loading configuration from eos_server , env : " + env + " , NAMESPACE : " + namespace ));
if(!ENV_DEV.equals(env)) {
logger.info(LogMessage.of(() -> "Wow, the production environment. The configuration center is quiet. I dare not do anything." ));
return new ConfigData(new ArrayList<>());
}
// When the namespace is not empty, the configuration can be loaded from the eos server.
if (namespace == null || namespace.trim().isEmpty()) {
logger.info(LogMessage.of(() -> "You don't seem to have configured NAMESPACE, right? Aren't you going to connect to the internal kubernetes?" ));
return new ConfigData(new ArrayList<>());
}
try {
RestTemplate restTemplate = new RestTemplate();
String kubernetesServer = System.getProperty(EOS_SERVER_HOST, "http://eos.quantgroups.com/");
String url = kubernetesServer + "api/apollo/env_vars?namespace=" + namespace;
ResponseEntity<EosConfigInfo> response = restTemplate.getForEntity(url, EosConfigInfo.class);
EosConfigInfo envInfo = response.getBody();
if (envInfo != null && envInfo.isSuccess() && envInfo.getDetails() != null) {
logger.info(LogMessage.of(() -> "The environment variables of kubernets have been init successed, and you can rest assured to start your service outside of kubernetes." ));
return new ConfigData(
Collections.singletonList(new MapPropertySource("eosConfig", envInfo.getDetails())));
}
} catch (Exception e) {
logger.error(LogMessage.of(() -> "The environment variable injection of kubernets failed, please troubleshoot."),e);
return new ConfigData(new ArrayList<>());
}
return new ConfigData(new ArrayList<>());
}
}
\ No newline at end of file
package com.quantgroup.eos.configuration;
import java.util.Collections;
import java.util.List;
import org.springframework.boot.context.config.ConfigDataLocation;
import org.springframework.boot.context.config.ConfigDataLocationResolver;
import org.springframework.boot.context.config.ConfigDataLocationResolverContext;
import org.springframework.boot.context.config.ConfigDataResourceNotFoundException;
import org.springframework.boot.context.config.Profiles;
public class EosConfigDataLocationResolver implements
ConfigDataLocationResolver<EosConfigDataResource> {
private static final String PREFIX = "qg-eos:";
@Override
public boolean isResolvable(ConfigDataLocationResolverContext context, ConfigDataLocation location) {
return location.hasPrefix(PREFIX);
}
@Override
public List<EosConfigDataResource> resolve(ConfigDataLocationResolverContext context, ConfigDataLocation location)
throws ConfigDataResourceNotFoundException {
String namespace = location.getNonPrefixedValue(PREFIX);
return Collections.singletonList(new EosConfigDataResource(namespace));
}
@Override
public List<EosConfigDataResource> resolveProfileSpecific(ConfigDataLocationResolverContext context,
ConfigDataLocation location, Profiles profiles) throws ConfigDataResourceNotFoundException {
return resolve(context, location);
}
}
package com.quantgroup.eos.configuration;
import java.util.Objects;
import org.springframework.boot.context.config.ConfigDataResource;
public class EosConfigDataResource extends ConfigDataResource {
private final String namespace;
public EosConfigDataResource(String namespace) {
this.namespace = namespace;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof EosConfigDataResource that)) return false;
return Objects.equals(namespace, that.namespace);
}
@Override
public int hashCode() {
return Objects.hash(namespace);
}
@Override
public String toString() {
return "EosConfigDataResource{" +
"namespace='" + namespace + '\'' +
'}';
}
public String getNamespace() {
return namespace;
}
}
package com.quantgroup.eos.configuration;
import java.util.Map;
public class EosConfigInfo {
private boolean success;
private Map<String, Object> details;
public boolean isSuccess() {
return success;
}
public void setSuccess(boolean success) {
this.success = success;
}
public Map<String, Object> getDetails() {
return details;
}
public void setDetails(Map<String, Object> details) {
this.details = details;
}
}
package com.quantgroup.eos.logging;
import com.quantgroup.eos.configuration.EosConfigDataLoader;
import org.springframework.boot.BootstrapRegistry;
import org.springframework.boot.BootstrapRegistryInitializer;
import org.springframework.boot.logging.DeferredLog;
/**
* spring 启动早期,日志系统尚未加载,通过DeferredLog记录日志,在 spring 日志启动完成后进行重播
* @author biao
* @since 2025-09-12
*/
public class EarlyLoggingInitializer implements BootstrapRegistryInitializer {
@Override
public void initialize(BootstrapRegistry registry) {
// 创建并立即使用日志记录器
DeferredLog logger = new DeferredLog();
// 将日志记录器注册到BootstrapRegistry中
registry.register(DeferredLog.class, context -> logger);
registry.addCloseListener(event -> logger.switchTo(EosConfigDataLoader.class));
}
}
org.springframework.boot.BootstrapRegistryInitializer=com.quantgroup.eos.logging.EarlyLoggingInitializer
org.springframework.boot.context.config.ConfigDataLocationResolver=com.quantgroup.eos.configuration.EosConfigDataLocationResolver
org.springframework.boot.context.config.ConfigDataLoader=com.quantgroup.eos.configuration.EosConfigDataLoader
spring.application.name=eos-config-loader
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment