Динамически работать со свойствами приложения - настройками хранилища (или любыми другими значениями) - PullRequest
2 голосов
/ 17 февраля 2020

Я хотел бы иметь возможность гибко выбирать сторонние компоненты, которые использует мое приложение. У меня есть жестко закодированные значения

spring.cloud.vault.token=ffffffff-ffff-ffff-ffff-ffffffffffff
spring.cloud.vault.scheme=http
spring.cloud.vault.application-name=test
spring.cloud.vault.host=127.0.0.1
spring.cloud.vault.port=8200

Цель:

  • Если установлено значение spring.cloud.vault.host, попробуйте использовать его. Если spring.cloud.vault.host пусто, используйте вместо этого локальную БД (с правильной конфигурацией)

Моей первой мыслью было использование environment переменных, таких как:

spring.cloud.vault.token=${VAULT_TOKEN}
spring.cloud.vault.scheme=${VAULT_SCHEME}
spring.cloud.vault.application-name=${VAULT_APP_NAME}
spring.cloud.vault.host=${VAULT_HOST}
spring.cloud.vault.port=${VAULT_PORT}

, а затем использование класса компонента например:

@Component
public class VaultHelper {
    private final VaultOperations vaultOperations;
    @Value("${spring.cloud.vault.host}")
    String vaultHostname;

    @Autowired
    public VaultHelper(VaultOperations vaultOperations){
        this.vaultOperations = vaultOperations;
    }

    public void saveToVault(String password){
        if (!vaultHostname.equals("")) { 
            // Use vaultOperations to store password
        } else {
            // Use plaintext db storage
        }
    }

    public byte[] readFromVault(String passwordLoc){
        if (!vaultHostname.equals("")) {
            // Use vaultOperations to access password
        } else {
            // return plaintext password
        }
        return new byte[0];
    }


}

Таким образом, я мог бы установить ${VAULT_HOST} как из переменной среды (запуск приложения из docker -compose), так и просто установить --spring.cloud.vault.host=URL на локальной машине в качестве параметра java.

К сожалению, я получаю исключение при разборе ${VAULT_PORT} поля

Caused by: org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [int] for value '${VAULT_PORT}'; nested exception is java.lang.NumberFormatException: For input string: "${VAULT_PORT}"
    at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:47) ~[spring-core-5.2.1.RELEASE.jar:5.2.1.RELEASE]
    at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:191) ~[spring-core-5.2.1.RELEASE.jar:5.2.1.RELEASE]
    at org.springframework.boot.context.properties.bind.BindConverter$CompositeConversionService.convert(BindConverter.java:170) ~[spring-boot-2.2.1.RELEASE.jar:2.2.1.RELEASE]
    at org.springframework.boot.context.properties.bind.BindConverter.convert(BindConverter.java:96) ~[spring-boot-2.2.1.RELEASE.jar:2.2.1.RELEASE]
    at org.springframework.boot.context.properties.bind.BindConverter.convert(BindConverter.java:88) ~[spring-boot-2.2.1.RELEASE.jar:2.2.1.RELEASE]
    at org.springframework.boot.context.properties.bind.Binder.bindProperty(Binder.java:435) ~[spring-boot-2.2.1.RELEASE.jar:2.2.1.RELEASE]
    at org.springframework.boot.context.properties.bind.Binder.bindObject(Binder.java:380) ~[spring-boot-2.2.1.RELEASE.jar:2.2.1.RELEASE]
    at org.springframework.boot.context.properties.bind.Binder.bind(Binder.java:320) ~[spring-boot-2.2.1.RELEASE.jar:2.2.1.RELEASE]
    ... 83 common frames omitted
Caused by: java.lang.NumberFormatException: For input string: "${VAULT_PORT}"
    at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65) ~[na:1.8.0_231]
    at java.lang.Integer.parseInt(Integer.java:569) ~[na:1.8.0_231]
    at java.lang.Integer.valueOf(Integer.java:766) ~[na:1.8.0_231]
    at org.springframework.util.NumberUtils.parseNumber(NumberUtils.java:211) ~[spring-core-5.2.1.RELEASE.jar:5.2.1.RELEASE]
    at org.springframework.core.convert.support.StringToNumberConverterFactory$StringToNumber.convert(StringToNumberConverterFactory.java:62) ~[spring-core-5.2.1.RELEASE.jar:5.2.1.RELEASE]
    at org.springframework.core.convert.support.StringToNumberConverterFactory$StringToNumber.convert(StringToNumberConverterFactory.java:49) ~[spring-core-5.2.1.RELEASE.jar:5.2.1.RELEASE]
    at org.springframework.core.convert.support.GenericConversionService$ConverterFactoryAdapter.convert(GenericConversionService.java:436) ~[spring-core-5.2.1.RELEASE.jar:5.2.1.RELEASE]
    at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:41) ~[spring-core-5.2.1.RELEASE.jar:5.2.1.RELEASE]
    ... 90 common frames omitted


Process finished with exit code 1

Может кто-нибудь дать мне подсказку, как заставить это работать?

1 Ответ

2 голосов
/ 17 февраля 2020

Полагаю, по сути, вы не предоставляете по умолчанию / откат. В этом случае, когда он не может найти соответствующую переменную среды, он просто объявляет поле PORT в качестве заданной строки. попробуйте что-нибудь со значением по умолчанию, используя (:).

Вы также можете указать другую переменную по умолчанию, которая, как вы знаете, будет установлена.

spring.cloud.vault.port=${VAULT_PORT}:9000


spring.cloud.vault.port=${VAULT_PORT:8200}
...