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

Stork environment variable resolution not working properly #41344

Closed
edeandrea opened this issue Jun 20, 2024 · 21 comments · Fixed by #41318
Closed

Stork environment variable resolution not working properly #41344

edeandrea opened this issue Jun 20, 2024 · 21 comments · Fixed by #41318
Labels
area/config kind/bug Something isn't working
Milestone

Comments

@edeandrea
Copy link
Contributor

edeandrea commented Jun 20, 2024

Describe the bug

When trying to use Stork and trying to set properties (i.e. the service-discovery.address-list property) it doesn't seem to resolve properly.

Expected behavior

I would expect to be able to set Stork properties via env variables.

Actual behavior

It doesn't seem that I can express quarkus.stork.vehicle-data-service.service-discovery.address-list=vpic.nhtsa.dot.gov as an environment variable.

How to Reproduce?

Reproducer:
stork-broken.zip

  1. Download and unzip
  2. cd stork-broken
  3. ./mvnw clean package
  4. export QUARKUS_STORK_VEHICLE_DATA_SERVICE_SERVICE_DISCOVERY_ADDRESS_LIST=vpic.nhtsa.dot.gov
  5. java -jar target/quarkus-app/quarkus-run.jar

You get the following error:

java.util.NoSuchElementException: SRCFG00014: The config property quarkus.stork.vehicle.service-discovery.type is required but it could not be found in any config source
        at io.smallrye.config.SmallRyeConfig.convertValue(SmallRyeConfig.java:435)
        at io.smallrye.config.SmallRyeConfig.getValue(SmallRyeConfig.java:380)
        at io.smallrye.config.ConfigMappingContext$ObjectCreator$9.apply(ConfigMappingContext.java:670)
        at io.smallrye.config.ConfigMappingContext$ObjectCreator$9.apply(ConfigMappingContext.java:665)
        at io.smallrye.config.ConfigMappingContext$ObjectCreator$1.accept(ConfigMappingContext.java:414)
        at io.smallrye.config.ConfigMappingContext$ObjectCreator$1.accept(ConfigMappingContext.java:411)
        at io.smallrye.config.ConfigMappingContext$ObjectCreator.value(ConfigMappingContext.java:665)
        at io.quarkus.stork.StorkServiceDiscoveryConfiguration1376039613Impl.<init>(Unknown Source)
        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 io.smallrye.config.ConfigMappingLoader.configMappingObject(ConfigMappingLoader.java:108)
        at io.smallrye.config.ConfigMappingContext.constructGroup(ConfigMappingContext.java:93)
        at io.smallrye.config.ConfigMappingContext$ObjectCreator$6.apply(ConfigMappingContext.java:610)
        at io.smallrye.config.ConfigMappingContext$ObjectCreator$6.apply(ConfigMappingContext.java:604)
        at io.smallrye.config.ConfigMappingContext$ObjectCreator$1.accept(ConfigMappingContext.java:414)
        at io.smallrye.config.ConfigMappingContext$ObjectCreator$1.accept(ConfigMappingContext.java:411)
        at io.smallrye.config.ConfigMappingContext$ObjectCreator.group(ConfigMappingContext.java:604)
        at io.quarkus.stork.ServiceConfiguration2122640426Impl.<init>(Unknown Source)
        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 io.smallrye.config.ConfigMappingLoader.configMappingObject(ConfigMappingLoader.java:108)
        at io.smallrye.config.ConfigMappingContext.constructGroup(ConfigMappingContext.java:93)
        at io.smallrye.config.ConfigMappingContext$ObjectCreator$7.apply(ConfigMappingContext.java:628)
        at io.smallrye.config.ConfigMappingContext$ObjectCreator$7.apply(ConfigMappingContext.java:621)
        at io.smallrye.config.ConfigMappingContext$ObjectCreator$3$4.accept(ConfigMappingContext.java:532)
        at io.smallrye.config.ConfigMappingContext$ObjectCreator$3$4.accept(ConfigMappingContext.java:514)
        at io.smallrye.config.ConfigMappingContext$ObjectCreator.lazyGroup(ConfigMappingContext.java:621)
        at io.quarkus.stork.StorkConfiguration-1155448456Impl.<init>(Unknown Source)
        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 io.smallrye.config.ConfigMappingLoader.configMappingObject(ConfigMappingLoader.java:108)
        at io.smallrye.config.ConfigMappingContext.constructGroup(ConfigMappingContext.java:93)
        at io.smallrye.config.ConfigMappingContext.constructRoot(ConfigMappingContext.java:88)
        at io.smallrye.config.ConfigMappingContext.<init>(ConfigMappingContext.java:81)
        at io.smallrye.config.ConfigMappingContext.<init>(ConfigMappingContext.java:50)
        at io.smallrye.config.SmallRyeConfig$1.get(SmallRyeConfig.java:128)
        at io.smallrye.config.SmallRyeConfig$1.get(SmallRyeConfig.java:125)
        at io.smallrye.config.SecretKeys.doUnlocked(SecretKeys.java:28)
        at io.smallrye.config.SmallRyeConfig.buildMappings(SmallRyeConfig.java:125)
        at io.smallrye.config.SmallRyeConfig.<init>(SmallRyeConfig.java:88)
        at io.smallrye.config.SmallRyeConfigBuilder.build(SmallRyeConfigBuilder.java:691)
        at io.quarkus.runtime.generated.Config.readConfig(Unknown Source)
        at io.quarkus.runtime.generated.Config.createRunTimeConfig(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:111)
        at io.quarkus.runtime.Quarkus.run(Quarkus.java:71)
        at io.quarkus.runtime.Quarkus.run(Quarkus.java:44)
        at io.quarkus.runtime.Quarkus.run(Quarkus.java:124)
        at io.quarkus.runner.GeneratedMain.main(Unknown Source)
        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.bootstrap.runner.QuarkusEntryPoint.doRun(QuarkusEntryPoint.java:62)
        at io.quarkus.bootstrap.runner.QuarkusEntryPoint.main(QuarkusEntryPoint.java:33)
Configuration validation failed:
        java.util.NoSuchElementException: SRCFG00014: The config property quarkus.stork.vehicle.service-discovery.type is required but it could not be found in any config source
java.lang.RuntimeException: Failed to start quarkus
        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:111)
        at io.quarkus.runtime.Quarkus.run(Quarkus.java:71)
        at io.quarkus.runtime.Quarkus.run(Quarkus.java:44)
        at io.quarkus.runtime.Quarkus.run(Quarkus.java:124)
        at io.quarkus.runner.GeneratedMain.main(Unknown Source)
        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.bootstrap.runner.QuarkusEntryPoint.doRun(QuarkusEntryPoint.java:62)
        at io.quarkus.bootstrap.runner.QuarkusEntryPoint.main(QuarkusEntryPoint.java:33)
Caused by: io.quarkus.runtime.configuration.ConfigurationException: Failed to read configuration properties
        at io.quarkus.deployment.steps.RuntimeConfigSetup.deploy(Unknown Source)
        ... 11 more
Caused by: io.smallrye.config.ConfigValidationException: Configuration validation failed:
        java.util.NoSuchElementException: SRCFG00014: The config property quarkus.stork.vehicle.service-discovery.type is required but it could not be found in any config source
        at io.smallrye.config.SmallRyeConfig.buildMappings(SmallRyeConfig.java:138)
        at io.smallrye.config.SmallRyeConfig.<init>(SmallRyeConfig.java:88)
        at io.smallrye.config.SmallRyeConfigBuilder.build(SmallRyeConfigBuilder.java:691)
        at io.quarkus.runtime.generated.Config.readConfig(Unknown Source)
        at io.quarkus.runtime.generated.Config.createRunTimeConfig(Unknown Source)
        ... 12 more

The value it should be trying to set is quarkus.stork.vehicle-data-service.service-discovery.address-list=vpic.nhtsa.dot.gov.

You can also try

  1. export QUARKUS_STORK__VEHICLE_DATA_SERVICE__SERVICE_DISCOVERY_ADDRESS_LIST=vpic.nhtsa.dot.gov
  2. java -jar target/quarkus-app/quarkus-run.jar

But that doesn't work either. It has the same error.

Output of uname -a or ver

Darwin edeandrea-m1pro 23.5.0 Darwin Kernel Version 23.5.0: Wed May 1 20:12:58 PDT 2024; root:xnu-10063.121.3~5/RELEASE_ARM64_T6000 arm64

Output of java -version

openjdk version "17.0.11" 2024-04-16
OpenJDK Runtime Environment Temurin-17.0.11+9 (build 17.0.11+9)
OpenJDK 64-Bit Server VM Temurin-17.0.11+9 (build 17.0.11+9, mixed mode)

Quarkus version or git rev

3.11.3

Build tool (ie. output of mvnw --version or gradlew --version)

Apache Maven 3.9.6 (bc0240f3c744dd6b6ec2920b3cd08dcc295161ae)
Maven home: /Users/edeandre/.m2/wrapper/dists/apache-maven-3.9.6-bin/3311e1d4/apache-maven-3.9.6
Java version: 17.0.11, vendor: Eclipse Adoptium, runtime: /Users/edeandre/.sdkman/candidates/java/17.0.11-tem
Default locale: en_US, platform encoding: UTF-8
OS name: "mac os x", version: "14.5", arch: "aarch64", family: "mac"

Additional information

If you run the app in dev mode it should work because I have %dev.quarkus.stork.vehicle-data-service.service-discovery.address-list=vpic.nhtsa.dot.gov in application.properties.

To see how it should behave, when running dev mode you can curl http://localhost:8080/vehicle-data/audi. You should get something back like this:

{
    "Count": 2,
    "Message": "Response returned successfully",
    "Results": [
        {
            "MakeId": 582,
            "MakeName": "AUDI",
            "VehicleTypeId": 2,
            "VehicleTypeName": "Passenger Car"
        },
        {
            "MakeId": 582,
            "MakeName": "AUDI",
            "VehicleTypeId": 7,
            "VehicleTypeName": "Multipurpose Passenger Vehicle (MPV)"
        }
    ],
    "SearchCriteria": "Make: audi"
}
@edeandrea edeandrea added the kind/bug Something isn't working label Jun 20, 2024
Copy link

quarkus-bot bot commented Jun 20, 2024

/cc @aureamunoz (stork), @cescoffier (stork)

@geoand
Copy link
Contributor

geoand commented Jun 21, 2024

cc @radcortez

@radcortez
Copy link
Member

Is this a new issue, or has it worked in the past?

@geoand geoand added the triage/needs-feedback We are waiting for feedback. label Jun 21, 2024
@edeandrea
Copy link
Contributor Author

I don't know exactly when it stopped working, but it has always worked. The example I put together is a simple example to illustrate the problem. I actually noticed it in the superheroes sample when trying to run the docker compose files.

@cescoffier
Copy link
Member

We had a similar report on reactive messaging. I suspect it is related.

@edeandrea
Copy link
Contributor Author

if you clone https://github.com/quarkusio/quarkus-super-heroes, cd quarkus-super-heroes, and run docker compose -f rest-fights/deploy/docker-compose/java17.yml up you'll see similar errors:

rest-fights-java17  | Configuration validation failed:
rest-fights-java17  | 	java.util.NoSuchElementException: SRCFG00014: The config property quarkus.stork.villain.service-discovery.type is required but it could not be found in any config source
rest-fights-java17  | 	java.util.NoSuchElementException: SRCFG00014: The config property quarkus.stork.narration.service-discovery.type is required but it could not be found in any config source
rest-fights-java17  | 	java.util.NoSuchElementException: SRCFG00014: The config property quarkus.stork.hero.service-discovery.type is required but it could not be found in any config source
rest-fights-java17  | java.lang.RuntimeException: Failed to start quarkus

The compose file (https://github.com/quarkusio/quarkus-super-heroes/blob/main/rest-fights/deploy/docker-compose/java17.yml) looks like this:

  rest-fights-java17:
    image: quay.io/quarkus-super-heroes/rest-fights:java17-latest
    container_name: rest-fights-java17
    depends_on:
      - fights-db
      - apicurio
      - fights-kafka
    ports:
      - "8082:8082"
    environment:
      QUARKUS_MONGODB_HOSTS: fights-db:27017
      KAFKA_BOOTSTRAP_SERVERS: PLAINTEXT://fights-kafka:9092
      QUARKUS_LIQUIBASE_MONGODB_MIGRATE_AT_START: "false"
      QUARKUS_MONGODB_CREDENTIALS_USERNAME: superfight
      QUARKUS_MONGODB_CREDENTIALS_PASSWORD: superfight
      QUARKUS_STORK_HERO_SERVICE_SERVICE_DISCOVERY_ADDRESS_LIST: rest-heroes:8083
      QUARKUS_STORK_VILLAIN_SERVICE_SERVICE_DISCOVERY_ADDRESS_LIST: rest-villains:8084
      QUARKUS_STORK_NARRATION_SERVICE_SERVICE_DISCOVERY_ADDRESS_LIST: rest-narration:8087
      QUARKUS_GRPC_CLIENTS_LOCATIONS_HOST: grpc-locations
      QUARKUS_GRPC_CLIENTS_LOCATIONS_PORT: 8089
      MP_MESSAGING_CONNECTOR_SMALLRYE_KAFKA_APICURIO_REGISTRY_URL: http://apicurio:8086/apis/registry/v2
      QUARKUS_OTEL_EXPORTER_OTLP_TRACES_ENDPOINT: http://otel-collector:4317
    restart: on-failure
    networks:
      default:
        aliases:
          - rest-fights
    deploy:
      resources:
        limits:
          memory: 1G
          cpus: '1'
        reservations:
          memory: 256M
          cpus: '0.5'

@edeandrea
Copy link
Contributor Author

I can verify it works with Quarkus 3.8, so it broke sometime between 3.8 & current.

@edeandrea
Copy link
Contributor Author

If you clone https://github.com/quarkusio/quarkus-super-heroes/tree/3.8.Final (3.8.Final branch)

and then do

docker compose -f rest-fights/deploy/docker-compose/java17-all-downstream.yml up

Wait for everything to come up

then do curl http://localhost:8082/api/fights/randomfighters, you should see a successful response, whereas if you do the same with the main branch you get config errors.

@radcortez
Copy link
Member

We had a similar report on reactive messaging. I suspect it is related.

I believe it is unrelated. I tried the fix from the other issue, but the problem remained. I've also tried with Quarkus 3.10.x, which worked for RM but failed with this scenario. That is why I was asking if it worked previously or if it was something new. I'll investigate.

@radcortez
Copy link
Member

It is the same issue, but the reproducer misled me. Remember, to be able to set QUARKUS_STORK__VEHICLE_DATA_SERVICE__SERVICE_DISCOVERY_ADDRESS_LIST, you need the dotted name property quarkus.stork.vehicle.service-discovery.address-list:
https://quarkus.io/guides/config-reference#environment-variables

There is indeed an issue where the matching is not currently working, which will be fixed by #41318

@radcortez radcortez added area/config and removed area/stork triage/needs-feedback We are waiting for feedback. labels Jun 22, 2024
@edeandrea
Copy link
Contributor Author

Why would it resolve to quarkus.stork.vehicle.service-discovery.address-list? Shouldn't it resolve to quarkus.stork.vehicle-data-service.service-discovery.address-list?

@quarkus-bot quarkus-bot bot added this to the 3.13 - main milestone Jun 24, 2024
@radcortez
Copy link
Member

Why would it resolve to quarkus.stork.vehicle.service-discovery.address-list? Shouldn't it resolve to quarkus.stork.vehicle-data-service.service-discovery.address-list?

In your reproducer the env var does not add quotes to VEHICLE_DATA_SERVICE.

4. export QUARKUS_STORK_VEHICLE_DATA_SERVICE_SERVICE_DISCOVERY_ADDRESS_LIST=vpic.nhtsa.dot.gov

So it gets translated to quarkus.stork.vehicle.data.service.service.discovery.address.list, so the Map mapping only takes vehicle as the map key and tries to resolve required configuration under that map key in quarkus.stork.vehicle.service-discovery.type.

@edeandrea
Copy link
Contributor Author

Got it. I didn't realize I needed the quotes. When using the dot notation (quarkus.stork.vehicle-data-service...) it works fine. I didn't realize the quotes were required.

@radcortez
Copy link
Member

The quotes are required when the map key contains a .. or else it is handled as a segment separator. In that case, the dotted format does not need quotes, because there is no . in map key. For Env Vars, the quotes are always required to help us disambiguate the cases since we cannot determine if a _ is a . or a -.

@edeandrea
Copy link
Contributor Author

Thank you for the explanation!

@gsmet gsmet modified the milestones: 3.13 - main, 3.12.1 Jun 26, 2024
edeandrea added a commit to quarkusio/quarkus-super-heroes that referenced this issue Jun 27, 2024
This coincides with quarkusio/quarkus#41344, which won't be released until Quarkus 3.12.1 (next micro-release). Its broken now anyways, so no harm with this change now.
@edeandrea
Copy link
Contributor Author

edeandrea commented Jul 12, 2024

Hey @radcortez I've updated the superheroes app to Quarkus 3.12.2 but this still seems to be broken...I've updated the config:

https://github.com/quarkusio/quarkus-super-heroes/blob/45345e4a4515cdcc94f107d443348acbc80b8c90/rest-fights/deploy/docker-compose/java17-all-downstream.yml#L60-L62

QUARKUS_STORK__HERO_SERVICE__SERVICE_DISCOVERY_ADDRESS_LIST: rest-heroes:8083
QUARKUS_STORK__VILLAIN_SERVICE__SERVICE_DISCOVERY_ADDRESS_LIST: rest-villains:8084
QUARKUS_STORK__NARRATION_SERVICE__SERVICE_DISCOVERY_ADDRESS_LIST: rest-narration:8087

But yet it still doesn't seem to take. These properties should resolve to

quarkus.stork."hero-service".service-discovery.address-list=rest-heroes:8083
quarkus.stork."villain-service".service-discovery.address-list=rest-villains:8084
quarkus.stork."narration-service".service-discovery.address-list=rest-narration:8087

@radcortez
Copy link
Member

What is the error exactly?

I've added exactly that mapping to SmallRye Config tests, and it works as expected:
smallrye/smallrye-config@4863a60

@edeandrea
Copy link
Contributor Author

edeandrea commented Jul 16, 2024

I'm not getting an error per-se, but the config does not bind properly.

@edeandrea
Copy link
Contributor Author

edeandrea commented Jul 16, 2024

  1. Clone https://github.com/quarkusio/quarkus-super-heroes.git
  2. cd rest-fights
  3. docker compose -f deploy/docker-compose/java17-all-downstream.yml up (or you can use podman compose)
  4. Wait for everything to start up
  5. Try to curl http://localhost:8082/api/fights/randomfighters. You'll notice you get the fallback hero & villain:
{
  "hero": {
    "name": "Fallback hero",
    "level": 1,
    "picture": "https://dummyimage.com/240x320/1e8fff/ffffff&text=Fallback+Hero",
    "powers": "Fallback hero powers"
  },
  "villain": {
    "name": "Fallback villain",
    "level": 45,
    "picture": "https://dummyimage.com/240x320/b22222/ffffff&text=Fallback+Villain",
    "powers": "Fallback villain powers"
  }
}

Thats because the default config is to go to localhost. The compose file overrides this via env variables (https://github.com/quarkusio/quarkus-super-heroes/blob/main/rest-fights/deploy/docker-compose/java17-all-downstream.yml#L60-L62):

      QUARKUS_STORK__HERO_SERVICE__SERVICE_DISCOVERY_ADDRESS_LIST: rest-heroes:8083
      QUARKUS_STORK__VILLAIN_SERVICE__SERVICE_DISCOVERY_ADDRESS_LIST: rest-villains:8084
      QUARKUS_STORK__NARRATION_SERVICE__SERVICE_DISCOVERY_ADDRESS_LIST: rest-narration:8087

@radcortez
Copy link
Member

Sorry, I was not clear.

When properties override dotted names, the env vars have to follow the same format. So either use:

quarkus.stork.hero-service.service-discovery.address-list
QUARKUS_STORK_HERO_SERVICE_SERVICE_DISCOVERY_ADDRESS_LIST

or

quarkus.stork."hero-service".service-discovery.address-list
QUARKUS_STORK__HERO_SERVICE__SERVICE_DISCOVERY_ADDRESS_LIST

I've just changed the env var to QUARKUS_STORK_HERO_SERVICE_SERVICE_DISCOVERY_ADDRESS_LIST, and it worked as expected.

We may consider adding a convenience to support mixed quoted mode.

@edeandrea
Copy link
Contributor Author

You're right, it does work. Maybe I mis-interpreted what you have said. I was under the assumption that I needed to use QUARKUS_STORK__HERO_SERVICE__SERVICE_DISCOVERY_ADDRESS_LIST due to needing " to wrap the service name (https://quarkus.io/guides/all-config#quarkus-smallrye-stork_quarkus-stork-service-name-service-discovery-type).

But using QUARKUS_STORK_HERO_SERVICE_SERVICE_DISCOVERY_ADDRESS_LIST does seem to work, which it did before it broke (hence why I created this issue in the first place). Now it seems to work again. Perhaps #41318 was the fix to make that work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/config kind/bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants