简体   繁体   English

Quarkus:以编程方式设置配置属性

[英]Quarkus: Programatically set a config property

I have a requirement to set a property in my Quarkus app, whereby the value of this property (a quarkus-vault property) needs to read from a file.我需要在我的 Quarkus 应用程序中设置一个属性,该属性的值(quarkus-vault 属性)需要从文件中读取。 For example, in the microprofile-config.properties file, this would be an example of such property:例如,在 microprofile-config.properties 文件中,这将是此类属性的示例:

myProperty.val=<value_from_a_file>

One thing I have tried is to create a ConfigSource , which by creating a hashmap and setting the property there, it works fine.我尝试过的一件事是创建一个ConfigSource ,它通过创建一个 hashmap 并在那里设置属性,它工作正常。 I referred to this web page:我参考了这个 web 页面:

https://quarkus.io/guides/config-extending-support https://quarkus.io/guides/config-extending-support

Here is an example of the ConfigSource implementation:以下是 ConfigSource 实现的示例:

public class SampleConfigSource implements ConfigSource {

private static final Map<String, String> configuration = new HashMap<>();
private static final Logger LOGGER = LoggerFactory.getLogger(SampleConfigSource.class);
private static final String secretFilePath = ConfigProvider.getConfig().getValue("application.vault.secret.file", String.class);

static {
    try {
        // read the value from the file and put it in the configuration map
        final String content = Files.readAllLines(Paths.get(secretFilePath)).get(0);
        configuration.put("quarkus.vault.authentication.app-role.secret-id", content);
    } catch (Exception e) {
        LOGGER.error(e.getMessage(), e);
    }
}

@Override
public Set<String> getPropertyNames() {
    return configuration.keySet();
}

@Override
public String getValue(String s) {
    return configuration.get(s);
}

@Override
public String getName() {
    return SampleConfigSource.class.getName();
}

} }

src/main/resources/META-INF/Services/org.eclipse.microprofile.config.spi.ConfigSource src/main/resources/META-INF/Services/org.eclipse.microprofile.config.spi.ConfigSource

com.example.config.SampleConfigSource

src/main/resources/META-INF/microprofile-config.properties src/main/resources/META-INF/microprofile-config.properties

 ....
 application.vault.secret.file=external/secret.txt
 quarkus.vault.connect-timeout=30S
 quarkus.vault.read-timeout=30S
 quarkus.vault.url=https://prod-vault
 quarkus.vault.authentication.app-role.role-id=abcde
 ....

Now the problem is that the microprofile-config.properties has the main properties for setting up vault.现在的问题是microprofile-config.properties具有设置保险库的主要属性。 It also requires the quarkus.vault.authentication.app-role.secret-id property as well, but because I'm reading this value from a file, I've added it to the SampleConfigSource class.它还需要quarkus.vault.authentication.app-role.secret-id属性,但因为我是从文件中读取此值,所以我已将其添加到SampleConfigSource class。 I would have thought that the property would have initialised fine on bootup, but instead I get the following stack trace error:我原以为该属性会在启动时很好地初始化,但我得到了以下堆栈跟踪错误:

15:37:05 ERROR [io.quarkus.runtime.Application] Failed to start application (with profile dev): java.lang.UnsupportedOperationException: unknown authType null
    at io.quarkus.vault.runtime.VaultAuthManager.login(VaultAuthManager.java:165)
    at io.quarkus.vault.runtime.VaultAuthManager.vaultLogin(VaultAuthManager.java:145)
    at io.quarkus.vault.runtime.VaultAuthManager.login(VaultAuthManager.java:116)
    at io.quarkus.vault.runtime.VaultAuthManager_Subclass.login$$superforward1(Unknown Source)
    at io.quarkus.vault.runtime.VaultAuthManager_Subclass$$function$$4.apply(Unknown Source)
    at io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:54)
    at io.quarkus.arc.runtime.devconsole.InvocationInterceptor.proceed(InvocationInterceptor.java:62)
    at io.quarkus.arc.runtime.devconsole.InvocationInterceptor.monitor(InvocationInterceptor.java:51)
    at io.quarkus.arc.runtime.devconsole.InvocationInterceptor_Bean.intercept(Unknown Source)
    at io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:41)
    at io.quarkus.arc.impl.AroundInvokeInvocationContext.perform(AroundInvokeInvocationContext.java:41)
    at io.quarkus.arc.impl.InvocationContexts.performAroundInvoke(InvocationContexts.java:32)
    at io.quarkus.vault.runtime.VaultAuthManager_Subclass.login(Unknown Source)
    at io.quarkus.vault.runtime.VaultAuthManager.login(VaultAuthManager.java:95)
    at io.quarkus.vault.runtime.VaultAuthManager.getClientToken(VaultAuthManager.java:79)
    at io.quarkus.vault.runtime.VaultAuthManager_Subclass.getClientToken$$superforward1(Unknown Source)
    at io.quarkus.vault.runtime.VaultAuthManager_Subclass$$function$$10.apply(Unknown Source)
    at io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:54)
    at io.quarkus.arc.runtime.devconsole.InvocationInterceptor.proceed(InvocationInterceptor.java:62)
    at io.quarkus.arc.runtime.devconsole.InvocationInterceptor.monitor(InvocationInterceptor.java:51)
    at io.quarkus.arc.runtime.devconsole.InvocationInterceptor_Bean.intercept(Unknown Source)
    at io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:41)
    at io.quarkus.arc.impl.AroundInvokeInvocationContext.perform(AroundInvokeInvocationContext.java:41)
    at io.quarkus.arc.impl.InvocationContexts.performAroundInvoke(InvocationContexts.java:32)
    at io.quarkus.vault.runtime.VaultAuthManager_Subclass.getClientToken(Unknown Source)
    at io.quarkus.vault.runtime.VaultKvManager.readSecret(VaultKvManager.java:36)
    at io.quarkus.vault.runtime.VaultKvManager_Subclass.readSecret$$superforward1(Unknown Source)
    at io.quarkus.vault.runtime.VaultKvManager_Subclass$$function$$4.apply(Unknown Source)
    at io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:54)
    at io.quarkus.arc.runtime.devconsole.InvocationInterceptor.proceed(InvocationInterceptor.java:62)
    at io.quarkus.arc.runtime.devconsole.InvocationInterceptor.monitor(InvocationInterceptor.java:51)
    at io.quarkus.arc.runtime.devconsole.InvocationInterceptor_Bean.intercept(Unknown Source)
    at io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:41)
    at io.quarkus.arc.impl.AroundInvokeInvocationContext.perform(AroundInvokeInvocationContext.java:41)
    at io.quarkus.arc.impl.InvocationContexts.performAroundInvoke(InvocationContexts.java:32)
    at io.quarkus.vault.runtime.VaultKvManager_Subclass.readSecret(Unknown Source)
    at io.quarkus.vault.runtime.VaultKvManager_ClientProxy.readSecret(Unknown Source)
    at io.quarkus.vault.runtime.config.VaultConfigSource.fetchSecrets(VaultConfigSource.java:131)
    at io.quarkus.vault.runtime.config.VaultConfigSource.lambda$fetchSecrets$2(VaultConfigSource.java:127)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1540)
    at io.quarkus.vault.runtime.config.VaultConfigSource.fetchSecrets(VaultConfigSource.java:127)
    at io.quarkus.vault.runtime.config.VaultConfigSource.lambda$fetchSecrets$0(VaultConfigSource.java:120)
    at java.base/java.util.Optional.ifPresent(Optional.java:183)
    at io.quarkus.vault.runtime.config.VaultConfigSource.fetchSecrets(VaultConfigSource.java:120)
    at io.quarkus.vault.runtime.config.VaultConfigSource.fetchSecretsFirstTime(VaultConfigSource.java:103)
    at io.quarkus.vault.runtime.config.VaultConfigSource.getSecretConfig(VaultConfigSource.java:81)
    at io.quarkus.vault.runtime.config.VaultConfigSource.getValue(VaultConfigSource.java:62)
    at io.smallrye.config.ConfigValueConfigSourceWrapper.getConfigValue(ConfigValueConfigSourceWrapper.java:20)
    at io.smallrye.config.SmallRyeConfigSources.getValue(SmallRyeConfigSources.java:29)
    at io.smallrye.config.SmallRyeConfigSourceInterceptorContext.proceed(SmallRyeConfigSourceInterceptorContext.java:20)
    at io.smallrye.config.SecretKeysConfigSourceInterceptor.getValue(SecretKeysConfigSourceInterceptor.java:22)
    at io.smallrye.config.SmallRyeConfigSourceInterceptorContext.proceed(SmallRyeConfigSourceInterceptorContext.java:20)
    at io.smallrye.config.FallbackConfigSourceInterceptor.getValue(FallbackConfigSourceInterceptor.java:24)
    at io.smallrye.config.SmallRyeConfigSourceInterceptorContext.proceed(SmallRyeConfigSourceInterceptorContext.java:20)
    at io.smallrye.config.RelocateConfigSourceInterceptor.getValue(RelocateConfigSourceInterceptor.java:29)
    at io.smallrye.config.SmallRyeConfigSourceInterceptorContext.proceed(SmallRyeConfigSourceInterceptorContext.java:20)
    at io.smallrye.config.RelocateConfigSourceInterceptor.getValue(RelocateConfigSourceInterceptor.java:29)
    at io.smallrye.config.SmallRyeConfigSourceInterceptorContext.proceed(SmallRyeConfigSourceInterceptorContext.java:20)
    at io.smallrye.config.ProfileConfigSourceInterceptor.convertProfile(ProfileConfigSourceInterceptor.java:120)
    at io.smallrye.config.ProfileConfigSourceInterceptor.<init>(ProfileConfigSourceInterceptor.java:44)
    at io.smallrye.config.SmallRyeConfigBuilder$1.getInterceptor(SmallRyeConfigBuilder.java:180)
    at io.smallrye.config.SmallRyeConfigBuilder$InterceptorWithPriority.getInterceptor(SmallRyeConfigBuilder.java:473)
    at io.smallrye.config.SmallRyeConfig$ConfigSources.<init>(SmallRyeConfig.java:522)
    at io.smallrye.config.SmallRyeConfig.<init>(SmallRyeConfig.java:66)
    at io.smallrye.config.SmallRyeConfigBuilder.build(SmallRyeConfigBuilder.java:419)
    at io.quarkus.runtime.generated.Config.readConfig(Unknown Source)
    at io.quarkus.deployment.steps.RuntimeConfigSetup.deploy(Unknown Source)
    at io.quarkus.runner.ApplicationImpl.doStart(Unknown Source)
    at io.quarkus.runtime.Application.start(Application.java:101)
    at io.quarkus.runtime.ApplicationLifecycleManager.run(ApplicationLifecycleManager.java:104)
    at io.quarkus.runtime.Quarkus.run(Quarkus.java:67)
    at io.quarkus.runtime.Quarkus.run(Quarkus.java:41)
    at io.quarkus.runtime.Quarkus.run(Quarkus.java:120)
    at io.quarkus.runner.GeneratedMain.main(Unknown Source)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at io.quarkus.runner.bootstrap.StartupActionImpl$1.run(StartupActionImpl.java:103)
    at java.base/java.lang.Thread.run(Thread.java:834)

If I put the quarkus.vault.authentication.app-role.secret-id property inside the microprofile-config.properties file (rather than SampleConfigSource class and instead hard code the secret in the property rather than reading from the file, then it works perfectly fine.如果我将quarkus.vault.authentication.app-role.secret-id属性放在 microprofile-config.properties 文件中(而不是SampleConfigSource class 而是硬编码属性中的秘密而不是从文件中读取,那么它可以工作完全没问题。

If I just use the SampleConfigSource to read the value from the file and put it in a different property name that does not start with quarkus.vault.* (eg application.property.key ), then the property is set correctly.如果我只是使用SampleConfigSource从文件中读取值并将其放在不以quarkus.vault.*开头的不同属性名称中(例如application.property.key ),则该属性设置正确。 It is only when I read from the file and set the value (from the file) into the quarkus.vault.authentication.app-role.secret-id config map within my custom ConfigSource ( SampleConfigSource ) then it throws this error on startup.只有当我从文件中读取并将值(从文件中)设置到我的自定义 ConfigSource ( SampleConfigSource )中的quarkus.vault.authentication.app-role.secret-id配置 map 时,它才会在启动时引发此错误。

It's almost like as if that quarkus.vault.authentication.app-role.secret-id property must live in microprofile-config.properties , but it can't read the value from the ConfigSource .就好像quarkus.vault.authentication.app-role.secret-id属性必须存在于microprofile-config.properties中,但它无法从ConfigSource读取值。

Another way I did it was to update the microprofile-config.properties to include the quarkus.vault.authentication.app-role.secret-id and set it to the property that contains the value in the file (eg):我这样做的另一种方法是更新 microprofile-config.properties 以包含quarkus.vault.authentication.app-role.secret-id并将其设置为包含文件中值的属性(例如):

quarkus.vault.authentication.app-role.secret-id=${app.value.read.from.file}

where app.value.read.from file is in the configurationMap in the SampleConfigSource that contains the value read from the file.其中app.value.read.from file位于SampleConfigSource中的configurationMap中,其中包含从文件中读取的值。 But that does not work either and I get the same stack trace error.但这也不起作用,我得到相同的堆栈跟踪错误。

Is there any other way where I can programatically override the property (to read the value from a file)?有没有其他方法可以以编程方式覆盖该属性(从文件中读取值)? Starting to feel like it might not be possible to do this for quarkus.vault.* properties but would really appreciate any insight or suggestions.开始觉得可能无法对quarkus.vault.*属性执行此操作,但非常感谢任何见解或建议。 Many thanks,非常感谢,

I think you need to override the Ordinal (the default is 100)我认为您需要覆盖序数(默认为 100)

@Override
public int getOrdinal() {
    return 275;
}

https://quarkus.io/guides/config-extending-support . https://quarkus.io/guides/config-extending-support

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM