Skip to content

Commit

Permalink
Support DeferredLogFactory injection
Browse files Browse the repository at this point in the history
Update `ConfigDataLoader` and `ConfigDataLocationResolver` to support
`DeferredLogFactory` injection.

Closes gh-24988
  • Loading branch information
philwebb committed Jan 26, 2021
1 parent 522f68c commit 1def245
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 7 deletions.
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2020 the original author or authors.
* Copyright 2012-2021 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.
Expand All @@ -23,14 +23,16 @@
import org.springframework.boot.BootstrapContext;
import org.springframework.boot.BootstrapRegistry;
import org.springframework.boot.ConfigurableBootstrapContext;
import org.springframework.boot.logging.DeferredLogFactory;

/**
* Strategy class that can be used used to load {@link ConfigData} for a given
* {@link ConfigDataResource}. Implementations should be added as a
* {@code spring.factories} entries. The following constructor parameter types are
* supported:
* <ul>
* <li>{@link Log} - if the resolver needs deferred logging</li>
* <li>{@link Log} or {@link DeferredLogFactory} - if the loader needs deferred
* logging</li>
* <li>{@link ConfigurableBootstrapContext} - A bootstrap context that can be used to
* store objects that may be expensive to create, or need to be shared
* ({@link BootstrapContext} or {@link BootstrapRegistry} may also be used).</li>
Expand Down
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2020 the original author or authors.
* Copyright 2012-2021 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.
Expand Down Expand Up @@ -68,6 +68,7 @@ class ConfigDataLoaders {
Instantiator<ConfigDataLoader<?>> instantiator = new Instantiator<>(ConfigDataLoader.class,
(availableParameters) -> {
availableParameters.add(Log.class, logFactory::getLog);
availableParameters.add(DeferredLogFactory.class, logFactory);
availableParameters.add(ConfigurableBootstrapContext.class, bootstrapContext);
availableParameters.add(BootstrapContext.class, bootstrapContext);
availableParameters.add(BootstrapRegistry.class, bootstrapContext);
Expand Down
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2020 the original author or authors.
* Copyright 2012-2021 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.
Expand All @@ -25,6 +25,7 @@
import org.springframework.boot.BootstrapRegistry;
import org.springframework.boot.ConfigurableBootstrapContext;
import org.springframework.boot.context.properties.bind.Binder;
import org.springframework.boot.logging.DeferredLogFactory;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.core.env.Environment;
Expand All @@ -36,7 +37,8 @@
* {@code spring.factories} entries. The following constructor parameter types are
* supported:
* <ul>
* <li>{@link Log} - if the resolver needs deferred logging</li>
* <li>{@link Log} or {@link DeferredLogFactory} - if the resolver needs deferred
* logging</li>
* <li>{@link Binder} - if the resolver needs to obtain values from the initial
* {@link Environment}</li>
* <li>{@link ResourceLoader} - if the resolver needs a resource loader</li>
Expand Down
Expand Up @@ -70,6 +70,7 @@ class ConfigDataLocationResolvers {
Instantiator<ConfigDataLocationResolver<?>> instantiator = new Instantiator<>(ConfigDataLocationResolver.class,
(availableParameters) -> {
availableParameters.add(Log.class, logFactory::getLog);
availableParameters.add(DeferredLogFactory.class, logFactory);
availableParameters.add(Binder.class, binder);
availableParameters.add(ResourceLoader.class, resourceLoader);
availableParameters.add(ConfigurableBootstrapContext.class, bootstrapContext);
Expand Down
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2020 the original author or authors.
* Copyright 2012-2021 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.
Expand Down Expand Up @@ -57,6 +57,20 @@ void createWhenLoaderHasLogParameterInjectsLog() {
Arrays.asList(LoggingConfigDataLoader.class.getName()));
}

@Test
void createWhenLoaderHasDeferredLogFactoryParameterInjectsDeferredLogFactory() {
ConfigDataLoaders loaders = new ConfigDataLoaders(this.logFactory, this.bootstrapContext,
Arrays.asList(DeferredLogFactoryConfigDataLoader.class.getName()));
assertThat(loaders).extracting("loaders").asList()
.satisfies(this::containsValidDeferredLogFactoryConfigDataLoader);
}

private void containsValidDeferredLogFactoryConfigDataLoader(List<?> list) {
assertThat(list).hasSize(1);
DeferredLogFactoryConfigDataLoader loader = (DeferredLogFactoryConfigDataLoader) list.get(0);
assertThat(loader.getLogFactory()).isSameAs(this.logFactory);
}

@Test
void createWhenLoaderHasBootstrapParametersInjectsBootstrapContext() {
new ConfigDataLoaders(this.logFactory, this.bootstrapContext,
Expand Down Expand Up @@ -144,6 +158,26 @@ public ConfigData load(ConfigDataLoaderContext context, ConfigDataResource resou

}

static class DeferredLogFactoryConfigDataLoader implements ConfigDataLoader<ConfigDataResource> {

private final DeferredLogFactory logFactory;

DeferredLogFactoryConfigDataLoader(DeferredLogFactory logFactory) {
assertThat(logFactory).isNotNull();
this.logFactory = logFactory;
}

@Override
public ConfigData load(ConfigDataLoaderContext context, ConfigDataResource resource) throws IOException {
throw new AssertionError("Unexpected call");
}

DeferredLogFactory getLogFactory() {
return this.logFactory;
}

}

static class BootstrappingConfigDataLoader implements ConfigDataLoader<ConfigDataResource> {

BootstrappingConfigDataLoader(ConfigurableBootstrapContext configurableBootstrapContext,
Expand Down
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2020 the original author or authors.
* Copyright 2012-2021 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.
Expand All @@ -23,6 +23,7 @@
import java.util.List;
import java.util.function.Supplier;

import org.apache.commons.logging.Log;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
Expand Down Expand Up @@ -68,6 +69,17 @@ class ConfigDataLocationResolversTests {

private ResourceLoader resourceLoader = new DefaultResourceLoader();

@Test
void createWhenInjectingLogAndDeferredLogFactoryCreatesResolver() {
ConfigDataLocationResolvers resolvers = new ConfigDataLocationResolvers(this.logFactory, this.bootstrapContext,
this.binder, this.resourceLoader, Collections.singletonList(TestLogResolver.class.getName()));
assertThat(resolvers.getResolvers()).hasSize(1);
assertThat(resolvers.getResolvers().get(0)).isExactlyInstanceOf(TestLogResolver.class);
TestLogResolver resolver = (TestLogResolver) resolvers.getResolvers().get(0);
assertThat(resolver.getDeferredLogFactory()).isSameAs(this.logFactory);
assertThat(resolver.getLog()).isNotNull();
}

@Test
void createWhenInjectingBinderCreatesResolver() {
ConfigDataLocationResolvers resolvers = new ConfigDataLocationResolvers(this.logFactory, this.bootstrapContext,
Expand Down Expand Up @@ -180,6 +192,27 @@ public List<TestConfigDataResource> resolveProfileSpecific(ConfigDataLocationRes

}

static class TestLogResolver extends TestResolver {

private final DeferredLogFactory deferredLogFactory;

private final Log log;

TestLogResolver(DeferredLogFactory deferredLogFactory, Log log) {
this.deferredLogFactory = deferredLogFactory;
this.log = log;
}

DeferredLogFactory getDeferredLogFactory() {
return this.deferredLogFactory;
}

Log getLog() {
return this.log;
}

}

static class TestBoundResolver extends TestResolver {

private final Binder binder;
Expand Down

0 comments on commit 1def245

Please sign in to comment.