dynamically created beans after application init

382 views
Skip to first unread message

V. Sevel

unread,
Jul 26, 2021, 2:36:31 PM7/26/21
to Quarkus Development mailing list
In this PR Add support for Vault’s PKI secret engine there was a need to create a bean that can be injected with default values, or created dynamically at runtime (even after bean discovery).

the proposed solution so far is to create the following components:
  • the VaultPKISecretEngine interface
  • a concrete implementation VaultPKIManager with 2 constructors
    • @Inject public VaultPKIManager(VaultAuthManager,VaultInternalPKISecretEngine), which calls a non CDI constructor:
    • a non CDI VaultPKIManager(String, VaultAuthManager vaultAuthManager,VaultInternalPKISecretEngine)
  • a bean VaultPKIManagerFactory, which acts as a factory to create plain VaultPKIManager instances through the second constructor
technically this works. but I find this unsatisfying because depending on the use case (straight injection of VaultPKIManager, or creation through the factory), it is a full fledged CDI bean in the first case, or only an implementation of the service in the second.

this means that some of the CDI features we could use (e.g. CDI interceptors), will work inconsistently (it will in the first case, and obviously not in the second).

I do not see a better solution at this point, especially given that the list of  VaultPKIManager instances cannot be created even at runtime from configuration (I will let Kevin describe how the factory gets called in his use case, and where the params come from). 

and it may even be an anti-pattern in quarkus, but I was wondering if someone would find a more elegant solution for this problem?

thanks for your thoughts.

Matej Novotny

unread,
Jul 27, 2021, 3:53:12 AM7/27/21
to Quarkus Development mailing list
I did look at the PR and while I don't understand Vault or why you need this given approach, I will comment from CDI perspective.

> there was a need to create a bean that can be injected with default values, or created dynamically at runtime (even after bean discovery).

This seems like anti-pattern in CDI. You cannot add beans after CDI container bootstrap (not just in Quarkus, but in Weld and other impls as well). CDI needs to know upfront what beans are present so that it can do validation. More so in build-time approach where Quarkus generates all proxies/subclasses before you even get to runtime. You are able to register synthetic beans (which happens after bean discovery, but still in build time for Quarkus) but from my understanding of comments on the PR, that is still too early.

One thing you could perhaps do to work around this is to create a CDI producer for  VaultPKIManager. That way you would control what the producer returns even at runtime (because producers get called when the bean is needed) and the result is still a CDI bean. However, you still lose the ability to use interceptors/decorators as those cannot be applied to producers.
Reply all
Reply to author
Forward
0 new messages