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

Conditional documents in profile specific file are not loaded consistently #11109

Closed
LProemer opened this issue Nov 22, 2017 · 7 comments
Closed
Labels
type: bug A general bug
Milestone

Comments

@LProemer
Copy link

LProemer commented Nov 22, 2017

I've following problem.

I've an instance with following active profiles:
dev, test, foo

and apllication-test.yaml file

---
my.prop1: default
my.prop2: default
---
spring.profiles: dev
my.
    prop1: dev
    prop3: abc
---
spring.profiles: foo
my.prop2: foo

My intuition would tell me:
my.prop1 = dev
my.prop2 = foo

Thought the result is really:
my.prop1 = default
my.prop2 = foo

It seems to use the order of profiles, rather then the order of the document.
This seems to be different then what the documentation is saying.
(Correct me if I'm wrong)

Further more my.prop3 seems to be not set at all as if this section is ignored even if dev is set active.

Is this a bug of Spring or is there a trick to it?

lG
Lukas

@LProemer LProemer changed the title application-{$profile} yaml, reading order is wired application-{$profile} yaml, reading order is weird Nov 22, 2017
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Nov 22, 2017
@wilkinsona
Copy link
Member

Sorry, I'm finding it a little hard to follow your description of the problem. Can you please provide a small sample that reproduces the problem so that we can be sure we're investigating the right thing?

@wilkinsona wilkinsona added the status: waiting-for-feedback We need additional information before we can continue label Nov 22, 2017
@LProemer
Copy link
Author

I'm sorry, my english isn't that good.
I do my best to give a good example.

Basically the problem is simple:
When you have an "application-bar.yaml",
And spring.profiles.active is set to "foo, bar"
Then the sub-section inside the yaml file where
"spring.profiles: foo" is set, is ignored.

application.properties:
spring.profiles.active = foo, bar, abc

application-bar.yaml

---
// default values
my.var: 1                   
other.var: 1               
---
spring.profiles: foo   
my.var: 2                  // is ignored, even thought profile foo is set
---
spring.profiles: abc 
other.var: 2             // is correctly applied 

Result:
my.var = 1
other.var = 2

Does that help?

lG

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels Nov 22, 2017
@philwebb
Copy link
Member

I think this is related to c6bf13c (issue #4132). Having profile specific sections in a profile specific file is a little unusual and I don't think we've considered this edge case.

@philwebb philwebb added priority: low type: bug A general bug and removed status: feedback-provided Feedback has been provided status: waiting-for-triage An issue we've not yet triaged labels Nov 23, 2017
@philwebb
Copy link
Member

@LProemer any specific reason you need to use application-bar.yaml to contain those extra sections?

@LProemer
Copy link
Author

The reason would be Feature-Configurations. The Feature is only enabled when the profile "bar" is set and should then configure it acording to the environment.
We've tenths of configurations files and we've to start cleaning them up and simplyfy them. And using yaml-configurations like this would have been one way.
Thought I'm aware that they are other ways to work around this problems.

@shakuzen
Copy link
Member

I also ran into this problem and it took quite some time to track it down and figure out why it was happening. My use case is that we have configuration properties specific to logical environments (say dev, stg, prod) and that we want to be active only when the application is running on our platform (Cloud Foundry as cloud profile; or our other platform that uses the server profile) as opposed to a developer's machine. The assumption being a developer might activate a logical environment profile from her or his machine but would not activate cloud or server.

Therefore, to achieve this, it seemed reasonable to me to put say the DEV environment spring.boot.admin.client.uri in a file application-dev.yml like:

---
spring:
  profiles: cloud,server

  boot.admin.client.uri: http://my-admin-url

The above works fine, actually, if the active profiles are in the "right" order dev,cloud, but it does not work if the order is cloud,dev. This can also be demonstrated by the following change to an existing Spring Boot test (switch the order of the active profiles):

===================================================================
--- spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/ConfigFileApplicationListenerTests.java	(revision 3ae4a541b630fb7bccf45ebd0922c19d099c2276)
+++ spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/ConfigFileApplicationListenerTests.java	(date 1521006994000)
@@ -777,7 +777,7 @@
 		SpringApplication application = new SpringApplication(Config.class);
 		application.setWebApplicationType(WebApplicationType.NONE);
 		this.context = application.run(
-				"--spring.profiles.active=activeprofilewithdifferentsubdoc,activeprofilewithdifferentsubdoc2");
+				"--spring.profiles.active=activeprofilewithdifferentsubdoc2,activeprofilewithdifferentsubdoc");
 		String property = this.context.getEnvironment().getProperty("foobar");
 		assertThat(property).isEqualTo("baz");
 	}

@Test
public void profileSubDocumentInDifferentProfileSpecificFile() {
// gh-4132
SpringApplication application = new SpringApplication(Config.class);
application.setWebApplicationType(WebApplicationType.NONE);
this.context = application.run(
"--spring.profiles.active=activeprofilewithdifferentsubdoc,activeprofilewithdifferentsubdoc2");
String property = this.context.getEnvironment().getProperty("foobar");
assertThat(property).isEqualTo("baz");
}

I've also pushed a repro project with a failing test case: https://github.com/shakuzen/demo-compound-profile

To summarize the use case, being able to use sub-documents in YAML files that are themselves profiled allows for AND semantics. In the example shown above, the dev profile AND the cloud (OR server) profile should be active for the property source to be included. #12469 was raised recently also regarding AND profile matching semantics. What I find nice about what I expected to work (and does if the active profile order is "right") is that it allows one AND and an arbitrary number of ORs. Perhaps the outcome of SPR-12458 will pave a way for something more robust.

For my specific use case mentioned above, we can work around this thanks to Spring Boot Admin client offering an enabled property that we can set to false by default and only make it true when the cloud OR server profile is active. Perhaps there are other use cases that aren't as easily worked around. At the least, the behavior was hard to understand and surprising.

@philwebb philwebb added this to the Icebox milestone Mar 21, 2018
@mbhave
Copy link
Contributor

mbhave commented Jul 31, 2020

This should be solved by config data rewrite in 2.4.x. For multi-document files, later documents can override the properties defined in earlier ones. With the following configuration in application-test.yml and active profiles of dev, foo, test,

---
my.prop1: default
my.prop2: default
---
spring.profiles: dev
my.
    prop1: dev
    prop3: abc
---
spring.profiles: foo
my.prop2: foo

the result is

my.prop1 = dev
my.prop2 = foo
my.prop3 = abc

@mbhave mbhave closed this as completed Jul 31, 2020
@mbhave mbhave modified the milestones: General Backlog, 2.4.x, 2.4.0-M2 Jul 31, 2020
@mbhave mbhave changed the title application-{$profile} yaml, reading order is weird Conditional documents in profile specific file are not loaded consistently Jul 31, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: bug A general bug
Projects
None yet
Development

No branches or pull requests

6 participants