From 83f70c2f88d4c1aa7b77e7e1739ebe3413d7c43b Mon Sep 17 00:00:00 2001 From: Jesse-Ma <24167796@qq.com> Date: Thu, 21 Jul 2022 11:45:02 +0800 Subject: [PATCH] gateway --- .gitignore | 48 +++--- pom.xml | 81 ++++++++++ .../flagnote/gateway/GatewayApplication.java | 12 ++ .../config/ApiLimiterConfiguration.java | 28 ++++ .../gateway/config/WebFluxWebConfig.java | 15 ++ .../filter/ValidateNoteCipherFilter.java | 57 +++++++ .../gateway/filter/ValidateNoteKeyFilter.java | 47 ++++++ ...alidateNoteCipherGatewayFilterFactory.java | 39 +++++ .../ValidateNoteKeyGatewayFilterFactory.java | 61 ++++++++ .../resolver/RemoteAddrKeyResolver.java | 19 +++ .../resolver/RemoteSessionKeyResolver.java | 19 +++ .../flagnote/gateway/utils/BizKeyUtils.java | 100 ++++++++++++ .../flagnote/gateway/utils/RandomUtils.java | 15 ++ src/main/resources/application.yml | 143 ++++++++++++++++++ .../gateway/GatewayApplicationTests.java | 13 ++ 15 files changed, 678 insertions(+), 19 deletions(-) create mode 100644 pom.xml create mode 100644 src/main/java/com/flagnote/gateway/GatewayApplication.java create mode 100644 src/main/java/com/flagnote/gateway/config/ApiLimiterConfiguration.java create mode 100644 src/main/java/com/flagnote/gateway/config/WebFluxWebConfig.java create mode 100644 src/main/java/com/flagnote/gateway/filter/ValidateNoteCipherFilter.java create mode 100644 src/main/java/com/flagnote/gateway/filter/ValidateNoteKeyFilter.java create mode 100644 src/main/java/com/flagnote/gateway/filter/factory/ValidateNoteCipherGatewayFilterFactory.java create mode 100644 src/main/java/com/flagnote/gateway/filter/factory/ValidateNoteKeyGatewayFilterFactory.java create mode 100644 src/main/java/com/flagnote/gateway/resolver/RemoteAddrKeyResolver.java create mode 100644 src/main/java/com/flagnote/gateway/resolver/RemoteSessionKeyResolver.java create mode 100644 src/main/java/com/flagnote/gateway/utils/BizKeyUtils.java create mode 100644 src/main/java/com/flagnote/gateway/utils/RandomUtils.java create mode 100644 src/main/resources/application.yml create mode 100644 src/test/java/com/flagnote/gateway/GatewayApplicationTests.java diff --git a/.gitignore b/.gitignore index a1c2a23..549e00a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,23 +1,33 @@ -# Compiled class file -*.class +HELP.md +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ -# Log file -*.log +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache -# BlueJ files -*.ctxt +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr -# Mobile Tools for Java (J2ME) -.mtj.tmp/ +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ -# Package Files # -*.jar -*.war -*.nar -*.ear -*.zip -*.tar.gz -*.rar - -# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml -hs_err_pid* +### VS Code ### +.vscode/ diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..8c4b549 --- /dev/null +++ b/pom.xml @@ -0,0 +1,81 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.7.0 + + + com.flagnote + gateway + 0.0.1-SNAPSHOT + gateway + Demo project for Spring Boot + + 11 + 2021.0.3 + + + + org.springframework.boot + spring-boot-starter-data-redis-reactive + + + org.springframework.cloud + spring-cloud-starter-gateway + + + org.springframework.cloud + spring-cloud-starter-loadbalancer + + + org.projectlombok + lombok + true + + + cn.hutool + hutool-all + 5.7.22 + + + + + org.springframework.boot + spring-boot-starter-test + test + + + io.projectreactor + reactor-test + test + + + + + + org.springframework.cloud + spring-cloud-dependencies + ${spring-cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + \ No newline at end of file diff --git a/src/main/java/com/flagnote/gateway/GatewayApplication.java b/src/main/java/com/flagnote/gateway/GatewayApplication.java new file mode 100644 index 0000000..9569dc4 --- /dev/null +++ b/src/main/java/com/flagnote/gateway/GatewayApplication.java @@ -0,0 +1,12 @@ +package com.flagnote.gateway; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class GatewayApplication { + + public static void main(String[] args) { + SpringApplication.run(GatewayApplication.class, args); + } +} diff --git a/src/main/java/com/flagnote/gateway/config/ApiLimiterConfiguration.java b/src/main/java/com/flagnote/gateway/config/ApiLimiterConfiguration.java new file mode 100644 index 0000000..3a97d3b --- /dev/null +++ b/src/main/java/com/flagnote/gateway/config/ApiLimiterConfiguration.java @@ -0,0 +1,28 @@ +package com.flagnote.gateway.config; + +import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; + +import reactor.core.publisher.Mono; + +@Configuration +public class ApiLimiterConfiguration { + + @Bean(name="remoteSessionKeyResolver") + public KeyResolver remoteSessionKeyResolver() { + return exchange -> Mono.just(exchange.getSession().block().getId()); + } + + @Bean(name="noteKeyResolver") + public KeyResolver noteKeyResolver() { + return exchange -> Mono.just(exchange.getRequest().getPath().toString()); + } + + @Primary + @Bean(name="remoteAddrKeyResolver") + public KeyResolver remoteAddrKeyResolver() { + return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getAddress().getHostAddress()); + } +} \ No newline at end of file diff --git a/src/main/java/com/flagnote/gateway/config/WebFluxWebConfig.java b/src/main/java/com/flagnote/gateway/config/WebFluxWebConfig.java new file mode 100644 index 0000000..eac6eb0 --- /dev/null +++ b/src/main/java/com/flagnote/gateway/config/WebFluxWebConfig.java @@ -0,0 +1,15 @@ +package com.flagnote.gateway.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.http.codec.ServerCodecConfigurer; +import org.springframework.web.reactive.config.EnableWebFlux; +import org.springframework.web.reactive.config.WebFluxConfigurer; + +@Configuration +@EnableWebFlux +public class WebFluxWebConfig implements WebFluxConfigurer { + @Override + public void configureHttpMessageCodecs(ServerCodecConfigurer configurer) { + configurer.defaultCodecs().maxInMemorySize(2 * 1024 * 1024); + } +} diff --git a/src/main/java/com/flagnote/gateway/filter/ValidateNoteCipherFilter.java b/src/main/java/com/flagnote/gateway/filter/ValidateNoteCipherFilter.java new file mode 100644 index 0000000..6afc18a --- /dev/null +++ b/src/main/java/com/flagnote/gateway/filter/ValidateNoteCipherFilter.java @@ -0,0 +1,57 @@ +package com.flagnote.gateway.filter; + +import java.util.Map; + +import org.springframework.cloud.gateway.filter.GatewayFilter; +import org.springframework.cloud.gateway.filter.GatewayFilterChain; +import org.springframework.cloud.gateway.support.ServerWebExchangeUtils; +import org.springframework.core.Ordered; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Component; +import org.springframework.web.server.ServerWebExchange; + +import com.flagnote.gateway.utils.BizKeyUtils; + +import cn.hutool.json.JSON; +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; +import reactor.core.publisher.Mono; + +@Component +public class ValidateNoteCipherFilter implements GatewayFilter, Ordered { + + @Override + public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { + Map uriVariables = ServerWebExchangeUtils.getUriTemplateVariables(exchange); + String noteKey = uriVariables.get("key"); + + String requestBody = exchange.getAttribute(ServerWebExchangeUtils.CACHED_REQUEST_BODY_ATTR); + JSONObject body = JSONUtil.parseObj(requestBody); + String cipher = body.getStr("cipher"); + String key = body.getStr("key"); + + if (!noteKey.equals(key)) { + exchange.getResponse().setStatusCode(HttpStatus.BAD_REQUEST); + return exchange.getResponse().setComplete(); + } + + if (!BizKeyUtils.validateCipher(noteKey, cipher)) { + exchange.getResponse().setStatusCode(HttpStatus.BAD_REQUEST); + return exchange.getResponse().setComplete(); + } + + + return chain.filter(exchange); + } + + /** + * 优先级: 数字越小优先级越高 + * + * @return + */ + @Override + public int getOrder() { + return 2; + } + +} diff --git a/src/main/java/com/flagnote/gateway/filter/ValidateNoteKeyFilter.java b/src/main/java/com/flagnote/gateway/filter/ValidateNoteKeyFilter.java new file mode 100644 index 0000000..f47762b --- /dev/null +++ b/src/main/java/com/flagnote/gateway/filter/ValidateNoteKeyFilter.java @@ -0,0 +1,47 @@ +package com.flagnote.gateway.filter; + +import java.util.Map; + +import org.springframework.cloud.gateway.filter.GatewayFilter; +import org.springframework.cloud.gateway.filter.GatewayFilterChain; +import org.springframework.cloud.gateway.support.ServerWebExchangeUtils; +import org.springframework.core.Ordered; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Component; +import org.springframework.web.server.ServerWebExchange; + +import com.flagnote.gateway.utils.BizKeyUtils; + +import reactor.core.publisher.Mono; + +/** + * 全局过滤器 + */ +@Component +public class ValidateNoteKeyFilter implements GatewayFilter, Ordered { + + @Override + public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { + Map uriVariables = ServerWebExchangeUtils.getUriTemplateVariables(exchange); + + String noteKey = uriVariables.get("key"); + + if (!BizKeyUtils.validateKey(noteKey)) { + exchange.getResponse().setStatusCode(HttpStatus.BAD_REQUEST); + return exchange.getResponse().setComplete(); + } + + return chain.filter(exchange); + } + + /** + * 优先级: 数字越小优先级越高 + * + * @return + */ + @Override + public int getOrder() { + return Ordered.LOWEST_PRECEDENCE; + } + +} diff --git a/src/main/java/com/flagnote/gateway/filter/factory/ValidateNoteCipherGatewayFilterFactory.java b/src/main/java/com/flagnote/gateway/filter/factory/ValidateNoteCipherGatewayFilterFactory.java new file mode 100644 index 0000000..08503a8 --- /dev/null +++ b/src/main/java/com/flagnote/gateway/filter/factory/ValidateNoteCipherGatewayFilterFactory.java @@ -0,0 +1,39 @@ +package com.flagnote.gateway.filter.factory; + +import java.net.URI; +import java.util.Arrays; +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cloud.gateway.filter.GatewayFilter; +import org.springframework.cloud.gateway.filter.GatewayFilterChain; +import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory; +import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory.NameConfig; +import org.springframework.cloud.gateway.support.GatewayToStringStyler; +import org.springframework.stereotype.Component; +import org.springframework.web.server.ServerWebExchange; + +import com.flagnote.gateway.filter.ValidateNoteCipherFilter; + +import lombok.extern.slf4j.Slf4j; +import reactor.core.publisher.Mono; + +@Slf4j +@Component +public class ValidateNoteCipherGatewayFilterFactory + extends AbstractGatewayFilterFactory { + + @Autowired + private ValidateNoteCipherFilter validateNoteCipherFilter; + + + public ValidateNoteCipherGatewayFilterFactory() { + super(NameConfig.class); + } + + @Override + public GatewayFilter apply(NameConfig config) { + + return validateNoteCipherFilter; + } +} \ No newline at end of file diff --git a/src/main/java/com/flagnote/gateway/filter/factory/ValidateNoteKeyGatewayFilterFactory.java b/src/main/java/com/flagnote/gateway/filter/factory/ValidateNoteKeyGatewayFilterFactory.java new file mode 100644 index 0000000..cd9ad08 --- /dev/null +++ b/src/main/java/com/flagnote/gateway/filter/factory/ValidateNoteKeyGatewayFilterFactory.java @@ -0,0 +1,61 @@ +package com.flagnote.gateway.filter.factory; + +import java.net.URI; +import java.util.Arrays; +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cloud.gateway.filter.GatewayFilter; +import org.springframework.cloud.gateway.filter.GatewayFilterChain; +import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory; +import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory.NameConfig; +import org.springframework.cloud.gateway.support.GatewayToStringStyler; +import org.springframework.stereotype.Component; +import org.springframework.web.server.ServerWebExchange; + +import com.flagnote.gateway.filter.ValidateNoteKeyFilter; + +import lombok.extern.slf4j.Slf4j; +import reactor.core.publisher.Mono; + +@Slf4j +@Component +public class ValidateNoteKeyGatewayFilterFactory + extends AbstractGatewayFilterFactory { + + @Autowired + private ValidateNoteKeyFilter validateNoteKeyFilter; + + + public ValidateNoteKeyGatewayFilterFactory() { + super(NameConfig.class); + } + +// @Override +// public List shortcutFieldOrder() { +// return Arrays.asList("name"); +// } + + @Override + public GatewayFilter apply(NameConfig config) { + + return validateNoteKeyFilter; + +// return new GatewayFilter() { +// @Override +// public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { +// // 获取请求路径 +// URI uri = exchange.getRequest().getURI(); +// log.info("获取到请求路径:{}", uri.toString()); +// // +// log.info("配置属性:{}", config.getName()); +// return chain.filter(exchange); +// } +// +// @Override +// public String toString() { +// return GatewayToStringStyler.filterToStringCreator(ValidateNoteKeyGatewayFilterFactory.this).toString(); +// } +// }; + } +} \ No newline at end of file diff --git a/src/main/java/com/flagnote/gateway/resolver/RemoteAddrKeyResolver.java b/src/main/java/com/flagnote/gateway/resolver/RemoteAddrKeyResolver.java new file mode 100644 index 0000000..e0cbf85 --- /dev/null +++ b/src/main/java/com/flagnote/gateway/resolver/RemoteAddrKeyResolver.java @@ -0,0 +1,19 @@ +//package com.flagnote.gateway.resolver; +// +//import org.springframework.beans.factory.annotation.Qualifier; +//import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver; +//import org.springframework.stereotype.Component; +//import org.springframework.web.server.ServerWebExchange; +// +//import reactor.core.publisher.Mono; +// +//@Component("remoteAddrKeyResolver") +//@Qualifier("remoteAddrKeyResolver") +//public class RemoteAddrKeyResolver implements KeyResolver { +// +// @Override +// public Mono resolve(ServerWebExchange exchange) { +// return Mono.just(exchange.getRequest().getRemoteAddress().getAddress().getHostAddress()); +// } +// +//} \ No newline at end of file diff --git a/src/main/java/com/flagnote/gateway/resolver/RemoteSessionKeyResolver.java b/src/main/java/com/flagnote/gateway/resolver/RemoteSessionKeyResolver.java new file mode 100644 index 0000000..67529fa --- /dev/null +++ b/src/main/java/com/flagnote/gateway/resolver/RemoteSessionKeyResolver.java @@ -0,0 +1,19 @@ +//package com.flagnote.gateway.resolver; +// +//import org.springframework.beans.factory.annotation.Qualifier; +//import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver; +//import org.springframework.stereotype.Component; +//import org.springframework.web.server.ServerWebExchange; +// +//import reactor.core.publisher.Mono; +// +//@Component("remoteSessionKeyResolver") +//@Qualifier("remoteSessionKeyResolver") +//public class RemoteSessionKeyResolver implements KeyResolver { +// +// @Override +// public Mono resolve(ServerWebExchange exchange) { +// return Mono.just(exchange.getSession().block().getId()); +// } +// +//} \ No newline at end of file diff --git a/src/main/java/com/flagnote/gateway/utils/BizKeyUtils.java b/src/main/java/com/flagnote/gateway/utils/BizKeyUtils.java new file mode 100644 index 0000000..30ac618 --- /dev/null +++ b/src/main/java/com/flagnote/gateway/utils/BizKeyUtils.java @@ -0,0 +1,100 @@ +package com.flagnote.gateway.utils; + +import java.io.UnsupportedEncodingException; +import java.util.Date; + +import org.springframework.util.DigestUtils; + +public class BizKeyUtils { + + public static final String MIX_STRING = "6v8muhqp8ta45ncsyi8y"; + + public static final String RANGE_STRING = "abcdefhikmnopqstuvwxyz23456789"; + + public static String getKey() { + + StringBuffer sb = new StringBuffer(); + + for (int i = 0; i < 13; i++) { + sb.append(RANGE_STRING.charAt(RandomUtils.nextInt(30))); + } + + sb.append(getFilteredKey(md5(sb.toString() + MIX_STRING + getPrefixTime()))); + + return sb.toString(); + } + + public static String getFilteredKey(String key) { + String result = ""; + for (int i = 0; i < key.length(); i++) { + String ts = String.valueOf(key.charAt(i)); + if (RANGE_STRING.indexOf(ts) >= 0) { + result += ts; + } + + if (result.length() == 3) { + return result; + } + } + + for (int i = 1; i < 3; i++) { + result += "x"; + } + + return result; + } + + public static Boolean validateKey(String key) { + String oKey = key.substring(0, 13); + + String cKey = oKey + getFilteredKey(md5(oKey + MIX_STRING + getPrefixTime())); + + if (cKey.equals(key)) { + return true; + } + + cKey = oKey + getFilteredKey(md5(oKey + MIX_STRING + (getPrefixTime() - 1))); + + if (cKey.equals(key)) { + return true; + } + + cKey = oKey + getFilteredKey(md5(oKey + MIX_STRING + (getPrefixTime() + 1))); + + if (cKey.equals(key)) { + return true; + } + + return false; + } + + public static String mixKey(String key) { + return md5(key + md5(MIX_STRING + key)); + } + + public static String md5(String text) { + try { + return DigestUtils.md5DigestAsHex(text.getBytes("UTF-8")); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException("无法生成MD5"); + } + } + + public static Integer getPrefixTime() { + return Integer.parseInt(String.valueOf(new Date().getTime()).substring(0, 4)); + } + + public static String getCipher(String key) { + return md5(key + MIX_STRING + key); + } + + public static Boolean validateCipher(String key,String cipher) { + return md5(key + MIX_STRING + key).equals(cipher); + } + + + public static String getSecretKey(String key, String password) { + return md5(key + md5(MIX_STRING + password)); + } + +} \ No newline at end of file diff --git a/src/main/java/com/flagnote/gateway/utils/RandomUtils.java b/src/main/java/com/flagnote/gateway/utils/RandomUtils.java new file mode 100644 index 0000000..2c9a6aa --- /dev/null +++ b/src/main/java/com/flagnote/gateway/utils/RandomUtils.java @@ -0,0 +1,15 @@ +package com.flagnote.gateway.utils; + +import java.util.concurrent.ThreadLocalRandom; + +public class RandomUtils { + + + public static ThreadLocalRandom getRandom() { + return ThreadLocalRandom.current(); + } + + public static Integer nextInt(Integer num) { + return getRandom().nextInt(num); + } +} \ No newline at end of file diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml new file mode 100644 index 0000000..54e975a --- /dev/null +++ b/src/main/resources/application.yml @@ -0,0 +1,143 @@ +server: + port: 55555 +spring: + codec: + max-in-memory-size: 100MB + servlet: + multipart: + # 最大支持文件大小 + max-file-size: 100MB + # 最大支持请求大小 + max-request-size: 100MB + redis: + host: cq.openif.com + port: 6379 + timeout: 1000 + poolMaxTotal: 10 + poolMaxIdle: 10 + poolMaxWait: 3 + password: 1qazx1qazx + application: + name: gateway + cloud: + discovery: + client: + simple: + instances: + keyMetaService: # 一定要带端口 + - uri: http://localhost:3333 +# - uri: http://flagnote.com:3333 + loadbalancer: + health-check: +# path: +# noteKey: /getHealth + initial-delay: 0 #运行状况检查计划程序的初始延迟值。 + interval: 5s # 重新运行运行状况检查计划程序的时间间隔。 + configurations: health-check #启用预定义的负载平衡器配置。 + + inetutils: + # 指定此客户端的ip + default-ip-address: localhost + gateway: + globalcors: + corsConfigurations: + '[/**]': + allowedOrigins: "*" + allowedMethods: "*" + routes: + - id: keyMeta + uri: lb://keyMetaService + order: -1 + predicates: + - Path=/note/keyMeta + - Method=GET + filters: + - name: RequestRateLimiter + args: + # 如果返回的key是空的话,false则不进行限流 +# deny-empty-key: true +# status-code: TOO_MANY_REQUESTS + # 每秒产生多少个令牌 + redis-rate-limiter.replenishRate: 1 + # 1秒内最大的令牌,即在1s内可以允许的突发流程,设置为0,表示阻止所有的请求 + redis-rate-limiter.burstCapacity: 1 + # 每次请求申请几个令牌 + redis-rate-limiter.requestedTokens: 1 + # IP 地址限流 + key-resolver: "#{@remoteAddrKeyResolver}" + + + - name: RequestRateLimiter + args: + # 如果返回的key是空的话,false则不进行限流 +# deny-empty-key: true +# status-code: TOO_MANY_REQUESTS + # 每秒产生多少个令牌 + redis-rate-limiter.replenishRate: 1 + # 1秒内最大的令牌,即在1s内可以允许的突发流程,设置为0,表示阻止所有的请求 + redis-rate-limiter.burstCapacity: 3 + # 每次请求申请几个令牌 + redis-rate-limiter.requestedTokens: 3 + # IP 地址限流 + key-resolver: "#{@remoteSessionKeyResolver}" + + + + - id: noteMeta + uri: lb://keyMetaService + order: -1 + predicates: + - Path=/note/{key:[abcdefhikmnopqstuvwxyz23456789]{16}}/noteMeta + - Method=GET + filters: + - ValidateNoteKey + - id: getNote + uri: lb://keyMetaService + order: -1 + predicates: + - Path=/note/{key:[abcdefhikmnopqstuvwxyz23456789]{16}} + - Method=GET + filters: + - ValidateNoteKey + - id: saveNote + uri: lb://keyMetaService + order: -1 + predicates: + - Path=/note/{key:[abcdefhikmnopqstuvwxyz23456789]{16}} + - Method=POST + filters: + - name: ValidateNoteKey + - name: CacheRequestBody + args: + bodyClass: java.lang.String + - name: ValidateNoteCipher + - id: deleteNote + uri: lb://keyMetaService + order: -1 + predicates: + - Path=/note/{key:[abcdefhikmnopqstuvwxyz23456789]{16}}/delete + - Method=POST + filters: + - ValidateNoteKey + - id: secretKey + uri: lb://keyMetaService + order: -1 + predicates: + - Path=/note/{key:[abcdefhikmnopqstuvwxyz23456789]{16}}/secretKey + - Method=POST + filters: + - ValidateNoteKey + + + + +management: + endpoint: + health: + show-details: always + +logging: + level: + org.springframework.cloud.gateway: trace + org.springframework.cloud.loadbalancer: trace +# org.springframework.web.reactive: trace \ No newline at end of file diff --git a/src/test/java/com/flagnote/gateway/GatewayApplicationTests.java b/src/test/java/com/flagnote/gateway/GatewayApplicationTests.java new file mode 100644 index 0000000..46c7a87 --- /dev/null +++ b/src/test/java/com/flagnote/gateway/GatewayApplicationTests.java @@ -0,0 +1,13 @@ +package com.flagnote.gateway; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class GatewayApplicationTests { + + @Test + void contextLoads() { + } + +}