Skip to content

Add prefix support for environment variables #3450

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

Closed
philwebb opened this issue Jul 8, 2015 · 16 comments
Closed

Add prefix support for environment variables #3450

philwebb opened this issue Jul 8, 2015 · 16 comments
Assignees
Labels
theme: config-data Issues related to the configuration theme type: enhancement A general enhancement
Milestone

Comments

@philwebb
Copy link
Member

philwebb commented Jul 8, 2015

Currently environment variables get bound to @Configuration properties directly (for example SERVER_PORT to Server.port). This can cause problems when trying to set ignoreInvalidFields or if you want to run two different boot apps as the same user.

@gregturn suggested that we consider supporting a prefix when binding. For example:

springApplication.setEnvironmentPrefix("MYAPP_");
...

Which would then bind MYAPP_SERVER_PORT rather than SERVER_PORT.

@philwebb philwebb added the type: enhancement A general enhancement label Jul 8, 2015
@snicoll
Copy link
Member

snicoll commented Jul 9, 2015

I like that.

@lucassaldanha
Copy link
Contributor

+1 for this feature!

@lucassaldanha
Copy link
Contributor

lucassaldanha commented Jul 13, 2015

Here is what I thought:

At the SpringApplication.configurePropertySources(..) we can filter the environment.getSystemEnvironment() map and replace it with a new one just with the properties which keys start with the prefix.

I though about something like this:

protected void configurePropertySources(ConfigurableEnvironment environment, String[] args) {
    ...
    if(this.environmentPrefix != null && !this.environmentPrefix.equals("")) {
        filterSystemEnvironmentPropertySourceByPrefix(environment);
    }
    ...
}

private void filterSystemEnvironmentPropertySourceByPrefix(ConfigurableEnvironment environment) {
    final Map<String, Object> systemEnvironment = environment.getSystemEnvironment();
    final Map<String, Object> prefixedSystemEnvironment = new HashMap<String, Object>(systemEnvironment.size());
    for(String key : systemEnvironment.keySet()) {
        if(key.startsWith(environmentPrefix)) {
            prefixedSystemEnvironment.put(key.substring(environmentPrefix.length()), systemEnvironment.get(key));
        }
    }   

    environment.getPropertySources().replace(
        StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME,
        new SystemEnvironmentPropertySource(StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, prefixedSystemEnvironment));
}

What do you think? There are any collateral damage doing this? I have tested myself and it seems o work quite well. If you want I can make a Gist or a PR with my code.

lucassaldanha added a commit to lucassaldanha/spring-boot that referenced this issue Jul 13, 2015
Creates an environmentPrefix property that is used to filter the
SystemEnvironmentPropertySource's map of environment
variables and create a new one only with the prefixed properties.
This new map is used on a new SystemEnvironmentPropertySource
that replaces the former one.

Fixes spring-projects#3450
lucassaldanha added a commit to lucassaldanha/spring-boot that referenced this issue Jul 14, 2015
Creates an environmentPrefix property that is used to filter the
SystemEnvironmentPropertySource's map of environment
variables and create a new one only with the prefixed properties.
This new map is used on a new SystemEnvironmentPropertySource
that replaces the former one.

Fixes spring-projects#3450
@snicoll snicoll changed the title Add prefix support for environment varaibles Add prefix support for environment variables Jul 14, 2015
lucassaldanha added a commit to lucassaldanha/spring-boot that referenced this issue Jul 14, 2015
Include a filter in ConfigurationPropertiesBindingPostProcessor
that checks if the property "spring.property.prefix" exists (not blank)
and filter the system properties ensuring that the properties with
the prefix are available on property binding.

Fixes spring-projects#3450
lucassaldanha added a commit to lucassaldanha/spring-boot that referenced this issue Jul 14, 2015
Include a filter in ConfigurationPropertiesBindingPostProcessor
that checks if the property "spring.property.prefix" exists (not blank)
and filter the system properties ensuring that the properties with
the prefix are available on property binding.

Fixes spring-projects#3450
lucassaldanha added a commit to lucassaldanha/spring-boot that referenced this issue Jul 18, 2015
Include a filter in ConfigurationPropertiesBindingPostProcessor
that checks if the property "spring.property.prefix" exists (not blank)
and filter the system properties ensuring that the properties with
the prefix are available on property binding.

Fixes spring-projects#3450
lucassaldanha added a commit to lucassaldanha/spring-boot that referenced this issue Oct 20, 2015
Include a filter in ConfigurationPropertiesBindingPostProcessor
that checks if the property "spring.property.prefix" exists (not blank)
and filter the system properties ensuring that the properties with
the prefix are available on property binding.

Fixes spring-projects#3450
lucassaldanha added a commit to lucassaldanha/spring-boot that referenced this issue Oct 22, 2015
Include a filter in ConfigurationPropertiesBindingPostProcessor
that checks if the property "spring.property.prefix" exists (not blank)
and filter the system properties ensuring that the properties with
the prefix are available on property binding.

Fixes spring-projects#3450
lucassaldanha added a commit to lucassaldanha/spring-boot that referenced this issue Oct 22, 2015
Include a filter in ConfigurationPropertiesBindingPostProcessor
that checks if the property "spring.property.prefix" exists (not blank)
and filter the system properties ensuring that the properties with
the prefix are available on property binding.

Fixes spring-projects#3450
lucassaldanha added a commit to lucassaldanha/spring-boot that referenced this issue Oct 22, 2015
Include a filter in ConfigurationPropertiesBindingPostProcessor
that checks if the property "spring.property.prefix" exists (not blank)
and filter the system properties ensuring that the properties with
the prefix are available on property binding.

Fixes spring-projects#3450
lucassaldanha added a commit to lucassaldanha/spring-boot that referenced this issue Mar 11, 2016
Include a filter in ConfigurationPropertiesBindingPostProcessor
that checks if the property "spring.property.prefix" exists (not blank)
and filter the system properties ensuring that the properties with
the prefix are available on property binding.

Fixes spring-projects#3450
@wilkinsona wilkinsona added the theme: config-data Issues related to the configuration theme label Jan 26, 2017
@mageddo
Copy link

mageddo commented Mar 29, 2017

I personally prefer something like that

application.properties

my.prefix.name=Elvis

Config.java

@Bean
public MyBean myBean(@ConfigurationProperties(prefix="my.prefix") Environment env) {
    env.getProperty("name");
....

Can it be implemented at this issue??

@philwebb
Copy link
Member Author

philwebb commented Apr 4, 2017

@mageddo This issue is specifically for adding a prefix to system environment variable. You example can't be implemented because we already support @ConfigurationProperties on @Bean methods (meaning bind properties the resulting bean). If you have questions please join us on Gitter or ask on stackoverflow.com.

@mcompton13
Copy link

@philwebb, @snicoll,
I've got a proposed fix for this change where I've slightly modified the classes that do the @ConfigurationProperties binding so to make it easy to add a prefix when looking up properties from the Environment source as suggested in this comment: #3480 (comment).

I've never submitted anything to the Spring project, so I was looking for some guidance before I submit my code for review so hopefully I get it right the first time. I found this page: https://github.com/spring-projects/spring-boot/wiki/Working-with-Git-branches and it seems like I need to pick the right branch to start with. I'm working off of the 2.1 branch because that's what my project is using. Is the 2.1 branch OK for this enhancement or would you like me to start it off of a different branch?

@snicoll
Copy link
Member

snicoll commented May 30, 2019

@mcompton13 thanks for working on this. Please create a branch from master and submit your proposal. The wiki page is intended to the core team and is not related to external contributions.

@philwebb philwebb added status: declined A suggestion or change that we don't feel we should currently apply and removed theme: config-data Issues related to the configuration theme type: enhancement A general enhancement labels Aug 14, 2020
@philwebb
Copy link
Member Author

We've renamed a lot of our own configuration properties since this was raised. The general shift to containers has also reduced the need for this feature.

@vpavic
Copy link
Contributor

vpavic commented Aug 14, 2020

Please consider adding support for this.

There are still plenty of Spring Boot based projects operating in environments which developers have little to no control over. I've been in this situation several times over the years and the ability to prefix the environment variables would make life easier.

An example: customer insisting on deploying multiple Spring Boot applications to the same WildFly instance, with each application using its own database - which makes using SPRING_DATASOURCE_* properties impossible to use without workarounds.

@philwebb philwebb reopened this Aug 14, 2020
@philwebb philwebb added type: enhancement A general enhancement and removed for: team-attention An issue we'd like other members of the team to review status: declined A suggestion or change that we don't feel we should currently apply labels Aug 14, 2020
@philwebb philwebb modified the milestones: 2.2.x, 2.x Aug 14, 2020
@philwebb
Copy link
Member Author

Well that didn't last long :) I'll reopen it again.

@jwedel
Copy link

jwedel commented Aug 15, 2020

Yup. We have multiple deployments, some with docker and some on premise.

For the latter, we created our own prefixed env variables of the most used spring ones and then used them as default values in the properties file. But that is very limiting and we cannot change others without rebuilding the application.

@lucassaldanha
Copy link
Contributor

Wow! It's been a few years since I first touched this. I'll give it a go later today! 👍

@rsenden
Copy link

rsenden commented Feb 5, 2021

Some environments add some standard prefix when setting environment variables. As an example, the GitHub Actions ecosystem uses environment variables with an INPUT_ prefix; a GitHub Actions input parameter named my-config-property will result in an INPUT_MY_CONFIG_PROPERTY environment variable being set.

In my Spring Boot applications I have implemented a somewhat hacky work-around for supporting this INPUT_ prefix if the application is running in GitHub; see #24202 for details. It would be nice if Spring Boot would support such (conditional) prefixes out of the box.

@wilkinsona wilkinsona added the for: team-meeting An issue we'd like to discuss as a team to make progress label Feb 9, 2021
@philwebb philwebb added the theme: config-data Issues related to the configuration theme label Feb 10, 2021
@philwebb philwebb modified the milestones: 2.x, 2.5.x Feb 10, 2021
@philwebb philwebb removed the for: team-meeting An issue we'd like to discuss as a team to make progress label Feb 22, 2021
@mbhave mbhave closed this as completed in a8592f3 Feb 25, 2021
@mbhave mbhave modified the milestones: 2.5.x, 2.5.0-M3 Feb 25, 2021
dreis2211 added a commit to dreis2211/spring-boot that referenced this issue Feb 26, 2021
philwebb added a commit that referenced this issue Mar 19, 2021
Polish the prefix support introduced in commit a8592f3 and fix a
package tangle between `boot.context.properties.source` and `boot.env`.

The `Prefix` interface has now been moved into a new default method on
`OriginLookup`.

See gh-3450
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
theme: config-data Issues related to the configuration theme type: enhancement A general enhancement
Projects
None yet
Development

Successfully merging a pull request may close this issue.