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

Profile-specific files should still be considered when processing 'spring.config.import' properties #26858

Closed
pneyer opened this issue Jun 10, 2021 · 12 comments
Assignees
Labels
type: regression A regression from a previous release
Milestone

Comments

@pneyer
Copy link

pneyer commented Jun 10, 2021

SB 2.5.1 breaks our project, since profile specific properties in combination with config-imports in a multi maven module are not properly resolved anymore. This worked for us with SB 2.5.0 and SB 2.4.5

My guess it's due to issues #26754 and #26755 fixed for SB 2.5.1/2.4.7, which imho are features, not bugs.

Consider following simplified project setup, maven multi module project, two SB applications and a shared common module:

module "application FOO"

  • application.properties
    • content: spring.config.import=classpath:common.properties
  • application-local.properties
  • application-yourname.properties
  • application-prod.properties

module "application BAR"

  • application.properties
    • content: spring.config.import=classpath:common.properties
  • application-local.properties
  • application-yourname.properties
  • application-prod.properties

module "COMMON"

  • common.properties
  • common-local.properties
  • common-yourname.properties
  • common-prod.properties

We have defined some common properties per profile in module "COMMON", so we don't have to copy&paste (DRY) all properties which are needed by application FOO and application BAR. (Actually we have way more modules/applications, so it was a real hassle to refactor this some weeks ago for SB 2.4.0).
Common properties for all applications end up in "common.properties", common properties for all production environments end up in "common-prod.properties" etc.

Behavior in SB 2.5.0 (and working from 2.4.0 to SB 2.4.5):
Running "application FOO" with spring.profiles.active="local,yourname" used properties in following order (the latter overwrites to former):
COMMON/common.properties < COMMON/common-local.properties < COMMON/common-yourname.properties < FOO/application.properties < FOO/application-local.properties < FOO/application-yourname.properties

This does not work with SB 2.5.1 anymore. Application startup fails, because it cannot resolve some properties/placeholders we inject in a @Service

Please consider reverting the mentioned fixes, because SB 2.5.1 (and probably 2.4.7) is not backward compatible and break existing applications that relied on these features

See attached example project for demo, Run "DemoApplication" in demo-module with spring.profiles.active="prod". Modify SB version in parent pom.xml.
SB 2.5.0 outputs "common-prod"
SB 2.5.1 outputs "application-prod"
demo.zip

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Jun 10, 2021
@ghillert
Copy link

I can confirm that some ConfigData API change breaks my app in 2.4.7. 2.4.6 works. Still investigating whether it is related to the above issue.

@adgoudz
Copy link

adgoudz commented Jun 11, 2021

The changes for #26752 in 2.4.7 broke all of our applications this week. StandardConfigDateLocationResolver.resolveProfileSpecific is returning early when resolving the ConfigDataResources for all of our imports, and I can see that this behavior was just added in d1b256a.

I really thought the import behavior in 2.4.0-2.4.6 was elegant... not surprising. We have dozens of applications that pull in common configuration from shared libraries, and sometimes those common configuration files pull in configuration from other shared libraries. We configure for 10+ profiles, so now we're needing to add imports to all of our profile-specific configuration. In some cases we don't have profile-specific configuration files, i.e. for the profiles that don't deviate from the defaults. Now we need to create files that contain only a sprint.config.import for other profile-specific files.

The last example I'll share is that we can no longer activate a profile to manipulate the shared configuration that gets imported. The best alternative I can think of is to do something like this:

spring:
  config:
    import: file-for-the-${shared-env-name:default}-environment.yaml

It seems like #26752, #26753, #26754, #26755 were added to prevent problems that I don't understand. If they can't be reverted, could there be a way for developers to opt-in to one behavior over the other?

@pavankjadda
Copy link

We have this issue as well. After upgrading to Spring Boot 2.5.1 the application failed to start. We load environment specific properties through yaml files.

@mtc3bmtc3b
Copy link

I'll chime in with "me too". In our case, we are using Vault to store credentials, Consul for some runtime configuration, and also profile-based configuration for 'configuration as code'. We have application-common.properties but also application-.properties for non-sensitive configuration values for specific environments (i.e. dev, test, prod) - like the location of some external services and our database URLs.

Consul/Vault appear to require the use of spring.config.import, but we also want to use profile-based configuration so we don't have the same configuration in 10+ places (all our microservices and our test infrastructure). On 2.4.5, we had the Consul/Vault config in application-common.properties along with the required spring.config.import=vault://,consul://. Everything just worked.

After upgrading to 2.5.1 (same with 2.4.7), it broke. Moving our Consul/Vault configuration (including the spring.config.import line to include it) to each application's application.properties appears to at least allow the application to start (not convinced it works fully yet). This works since our Consul/Vault config is the same across environments, except for our access tokens which are retrieved via the environment or k8s secrets. So, we don't need environment-specific Consul/Vault config. If we did, then that would also have to move outside of the app. Using this approach of spring.config.import residing in application.properties seems to import both ConsulVault and the environment-specific config files.

I'll second the notion that this change really does not belong in a patch release. It is a change in behavior that really belongs in a minor or major release - with explicit mention in the Release Notes.

@philwebb philwebb added the for: team-meeting An issue we'd like to discuss as a team to make progress label Jun 14, 2021
@philwebb philwebb changed the title Allow profile-specific config-imports again in property files (please revert 26754 and/or 26755) Profile-specific files should still be considered when processing 'spring.config.import' properties Jun 16, 2021
@philwebb philwebb added type: regression A regression from a previous release and removed for: team-meeting An issue we'd like to discuss as a team to make progress status: waiting-for-triage An issue we've not yet triaged labels Jun 16, 2021
@philwebb philwebb added this to the 2.4.x milestone Jun 16, 2021
@philwebb
Copy link
Member

Sorry for the inconvenience this change made. Importing profile specific files was somewhat accidental and we didn't anticipate that people would be using it. We'll look at reverting the change and adding some additional tests and docs.

@pavankjadda
Copy link

@philwebb Unless I am missing something here, isn't that the reason different profiles exist? If not what's the recommended way to load environment specific properties through profiles(if possible please update the docs)?

@philwebb
Copy link
Member

@pavankjadda The spring.config.import feature is new in 2.4 and we primarily expected it to be used in the form spring-config.import=some.properties (without some-<profile>.properties being considered). For profile-specific imports, we anticipated that they'd be referenced via profile-specific sections, E.g.:

application.properties

some.property=test
#---
spring.config.activate.on-profile=prod
spring.config.import=production.properties

We're going to restore the old behavior so some-<profile>.properties will be considered again. We'll also try to clarify the documentation.

@philwebb philwebb self-assigned this Jun 17, 2021
@pavankjadda

This comment has been minimized.

@philwebb

This comment has been minimized.

@philwebb
Copy link
Member

I've pushed a fix that should hopefully restore the old behavior. CI should publish a new SNAPSHOT in the next hour or so. It would be helpful if someone watching this issue could give it a spin.

@kaliy
Copy link
Contributor

kaliy commented Jun 18, 2021

In my case it didn't work, because it's related to 0da0d2d commit.

I have profile groups for different environments specified like

spring:
  profiles:
    group:
      prod:
        - vault
        - consul

So for prod I have consul profile set up and configuration inside the application-consul.yml is following:

spring:
  config:
    import: "consul://"
# consul-specific properties are omitted

In spring cloud consul integration the method resolve() returns empty list (the same is with spring cloud vault). resolveProfileSpecific() is not called at all.

@kaliy
Copy link
Contributor

kaliy commented Jun 18, 2021

Ok, I guess my issue is related to #26950 rather than #26858

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: regression A regression from a previous release
Projects
None yet
Development

No branches or pull requests

8 participants