Home / Class/ ConfigDataEnvironmentContributorsTests Class — spring-boot Architecture

ConfigDataEnvironmentContributorsTests Class — spring-boot Architecture

Architecture documentation for the ConfigDataEnvironmentContributorsTests class in ConfigDataEnvironmentContributorsTests.java from the spring-boot codebase.

Entity Profile

Relationship Graph

Source Code

core/spring-boot/src/test/java/org/springframework/boot/context/config/ConfigDataEnvironmentContributorsTests.java lines 62–440

@ExtendWith(MockitoExtension.class)
class ConfigDataEnvironmentContributorsTests {

	private static final ConfigDataLocation LOCATION_1 = ConfigDataLocation.of("location1");

	private static final ConfigDataLocation LOCATION_2 = ConfigDataLocation.of("location2");

	private final DeferredLogFactory logFactory = Supplier::get;

	private final DefaultBootstrapContext bootstrapContext = new DefaultBootstrapContext();

	private final ConversionService conversionService = DefaultConversionService.getSharedInstance();

	private ConfigDataImporter importer;

	private ConfigDataActivationContext activationContext;

	@BeforeEach
	void setup() {
		MockEnvironment environment = new MockEnvironment();
		Binder binder = Binder.get(environment);
		ConfigDataLocationResolvers resolvers = new ConfigDataLocationResolvers(this.logFactory, this.bootstrapContext,
				binder, new DefaultResourceLoader(getClass().getClassLoader()),
				SpringFactoriesLoader.forDefaultResourceLocation(getClass().getClassLoader()));
		ConfigDataLoaders loaders = new ConfigDataLoaders(this.logFactory, this.bootstrapContext,
				SpringFactoriesLoader.forDefaultResourceLocation());
		this.importer = new ConfigDataImporter(this.logFactory, ConfigDataNotFoundAction.FAIL, resolvers, loaders);
		this.activationContext = new ConfigDataActivationContext(CloudPlatform.KUBERNETES, null);
	}

	@Test
	void createCreatesWithInitialContributors() {
		ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofInitialImport(LOCATION_1,
				this.conversionService);
		ConfigDataEnvironmentContributors contributors = new ConfigDataEnvironmentContributors(this.logFactory,
				this.bootstrapContext, List.of(contributor), this.conversionService,
				ConfigDataEnvironmentUpdateListener.NONE);
		Iterator<ConfigDataEnvironmentContributor> iterator = contributors.iterator();
		assertThat(iterator.next()).isSameAs(contributor);
		assertThat(iterator.next().getKind()).isEqualTo(Kind.ROOT);
	}

	@Test
	void withProcessedImportsWhenHasNoUnprocessedImportsReturnsSameInstance() {
		ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor
			.ofExisting(new MockPropertySource(), this.conversionService);
		ConfigDataEnvironmentContributors contributors = new ConfigDataEnvironmentContributors(this.logFactory,
				this.bootstrapContext, List.of(contributor), this.conversionService,
				ConfigDataEnvironmentUpdateListener.NONE);
		ConfigDataEnvironmentContributors withProcessedImports = contributors.withProcessedImports(this.importer,
				this.activationContext);
		assertThat(withProcessedImports).isSameAs(contributors);
	}

	@Test
	void withProcessedImportsResolvesAndLoads() {
		this.importer = mock(ConfigDataImporter.class);
		List<ConfigDataLocation> locations = Collections.singletonList(LOCATION_1);
		MockPropertySource propertySource = new MockPropertySource();
		Map<ConfigDataResolutionResult, ConfigData> imported = new LinkedHashMap<>();
		imported.put(new ConfigDataResolutionResult(LOCATION_1, new TestConfigDataResource("a"), false),
				new ConfigData(List.of(propertySource)));
		given(this.importer.resolveAndLoad(eq(this.activationContext), any(), any(), eq(locations)))
			.willReturn(imported);
		ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofInitialImport(LOCATION_1,
				this.conversionService);
		ConfigDataEnvironmentContributors contributors = new ConfigDataEnvironmentContributors(this.logFactory,
				this.bootstrapContext, List.of(contributor), this.conversionService,
				ConfigDataEnvironmentUpdateListener.NONE);
		ConfigDataEnvironmentContributors withProcessedImports = contributors.withProcessedImports(this.importer,
				this.activationContext);
		Iterator<ConfigDataEnvironmentContributor> iterator = withProcessedImports.iterator();
		assertThat(iterator.next().getPropertySource()).isSameAs(propertySource);
		assertThat(iterator.next().getKind()).isEqualTo(Kind.INITIAL_IMPORT);
		assertThat(iterator.next().getKind()).isEqualTo(Kind.ROOT);
		assertThat(iterator.hasNext()).isFalse();
	}

	@Test
	void withProcessedImportsResolvesAndLoadsChainedImports() {
		this.importer = mock(ConfigDataImporter.class);
		List<ConfigDataLocation> initialLocations = Collections.singletonList(LOCATION_1);
		MockPropertySource initialPropertySource = new MockPropertySource();
		initialPropertySource.setProperty("spring.config.import", "location2");
		Map<ConfigDataResolutionResult, ConfigData> initialImported = new LinkedHashMap<>();
		initialImported.put(new ConfigDataResolutionResult(LOCATION_1, new TestConfigDataResource("a"), false),
				new ConfigData(List.of(initialPropertySource)));
		given(this.importer.resolveAndLoad(eq(this.activationContext), any(), any(), eq(initialLocations)))
			.willReturn(initialImported);
		List<ConfigDataLocation> secondLocations = Collections.singletonList(LOCATION_2);
		MockPropertySource secondPropertySource = new MockPropertySource();
		Map<ConfigDataResolutionResult, ConfigData> secondImported = new LinkedHashMap<>();
		secondImported.put(new ConfigDataResolutionResult(LOCATION_2, new TestConfigDataResource("b"), false),
				new ConfigData(List.of(secondPropertySource)));
		given(this.importer.resolveAndLoad(eq(this.activationContext), any(), any(), eq(secondLocations)))
			.willReturn(secondImported);
		ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofInitialImport(LOCATION_1,
				this.conversionService);
		ConfigDataEnvironmentContributors contributors = new ConfigDataEnvironmentContributors(this.logFactory,
				this.bootstrapContext, List.of(contributor), this.conversionService,
				ConfigDataEnvironmentUpdateListener.NONE);
		ConfigDataEnvironmentContributors withProcessedImports = contributors.withProcessedImports(this.importer,
				this.activationContext);
		Iterator<ConfigDataEnvironmentContributor> iterator = withProcessedImports.iterator();
		assertThat(iterator.next().getPropertySource()).isSameAs(secondPropertySource);
		assertThat(iterator.next().getPropertySource()).isSameAs(initialPropertySource);
		assertThat(iterator.next().getKind()).isEqualTo(Kind.INITIAL_IMPORT);
		assertThat(iterator.next().getKind()).isEqualTo(Kind.ROOT);
		assertThat(iterator.hasNext()).isFalse();
	}

	@Test
	void withProcessedImportsProvidesLocationResolverContextWithAccessToBinder() {
		MockPropertySource existingPropertySource = new MockPropertySource();
		existingPropertySource.setProperty("test", "springboot");
		ConfigDataEnvironmentContributor existingContributor = ConfigDataEnvironmentContributor
			.ofExisting(existingPropertySource, this.conversionService);
		this.importer = mock(ConfigDataImporter.class);
		List<ConfigDataLocation> locations = Collections.singletonList(LOCATION_1);
		MockPropertySource propertySource = new MockPropertySource();
		Map<ConfigDataResolutionResult, ConfigData> imported = new LinkedHashMap<>();
		imported.put(new ConfigDataResolutionResult(LOCATION_1, new TestConfigDataResource("a'"), false),
				new ConfigData(List.of(propertySource)));
		given(this.importer.resolveAndLoad(eq(this.activationContext), any(), any(), eq(locations)))
			.willReturn(imported);
		ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofInitialImport(LOCATION_1,
				this.conversionService);
		ConfigDataEnvironmentContributors contributors = new ConfigDataEnvironmentContributors(this.logFactory,
				this.bootstrapContext, Arrays.asList(existingContributor, contributor), this.conversionService,
				ConfigDataEnvironmentUpdateListener.NONE);
		contributors.withProcessedImports(this.importer, this.activationContext);
		then(this.importer).should()
			.resolveAndLoad(any(),
					assertArg((context) -> assertThat(context.getBinder().bind("test", String.class).get())
						.isEqualTo("springboot")),
					any(), any());
	}

	@Test
	void withProcessedImportsProvidesLocationResolverContextWithAccessToParent() {
		this.importer = mock(ConfigDataImporter.class);
		List<ConfigDataLocation> initialLocations = Collections.singletonList(LOCATION_1);
		MockPropertySource initialPropertySource = new MockPropertySource();
		initialPropertySource.setProperty("spring.config.import", "location2");
		Map<ConfigDataResolutionResult, ConfigData> initialImported = new LinkedHashMap<>();
		initialImported.put(new ConfigDataResolutionResult(LOCATION_1, new TestConfigDataResource("a"), false),
				new ConfigData(List.of(initialPropertySource)));
		given(this.importer.resolveAndLoad(eq(this.activationContext), any(), any(), eq(initialLocations)))
			.willReturn(initialImported);
		List<ConfigDataLocation> secondLocations = Collections.singletonList(LOCATION_2);
		MockPropertySource secondPropertySource = new MockPropertySource();
		Map<ConfigDataResolutionResult, ConfigData> secondImported = new LinkedHashMap<>();
		secondImported.put(new ConfigDataResolutionResult(LOCATION_2, new TestConfigDataResource("b"), false),
				new ConfigData(List.of(secondPropertySource)));
		given(this.importer.resolveAndLoad(eq(this.activationContext), any(), any(), eq(secondLocations)))
			.willReturn(secondImported);
		ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofInitialImport(LOCATION_1,
				this.conversionService);
		ConfigDataEnvironmentContributors contributors = new ConfigDataEnvironmentContributors(this.logFactory,
				this.bootstrapContext, List.of(contributor), this.conversionService,
				ConfigDataEnvironmentUpdateListener.NONE);
		ArgumentCaptor<ConfigDataLocationResolverContext> locationResolverContext = ArgumentCaptor
			.forClass(ConfigDataLocationResolverContext.class);
		contributors.withProcessedImports(this.importer, this.activationContext);
		then(this.importer).should()
			.resolveAndLoad(any(), locationResolverContext.capture(), any(), eq(secondLocations));
		ConfigDataLocationResolverContext context = locationResolverContext.getValue();
		assertThat(context.getParent()).hasToString("a");
	}

	@Test
	void withProcessedImportsProvidesLocationResolverContextWithAccessToBootstrapRegistry() {
		MockPropertySource existingPropertySource = new MockPropertySource();
		existingPropertySource.setProperty("test", "springboot");
		ConfigDataEnvironmentContributor existingContributor = ConfigDataEnvironmentContributor
			.ofExisting(existingPropertySource, this.conversionService);
		this.importer = mock(ConfigDataImporter.class);
		List<ConfigDataLocation> locations = Collections.singletonList(LOCATION_1);
		MockPropertySource propertySource = new MockPropertySource();
		Map<ConfigDataResolutionResult, ConfigData> imported = new LinkedHashMap<>();
		imported.put(new ConfigDataResolutionResult(LOCATION_1, new TestConfigDataResource("a'"), false),
				new ConfigData(List.of(propertySource)));
		given(this.importer.resolveAndLoad(eq(this.activationContext), any(), any(), eq(locations)))
			.willReturn(imported);
		ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofInitialImport(LOCATION_1,
				this.conversionService);
		ConfigDataEnvironmentContributors contributors = new ConfigDataEnvironmentContributors(this.logFactory,
				this.bootstrapContext, Arrays.asList(existingContributor, contributor), this.conversionService,
				ConfigDataEnvironmentUpdateListener.NONE);
		contributors.withProcessedImports(this.importer, this.activationContext);
		then(this.importer).should()
			.resolveAndLoad(any(),
					assertArg((context) -> assertThat(context.getBootstrapContext()).isSameAs(this.bootstrapContext)),
					any(), any());
	}

	@Test
	void withProcessedImportsProvidesLoaderContextWithAccessToBootstrapRegistry() {
		MockPropertySource existingPropertySource = new MockPropertySource();
		existingPropertySource.setProperty("test", "springboot");
		ConfigDataEnvironmentContributor existingContributor = ConfigDataEnvironmentContributor
			.ofExisting(existingPropertySource, this.conversionService);
		this.importer = mock(ConfigDataImporter.class);
		List<ConfigDataLocation> locations = Collections.singletonList(LOCATION_1);
		MockPropertySource propertySource = new MockPropertySource();
		Map<ConfigDataResolutionResult, ConfigData> imported = new LinkedHashMap<>();
		imported.put(new ConfigDataResolutionResult(LOCATION_1, new TestConfigDataResource("a'"), false),
				new ConfigData(List.of(propertySource)));
		given(this.importer.resolveAndLoad(eq(this.activationContext), any(), any(), eq(locations)))
			.willReturn(imported);
		ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofInitialImport(LOCATION_1,
				this.conversionService);
		ConfigDataEnvironmentContributors contributors = new ConfigDataEnvironmentContributors(this.logFactory,
				this.bootstrapContext, Arrays.asList(existingContributor, contributor), this.conversionService,
				ConfigDataEnvironmentUpdateListener.NONE);
		contributors.withProcessedImports(this.importer, this.activationContext);
		then(this.importer).should()
			.resolveAndLoad(any(), any(),
					assertArg((context) -> assertThat(context.getBootstrapContext()).isSameAs(this.bootstrapContext)),
					any());
	}

	@Test
	void getBinderProvidesBinder() {
		MockPropertySource propertySource = new MockPropertySource();
		propertySource.setProperty("test", "springboot");
		ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofExisting(propertySource,
				this.conversionService);
		ConfigDataEnvironmentContributors contributors = new ConfigDataEnvironmentContributors(this.logFactory,
				this.bootstrapContext, List.of(contributor), this.conversionService,
				ConfigDataEnvironmentUpdateListener.NONE);
		Binder binder = contributors.getBinder(this.activationContext);
		assertThat(binder.bind("test", String.class).get()).isEqualTo("springboot");
	}

	@Test
	void getBinderWhenHasMultipleSourcesPicksFirst() {
		MockPropertySource firstPropertySource = new MockPropertySource();
		firstPropertySource.setProperty("test", "one");
		MockPropertySource secondPropertySource = new MockPropertySource();
		secondPropertySource.setProperty("test", "two");
		ConfigData configData = new ConfigData(Arrays.asList(firstPropertySource, secondPropertySource));
		ConfigDataEnvironmentContributor firstContributor = createBoundImportContributor(configData, 0);
		ConfigDataEnvironmentContributor secondContributor = createBoundImportContributor(configData, 1);
		ConfigDataEnvironmentContributors contributors = new ConfigDataEnvironmentContributors(this.logFactory,
				this.bootstrapContext, Arrays.asList(firstContributor, secondContributor), this.conversionService,
				ConfigDataEnvironmentUpdateListener.NONE);
		Binder binder = contributors.getBinder(this.activationContext);
		assertThat(binder.bind("test", String.class).get()).isEqualTo("one");
	}

	@Test
	void getBinderWhenHasInactiveIgnoresInactive() {
		MockPropertySource firstPropertySource = new MockPropertySource();
		firstPropertySource.setProperty("test", "one");
		firstPropertySource.setProperty("spring.config.activate.on-profile", "production");
		MockPropertySource secondPropertySource = new MockPropertySource();
		secondPropertySource.setProperty("test", "two");
		ConfigData configData = new ConfigData(Arrays.asList(firstPropertySource, secondPropertySource));
		ConfigDataEnvironmentContributor firstContributor = createBoundImportContributor(configData, 0);
		ConfigDataEnvironmentContributor secondContributor = createBoundImportContributor(configData, 1);
		ConfigDataEnvironmentContributors contributors = new ConfigDataEnvironmentContributors(this.logFactory,
				this.bootstrapContext, Arrays.asList(firstContributor, secondContributor), this.conversionService,
				ConfigDataEnvironmentUpdateListener.NONE);
		Binder binder = contributors.getBinder(this.activationContext);
		assertThat(binder.bind("test", String.class).get()).isEqualTo("two");
	}

	@Test
	void getBinderWhenHasPlaceholderResolvesPlaceholder() {
		MockPropertySource propertySource = new MockPropertySource();
		propertySource.setProperty("test", "${other}");
		propertySource.setProperty("other", "springboot");
		ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofExisting(propertySource,
				this.conversionService);
		ConfigDataEnvironmentContributors contributors = new ConfigDataEnvironmentContributors(this.logFactory,
				this.bootstrapContext, List.of(contributor), this.conversionService,
				ConfigDataEnvironmentUpdateListener.NONE);
		Binder binder = contributors.getBinder(this.activationContext);
		assertThat(binder.bind("test", String.class).get()).isEqualTo("springboot");
	}

	@Test
	void getBinderWhenHasPlaceholderAndInactiveResolvesPlaceholderOnlyFromActive() {
		MockPropertySource firstPropertySource = new MockPropertySource();
		firstPropertySource.setProperty("other", "one");
		firstPropertySource.setProperty("spring.config.activate.on-profile", "production");
		MockPropertySource secondPropertySource = new MockPropertySource();
		secondPropertySource.setProperty("other", "two");
		secondPropertySource.setProperty("test", "${other}");
		ConfigData configData = new ConfigData(Arrays.asList(firstPropertySource, secondPropertySource));
		ConfigDataEnvironmentContributor firstContributor = createBoundImportContributor(configData, 0);
		ConfigDataEnvironmentContributor secondContributor = createBoundImportContributor(configData, 1);
		ConfigDataEnvironmentContributors contributors = new ConfigDataEnvironmentContributors(this.logFactory,
				this.bootstrapContext, Arrays.asList(firstContributor, secondContributor), this.conversionService,
				ConfigDataEnvironmentUpdateListener.NONE);
		Binder binder = contributors.getBinder(this.activationContext);
		assertThat(binder.bind("test", String.class).get()).isEqualTo("two");
	}

	@Test
	void getBinderWhenFailOnBindToInactiveSourceWithFirstInactiveThrowsException() {
		MockPropertySource firstPropertySource = new MockPropertySource();
		firstPropertySource.setProperty("test", "one");
		firstPropertySource.setProperty("spring.config.activate.on-profile", "production");
		MockPropertySource secondPropertySource = new MockPropertySource();
		secondPropertySource.setProperty("test", "two");
		ConfigData configData = new ConfigData(Arrays.asList(firstPropertySource, secondPropertySource));
		ConfigDataEnvironmentContributor firstContributor = createBoundImportContributor(configData, 0);
		ConfigDataEnvironmentContributor secondContributor = createBoundImportContributor(configData, 1);
		ConfigDataEnvironmentContributors contributors = new ConfigDataEnvironmentContributors(this.logFactory,
				this.bootstrapContext, Arrays.asList(firstContributor, secondContributor), this.conversionService,
				ConfigDataEnvironmentUpdateListener.NONE);
		Binder binder = contributors.getBinder(this.activationContext, BinderOption.FAIL_ON_BIND_TO_INACTIVE_SOURCE);
		assertThatExceptionOfType(BindException.class).isThrownBy(() -> binder.bind("test", String.class))
			.satisfies((ex) -> assertThat(ex.getCause()).isInstanceOf(InactiveConfigDataAccessException.class));
	}

	@Test
	void getBinderWhenFailOnBindToInactiveSourceWithLastInactiveThrowsException() {
		MockPropertySource firstPropertySource = new MockPropertySource();
		firstPropertySource.setProperty("test", "one");
		MockPropertySource secondPropertySource = new MockPropertySource();
		secondPropertySource.setProperty("spring.config.activate.on-profile", "production");
		secondPropertySource.setProperty("test", "two");
		ConfigData configData = new ConfigData(Arrays.asList(firstPropertySource, secondPropertySource));
		ConfigDataEnvironmentContributor firstContributor = createBoundImportContributor(configData, 0);
		ConfigDataEnvironmentContributor secondContributor = createBoundImportContributor(configData, 1);
		ConfigDataEnvironmentContributors contributors = new ConfigDataEnvironmentContributors(this.logFactory,
				this.bootstrapContext, Arrays.asList(firstContributor, secondContributor), this.conversionService,
				ConfigDataEnvironmentUpdateListener.NONE);
		Binder binder = contributors.getBinder(this.activationContext, BinderOption.FAIL_ON_BIND_TO_INACTIVE_SOURCE);
		assertThatExceptionOfType(BindException.class).isThrownBy(() -> binder.bind("test", String.class))
			.satisfies((ex) -> assertThat(ex.getCause()).isInstanceOf(InactiveConfigDataAccessException.class));
	}

	@Test
	void getBinderWhenFailOnBindToInactiveSourceWithResolveToInactiveThrowsException() {
		MockPropertySource firstPropertySource = new MockPropertySource();
		firstPropertySource.setProperty("other", "one");
		firstPropertySource.setProperty("spring.config.activate.on-profile", "production");
		MockPropertySource secondPropertySource = new MockPropertySource();
		secondPropertySource.setProperty("test", "${other}");
		secondPropertySource.setProperty("other", "one");
		ConfigData configData = new ConfigData(Arrays.asList(firstPropertySource, secondPropertySource));
		ConfigDataEnvironmentContributor firstContributor = createBoundImportContributor(configData, 0);
		ConfigDataEnvironmentContributor secondContributor = createBoundImportContributor(configData, 1);
		ConfigDataEnvironmentContributors contributors = new ConfigDataEnvironmentContributors(this.logFactory,
				this.bootstrapContext, Arrays.asList(firstContributor, secondContributor), this.conversionService,
				ConfigDataEnvironmentUpdateListener.NONE);
		Binder binder = contributors.getBinder(this.activationContext, BinderOption.FAIL_ON_BIND_TO_INACTIVE_SOURCE);
		assertThatExceptionOfType(BindException.class).isThrownBy(() -> binder.bind("test", String.class))
			.satisfies((ex) -> assertThat(ex.getCause()).isInstanceOf(InactiveConfigDataAccessException.class));
	}

	private ConfigDataEnvironmentContributor createBoundImportContributor(ConfigData configData,
			int propertySourceIndex) {
		ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofUnboundImport(null, null,
				false, configData, propertySourceIndex, this.conversionService,
				ConfigDataEnvironmentUpdateListener.NONE);
		return contributor.withBoundProperties(Collections.singleton(contributor), null);
	}

	private static class TestConfigDataResource extends ConfigDataResource {

		private final String value;

		TestConfigDataResource(String value) {
			this.value = value;
		}

		@Override
		public String toString() {
			return this.value;
		}

	}

}

Domain

Analyze Your Own Codebase

Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.

Try Supermodel Free