Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ensure YAML configuration is taken into account for DynamicFeatures #18238

Merged
merged 1 commit into from
Jul 13, 2021

Conversation

essobedo
Copy link
Contributor

@essobedo essobedo commented Jun 29, 2021

fixes #18237

Motivation

Value of properties defined into a YAML file cannot be used anymore since Quarkus 2.0 in case of JAX-RS DynamicFeatures

Modifications:

  • Adds a test case showing the problem
  • Proposes a potential fix to define the ConfigPropertyProvider of the yaml extension as StaticInitConfigSourceProviderBuildItem

@essobedo essobedo changed the title Ensure YAML configuration is taken into account for JAX-RS Dynamic Features Ensure YAML configuration is taken into account for Dynamic Features Jun 29, 2021
@essobedo essobedo changed the title Ensure YAML configuration is taken into account for Dynamic Features Ensure YAML configuration is taken into account for DynamicFeatures Jun 29, 2021
@essobedo essobedo marked this pull request as ready for review June 29, 2021 15:42
@gsmet gsmet requested a review from radcortez June 29, 2021 17:35
@geoand
Copy link
Contributor

geoand commented Jul 1, 2021

This seems perfectly reasonable to me

@essobedo
Copy link
Contributor Author

essobedo commented Jul 1, 2021

@geoand

This seems perfectly reasonable to me

Not for @radcortez as he prefers a solution that would work with all ConfigPropertyProviders. See the discussion in the original ticket for more details #18237 (comment)

@radcortez Do I close this PR?

@geoand
Copy link
Contributor

geoand commented Jul 1, 2021

Of course Roberto is the subject matter expert here, so it's up to him

@radcortez
Copy link
Member

@geoand

This seems perfectly reasonable to me

Not for @radcortez as he prefers a solution that would work with all ConfigPropertyProviders. See the discussion in the original ticket for more details #18237 (comment)

@radcortez Do I close this PR?

If you can work around with my proposal, yes :) Did that work?

@essobedo
Copy link
Contributor Author

essobedo commented Jul 1, 2021

@radcortez If your workaround is to initialize "manually" the Bean that I inject into my DynamicFeature as next:

My class file

@Singleton
public class MyBean {

    String property;

    @Inject
    void init(Config config) {
        this.property = config.getValue("property.value", String.class);
    }
}

My file config/application.yml

property:
   value: foo

The answer is no, it doesn't work as it still uses a Config instance created during the static init phase which does use the "discovered" config sources like the Yaml config sources.

My current workaround is to somehow fork the config-yaml extension with this fix, I could not found any better way for now 😞

@radcortez
Copy link
Member

No, that was not what I was thinking.

You need to do the lookup in the filter method with ConfigProvider.getConfig and retrieve the value there. Yes, this adds some extra calls on each call, but it should be ok. An alternative is to just lazy load the field in an AtomicReference on the first filter call and then you avoid additional calls to Config.

@essobedo
Copy link
Contributor Author

essobedo commented Jul 1, 2021

No, that was not what I was thinking.

You need to do the lookup in the filter method with ConfigProvider.getConfig and retrieve the value there. Yes, this adds some extra calls on each call, but it should be ok. An alternative is to just lazy load the field in an AtomicReference on the first filter call and then you avoid additional calls to Config.

Ah I see, your idea is to delay the initialization to make it happen during at worse the startup time but in my use case I cannot do that, I need my bean to be initialized when calling the configure method of my DynamicFeature which happens during the static init phase.

@radcortez
Copy link
Member

radcortez commented Jul 1, 2021

Not exactly. You let the bean initialize without any value (or a default). Then inside the filter method, you do a lookup of the right configuration value (this will only be called when the filter is called and way beyond startup).

Something like:

@Priority(1001)
 public class GreetingFilter implements ContainerResponseFilter {
     private AtomicReference<String> message = new AtomicReference();
     private CountDownLatch init = new CountDownLatch(1);

     @Override
     public void filter(ContainerRequestContext containerRequestContext, ContainerResponseContext containerResponseContext)
             throws IOException {

        ensureInit();

         containerResponseContext.getHeaders().add("X-MESSAGE", message);
     }

     private void ensureInit( {
            if (message.compareAndSet(null, "some-default"))) {
                ConfigProvider.getConfig().getOptionalValue("my.property", String.class).ifPresent(message::set);
                init.countDown();
            } else {
                try {
                    init.await();
                } catch (final InterruptedException e) {
                    // log
                }
            }
        }
 }

I did by memory, so I hope I didn't forget anything, but I hope you get the idea :)

@essobedo
Copy link
Contributor Author

essobedo commented Jul 2, 2021

@radcortez Yeah it is what I understood from your previous comment but unfortunately my real use case is not exactly what I put in the PR, I added a filter just to be able to easily test the value injected into the DynamicFeature.

My real use case is more:

@Provider
public class MyDynamicFeature implements DynamicFeature {

    @Inject
    MyBean bean;

    @Override
    public void configure(ResourceInfo resourceInfo, FeatureContext featureContext) {
        if ("foo".equals(bean.property)) {
            // Do something in case of foo
        } else if ("bar".equals(bean.property)) {
            // Do something in case of bar
        }
    }
}

I'm afraid that your workaround is not applicable in my use case since the bean needs to be initialized when calling the configure method and the configure method is called during the static init phase 😢

@radcortez
Copy link
Member

Ok, let's work on this PR and try to solve this use case while we think of another solution for the overall problem.

@essobedo essobedo force-pushed the config-regression branch 2 times, most recently from 4c88cde to 51fa71c Compare July 2, 2021 17:11
@quarkus-bot
Copy link

quarkus-bot bot commented Jul 2, 2021

This workflow status is outdated as a new workflow run has been triggered.

🚫 This workflow run has been cancelled.

Failing Jobs - Building 4c88cde

⚠️ Artifacts of the workflow run were not available thus the report misses some details.

Status Name Step Test failures Logs Raw logs
Initial JDK 11 Build Set up JDK 11 ⚠️ Check → Logs Raw logs

@essobedo essobedo requested a review from radcortez July 2, 2021 17:12
@essobedo
Copy link
Contributor Author

essobedo commented Jul 2, 2021

@radcortez remarks addressed, please check again

Copy link
Member

@radcortez radcortez left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better. Thank you. Let's wait for CI now.

@essobedo
Copy link
Contributor Author

@radcortez the CI seems to be happy, is something missing before being merged?

@radcortez
Copy link
Member

Yes. This one should go first: #17483 and then this one rebased on.

@gsmet
Copy link
Member

gsmet commented Jul 13, 2021

@radcortez I merged #17483 . It appears this one still applies cleanly. Should we merge or it requires additional adjustments?

@radcortez
Copy link
Member

The used AdditionalStaticInitConfigSourceProviderBuildItem is now deprecated in favour of StaticInitConfigSourceProviderBuildItem. If @essobedo wants to update it it :)

@essobedo
Copy link
Contributor Author

The used AdditionalStaticInitConfigSourceProviderBuildItem is now deprecated in favour of StaticInitConfigSourceProviderBuildItem. If @essobedo wants to update it it :)

No PBR, I will

@radcortez
Copy link
Member

The used AdditionalStaticInitConfigSourceProviderBuildItem is now deprecated in favour of StaticInitConfigSourceProviderBuildItem. If @essobedo wants to update it it :)

No PBR, I will

Thanks!

@essobedo
Copy link
Contributor Author

Should be done, let's see what the CI says

@gsmet
Copy link
Member

gsmet commented Jul 13, 2021

CI looks happy :). @radcortez I let you check that everything is OK and merge? Thanks!

@radcortez radcortez merged commit 1dd6b9c into quarkusio:main Jul 13, 2021
@quarkus-bot quarkus-bot bot added this to the 2.1 - main milestone Jul 13, 2021
@essobedo essobedo deleted the config-regression branch January 17, 2022 11:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

YAML configuration ignored for JAX-RS Dynamic Features
4 participants