quarkus
quarkus copied to clipboard
Dev services check property value existence with expression expansion
Fixes #41128 replaces #41143
Thanks to @The-Funk !
@ozangunalp @gsmet @geoand can this be backported to 3.8 for those of us on the LTS?
I don't see any conflicts for 3.8 so it should be fine.
I added the label but we discuss backports for 3.8 in a committee so we will see how it goes when we discuss the next round of backports.
:waning_crescent_moon: This workflow status is outdated as a new workflow run has been triggered.
Status for workflow Quarkus CI
This is the status report for running Quarkus CI on commit 04753d77a05f6d3078a18c44495c07c4201ff233.
Failing Jobs
| Status | Name | Step | Failures | Logs | Raw logs | Build scan |
|---|---|---|---|---|---|---|
| ✖ | JVM Tests - JDK 17 | Build |
Failures | Logs | Raw logs | :mag: |
| ✖ | JVM Tests - JDK 21 | Build |
Failures | Logs | Raw logs | :mag: |
| ✖ | Native Tests - Security2 | Build |
Failures | Logs | Raw logs | :mag: |
Full information is available in the Build summary check run. You can consult the Develocity build scans.
Failures
:gear: JVM Tests - JDK 17 #
- Failing: extensions/oidc-token-propagation-reactive/deployment extensions/oidc-token-propagation/deployment integration-tests/oidc
! Skipped: integration-tests/oidc-token-propagation integration-tests/oidc-token-propagation-reactive integration-tests/smallrye-jwt-token-propagation
:package: extensions/oidc-token-propagation-reactive/deployment
✖ io.quarkus.oidc.token.propagation.reactive.AccessTokenAnnotationTest.testDefaultClientDefaultTokenExchange line 78 - History - More details - Source on GitHub
java.lang.AssertionError:
1 expectation failed.
Expected status code <200> but was <401>.
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
✖ io.quarkus.oidc.token.propagation.reactive.AccessTokenAnnotationTest.testDefaultClientEnabledTokenExchange line 73 - History - More details - Source on GitHub
java.lang.AssertionError:
1 expectation failed.
Expected status code <200> but was <401>.
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
✖ io.quarkus.oidc.token.propagation.reactive.AccessTokenAnnotationTest.testNamedClientDefaultTokenExchange line 83 - History - More details - Source on GitHub
java.lang.AssertionError:
1 expectation failed.
Expected status code <200> but was <401>.
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
:package: extensions/oidc-token-propagation/deployment
✖ io.quarkus.oidc.token.propagation.AccessTokenAnnotationTest.testDefaultClientDefaultTokenExchange line 77 - History - More details - Source on GitHub
java.lang.AssertionError:
1 expectation failed.
Expected status code <200> but was <401>.
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
✖ io.quarkus.oidc.token.propagation.AccessTokenAnnotationTest.testDefaultClientEnabledTokenExchange line 72 - History - More details - Source on GitHub
java.lang.AssertionError:
1 expectation failed.
Expected status code <200> but was <401>.
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
✖ io.quarkus.oidc.token.propagation.AccessTokenAnnotationTest.testNamedClientDefaultTokenExchange line 82 - History - More details - Source on GitHub
java.lang.AssertionError:
1 expectation failed.
Expected status code <200> but was <401>.
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
✖ io.quarkus.oidc.token.propagation.OidcTokenPropagationTest.testGetUserNameWithTokenPropagation line 42 - History - More details - Source on GitHub
java.lang.AssertionError:
1 expectation failed.
Expected status code <200> but was <401>.
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
:package: integration-tests/oidc
✖ io.quarkus.it.keycloak.HelloResourceTest.testHelloEndpoint - History - More details - Source on GitHub
java.lang.RuntimeException:
java.lang.RuntimeException: io.quarkus.builder.BuildException: Build failure: Build failed due to errors
[error]: Build step io.quarkus.oidc.deployment.devservices.keycloak.KeycloakDevServicesProcessor#startKeycloakContainer threw an exception: java.lang.RuntimeException: java.lang.IllegalArgumentException: SRCFG00025: Recursive expression expansion is too deep for quarkus.oidc.auth-server-url
at io.quarkus.oidc.deployment.devservices.keycloak.KeycloakDevServicesProcessor.startKeycloakContainer(KeycloakDevServicesProcessor.java:250)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
:gear: JVM Tests - JDK 21 #
- Failing: extensions/oidc-token-propagation-reactive/deployment extensions/oidc-token-propagation/deployment integration-tests/oidc
! Skipped: integration-tests/oidc-token-propagation integration-tests/oidc-token-propagation-reactive integration-tests/smallrye-jwt-token-propagation
:package: extensions/oidc-token-propagation-reactive/deployment
✖ io.quarkus.oidc.token.propagation.reactive.AccessTokenAnnotationTest.testDefaultClientDefaultTokenExchange line 78 - History - More details - Source on GitHub
java.lang.AssertionError:
1 expectation failed.
Expected status code <200> but was <401>.
at java.base/jdk.internal.reflect.DirectConstructorHandleAccessor.newInstance(DirectConstructorHandleAccessor.java:62)
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:502)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:486)
at org.codehaus.groovy.reflection.CachedConstructor.invoke(CachedConstructor.java:73)
✖ io.quarkus.oidc.token.propagation.reactive.AccessTokenAnnotationTest.testDefaultClientEnabledTokenExchange line 73 - History - More details - Source on GitHub
java.lang.AssertionError:
1 expectation failed.
Expected status code <200> but was <401>.
at java.base/jdk.internal.reflect.DirectConstructorHandleAccessor.newInstance(DirectConstructorHandleAccessor.java:62)
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:502)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:486)
at org.codehaus.groovy.reflection.CachedConstructor.invoke(CachedConstructor.java:73)
✖ io.quarkus.oidc.token.propagation.reactive.AccessTokenAnnotationTest.testNamedClientDefaultTokenExchange line 83 - History - More details - Source on GitHub
java.lang.AssertionError:
1 expectation failed.
Expected status code <200> but was <401>.
at java.base/jdk.internal.reflect.DirectConstructorHandleAccessor.newInstance(DirectConstructorHandleAccessor.java:62)
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:502)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:486)
at org.codehaus.groovy.reflection.CachedConstructor.invoke(CachedConstructor.java:73)
:package: extensions/oidc-token-propagation/deployment
✖ io.quarkus.oidc.token.propagation.AccessTokenAnnotationTest.testDefaultClientDefaultTokenExchange line 77 - History - More details - Source on GitHub
java.lang.AssertionError:
1 expectation failed.
Expected status code <200> but was <401>.
at java.base/jdk.internal.reflect.DirectConstructorHandleAccessor.newInstance(DirectConstructorHandleAccessor.java:62)
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:502)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:486)
at org.codehaus.groovy.reflection.CachedConstructor.invoke(CachedConstructor.java:73)
✖ io.quarkus.oidc.token.propagation.AccessTokenAnnotationTest.testDefaultClientEnabledTokenExchange line 72 - History - More details - Source on GitHub
java.lang.AssertionError:
1 expectation failed.
Expected status code <200> but was <401>.
at java.base/jdk.internal.reflect.DirectConstructorHandleAccessor.newInstance(DirectConstructorHandleAccessor.java:62)
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:502)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:486)
at org.codehaus.groovy.reflection.CachedConstructor.invoke(CachedConstructor.java:73)
✖ io.quarkus.oidc.token.propagation.AccessTokenAnnotationTest.testNamedClientDefaultTokenExchange line 82 - History - More details - Source on GitHub
java.lang.AssertionError:
1 expectation failed.
Expected status code <200> but was <401>.
at java.base/jdk.internal.reflect.DirectConstructorHandleAccessor.newInstance(DirectConstructorHandleAccessor.java:62)
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:502)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:486)
at org.codehaus.groovy.reflection.CachedConstructor.invoke(CachedConstructor.java:73)
✖ io.quarkus.oidc.token.propagation.OidcTokenPropagationTest.testGetUserNameWithTokenPropagation line 42 - History - More details - Source on GitHub
java.lang.AssertionError:
1 expectation failed.
Expected status code <200> but was <401>.
at java.base/jdk.internal.reflect.DirectConstructorHandleAccessor.newInstance(DirectConstructorHandleAccessor.java:62)
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:502)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:486)
at org.codehaus.groovy.reflection.CachedConstructor.invoke(CachedConstructor.java:73)
:package: integration-tests/oidc
✖ io.quarkus.it.keycloak.HelloResourceTest.testHelloEndpoint - History - More details - Source on GitHub
java.lang.RuntimeException:
java.lang.RuntimeException: io.quarkus.builder.BuildException: Build failure: Build failed due to errors
[error]: Build step io.quarkus.oidc.deployment.devservices.keycloak.KeycloakDevServicesProcessor#startKeycloakContainer threw an exception: java.lang.RuntimeException: java.lang.IllegalArgumentException: SRCFG00025: Recursive expression expansion is too deep for quarkus.oidc.auth-server-url
at io.quarkus.oidc.deployment.devservices.keycloak.KeycloakDevServicesProcessor.startKeycloakContainer(KeycloakDevServicesProcessor.java:250)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at io.quarkus.deployment.ExtensionLoader$3.execute(ExtensionLoader.java:849)
at io.quarkus.builder.BuildContext.run(BuildContext.java:256)
:gear: Native Tests - Security2 #
- Failing: integration-tests/oidc
:package: integration-tests/oidc
✖ io.quarkus.it.keycloak.BearerTokenAuthorizationInGraalITCase.testAccessAdminResourceCustomHeaderNoBearerScheme - History - More details - Source on GitHub
java.lang.RuntimeException:
java.lang.RuntimeException: io.quarkus.builder.BuildException: Build failure: Build failed due to errors
[error]: Build step io.quarkus.oidc.deployment.devservices.keycloak.KeycloakDevServicesProcessor#startKeycloakContainer threw an exception: java.lang.RuntimeException: java.lang.IllegalArgumentException: SRCFG00025: Recursive expression expansion is too deep for quarkus.oidc.auth-server-url
at io.quarkus.oidc.deployment.devservices.keycloak.KeycloakDevServicesProcessor.startKeycloakContainer(KeycloakDevServicesProcessor.java:250)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
Flaky tests - Develocity
:gear: JVM Tests - JDK 17
:package: extensions/smallrye-reactive-messaging-kafka/deployment
✖ io.quarkus.smallrye.reactivemessaging.kafka.deployment.dev.KafkaDevServicesDevModeTestCase.sseStream - History
Assertion condition defined as a Lambda expression in io.quarkus.smallrye.reactivemessaging.kafka.deployment.dev.KafkaDevServicesDevModeTestCase Expecting size of: [] to be greater than or equal to 2 but was 0 within 10 seconds.-org.awaitility.core.ConditionTimeoutException
org.awaitility.core.ConditionTimeoutException:
Assertion condition defined as a Lambda expression in io.quarkus.smallrye.reactivemessaging.kafka.deployment.dev.KafkaDevServicesDevModeTestCase
Expecting size of:
[]
to be greater than or equal to 2 but was 0 within 10 seconds.
at org.awaitility.core.ConditionAwaiter.await(ConditionAwaiter.java:167)
at org.awaitility.core.AssertionCondition.await(AssertionCondition.java:119)
at org.awaitility.core.AssertionCondition.await(AssertionCondition.java:31)
:gear: JVM Tests - JDK 21
:package: integration-tests/reactive-messaging-kafka
✖ io.quarkus.it.kafka.KafkaConnectorTest.testFruits - History
Assertion condition defined as a Lambda expression in io.quarkus.it.kafka.KafkaConnectorTest expected: <6> but was: <5> within 10 seconds.-org.awaitility.core.ConditionTimeoutException
org.awaitility.core.ConditionTimeoutException: Assertion condition defined as a Lambda expression in io.quarkus.it.kafka.KafkaConnectorTest expected: <6> but was: <5> within 10 seconds.
at org.awaitility.core.ConditionAwaiter.await(ConditionAwaiter.java:167)
at org.awaitility.core.AssertionCondition.await(AssertionCondition.java:119)
at org.awaitility.core.AssertionCondition.await(AssertionCondition.java:31)
at org.awaitility.core.ConditionFactory.until(ConditionFactory.java:1006)
at org.awaitility.core.ConditionFactory.untilAsserted(ConditionFactory.java:790)
at io.quarkus.it.kafka.KafkaConnectorTest.testFruits(KafkaConnectorTest.java:63)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
@ozangunalp the extensions/oidc-token-propagation-reactive/deployment errors look suspicious. I wouldn't be surprised if there was an issue with the Keycloak Dev Services new behavior?
@gsmet I am checking this right now.
I'll also disable those flaky Kafka ITs and revisit them later.
Found the problems:
- The oidc extension IT application.properties was self referencing the auth-server config
- The oidc extension tests did use wiremock to simulate the keycloak, so auth-server config needed to be present but replaced by the tests.
:waning_crescent_moon: This workflow status is outdated as a new workflow run has been triggered.
Status for workflow Quarkus CI
This is the status report for running Quarkus CI on commit 5d068ccb22caf6173eb475051904e85d7a0287aa.
Failing Jobs
| Status | Name | Step | Failures | Logs | Raw logs | Build scan |
|---|---|---|---|---|---|---|
| ✖ | Initial JDK 17 Build | Build |
Failures | Logs | Raw logs | :mag: |
You can consult the Develocity build scans.
Failures
:gear: Initial JDK 17 Build #
- Failing: extensions/oidc-token-propagation-reactive/deployment
! Skipped: docs integration-tests/oidc-token-propagation-reactive
:package: extensions/oidc-token-propagation-reactive/deployment
✖ Failed to execute goal net.revelc.code.formatter:formatter-maven-plugin:2.24.1:validate (default) on project quarkus-rest-client-oidc-token-propagation-deployment: File '/home/runner/work/quarkus/quarkus/extensions/oidc-token-propagation-reactive/deployment/src/test/java/io/quarkus/oidc/token/propagation/reactive/AccessTokenAnnotationTest.java' has not been previously formatted. Please format file (for example by invoking `mvn -f extensions/oidc-token-propagation-reactive/deployment net.revelc.code.formatter:formatter-maven-plugin:2.24.1:format`) and commit before running validation!
Status for workflow Quarkus CI
This is the status report for running Quarkus CI on commit 3f11f082aca72393884f6b5cfd355211faa43eeb.
:white_check_mark: The latest workflow run for the pull request has completed successfully.
It should be safe to merge provided you have a look at the other checks in the summary.
Flaky tests - Develocity
:gear: JVM Tests - JDK 21
:package: extensions/smallrye-reactive-messaging/deployment
✖ io.quarkus.smallrye.reactivemessaging.hotreload.ConnectorChangeTest.testUpdatingConnector - History
Expecting actual: ["-6","-7","-9","-10","-11","-12","-13","-14"] to start with: ["-6", "-7", "-8", "-9"]-java.lang.AssertionError
java.lang.AssertionError:
Expecting actual:
["-6","-7","-9","-10","-11","-12","-13","-14"]
to start with:
["-6", "-7", "-8", "-9"]
at io.quarkus.smallrye.reactivemessaging.hotreload.ConnectorChangeTest.testUpdatingConnector(ConnectorChangeTest.java:41)
:gear: Gradle Tests - JDK 17 Windows
:package: integration-tests/gradle
✖ io.quarkus.gradle.devmode.MultiSourceProjectDevModeTest.main - History
Condition with Lambda expression in io.quarkus.test.devmode.util.DevModeClient was not fulfilled within 1 minutes 30 seconds.-org.awaitility.core.ConditionTimeoutException
org.awaitility.core.ConditionTimeoutException: Condition with Lambda expression in io.quarkus.test.devmode.util.DevModeClient was not fulfilled within 1 minutes 30 seconds.
at app//org.awaitility.core.ConditionAwaiter.await(ConditionAwaiter.java:167)
at app//org.awaitility.core.CallableCondition.await(CallableCondition.java:78)
at app//org.awaitility.core.CallableCondition.await(CallableCondition.java:26)
at app//org.awaitility.core.ConditionFactory.until(ConditionFactory.java:1006)
at app//org.awaitility.core.ConditionFactory.until(ConditionFactory.java:975)
at app//io.quarkus.test.devmode.util.DevModeClient.getHttpResponse(DevModeClient.java:164)
at app//io.quarkus.gradle.devmode.QuarkusDevGradleTestBase.getHttpResponse(QuarkusDevGradleTestBase.java:164)
Impacted tests are now green. There is however a behavior change that I've noticed fixing OIDC tests:
Before when a config property was supplied with an expression that is not resolved, the dev service looking at that property would not kick in, because the property value is still non-null. Now with this change, when the expression is not resolved the dev service property check resolves to null, enabling the dev service.
In most cases this is not an issue, you either have a value for that property or not, but for OIDC tests in the quarkus core, there was an interesting case :
Some tests use the OidcWiremockTestResource provided by the test library quarkus-test-oidc-server, which mocks the OIDC flow and provides only the keycloak.url property, not quarkus.oidc.auth-server-url. The OIDC extension was configured in properties with
quarkus.oidc.auth-server-url=${keycloak.url}/realms/quarkus. So when the dev service processor looks at the property, the expression is not resolved thus the property null and starts the dev service. But the test expects the mocked OIDC provider not the dev service.
The workaround I applied is to change the expression to quarkus.oidc.auth-server-url=${keycloak.url:replaced-by-tests}/realms/quarkus.
I am not sure if this would qualify as a breaking change and block the backport. But worth discussing.
@The-Funk @gsmet @geoand
Thanks for raising that.
To be honest, I had been +0 on the backport thing, so this probably tips me to -0.5 :)
Same for me. It is a very minor breaking change, but we should refrain from backporting.
I actually missed the ping and I think it's a bit problematic. I don't see a way to fix this given how things are ordered (and the order makes sense) but we already have one complaint here: https://github.com/quarkusio/quarkus/issues/42273 .
And I suspect we will have more.
I added a note in the migration guide as it's the least we have to do.
Hi @ozangunalp, @gsmet I've missed this whole conversation, but I'm seeing a 2nd issue related to this change,
Can you clarify please, given quarkus.oidc.auth-server-url=${keycloak.url}/realms/quarkus, what exactly has changed that made keycloak.url unresolvable, given that the OIDC test library sets keycloak.url ?
I see #42392, but keycloak.url is defined. What am I missing ?
To summarize, every dev service checks whether a service has already been configured AT BUILD TIME to decide whether to kick in. Before this change, those checks were done without taking the expression expansion into account.
So for a given configuration with quarkus.oidc.auth-server-url=${keycloak.url}/realms/quarkus, when keycloak.url is not set, the value evaluation:
- Without the expression expansion, the value would be
/realms/quarkus(a non-empty value) - With the expression expansion, the value would be
null, because a used expression is not defined, like : https://github.com/quarkusio/quarkus/issues/42392
After this change taking the expression expansion into account, even if a test resource would inject the keycloak.url property, the dev service would've already kicked in because quarkus.oidc.auth-server-url would be evaluated to null.
The workaround I've employed was to provide a fallback to the expression expansion like %test.quarkus.oidc.auth-server-url=${keycloak.url:replaced-by-tests}/realms/quarkus
OK, thanks for the summary @ozangunalp