Skip to content

Commit

Permalink
Merge branch '2.4.x'
Browse files Browse the repository at this point in the history
Closes gh-24524
  • Loading branch information
philwebb committed Dec 16, 2020
2 parents 308c204 + 38e4c2a commit 5bd5ca5
Show file tree
Hide file tree
Showing 8 changed files with 237 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ class ConfigDataEnvironment {
locations.add(ConfigDataLocation.of("optional:file:./config/"));
locations.add(ConfigDataLocation.of("optional:file:./config/*/"));
DEFAULT_SEARCH_LOCATIONS = locations.toArray(new ConfigDataLocation[0]);
};
}

private static final ConfigDataLocation[] EMPTY_LOCATIONS = new ConfigDataLocation[0];

Expand All @@ -119,6 +119,8 @@ class ConfigDataEnvironment {

private final Collection<String> additionalProfiles;

private final ConfigDataEnvironmentUpdateListener environmentUpdateListener;

private final ConfigDataLoaders loaders;

private final ConfigDataEnvironmentContributors contributors;
Expand All @@ -130,9 +132,13 @@ class ConfigDataEnvironment {
* @param environment the Spring {@link Environment}.
* @param resourceLoader {@link ResourceLoader} to load resource locations
* @param additionalProfiles any additional profiles to activate
* @param environmentUpdateListener optional
* {@link ConfigDataEnvironmentUpdateListener} that can be used to track
* {@link Environment} updates.
*/
ConfigDataEnvironment(DeferredLogFactory logFactory, ConfigurableBootstrapContext bootstrapContext,
ConfigurableEnvironment environment, ResourceLoader resourceLoader, Collection<String> additionalProfiles) {
ConfigurableEnvironment environment, ResourceLoader resourceLoader, Collection<String> additionalProfiles,
ConfigDataEnvironmentUpdateListener environmentUpdateListener) {
Binder binder = Binder.get(environment);
UseLegacyConfigProcessingException.throwIfRequested(binder);
this.logFactory = logFactory;
Expand All @@ -143,6 +149,8 @@ class ConfigDataEnvironment {
this.environment = environment;
this.resolvers = createConfigDataLocationResolvers(logFactory, bootstrapContext, binder, resourceLoader);
this.additionalProfiles = additionalProfiles;
this.environmentUpdateListener = (environmentUpdateListener != null) ? environmentUpdateListener
: ConfigDataEnvironmentUpdateListener.NONE;
this.loaders = new ConfigDataLoaders(logFactory, bootstrapContext);
this.contributors = createContributors(binder);
}
Expand Down Expand Up @@ -301,16 +309,18 @@ private void applyToEnvironment(ConfigDataEnvironmentContributors contributors,
MutablePropertySources propertySources = this.environment.getPropertySources();
this.logger.trace("Applying config data environment contributions");
for (ConfigDataEnvironmentContributor contributor : contributors) {
if (contributor.getKind() == ConfigDataEnvironmentContributor.Kind.BOUND_IMPORT
&& contributor.getPropertySource() != null) {
PropertySource<?> propertySource = contributor.getPropertySource();
if (contributor.getKind() == ConfigDataEnvironmentContributor.Kind.BOUND_IMPORT && propertySource != null) {
if (!contributor.isActive(activationContext)) {
this.logger.trace(LogMessage.format("Skipping inactive property source '%s'",
contributor.getPropertySource().getName()));
this.logger.trace(
LogMessage.format("Skipping inactive property source '%s'", propertySource.getName()));
}
else {
this.logger.trace(LogMessage.format("Adding imported property source '%s'",
contributor.getPropertySource().getName()));
propertySources.addLast(contributor.getPropertySource());
this.logger
.trace(LogMessage.format("Adding imported property source '%s'", propertySource.getName()));
propertySources.addLast(propertySource);
this.environmentUpdateListener.onPropertySourceAdded(propertySource, contributor.getLocation(),
contributor.getResource());
}
}
}
Expand All @@ -320,6 +330,7 @@ private void applyToEnvironment(ConfigDataEnvironmentContributors contributors,
this.environment.setDefaultProfiles(StringUtils.toStringArray(profiles.getDefault()));
this.logger.trace(LogMessage.format("Setting active profiles: %s", profiles.getActive()));
this.environment.setActiveProfiles(StringUtils.toStringArray(profiles.getActive()));
this.environmentUpdateListener.onSetProfiles(profiles);
}

private void checkForInvalidProperties(ConfigDataEnvironmentContributors contributors) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,20 @@ public class ConfigDataEnvironmentPostProcessor implements EnvironmentPostProces

private final ConfigurableBootstrapContext bootstrapContext;

private final ConfigDataEnvironmentUpdateListener environmentUpdateListener;

public ConfigDataEnvironmentPostProcessor(DeferredLogFactory logFactory,
ConfigurableBootstrapContext bootstrapContext) {
this(logFactory, bootstrapContext, null);
}

public ConfigDataEnvironmentPostProcessor(DeferredLogFactory logFactory,
ConfigurableBootstrapContext bootstrapContext,
ConfigDataEnvironmentUpdateListener environmentUpdateListener) {
this.logFactory = logFactory;
this.logger = logFactory.getLog(getClass());
this.bootstrapContext = bootstrapContext;
this.environmentUpdateListener = environmentUpdateListener;
}

@Override
Expand Down Expand Up @@ -97,7 +106,7 @@ void postProcessEnvironment(ConfigurableEnvironment environment, ResourceLoader
ConfigDataEnvironment getConfigDataEnvironment(ConfigurableEnvironment environment, ResourceLoader resourceLoader,
Collection<String> additionalProfiles) {
return new ConfigDataEnvironment(this.logFactory, this.bootstrapContext, environment, resourceLoader,
additionalProfiles);
additionalProfiles, this.environmentUpdateListener);
}

private void postProcessUsingLegacyApplicationListener(ConfigurableEnvironment environment,
Expand Down Expand Up @@ -154,6 +163,29 @@ public static void applyTo(ConfigurableEnvironment environment, ResourceLoader r
postProcessor.postProcessEnvironment(environment, resourceLoader, additionalProfiles);
}

/**
* Apply {@link ConfigData} post-processing to an existing {@link Environment}. This
* method can be useful when working with an {@link Environment} that has been created
* directly and not necessarily as part of a {@link SpringApplication}.
* @param environment the environment to apply {@link ConfigData} to
* @param resourceLoader the resource loader to use
* @param bootstrapContext the bootstrap context to use or {@code null} to use a
* throw-away context
* @param additionalProfiles any additional profiles that should be applied
* @param environmentUpdateListener optional
* {@link ConfigDataEnvironmentUpdateListener} that can be used to track
* {@link Environment} updates.
*/
public static void applyTo(ConfigurableEnvironment environment, ResourceLoader resourceLoader,
ConfigurableBootstrapContext bootstrapContext, Collection<String> additionalProfiles,
ConfigDataEnvironmentUpdateListener environmentUpdateListener) {
DeferredLogFactory logFactory = Supplier::get;
bootstrapContext = (bootstrapContext != null) ? bootstrapContext : new DefaultBootstrapContext();
ConfigDataEnvironmentPostProcessor postProcessor = new ConfigDataEnvironmentPostProcessor(logFactory,
bootstrapContext, environmentUpdateListener);
postProcessor.postProcessEnvironment(environment, resourceLoader, additionalProfiles);
}

@SuppressWarnings("deprecation")
static class LegacyConfigFileApplicationListener extends ConfigFileApplicationListener {

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* Copyright 2012-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.springframework.boot.context.config;

import java.util.EventListener;

import org.springframework.core.env.Environment;
import org.springframework.core.env.PropertySource;

/**
* {@link EventListener} to listen to {@link Environment} updates triggered by the
* {@link ConfigDataEnvironmentPostProcessor}.
*
* @author Phillip Webb
* @since 2.4.2
*/
public interface ConfigDataEnvironmentUpdateListener extends EventListener {

/**
* A {@link ConfigDataEnvironmentUpdateListener} that does nothing.
*/
ConfigDataEnvironmentUpdateListener NONE = new ConfigDataEnvironmentUpdateListener() {
};

/**
* Called when a new {@link PropertySource} is added to the {@link Environment}.
* @param propertySource the {@link PropertySource} that was added
* @param location the original {@link ConfigDataLocation} of the source.
* @param resource the {@link ConfigDataResource} of the source.
*/
default void onPropertySourceAdded(PropertySource<?> propertySource, ConfigDataLocation location,
ConfigDataResource resource) {
}

/**
* Called when {@link Environment} profiles are set.
* @param profiles the profiles being set
*/
default void onSetProfiles(Profiles profiles) {
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package org.springframework.boot.context.config;

import java.util.Collections;
import java.util.Set;
import java.util.function.Supplier;

Expand Down Expand Up @@ -119,9 +120,13 @@ void postProcessEnvironmentWhenUseLegacyProcessingSwitchesToLegacyMethod() {
@Test
void applyToAppliesPostProcessing() {
int before = this.environment.getPropertySources().size();
ConfigDataEnvironmentPostProcessor.applyTo(this.environment, null, null, "dev");
TestConfigDataEnvironmentUpdateListener listener = new TestConfigDataEnvironmentUpdateListener();
ConfigDataEnvironmentPostProcessor.applyTo(this.environment, null, null, Collections.singleton("dev"),
listener);
assertThat(this.environment.getPropertySources().size()).isGreaterThan(before);
assertThat(this.environment.getActiveProfiles()).containsExactly("dev");
assertThat(listener.getAddedPropertySources()).hasSizeGreaterThan(0);
assertThat(listener.getProfiles().getActive()).containsExactly("dev");
}

}
Loading

0 comments on commit 5bd5ca5

Please sign in to comment.