Spring

AWS 파라미터 스토어에서 스프링 부트 읽기 파라미터

기록만이살길 2023. 1. 16. 20:54
반응형

AWS 파라미터 스토어에서 스프링 부트 읽기 파라미터 질문하다

1. 질문(문제점):

스프링 부트(gradle) 애플리케이션을 만들고 의존성을 포함 org.springframework.cloud:spring-cloud-starter-aws-parameter-store-config했습니다.

AWS 파라미터 스토어에서 구성을 읽는 데 사용하고 싶지만 AWSSimpleSystemsManagement다음과 같이 작성해야 합니다(aws에서).

 config/application_dev/server.port: 8080

스프링 부트에서 이와 같은 것을 읽을 수 있는 방법이 있습니까?dev.application.server.port:8080

현재 이 모든 것이 자동 구성에서 관리되고 있다고 생각합니다. 재정의할 수 있는 방법이 있습니까?

2. 해결방안:

application.properties 에서 property를 정의할 수 있습니다 server.port=8081.

spring-cloud-starter-aws-parameter-store-config에서 지원하는 파라미터 형식 은 다음과 같습니다.

  • /config/application/server.port
  • /config/application_dev/server.port
  • /config/my-service/server.port
  • /config/my-service_dev/server.port

bootstrap.properties 에서 다음 속성을 정의하면 어떤 식으로든 형식을 변경할 수 있습니다.

spring.application.name=my-service
aws.paramstore.prefix=/config
aws.paramstore.defaultContext=application
aws.paramstore.profileSeparator=_

그러나 기본 매개변수 명명 논리가 AwsParamStorePropertySourceLocator.

매개변수 형식을 극적으로 변경하려면 사용자 지정을 정의하고 PropertySourceLocator부트스트랩 구성으로 등록해야 합니다.

문제는 dev.application.server.port유효하지 않은 매개변수 이름입니다.

AWS Systems Manager Parameter Store는 /경로 구분 기호로 사용하고 Spring은 get-parameters-by-path 작업을 사용합니다 . 해결 방법은 name 을 사용하는 것 dev.application/server.port입니다.

그러나이 이름도 유효하지 않습니다. 매개변수 이름은 정규화된 이름이어야 하므로 유효한 이름은 /dev.application/server.port입니다.

이러한 매개변수 형식을 지원하려면 사용자 정의를 정의하십시오.PropertySourceLocator

@Configuration
public class CustomAwsParamStorePropertySourceLocator implements PropertySourceLocator {

  private static final Logger LOGGER =
      LoggerFactory.getLogger(CustomAwsParamStorePropertySourceLocator.class);

  private AWSSimpleSystemsManagement ssmClient;

  private List<String> contexts = new ArrayList<>();

  public CustomAwsParamStorePropertySourceLocator(AWSSimpleSystemsManagement ssmClient) {
    this.ssmClient = ssmClient;
  }

  public List<String> getContexts() {
    return contexts;
  }

  @Override
  public PropertySource<?> locate(Environment environment) {
    if (!(environment instanceof ConfigurableEnvironment)) {
      return null;
    }

    ConfigurableEnvironment env = (ConfigurableEnvironment) environment;

    List<String> profiles = Arrays.asList(env.getActiveProfiles());

    String defaultAppName = "application";
    this.contexts.add("/" + defaultAppName + "/");
    addProfiles(this.contexts, defaultAppName, profiles);

    String appName = env.getProperty("spring.application.name");
    this.contexts.add("/" + appName + "/");
    addProfiles(this.contexts, appName, profiles);

    Collections.reverse(this.contexts);

    CompositePropertySource composite = new CompositePropertySource("custom-aws-param-store");

    for (String propertySourceContext : this.contexts) {
      try {
        composite.addPropertySource(create(propertySourceContext));
      } catch (Exception e) {
        LOGGER.warn("Unable to load AWS config from " + propertySourceContext, e);
      }
    }

    return composite;
  }

  private void addProfiles(List<String> contexts, String appName, List<String> profiles) {
    for (String profile : profiles) {
      contexts.add("/" + profile + "." + appName + "/");
    }
  }

  private AwsParamStorePropertySource create(String context) {
    AwsParamStorePropertySource propertySource =
        new AwsParamStorePropertySource(context, this.ssmClient);
    propertySource.init();
    return propertySource;
  }
}

파일을 추가하여 부트스트랩 컨텍스트에 등록합니다.META-INF/spring.factories

org.springframework.cloud.bootstrap.BootstrapConfiguration=\
com.example.CustomAwsParamStorePropertySourceLocator
반응형