From 8e81f0c23d7095b38144d8f4ea3c33e7b9cd45f4 Mon Sep 17 00:00:00 2001 From: Madhura Bhave Date: Mon, 2 Apr 2018 12:57:28 -0700 Subject: [PATCH] Fix conditions report message for same short name If two auto-configuration classes with the same name are present, the conditions report message now uses the fully qualified name for both instead of the short name. Fixes gh-11710 --- .../ConditionEvaluationReportMessage.java | 31 +++++++++------ .../ConditionEvaluationReportTests.java | 38 ++++++++++++++++-- .../config/first/SampleAutoConfiguration.java | 39 +++++++++++++++++++ .../second/SampleAutoConfiguration.java | 39 +++++++++++++++++++ 4 files changed, 133 insertions(+), 14 deletions(-) create mode 100644 spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/condition/config/first/SampleAutoConfiguration.java create mode 100644 spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/condition/config/second/SampleAutoConfiguration.java diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/logging/ConditionEvaluationReportMessage.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/logging/ConditionEvaluationReportMessage.java index 7da1b0837d..a4cc198552 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/logging/ConditionEvaluationReportMessage.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/logging/ConditionEvaluationReportMessage.java @@ -18,17 +18,19 @@ package org.springframework.boot.autoconfigure.logging; import java.util.ArrayList; import java.util.Collections; -import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.Set; import java.util.stream.Collectors; import org.springframework.boot.autoconfigure.condition.ConditionEvaluationReport; import org.springframework.boot.autoconfigure.condition.ConditionEvaluationReport.ConditionAndOutcome; import org.springframework.boot.autoconfigure.condition.ConditionEvaluationReport.ConditionAndOutcomes; import org.springframework.util.ClassUtils; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; import org.springframework.util.StringUtils; /** @@ -135,21 +137,28 @@ public class ConditionEvaluationReportMessage { private Map orderByName( Map outcomes) { - List names = new ArrayList<>(); - Map classNames = new HashMap<>(); - for (String name : outcomes.keySet()) { - String shortName = ClassUtils.getShortName(name); - names.add(shortName); - classNames.put(shortName, name); - } - Collections.sort(names); + MultiValueMap map = mapShortNameToFullyQualifiedNames(outcomes.keySet()); + List shortNames = new ArrayList<>(map.keySet()); + Collections.sort(shortNames); Map result = new LinkedHashMap<>(); - for (String shortName : names) { - result.put(shortName, outcomes.get(classNames.get(shortName))); + for (String shortName : shortNames) { + List fullyQualifiedNames = map.get(shortName); + if (fullyQualifiedNames.size() > 1) { + fullyQualifiedNames.forEach(k -> result.put(k, outcomes.get(k))); + } + else { + result.put(shortName, outcomes.get(fullyQualifiedNames.get(0))); + } } return result; } + private MultiValueMap mapShortNameToFullyQualifiedNames(Set keySet) { + LinkedMultiValueMap map = new LinkedMultiValueMap<>(); + keySet.forEach(k -> map.add(ClassUtils.getShortName(k), k)); + return map; + } + private void addMatchLogMessage(StringBuilder message, String source, ConditionAndOutcomes matches) { message.append(String.format("%n %s matched:%n", source)); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/condition/ConditionEvaluationReportTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/condition/ConditionEvaluationReportTests.java index 4515319d44..a8352d88a1 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/condition/ConditionEvaluationReportTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/condition/ConditionEvaluationReportTests.java @@ -30,6 +30,7 @@ import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.boot.autoconfigure.condition.ConditionEvaluationReport.ConditionAndOutcome; import org.springframework.boot.autoconfigure.condition.ConditionEvaluationReport.ConditionAndOutcomes; +import org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportMessage; import org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfiguration; import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; import org.springframework.boot.test.util.TestPropertyValues; @@ -241,6 +242,37 @@ public class ConditionEvaluationReportTests { assertThat(sourceOutcomes.get(positiveConfig).isFullMatch()).isFalse(); } + @Test + public void reportWhenSameShortNamePresentMoreThanOnceShouldUseFullyQualifiedName() { + AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); + context.register(WebMvcAutoConfiguration.class, + org.springframework.boot.autoconfigure.condition.config.first.SampleAutoConfiguration.class, + org.springframework.boot.autoconfigure.condition.config.second.SampleAutoConfiguration.class); + context.refresh(); + ConditionEvaluationReport report = ConditionEvaluationReport + .get(context.getBeanFactory()); + assertThat(report.getConditionAndOutcomesBySource()) + .containsKeys("org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration", + "org.springframework.boot.autoconfigure.condition.config.first.SampleAutoConfiguration", + "org.springframework.boot.autoconfigure.condition.config.second.SampleAutoConfiguration"); + } + + @Test + public void reportMessageWhenSameShortNamePresentMoreThanOnceShouldUseFullyQualifiedName() { + AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); + context.register(WebMvcAutoConfiguration.class, + org.springframework.boot.autoconfigure.condition.config.first.SampleAutoConfiguration.class, + org.springframework.boot.autoconfigure.condition.config.second.SampleAutoConfiguration.class); + context.refresh(); + ConditionEvaluationReport report = ConditionEvaluationReport + .get(context.getBeanFactory()); + String reportMessage = new ConditionEvaluationReportMessage(report).toString(); + assertThat(reportMessage) + .contains("WebMvcAutoConfiguration", "org.springframework.boot.autoconfigure.condition.config.first.SampleAutoConfiguration", + "org.springframework.boot.autoconfigure.condition.config.second.SampleAutoConfiguration"); + assertThat(reportMessage).doesNotContain("org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration"); + } + private int getNumberOfOutcomes(ConditionAndOutcomes outcomes) { Iterator iterator = outcomes.iterator(); int numberOfOutcomesAdded = 0; @@ -264,12 +296,12 @@ public class ConditionEvaluationReportTests { } @Configuration - @Conditional({ ConditionEvaluationReportTests.MatchParseCondition.class, - ConditionEvaluationReportTests.NoMatchBeanCondition.class }) + @Conditional({ConditionEvaluationReportTests.MatchParseCondition.class, + ConditionEvaluationReportTests.NoMatchBeanCondition.class}) public static class NegativeOuterConfig { @Configuration - @Conditional({ ConditionEvaluationReportTests.MatchParseCondition.class }) + @Conditional({ConditionEvaluationReportTests.MatchParseCondition.class}) public static class PositiveInnerConfig { @Bean diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/condition/config/first/SampleAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/condition/config/first/SampleAutoConfiguration.java new file mode 100644 index 0000000000..778c2403ed --- /dev/null +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/condition/config/first/SampleAutoConfiguration.java @@ -0,0 +1,39 @@ +/* + * Copyright 2012-2018 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 + * + * http://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.autoconfigure.condition.config.first; + +import org.springframework.boot.autoconfigure.condition.ConditionEvaluationReport; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * Sample auto-configuration for {@link ConditionEvaluationReport} tests. + * + * @author Madhura Bhave + */ +@Configuration("autoConfigOne") +@ConditionalOnProperty("sample.first") +public class SampleAutoConfiguration { + + @Bean + public String one() { + return "one"; + } + +} + diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/condition/config/second/SampleAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/condition/config/second/SampleAutoConfiguration.java new file mode 100644 index 0000000000..8096c88122 --- /dev/null +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/condition/config/second/SampleAutoConfiguration.java @@ -0,0 +1,39 @@ +/* + * Copyright 2012-2018 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 + * + * http://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.autoconfigure.condition.config.second; + +import org.springframework.boot.autoconfigure.condition.ConditionEvaluationReport; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * Sample auto-configuration for {@link ConditionEvaluationReport} tests. + * + * @author Madhura Bhave + */ +@Configuration("autoConfigTwo") +@ConditionalOnProperty("sample.second") +public class SampleAutoConfiguration { + + @Bean + public String two() { + return "two"; + } + +} +