Commit 4f8a3d2a by 张子昊

第一版

parents
.idea/
log/
**/log/
logs/
**/logs/
target/
**/target/
# 默认忽略的文件
/shelf/
/workspace.xml
# 基于编辑器的 HTTP 客户端请求
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="file://$PROJECT_DIR$/eureka-server/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/eureka-server/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/gateway/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/gateway/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
<file url="PROJECT" charset="UTF-8" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="MavenProjectsManager">
<option name="originalFiles">
<list>
<option value="$PROJECT_DIR$/pom.xml" />
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>
\ No newline at end of file
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="EurekaServer" type="SpringBootApplicationConfigurationType" factoryName="Spring Boot" activateToolWindowBeforeRun="false" nameIsGenerated="true">
<module name="eureka-server" />
<option name="SPRING_BOOT_MAIN_CLASS" value="com.winsun.clolud.server.EurekaServer" />
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
</component>
\ No newline at end of file
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="GatewayApplication" type="SpringBootApplicationConfigurationType" factoryName="Spring Boot" activateToolWindowBeforeRun="false" nameIsGenerated="true">
<option name="ACTIVE_PROFILES" value="test" />
<module name="gateway" />
<option name="SPRING_BOOT_MAIN_CLASS" value="com.winsun.cloud.gateway.GatewayApplication" />
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
</component>
\ No newline at end of file
<?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>com.winsun.cloud</groupId>
<artifactId>publicCloud</artifactId>
<version>1.0</version>
</parent>
<artifactId>eureka-server</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
package com.winsun.clolud.server;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer
public class EurekaServer {
public static void main(String[] args) {
SpringApplication.run(EurekaServer.class, args);
}
}
package com.winsun.clolud.server.config;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.Environment;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertiesPropertySource;
import org.springframework.core.io.ClassPathResource;
import org.springframework.lang.NonNull;
import java.util.Base64;
import java.util.Map;
import java.util.Properties;
/**
* @author denghengtong,zzh
* @version 3.0
*/
@Configuration
public class ResourcePlaceholderConfig {
/**
* 配置解密,只能自定义一个PropertySourcesPlaceholderConfigurer,否则会报异常
**/
static class EncryptPropertyPlaceholderConfigurer extends PropertySourcesPlaceholderConfigurer implements InitializingBean {
/**
* 需要解密的配置项前缀
*/
private static final String PREFIX_ENC = "ENC(";
private static final String SUFFIX_ENC = ")";
private static final String EMPTY = "";
private Environment environment;
@Override
public void setEnvironment(@NonNull Environment environment) {
this.environment = environment;
}
@Override
@NonNull
protected Properties mergeProperties() {
Properties mergedProperties = new Properties();
if (localProperties != null){
for (Properties localProp : localProperties) {
mergedProperties.putAll(localProp);
}
}
Properties waitAdd = new Properties();
for (Map.Entry entry : mergedProperties.entrySet()) {
if (entry.getValue().toString().startsWith(PREFIX_ENC)) {
//格式 xxxx.xxxx.xxxx 取最后一个节点解密
String key = entry.getKey().toString();
String[] keyArr = key.split("\\.");
int length = keyArr.length;
keyArr[length-1] = new String(Base64.getMimeDecoder().decode(keyArr[length-1]));
StringBuilder realKey = new StringBuilder();
for (String str: keyArr) {
realKey.append(str).append(".");
}
realKey.deleteCharAt(realKey.length() - 1);
String value = entry.getValue().toString().replace(PREFIX_ENC, EMPTY).replace(SUFFIX_ENC, EMPTY);
//因为解密后的key属于新的属性 所以此处set是新增一个节点 但因为在for循环 所以先存放到等待的队列中 结束后在统一添加
waitAdd.setProperty(realKey.toString(), new String(Base64.getDecoder().decode(value)));
}
}
waitAdd.forEach((key,value)-> mergedProperties.setProperty(key.toString(), value.toString()));
//针对sharding-jdbc datasource自定义解密的特殊处理
//因为sharding-jdbc的datasource注入是从environment中获取propertySource,
//不能直接通过PropertySourcesPlaceholderConfigurer定义的resource获取
MutablePropertySources sources = ((ConfigurableEnvironment) environment).getPropertySources();
sources.addFirst(new PropertiesPropertySource(LOCAL_PROPERTIES_PROPERTY_SOURCE_NAME, mergedProperties));
return mergedProperties;
}
@Override
public void afterPropertiesSet() {
localOverride = true;
}
}
@Bean
public PropertySourcesPlaceholderConfigurer propertyConfigurer(Environment env) {
PropertySourcesPlaceholderConfigurer config = new EncryptPropertyPlaceholderConfigurer();
YamlPropertiesFactoryBean yaml = new YamlPropertiesFactoryBean();
//获取环境变量,只能使用一个环境
String[] actives = env.getActiveProfiles();
if (actives.length == 0){
ClassPathResource bootstrap = new ClassPathResource("bootstrap.yml");
if (bootstrap.exists()){
System.out.println("使用 bootstrap配置 启动");
yaml.setResources(new ClassPathResource("bootstrap.yml"));
} else {
System.out.println("使用默认环境");
//指定需要解密的配置文件
yaml.setResources(new ClassPathResource("application.yml"));
}
} else {
if (actives.length != 1) {
System.out.println("未明确指定单一环境,系统自动关闭....");
System.exit(0);
throw new RuntimeException();
}
//指定需要解密的配置文件
yaml.setResources(new ClassPathResource("application-"+actives[0]+".yml"));
}
Properties properties = yaml.getObject();
config.setProperties(properties);
config.setIgnoreUnresolvablePlaceholders(true);
return config;
}
}
package com.winsun.clolud.server.config;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@EnableWebSecurity
public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().ignoringAntMatchers("/eureka/**");
super.configure(http);
}
}
\ No newline at end of file
server:
port: 7001
spring:
application:
name: public-eureka-server
security:
basic:
enabled: false
user:
name: name
password: password
eureka:
instance:
# 本地调试时,可以是localhost,实际上应为指向当前主机的域名,或使用ip模式
hostname: localhost
client:
registerWithEureka: false
fetchRegistry: false
serviceUrl:
defaultZone: http://${spring.security.user.name}:${spring.security.user.password}@${eureka.instance.hostname}:${server.port}/eureka/
# server:
# enable-self-preservation: false
\ No newline at end of file
<?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>com.winsun.cloud</groupId>
<artifactId>publicCloud</artifactId>
<version>1.0</version>
</parent>
<artifactId>gateway</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
package com.winsun.cloud.gateway;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@SpringBootApplication
@EnableEurekaClient
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
}
package com.winsun.cloud.gateway.com.config;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.Environment;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertiesPropertySource;
import org.springframework.core.io.ClassPathResource;
import org.springframework.lang.NonNull;
import java.util.Base64;
import java.util.Map;
import java.util.Properties;
/**
* @author denghengtong,zzh
* @version 3.0
*/
@Configuration
public class ResourcePlaceholderConfig {
/**
* 配置解密,只能自定义一个PropertySourcesPlaceholderConfigurer,否则会报异常
**/
static class EncryptPropertyPlaceholderConfigurer extends PropertySourcesPlaceholderConfigurer implements InitializingBean {
/**
* 需要解密的配置项前缀
*/
private static final String PREFIX_ENC = "ENC(";
private static final String SUFFIX_ENC = ")";
private static final String EMPTY = "";
private Environment environment;
@Override
public void setEnvironment(@NonNull Environment environment) {
this.environment = environment;
}
@Override
@NonNull
protected Properties mergeProperties() {
Properties mergedProperties = new Properties();
if (localProperties != null){
for (Properties localProp : localProperties) {
mergedProperties.putAll(localProp);
}
}
Properties waitAdd = new Properties();
for (Map.Entry entry : mergedProperties.entrySet()) {
if (entry.getValue().toString().startsWith(PREFIX_ENC)) {
//格式 xxxx.xxxx.xxxx 取最后一个节点解密
String key = entry.getKey().toString();
String[] keyArr = key.split("\\.");
int length = keyArr.length;
keyArr[length-1] = new String(Base64.getMimeDecoder().decode(keyArr[length-1]));
StringBuilder realKey = new StringBuilder();
for (String str: keyArr) {
realKey.append(str).append(".");
}
realKey.deleteCharAt(realKey.length() - 1);
String value = entry.getValue().toString().replace(PREFIX_ENC, EMPTY).replace(SUFFIX_ENC, EMPTY);
//因为解密后的key属于新的属性 所以此处set是新增一个节点 但因为在for循环 所以先存放到等待的队列中 结束后在统一添加
waitAdd.setProperty(realKey.toString(), new String(Base64.getDecoder().decode(value)));
}
}
waitAdd.forEach((key,value)-> mergedProperties.setProperty(key.toString(), value.toString()));
//针对sharding-jdbc datasource自定义解密的特殊处理
//因为sharding-jdbc的datasource注入是从environment中获取propertySource,
//不能直接通过PropertySourcesPlaceholderConfigurer定义的resource获取
MutablePropertySources sources = ((ConfigurableEnvironment) environment).getPropertySources();
sources.addFirst(new PropertiesPropertySource(LOCAL_PROPERTIES_PROPERTY_SOURCE_NAME, mergedProperties));
return mergedProperties;
}
@Override
public void afterPropertiesSet() {
localOverride = true;
}
}
@Bean
public PropertySourcesPlaceholderConfigurer propertyConfigurer(Environment env) {
PropertySourcesPlaceholderConfigurer config = new EncryptPropertyPlaceholderConfigurer();
YamlPropertiesFactoryBean yaml = new YamlPropertiesFactoryBean();
//获取环境变量,只能使用一个环境
String[] actives = env.getActiveProfiles();
if (actives.length == 0){
ClassPathResource bootstrap = new ClassPathResource("bootstrap.yml");
if (bootstrap.exists()){
System.out.println("使用 bootstrap配置 启动");
yaml.setResources(new ClassPathResource("bootstrap.yml"));
} else {
System.out.println("使用默认环境");
//指定需要解密的配置文件
yaml.setResources(new ClassPathResource("application.yml"));
}
} else {
if (actives.length != 1) {
System.out.println("未明确指定单一环境,系统自动关闭....");
System.exit(0);
throw new RuntimeException();
}
//指定需要解密的配置文件
yaml.setResources(new ClassPathResource("application-"+actives[0]+".yml"));
}
Properties properties = yaml.getObject();
config.setProperties(properties);
config.setIgnoreUnresolvablePlaceholders(true);
return config;
}
}
server:
port: 9998
spring:
application:
name: public-gateway
# 安全认证的配置
security:
user:
name: name
password: password
cloud:
gateway:
discovery:
locator:
# 开启从注册中心动态创建路由的功能,利用微服务进行路由
enabled: true
# 使用小写服务名,只能大写或小写,两者无法通过此配置兼容
lower-case-service-id: true
eureka:
server:
# 自定义配置,简化、统一配置逻辑
# target: localhost:7001
# 使用公司 eureka
target: 172.18.101.171:58336
instance:
# 实例host,本地调试时,可以是localhost,实际上应为指向当前主机的域名,或使用ip模式
hostname: localhost
client:
# 作为公共gateway,自身不注册,仅提供对外转发
# register-with-eureka: true
fetch-registry: true
service-url:
# defaultZone: http://${spring.security.user.name}:${spring.security.user.password}@${eureka.server.target}/eureka
defaultZone: http://${eureka.server.target}/eureka
\ No newline at end of file
server:
port: 9998
spring:
application:
name: public-gateway
# 安全认证的配置
security:
user:
name: name
password: password
cloud:
gateway:
discovery:
locator:
# 开启从注册中心动态创建路由的功能,利用微服务进行路由
enabled: true
# 使用小写服务名,只能大写或小写,两者无法通过此配置兼容
lower-case-service-id: true
eureka:
server:
# 自定义配置,简化、统一配置逻辑
target: localhost:7001
instance:
# 实例host,本地调试时,可以是localhost,实际上应为指向当前主机的域名,或使用ip模式
hostname: localhost
client:
# 作为公共gateway,自身不注册,仅提供对外转发
# register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://${spring.security.user.name}:${spring.security.user.password}@${eureka.server.target}/eureka
\ No newline at end of file
<?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>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.12.RELEASE</version>
</parent>
<groupId>com.winsun.cloud</groupId>
<artifactId>publicCloud</artifactId>
<version>1.0</version>
<packaging>pom</packaging>
<modules>
<module>eureka-server</module>
<module>gateway</module>
</modules>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<tomcat.version>9.0.65</tomcat.version>
<spring-cloud.version>Hoxton.SR11</spring-cloud.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
</project>
\ No newline at end of file
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