Describe the bug
AwsS3EnvironmentRepository appears to return PropertySources in the wrong precedence order when multiple profiles are requested.
According to the Spring Cloud Config documentation:
Active profiles take precedence over defaults, and, if there are multiple profiles, the last one wins.
The documentation also states that higher-precedence property sources should appear earlier in the returned Environment.
For example, given the profiles:
default,dev,ap-southeast-1
the expected precedence is:
ap-southeast-1 > dev > default
However, AwsS3EnvironmentRepository returns the property sources in the same order as the requested profiles:
default
dev
ap-southeast-1
Since property sources listed earlier in the Environment have higher precedence, this effectively gives default the highest precedence, which is the opposite of the documented profile precedence.
Version
Observed with:
Spring Cloud: 2023.0.0
Spring Cloud Config Server: 4.1.0
Backend: AwsS3EnvironmentRepository
Steps to reproduce
Assume the following S3 configuration files:
# demo-service-default.yml
test:
value: default
# demo-service-dev.yml
test:
value: dev
# demo-service-ap-southeast-1.yml
test:
value: regional
Request the Config Server environment using multiple profiles:
GET /demo-service/default,dev,ap-southeast-1
The returned Environment.propertySources are ordered like this:
s3:demo-service-default
s3:demo-service-dev
s3:demo-service-ap-southeast-1
Actual behavior
The returned order is:
default
dev
ap-southeast-1
Because the first PropertySource has the highest precedence, the effective precedence becomes:
default > dev > ap-southeast-1
For a property defined in all three profiles, the default value wins.
Expected behavior
Based on Spring Cloud Config's documented profile precedence, the last active profile should have the highest precedence.
Therefore, for:
default,dev,ap-southeast-1
the expected PropertySource order should be:
s3:demo-service-ap-southeast-1
s3:demo-service-dev
s3:demo-service-default
and the effective precedence should be:
ap-southeast-1 > dev > default
so that:
Additional context
This issue became visible to us after upgrading a Quarkus application.
Prior to Quarkus 3.32.0, quarkus-spring-cloud-config-client requested each active profile separately and represented the returned values as profile-specific SmallRye Config properties. As a result, the Config Server's ordering across multiple profiles was not used to determine the final value.
Starting with Quarkus 3.32.0, the client behavior was intentionally changed to send all profiles in a single Spring Cloud Config request, matching the behavior of the standard Spring Cloud Config client:
/demo-service/default,dev,ap-southeast-1
Relevant Quarkus change:
quarkusio/quarkus#52435
This caused the ordering returned by AwsS3EnvironmentRepository to directly affect configuration precedence and exposed the issue.
Reversing the profiles in the request confirms that this is an ordering issue.
For example:
GET /demo-service/ap-southeast-1,dev,default
causes the S3 repository to return:
s3:demo-service-ap-southeast-1
s3:demo-service-dev
s3:demo-service-default
and the regional configuration then correctly wins.
Why this appears inconsistent
The documented Spring Cloud Config behavior is:
profiles = default,dev,ap-southeast-1
precedence:
ap-southeast-1 > dev > default
but AwsS3EnvironmentRepository appears to preserve the incoming profile iteration order when constructing the Environment:
default
dev
ap-southeast-1
Since higher precedence corresponds to appearing earlier in Environment.propertySources, preserving the incoming profile order reverses the intended profile precedence.
Documentation reference
Spring Cloud Config Environment Repository documentation:
https://docs.spring.io/spring-cloud-config/reference/server/environment-repository.html
Relevant documented behavior:
- Active profiles take precedence over defaults.
- If there are multiple profiles, the last one wins.
- Higher precedence translates to a
PropertySource listed earlier in the Environment.
Describe the bug
AwsS3EnvironmentRepositoryappears to returnPropertySources in the wrong precedence order when multiple profiles are requested.According to the Spring Cloud Config documentation:
The documentation also states that higher-precedence property sources should appear earlier in the returned
Environment.For example, given the profiles:
the expected precedence is:
However,
AwsS3EnvironmentRepositoryreturns the property sources in the same order as the requested profiles:Since property sources listed earlier in the
Environmenthave higher precedence, this effectively givesdefaultthe highest precedence, which is the opposite of the documented profile precedence.Version
Observed with:
Steps to reproduce
Assume the following S3 configuration files:
Request the Config Server environment using multiple profiles:
The returned
Environment.propertySourcesare ordered like this:Actual behavior
The returned order is:
Because the first
PropertySourcehas the highest precedence, the effective precedence becomes:For a property defined in all three profiles, the
defaultvalue wins.Expected behavior
Based on Spring Cloud Config's documented profile precedence, the last active profile should have the highest precedence.
Therefore, for:
the expected
PropertySourceorder should be:and the effective precedence should be:
so that:
Additional context
This issue became visible to us after upgrading a Quarkus application.
Prior to Quarkus 3.32.0,
quarkus-spring-cloud-config-clientrequested each active profile separately and represented the returned values as profile-specific SmallRye Config properties. As a result, the Config Server's ordering across multiple profiles was not used to determine the final value.Starting with Quarkus 3.32.0, the client behavior was intentionally changed to send all profiles in a single Spring Cloud Config request, matching the behavior of the standard Spring Cloud Config client:
Relevant Quarkus change:
quarkusio/quarkus#52435
This caused the ordering returned by
AwsS3EnvironmentRepositoryto directly affect configuration precedence and exposed the issue.Reversing the profiles in the request confirms that this is an ordering issue.
For example:
causes the S3 repository to return:
and the regional configuration then correctly wins.
Why this appears inconsistent
The documented Spring Cloud Config behavior is:
but
AwsS3EnvironmentRepositoryappears to preserve the incoming profile iteration order when constructing theEnvironment:Since higher precedence corresponds to appearing earlier in
Environment.propertySources, preserving the incoming profile order reverses the intended profile precedence.Documentation reference
Spring Cloud Config Environment Repository documentation:
https://docs.spring.io/spring-cloud-config/reference/server/environment-repository.html
Relevant documented behavior:
PropertySourcelisted earlier in theEnvironment.