본문 바로가기

개발(합니다)/Java&Spring

[spring boot 설정하기-21] spring cloud gateway(2) 설정 및 테스트 소스

반응형

지난번 포스팅에서는 이론에 관한 정리를 했고 이번 포스팅에는 구현에 관해 포스팅 하도록 하겠습니다.


1. Cloud Config Server 및 설정

아래 설정은 예시이며 search-path 구성파일 찾을 경로에 gatewayserver를 추가합니다.
search-paths: member-service, eurekaserver, gatewayserver # 구성파일 찾을 폴더 경로

bootstrap.yml

#bootstrap.yml
spring:
  application:
    name: configserver

  cloud:
    config:
      server:
        encrypt:
          enabled: false # Config Server에서 복호화 비화성화
        git:
          ignore-local-ssh-settings: true
          uri: git@github.com:otrodevym/spring-cloud-config-repo.git  # ssh
          search-paths: member-service, eurekaserver, gatewayserver # 구성파일 찾을 폴더 경로
          private-key: |
                      -----BEGIN RSA PRIVATE KEY-----
                      MIIJKAIBAAKCAgEAvAFToUY4/x1f0RJneCruJlJpEJRL7hSBmcH/kYvj8oZKa+V1
                      ...
encrypt:
  key: my_config_key

spring-cloud-confog-repo 설정 : gatewayserver/gatewayserver.yml

패키지 구성은 아래 사진을 참고합니다.

# gatewayserver.yml
spring:
  cloud:
    gateway:
      default-filters:
        - name: GlobalFilter
          args:
            baseMessage: Spring Cloud Gateway GlobalFilter
            preLogger: true
            postLogger: true
      routes:
        - id: user-service
          uri: http://localhost:6666
          predicates:
            - Path=/user/**
          filters:
            - name: GlobalFilter
              ages:
                baseMessage: Spring Cloud Gateway GlobalFilter
                preLogger: true
                postLogger: true
#            - RewritePath=/order/(?<path>.*),/$\{path}

        - id: cafe-service
          uri: http://localhost:7777
          predicates:
            - Path=/cafe/**
          filters:
            - name: GlobalFilter
              args:
                baseMessage: Spring Cloud Gateway GlobalFilter
                preLogger: true
                postLogger: true
#            - RewritePath=/cafe/(?<path>.*),/$\{path}
  rabbitmq:
    host: localhost
    port: 5672
    username: guest
    password: "{cipher}08fde35c4f79cc080854c47871e241fc293fa157b5d9151be5a05fc5aed1d2bb"


management:
  endpoints:
    web:
      exposure:
        include: "*"
  endpoint:
    gateway:
      enabled: true

2. Cloud Gateway Server

2-1. 의존성 추가

기존에 구성한 Cloud Config를 사용하기 위해 아래를 추가하고
implementation 'org.springframework.cloud:spring-cloud-starter-config'
implementation 'org.springframework.cloud:spring-cloud-starter-bus-amqp'
implementation 'org.springframework.security:spring-security-rsa'
implementation 'org.springframework.cloud:spring-cloud-starter-bootstrap'

gateway를 사용하기 위해 아래를 추가합니다.
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.cloud:spring-cloud-starter-gateway'

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-actuator'
    implementation 'org.springframework.cloud:spring-cloud-starter-gateway'
    compileOnly 'org.projectlombok:lombok'
    annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
    annotationProcessor 'org.projectlombok:lombok'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'


    implementation 'org.springframework.cloud:spring-cloud-starter-config'
    implementation 'org.springframework.cloud:spring-cloud-starter-bus-amqp'
    implementation 'org.springframework.security:spring-security-rsa'
    implementation 'org.springframework.cloud:spring-cloud-starter-bootstrap'

}

2-2. application.yml과 bootstrap.yml 설정

application.yml

# application.yml
server:
  port: 9999

bootstrap.yml

# bootstrap.yml
spring:
  application:
    name: gatewayserver
  profiles:
    active: default
  config:
    import: optional:configserver:http://localhost:8888

encrypt:
  key: my_config_key

2-3. GlobalFilter.java

gateway server에 filter를 설정하기 위한 class 파일입니다.
AbstractGatewayFilterFactory를 상속받아 필터를 설정합니다.
exchange를 이용해 서비스 요청과 응답을 가지고 있는 변수의 값을 출력하거나 변환할 때 사용합니다.
config는 gatewayserver.yml에 설정한 filter의 args를 사용할 수 있습니다.

package com.otrodevym.gatewayserver;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;


@Component
@Slf4j
public class GlobalFilter extends AbstractGatewayFilterFactory<GlobalFilter.Config> {
    public GlobalFilter() {
        super(Config.class);
    }

    @Override
    public GatewayFilter apply(Config config) {
        return ((exchange, chain) -> {
            log.info("GlobalFilter baseMessage >>>" + config.getBaseMessage());
            if (config.isPreLogger()) {
                log.info("GlobalFilter Start >>>" + exchange.getRequest());
            }
            return chain.filter(exchange).then(Mono.fromRunnable(()->{
                if (config.isPostLogger()) {
                    log.info("GlobalFilter End >>>" + exchange.getResponse());
                }
            }));
        });
    }

    @Data
    public static class Config {
        private String baseMessage;
        private boolean preLogger;
        private boolean postLogger;
    }
}

3. Cloud Gateway Client

gateway-user와 gateway-cafe로 구성된 클라이언트를 생성합니다.
테스트용이라 해당 클라이언트는 cloud-config는 제외하도록하겠습니다.

3-1. gateway-user

3-1-1. 의존성 추가

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-webflux'
    compileOnly 'org.projectlombok:lombok'
    annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
    annotationProcessor 'org.projectlombok:lombok'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    testImplementation 'io.projectreactor:reactor-test'
}

3-1-2. application.yml 설정

server:
  port: 6666

3-1-3. CloudGatewayUserContoller.java

package com.otrodevym.gatewayuser;

import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;


@RestController
@RequestMapping("/user")
@Slf4j
public class CloudGatewayUserContoller {
    @GetMapping("/info")
    public Mono<String> getUser(ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
        log.info("User MicroService Start >>> ");
        HttpHeaders httpHeaders = serverHttpRequest.getHeaders();
        httpHeaders.forEach((k, v) -> {
            log.info(k + " : " + v);
        });
        log.info("User MicroService End >>>");
        return Mono.just("This is User MicroService!!! ");
    }
}

3-2. gateway-cafe

3-2-1. 의존성 추가

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-webflux'
    compileOnly 'org.projectlombok:lombok'
    developmentOnly 'org.springframework.boot:spring-boot-devtools'
    annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
    annotationProcessor 'org.projectlombok:lombok'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    testImplementation 'io.projectreactor:reactor-test'
}

3-2-2. application.yml 설정

server:
  port: 7777

3-2-3. CloudGatewayUserContoller.java

package com.otrodevym.gatewaycafe;

import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;


@RestController
@RequestMapping("/cafe")
@Slf4j
public class CloudGatewayCafeContoller {
    @GetMapping("/info")
    public Mono<String> getCafe(ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
        log.info("Cafe MicroService Start >>> ");
        HttpHeaders httpHeaders = serverHttpRequest.getHeaders();
        httpHeaders.forEach((k, v) -> {
            log.info(k + " : " + v);
        });
        log.info("Cafe MicroService End >>>");
        return Mono.just("This is Cafe MicroService!!! ");
    }
}

4. 테스트

4-1. cloud-config에 gateway-server 확인

http://localhost:8888/gatewayserver/default

4-2. cloud-gateway에 config 설정확인

1. http://localhost:9999/actuator 실행 시 전체 값이 표출되어야 합니다.

그 중 gateway가 노출된걸 확인할 수 있습니다.

http://localhost:9999/actuator/gateway/routes를 이용해 routes 정보를 얻을 수 있습니다.

2. gateway-server 실행 콘솔에서 config-server의 주소가 표시되어야합니다.

4-3. cloud-gateway와 gateway-user, gateway-cafe 연동 테스트

cloud-gateway로 gateway-user와 gateway-cafe에 접근하는 테스트입니다.

1. http://localhost:9999/user/info

2. http://localhost:9999/cafe/info

반응형