From 99a3b6e226189c799118eebe2784e0084b3725e6 Mon Sep 17 00:00:00 2001 From: Ryan Baxter Date: Tue, 4 Sep 2018 15:59:50 -0400 Subject: [PATCH 1/5] Adding additional-spring-configuraition-metadata.json (#408) * Adding additional-spring-configuraition-metadata.json. Fixes #407 --- ...itional-spring-configuration-metadata.json | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 spring-cloud-commons/src/main/resources/META-INF/additional-spring-configuration-metadata.json diff --git a/spring-cloud-commons/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-cloud-commons/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 00000000..04e0911a --- /dev/null +++ b/spring-cloud-commons/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,46 @@ +{ + "properties": [ + { + "defaultValue": "true", + "name": "spring.cloud.refresh.enabled", + "description": "Enables autoconfiguration for the refresh scope and associated features.", + "type": "java.lang.Boolean" + }, + { + "defaultValue": true, + "name": "spring.cloud.httpclientfactories.apache.enabled", + "description": "Enables creation of Apache Http Client factory beans.", + "type": "java.lang.Boolean" + }, + { + "defaultValue": "true", + "name": "spring.cloud.httpclientfactories.ok.enabled", + "description": "Enables creation of OK Http Client factory beans.", + "type": "java.lang.Boolean" + }, + { + "defaultValue": true, + "name": "spring.cloud.util.enabled", + "description": "Enables creation of Spring Cloud utility beans.", + "type": "java.lang.Boolean" + }, + { + "defaultValue": true, + "name": "spring.cloud.features.enabled", + "description": "Enables the features endpoint.", + "type": "java.lang.Boolean" + }, + { + "defaultValue": true, + "name": "spring.cloud.discovery.enabled", + "description": "Enables discovery client health indicators.", + "type": "java.lang.Boolean" + }, + { + "defaultValue": true, + "name": "spring.cloud.discovery.client.composite-indicator.enabled", + "description": "Enables discovery client composite health indicator.", + "type": "java.lang.Boolean" + } + ] +} \ No newline at end of file From da245fc428402a71b1b27165062b756bb5f760df Mon Sep 17 00:00:00 2001 From: Ryan Baxter Date: Mon, 15 Oct 2018 14:28:06 -0400 Subject: [PATCH 2/5] Update SNAPSHOT to 1.3.5.RELEASE --- docs/pom.xml | 2 +- pom.xml | 4 ++-- spring-cloud-commons-dependencies/pom.xml | 4 ++-- spring-cloud-commons/pom.xml | 2 +- spring-cloud-context/pom.xml | 2 +- spring-cloud-starter/pom.xml | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/pom.xml b/docs/pom.xml index 2bc6addd..5a1be22b 100644 --- a/docs/pom.xml +++ b/docs/pom.xml @@ -6,7 +6,7 @@ org.springframework.cloud spring-cloud-commons-parent - 1.3.5.BUILD-SNAPSHOT + 1.3.5.RELEASE pom Spring Cloud Commons Docs diff --git a/pom.xml b/pom.xml index 1f6ae661..6904b11d 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 org.springframework.cloud spring-cloud-commons-parent - 1.3.5.BUILD-SNAPSHOT + 1.3.5.RELEASE pom Spring Cloud Commons Parent Spring Cloud Commons Parent @@ -11,7 +11,7 @@ org.springframework.cloud spring-cloud-build - 1.3.10.RELEASE + 1.3.11.RELEASE diff --git a/spring-cloud-commons-dependencies/pom.xml b/spring-cloud-commons-dependencies/pom.xml index 1ca4c6eb..0d978632 100644 --- a/spring-cloud-commons-dependencies/pom.xml +++ b/spring-cloud-commons-dependencies/pom.xml @@ -5,11 +5,11 @@ spring-cloud-dependencies-parent org.springframework.cloud - 1.3.10.RELEASE + 1.3.11.RELEASE spring-cloud-commons-dependencies - 1.3.5.BUILD-SNAPSHOT + 1.3.5.RELEASE pom spring-cloud-commons-dependencies Spring Cloud Commons Dependencies diff --git a/spring-cloud-commons/pom.xml b/spring-cloud-commons/pom.xml index 55a9a9b0..d5a01dd0 100644 --- a/spring-cloud-commons/pom.xml +++ b/spring-cloud-commons/pom.xml @@ -6,7 +6,7 @@ org.springframework.cloud spring-cloud-commons-parent - 1.3.5.BUILD-SNAPSHOT + 1.3.5.RELEASE .. spring-cloud-commons diff --git a/spring-cloud-context/pom.xml b/spring-cloud-context/pom.xml index 1fb13099..a7cd99e5 100644 --- a/spring-cloud-context/pom.xml +++ b/spring-cloud-context/pom.xml @@ -6,7 +6,7 @@ org.springframework.cloud spring-cloud-commons-parent - 1.3.5.BUILD-SNAPSHOT + 1.3.5.RELEASE .. spring-cloud-context diff --git a/spring-cloud-starter/pom.xml b/spring-cloud-starter/pom.xml index 6b76c1a3..b89a992d 100644 --- a/spring-cloud-starter/pom.xml +++ b/spring-cloud-starter/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-commons-parent - 1.3.5.BUILD-SNAPSHOT + 1.3.5.RELEASE spring-cloud-starter spring-cloud-starter From dcc1a8339efb17673b54389890c52434cd4120e4 Mon Sep 17 00:00:00 2001 From: Ryan Baxter Date: Mon, 15 Oct 2018 14:29:41 -0400 Subject: [PATCH 3/5] Going back to snapshots --- docs/pom.xml | 2 +- pom.xml | 4 ++-- spring-cloud-commons-dependencies/pom.xml | 4 ++-- spring-cloud-commons/pom.xml | 2 +- spring-cloud-context/pom.xml | 2 +- spring-cloud-starter/pom.xml | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/pom.xml b/docs/pom.xml index 5a1be22b..2bc6addd 100644 --- a/docs/pom.xml +++ b/docs/pom.xml @@ -6,7 +6,7 @@ org.springframework.cloud spring-cloud-commons-parent - 1.3.5.RELEASE + 1.3.5.BUILD-SNAPSHOT pom Spring Cloud Commons Docs diff --git a/pom.xml b/pom.xml index 6904b11d..1f6ae661 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 org.springframework.cloud spring-cloud-commons-parent - 1.3.5.RELEASE + 1.3.5.BUILD-SNAPSHOT pom Spring Cloud Commons Parent Spring Cloud Commons Parent @@ -11,7 +11,7 @@ org.springframework.cloud spring-cloud-build - 1.3.11.RELEASE + 1.3.10.RELEASE diff --git a/spring-cloud-commons-dependencies/pom.xml b/spring-cloud-commons-dependencies/pom.xml index 0d978632..1ca4c6eb 100644 --- a/spring-cloud-commons-dependencies/pom.xml +++ b/spring-cloud-commons-dependencies/pom.xml @@ -5,11 +5,11 @@ spring-cloud-dependencies-parent org.springframework.cloud - 1.3.11.RELEASE + 1.3.10.RELEASE spring-cloud-commons-dependencies - 1.3.5.RELEASE + 1.3.5.BUILD-SNAPSHOT pom spring-cloud-commons-dependencies Spring Cloud Commons Dependencies diff --git a/spring-cloud-commons/pom.xml b/spring-cloud-commons/pom.xml index d5a01dd0..55a9a9b0 100644 --- a/spring-cloud-commons/pom.xml +++ b/spring-cloud-commons/pom.xml @@ -6,7 +6,7 @@ org.springframework.cloud spring-cloud-commons-parent - 1.3.5.RELEASE + 1.3.5.BUILD-SNAPSHOT .. spring-cloud-commons diff --git a/spring-cloud-context/pom.xml b/spring-cloud-context/pom.xml index a7cd99e5..1fb13099 100644 --- a/spring-cloud-context/pom.xml +++ b/spring-cloud-context/pom.xml @@ -6,7 +6,7 @@ org.springframework.cloud spring-cloud-commons-parent - 1.3.5.RELEASE + 1.3.5.BUILD-SNAPSHOT .. spring-cloud-context diff --git a/spring-cloud-starter/pom.xml b/spring-cloud-starter/pom.xml index b89a992d..6b76c1a3 100644 --- a/spring-cloud-starter/pom.xml +++ b/spring-cloud-starter/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-commons-parent - 1.3.5.RELEASE + 1.3.5.BUILD-SNAPSHOT spring-cloud-starter spring-cloud-starter From a2ba7a57e3b1bcad83edd1e95d0848a39577702b Mon Sep 17 00:00:00 2001 From: Ryan Baxter Date: Mon, 15 Oct 2018 14:29:42 -0400 Subject: [PATCH 4/5] Bumping versions to 1.3.6.BUILD-SNAPSHOT after release --- docs/pom.xml | 2 +- pom.xml | 4 ++-- spring-cloud-commons-dependencies/pom.xml | 4 ++-- spring-cloud-commons/pom.xml | 2 +- spring-cloud-context/pom.xml | 2 +- spring-cloud-starter/pom.xml | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/pom.xml b/docs/pom.xml index 2bc6addd..fb313b59 100644 --- a/docs/pom.xml +++ b/docs/pom.xml @@ -6,7 +6,7 @@ org.springframework.cloud spring-cloud-commons-parent - 1.3.5.BUILD-SNAPSHOT + 1.3.6.BUILD-SNAPSHOT pom Spring Cloud Commons Docs diff --git a/pom.xml b/pom.xml index 1f6ae661..f1f1edbf 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 org.springframework.cloud spring-cloud-commons-parent - 1.3.5.BUILD-SNAPSHOT + 1.3.6.BUILD-SNAPSHOT pom Spring Cloud Commons Parent Spring Cloud Commons Parent @@ -11,7 +11,7 @@ org.springframework.cloud spring-cloud-build - 1.3.10.RELEASE + 1.3.11.RELEASE diff --git a/spring-cloud-commons-dependencies/pom.xml b/spring-cloud-commons-dependencies/pom.xml index 1ca4c6eb..1c9a3689 100644 --- a/spring-cloud-commons-dependencies/pom.xml +++ b/spring-cloud-commons-dependencies/pom.xml @@ -5,11 +5,11 @@ spring-cloud-dependencies-parent org.springframework.cloud - 1.3.10.RELEASE + 1.3.11.RELEASE spring-cloud-commons-dependencies - 1.3.5.BUILD-SNAPSHOT + 1.3.6.BUILD-SNAPSHOT pom spring-cloud-commons-dependencies Spring Cloud Commons Dependencies diff --git a/spring-cloud-commons/pom.xml b/spring-cloud-commons/pom.xml index 55a9a9b0..23876cd5 100644 --- a/spring-cloud-commons/pom.xml +++ b/spring-cloud-commons/pom.xml @@ -6,7 +6,7 @@ org.springframework.cloud spring-cloud-commons-parent - 1.3.5.BUILD-SNAPSHOT + 1.3.6.BUILD-SNAPSHOT .. spring-cloud-commons diff --git a/spring-cloud-context/pom.xml b/spring-cloud-context/pom.xml index 1fb13099..8ec2120f 100644 --- a/spring-cloud-context/pom.xml +++ b/spring-cloud-context/pom.xml @@ -6,7 +6,7 @@ org.springframework.cloud spring-cloud-commons-parent - 1.3.5.BUILD-SNAPSHOT + 1.3.6.BUILD-SNAPSHOT .. spring-cloud-context diff --git a/spring-cloud-starter/pom.xml b/spring-cloud-starter/pom.xml index 6b76c1a3..e7330eef 100644 --- a/spring-cloud-starter/pom.xml +++ b/spring-cloud-starter/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-commons-parent - 1.3.5.BUILD-SNAPSHOT + 1.3.6.BUILD-SNAPSHOT spring-cloud-starter spring-cloud-starter From 80659a36b11f24b8a3ea9c117c49f73824932cc0 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Thu, 15 Nov 2018 15:40:29 +0100 Subject: [PATCH 5/5] Spring Cloud Compatibility Verification Due to the fact that some users have problem with setting up Spring Cloud application, we've decided to add a compatibility verification mechanism. It will break if your current setup is not compatible with Spring Cloud requirements, together with a report, showing what exactly went wrong. At the moment we verify which version of Spring Boot is added to your classpath. Example of a report ``` *************************** APPLICATION FAILED TO START *************************** Description: Your project setup is incompatible with our requirements due to following reasons: - Spring Boot [1.5.16.RELEASE] is not compatible with this Spring Cloud release train Action: Consider applying the following actions: - Change Spring Boot version to one of the following versions [1.2.x, 1.3.x] . You can find the latest Spring Boot versions here [https://spring.io/projects/spring-boot#learn]. If you want to learn more about the Spring Cloud Release train compatibility, you can visit this page [https://spring.io/projects/spring-cloud#overview] and check the [Release Trains] section. ``` In order to disable this feature, set `spring.cloud.compatibility-verifier.enabled` to `false`. If you want to override the compatible Spring Boot versions, just set the `spring.cloud.compatibility-verifier.compatible-boot-versions` property with a comma separated list of compatible Spring Boot versions. fixes gh-442 --- .../main/asciidoc/spring-cloud-commons.adoc | 39 +++- .../CompatibilityNotMetException.java | 29 +++ .../CompatibilityNotMetFailureAnalyzer.java | 46 ++++ .../configuration/CompatibilityPredicate.java | 21 ++ .../configuration/CompatibilityVerifier.java | 24 ++ ...ompatibilityVerifierAutoConfiguration.java | 52 +++++ .../CompatibilityVerifierProperties.java | 53 +++++ .../CompositeCompatibilityVerifier.java | 55 +++++ .../SpringBootVersionVerifier.java | 178 +++++++++++++++ .../configuration/VerificationResult.java | 48 ++++ .../main/resources/META-INF/spring.factories | 5 + ...ibilityVerifierAutoConfigurationTests.java | 61 +++++ ...erifierDisabledAutoConfigurationTests.java | 45 ++++ ...VerifierFailureAutoConfigurationTests.java | 50 +++++ .../CompatibilityVerifierTests.java | 65 ++++++ .../SpringBootDependencyTests.java | 209 ++++++++++++++++++ 16 files changed, 979 insertions(+), 1 deletion(-) create mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/CompatibilityNotMetException.java create mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/CompatibilityNotMetFailureAnalyzer.java create mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/CompatibilityPredicate.java create mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/CompatibilityVerifier.java create mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/CompatibilityVerifierAutoConfiguration.java create mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/CompatibilityVerifierProperties.java create mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/CompositeCompatibilityVerifier.java create mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/SpringBootVersionVerifier.java create mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/VerificationResult.java create mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/configuration/CompatibilityVerifierAutoConfigurationTests.java create mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/configuration/CompatibilityVerifierDisabledAutoConfigurationTests.java create mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/configuration/CompatibilityVerifierFailureAutoConfigurationTests.java create mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/configuration/CompatibilityVerifierTests.java create mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/configuration/SpringBootDependencyTests.java diff --git a/docs/src/main/asciidoc/spring-cloud-commons.adoc b/docs/src/main/asciidoc/spring-cloud-commons.adoc index 77edc054..dd1dc39e 100644 --- a/docs/src/main/asciidoc/spring-cloud-commons.adoc +++ b/docs/src/main/asciidoc/spring-cloud-commons.adoc @@ -576,4 +576,41 @@ HTTP client and `OkHttpClientConnectionPoolFactory` for the OK HTTP client. You your own implementation of these beans if you would like to customize how the HTTP clients are created in downstream projects. You can also disable the creation of these beans by setting `spring.cloud.httpclientfactories.apache.enabled` or `spring.cloud.httpclientfactories.ok.enabled` to -`false`. \ No newline at end of file +`false`. + +=== Spring Cloud Compatibility Verification + +Due to the fact that some users have problem with setting up Spring Cloud application, we've decided +to add a compatibility verification mechanism. It will break if your current setup is not compatible +with Spring Cloud requirements, together with a report, showing what exactly went wrong. + +At the moment we verify which version of Spring Boot is added to your classpath. + +Example of a report + +---- +*************************** +APPLICATION FAILED TO START +*************************** + +Description: + +Your project setup is incompatible with our requirements due to following reasons: + +- Spring Boot [1.5.16.RELEASE] is not compatible with this Spring Cloud release train + + +Action: + +Consider applying the following actions: + +- Change Spring Boot version to one of the following versions [1.2.x, 1.3.x] . +You can find the latest Spring Boot versions here [https://spring.io/projects/spring-boot#learn]. +If you want to learn more about the Spring Cloud Release train compatibility, you can visit this page [https://spring.io/projects/spring-cloud#overview] and check the [Release Trains] section. +---- + + +In order to disable this feature, set `spring.cloud.compatibility-verifier.enabled` to `false`. +If you want to override the compatible Spring Boot versions, just set the +`spring.cloud.compatibility-verifier.compatible-boot-versions` property with a comma separated list +of compatible Spring Boot versions. \ No newline at end of file diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/CompatibilityNotMetException.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/CompatibilityNotMetException.java new file mode 100644 index 00000000..6be61a3f --- /dev/null +++ b/spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/CompatibilityNotMetException.java @@ -0,0 +1,29 @@ +/* + * Copyright 2002-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.cloud.configuration; + +import java.util.List; + +/** + * Exception thrown when the current setup is not compatible + * + * @author Marcin Grzejszczak + * @since 1.3.6 + */ +class CompatibilityNotMetException extends RuntimeException { + final List results; + + CompatibilityNotMetException(List results) { + this.results = results; + } +} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/CompatibilityNotMetFailureAnalyzer.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/CompatibilityNotMetFailureAnalyzer.java new file mode 100644 index 00000000..c4703e99 --- /dev/null +++ b/spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/CompatibilityNotMetFailureAnalyzer.java @@ -0,0 +1,46 @@ +package org.springframework.cloud.configuration; + +import java.util.List; + +import org.springframework.boot.diagnostics.AbstractFailureAnalyzer; +import org.springframework.boot.diagnostics.FailureAnalysis; + +/** + * Analyzer for the {@link CompatibilityNotMetException}. Prints a list of found + * issues and actions that should be taken to fix them. + * + * @author Marcin Grzejszczak + * @since 1.3.6 + */ +public final class CompatibilityNotMetFailureAnalyzer extends AbstractFailureAnalyzer { + @Override + protected FailureAnalysis analyze(Throwable rootFailure, CompatibilityNotMetException cause) { + return new FailureAnalysis(getDescription(cause), getAction(cause), cause); + } + + private String getDescription(CompatibilityNotMetException ex) { + return String.format("Your project setup is incompatible with our requirements " + + "due to following reasons:%s", descriptions(ex.results)); + } + + private String descriptions(List results) { + StringBuilder builder = new StringBuilder("\n\n"); + for (VerificationResult result : results) { + builder.append("- ").append(result.description).append("\n"); + } + return builder.toString(); + } + + private String getAction(CompatibilityNotMetException ex) { + return String.format("Consider applying the following actions:%s", + actions(ex.results)); + } + + private String actions(List results) { + StringBuilder builder = new StringBuilder("\n\n"); + for (VerificationResult result : results) { + builder.append("- ").append(result.action).append("\n"); + } + return builder.toString(); + } +} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/CompatibilityPredicate.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/CompatibilityPredicate.java new file mode 100644 index 00000000..5e564ed7 --- /dev/null +++ b/spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/CompatibilityPredicate.java @@ -0,0 +1,21 @@ +/* + * Copyright 2002-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.cloud.configuration; + +/** + * So that can be used for jdk 7 - otherwise we would use a predicate + * @author Marcin Grzejszczak + */ +interface CompatibilityPredicate { + boolean isCompatible(); +} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/CompatibilityVerifier.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/CompatibilityVerifier.java new file mode 100644 index 00000000..c6ae7b60 --- /dev/null +++ b/spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/CompatibilityVerifier.java @@ -0,0 +1,24 @@ +/* + * Copyright 2002-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.cloud.configuration; + +/** + * Implementations will verify the compatibility and return a result that + * says whether the check is compatible or not for the current release train + * + * @author Marcin Grzejszczak + * @since 1.3.6 + */ +interface CompatibilityVerifier { + VerificationResult verify(); +} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/CompatibilityVerifierAutoConfiguration.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/CompatibilityVerifierAutoConfiguration.java new file mode 100644 index 00000000..c31916d4 --- /dev/null +++ b/spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/CompatibilityVerifierAutoConfiguration.java @@ -0,0 +1,52 @@ +/* + * Copyright 2002-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.cloud.configuration; + +import java.util.List; + +import org.springframework.boot.autoconfigure.AutoConfigureOrder; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + + +/** + * {@link EnableAutoConfiguration Auto-configuration} that fails the build fast for incompatible + * versions of dependencies (e.g. invalid version of Boot). + * + * @author Marcin Grzejszczak + * @since 1.3.6 + */ +@Configuration +@ConditionalOnProperty(value = "spring.cloud.compatibility-verifier.enabled", matchIfMissing = true) +@AutoConfigureOrder(0) +@EnableConfigurationProperties(CompatibilityVerifierProperties.class) +public class CompatibilityVerifierAutoConfiguration { + + @Bean + CompositeCompatibilityVerifier compositeCompatibilityVerifier(List verifiers) { + CompositeCompatibilityVerifier verifier = new CompositeCompatibilityVerifier(verifiers); + verifier.verifyDependencies(); + return verifier; + } + + @Bean + SpringBootVersionVerifier springBootVersionVerifier( + CompatibilityVerifierProperties properties) { + return new SpringBootVersionVerifier(properties.getCompatibleBootVersions()); + } + +} + diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/CompatibilityVerifierProperties.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/CompatibilityVerifierProperties.java new file mode 100644 index 00000000..24b6fb18 --- /dev/null +++ b/spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/CompatibilityVerifierProperties.java @@ -0,0 +1,53 @@ +/* + * Copyright 2002-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.cloud.configuration; + +import java.util.Collections; +import java.util.List; + +import org.springframework.boot.context.properties.ConfigurationProperties; + +/** + * @author Marcin Grzejszczak + */ +@ConfigurationProperties("spring.cloud.compatibility-verifier") +public class CompatibilityVerifierProperties { + + /** + * Enables creation of Spring Cloud compatibility verification. + */ + private boolean enabled; + + /** + * Default accepted versions for the Spring Boot dependency. You can set {@code x} + * for the patch version if you don't want to specify a concrete value. + * Example: {@code 3.4.x} + */ + private List compatibleBootVersions = Collections.singletonList("1.5.x"); + + public boolean isEnabled() { + return this.enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + public List getCompatibleBootVersions() { + return this.compatibleBootVersions; + } + + public void setCompatibleBootVersions(List compatibleBootVersions) { + this.compatibleBootVersions = compatibleBootVersions; + } +} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/CompositeCompatibilityVerifier.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/CompositeCompatibilityVerifier.java new file mode 100644 index 00000000..7a01fc6c --- /dev/null +++ b/spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/CompositeCompatibilityVerifier.java @@ -0,0 +1,55 @@ +/* + * Copyright 2002-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.cloud.configuration; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * Iterates over {@link CompatibilityVerifier} and prepares a report if exceptions were found + */ +class CompositeCompatibilityVerifier { + + private static final Log log = LogFactory.getLog(CompositeCompatibilityVerifier.class); + + private final List verifiers; + + CompositeCompatibilityVerifier(List verifiers) { + this.verifiers = verifiers; + } + + void verifyDependencies() { + List errors = verifierErrors(); + if (errors.isEmpty()) { + if (log.isDebugEnabled()) { + log.debug("All conditions are passing"); + } + return; + } + throw new CompatibilityNotMetException(errors); + } + + private List verifierErrors() { + List errors = new ArrayList<>(); + for (CompatibilityVerifier verifier : this.verifiers) { + VerificationResult result = verifier.verify(); + if (result.isNotCompatible()) { + errors.add(result); + } + } + return errors; + } +} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/SpringBootVersionVerifier.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/SpringBootVersionVerifier.java new file mode 100644 index 00000000..525a014e --- /dev/null +++ b/spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/SpringBootVersionVerifier.java @@ -0,0 +1,178 @@ +/* + * Copyright 2002-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.cloud.configuration; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.springframework.boot.SpringBootVersion; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.util.StringUtils; + +/** + * Verifies if Spring Boot has proper version + */ +class SpringBootVersionVerifier implements CompatibilityVerifier { + + private static final Log log = LogFactory.getLog(SpringBootVersionVerifier.class); + + final Map ACCEPTED_VERSIONS = new HashMap() { + { + this.put("1.5", is1_5()); + this.put("2.0", is2_0()); + this.put("2.1", is2_1()); + } + }; + + private final List acceptedVersions; + + SpringBootVersionVerifier(List acceptedVersions) { + this.acceptedVersions = acceptedVersions; + } + + @Override + public VerificationResult verify() { + boolean matches = springBootVersionMatches(); + if (matches) { + return VerificationResult.compatible(); + } + return VerificationResult.notCompatible(errorDescription(), action()); + } + + CompatibilityPredicate is1_5() { + return new CompatibilityPredicate() { + + @Override + public String toString() { + return "Predicate for Boot 1.5"; + } + + @Override + public boolean isCompatible() { + try { + // deprecated 1.5 + Class.forName("org.springframework.boot.context.config.ResourceNotFoundException"); + return true; + } + catch (ClassNotFoundException e) { + return false; + } + } + }; + } + + private boolean bootVersionFromManifest(String s) { + String version = getVersionFromManifest(); + if (log.isDebugEnabled()) { + log.debug("Version found in Boot manifest [" + version + "]"); + } + return StringUtils.hasText(version) && version.startsWith(s); + } + + String getVersionFromManifest() { + return SpringBootVersion.getVersion(); + } + + CompatibilityPredicate is2_0() { + return new CompatibilityPredicate() { + @Override + public String toString() { + return "Predicate for Boot 2.0"; + } + + @Override + public boolean isCompatible() { + + try { + // present in 2.0, 1.5 missing in 2.1 + SpringApplicationBuilder.class.getMethod("web", boolean.class); + return !is1_5().isCompatible(); + } + catch (NoSuchMethodException e) { + return false; + } + } + }; + } + + CompatibilityPredicate is2_1() { + return new CompatibilityPredicate() { + + @Override + public String toString() { + return "Predicate for Boot 2.1"; + } + + @Override + public boolean isCompatible() { + try { + // since 2.1 + Class.forName("org.springframework.boot.task.TaskExecutorCustomizer"); + return true; + } + catch (ClassNotFoundException e) { + return false; + } + + + } + }; + } + + private String errorDescription() { + String versionFromManifest = getVersionFromManifest(); + if (StringUtils.hasText(versionFromManifest)) { + return String.format("Spring Boot [%s] is not compatible with this Spring Cloud release train", versionFromManifest); + } + return "Spring Boot is not compatible with this Spring Cloud release train"; + } + + private String action() { + return String.format("Change Spring Boot version to one of the following versions %s .\n" + + "You can find the latest Spring Boot versions here [%s]. \n" + + "If you want to learn more about the Spring Cloud Release train compatibility, you " + + "can visit this page [%s] and check the [Release Trains] section.", + this.acceptedVersions, "https://spring.io/projects/spring-boot#learn", "https://spring.io/projects/spring-cloud#overview"); + } + + private boolean springBootVersionMatches() { + for (String acceptedVersion : acceptedVersions) { + if (bootVersionFromManifest(acceptedVersion)) { + return true; + } + else { + // 2.0, 2.1 + CompatibilityPredicate predicate = ACCEPTED_VERSIONS.get( + acceptedVersionWithoutX(acceptedVersion)); + if (predicate != null && predicate.isCompatible()) { + if (log.isDebugEnabled()) { + log.debug("Predicate [" + predicate + "] was matched"); + } + return true; + } + } + } + return false; + } + + private String acceptedVersionWithoutX(String acceptedVersion) { + if (acceptedVersion.endsWith(".x")) { + return acceptedVersion.substring(0, acceptedVersion.indexOf(".x")); + } + return acceptedVersion; + } +} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/VerificationResult.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/VerificationResult.java new file mode 100644 index 00000000..e3b53b3d --- /dev/null +++ b/spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/VerificationResult.java @@ -0,0 +1,48 @@ +/* + * Copyright 2002-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.cloud.configuration; + +import org.springframework.util.StringUtils; + +/** + * @author Marcin Grzejszczak + */ +class VerificationResult { + final String description; + final String action; + + // if OK + private VerificationResult() { + this.description = ""; + this.action = ""; + } + + // if not OK + private VerificationResult(String errorDescription, String action) { + this.description = errorDescription; + this.action = action; + } + + static VerificationResult compatible() { + return new VerificationResult(); + } + + static VerificationResult notCompatible(String errorDescription, String action) { + return new VerificationResult(errorDescription, action); + } + + boolean isNotCompatible() { + return StringUtils.hasText(this.description) || StringUtils.hasText(this.action); + } + +} diff --git a/spring-cloud-commons/src/main/resources/META-INF/spring.factories b/spring-cloud-commons/src/main/resources/META-INF/spring.factories index 71538019..059bb891 100644 --- a/spring-cloud-commons/src/main/resources/META-INF/spring.factories +++ b/spring-cloud-commons/src/main/resources/META-INF/spring.factories @@ -7,6 +7,7 @@ org.springframework.cloud.client.loadbalancer.AsyncLoadBalancerAutoConfiguration org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration,\ org.springframework.cloud.client.serviceregistry.ServiceRegistryAutoConfiguration,\ org.springframework.cloud.commons.util.UtilAutoConfiguration,\ +org.springframework.cloud.configuration.CompatibilityVerifierAutoConfiguration,\ org.springframework.cloud.client.discovery.composite.CompositeDiscoveryClientAutoConfiguration,\ org.springframework.cloud.client.discovery.simple.SimpleDiscoveryClientAutoConfiguration,\ org.springframework.cloud.commons.httpclient.HttpClientConfiguration,\ @@ -16,3 +17,7 @@ org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationAutoConf # Environment Post Processors org.springframework.boot.env.EnvironmentPostProcessor=\ org.springframework.cloud.client.HostInfoEnvironmentPostProcessor + +# Failure Analyzers +org.springframework.boot.diagnostics.FailureAnalyzer=\ +org.springframework.cloud.configuration.CompatibilityNotMetFailureAnalyzer \ No newline at end of file diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/configuration/CompatibilityVerifierAutoConfigurationTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/configuration/CompatibilityVerifierAutoConfigurationTests.java new file mode 100644 index 00000000..5b821d1a --- /dev/null +++ b/spring-cloud-commons/src/test/java/org/springframework/cloud/configuration/CompatibilityVerifierAutoConfigurationTests.java @@ -0,0 +1,61 @@ +/* + * Copyright 2002-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.cloud.configuration; + +import org.assertj.core.api.BDDAssertions; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.context.junit4.SpringRunner; + +/** + * @author Marcin Grzejszczak + */ +@RunWith(SpringRunner.class) +@SpringBootTest +public class CompatibilityVerifierAutoConfigurationTests { + + @Autowired + MyCompatibilityVerifier myMismatchVerifier; + + @Test + public void contextLoads() { + BDDAssertions.then(this.myMismatchVerifier.called).isTrue(); + } + + @Configuration + @EnableAutoConfiguration + static class TestConfiguration { + @Bean + MyCompatibilityVerifier myMismatchVerifier() { + return new MyCompatibilityVerifier(); + } + } + + private static class MyCompatibilityVerifier implements CompatibilityVerifier { + + boolean called; + + @Override + public VerificationResult verify() { + this.called = true; + return VerificationResult.compatible(); + } + } +} + diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/configuration/CompatibilityVerifierDisabledAutoConfigurationTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/configuration/CompatibilityVerifierDisabledAutoConfigurationTests.java new file mode 100644 index 00000000..ba803079 --- /dev/null +++ b/spring-cloud-commons/src/test/java/org/springframework/cloud/configuration/CompatibilityVerifierDisabledAutoConfigurationTests.java @@ -0,0 +1,45 @@ +/* + * Copyright 2002-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.cloud.configuration; + +import org.assertj.core.api.BDDAssertions; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.context.junit4.SpringRunner; + +/** + * @author Marcin Grzejszczak + */ +@RunWith(SpringRunner.class) +@SpringBootTest(properties = "spring.cloud.compatibility-verifier.enabled=false") +public class CompatibilityVerifierDisabledAutoConfigurationTests { + + @Autowired(required = false) + CompositeCompatibilityVerifier compositeCompatibilityVerifier; + + @Test + public void contextLoads() { + BDDAssertions.then(this.compositeCompatibilityVerifier).isNull(); + } + + @Configuration + @EnableAutoConfiguration + static class TestConfiguration { + } +} + diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/configuration/CompatibilityVerifierFailureAutoConfigurationTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/configuration/CompatibilityVerifierFailureAutoConfigurationTests.java new file mode 100644 index 00000000..a081b851 --- /dev/null +++ b/spring-cloud-commons/src/test/java/org/springframework/cloud/configuration/CompatibilityVerifierFailureAutoConfigurationTests.java @@ -0,0 +1,50 @@ +/* + * Copyright 2002-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.cloud.configuration; + +import org.assertj.core.api.BDDAssertions; +import org.junit.Rule; +import org.junit.Test; + +import org.springframework.beans.factory.BeanCreationException; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.test.rule.OutputCapture; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.NestedExceptionUtils; + +/** + * @author Marcin Grzejszczak + */ +public class CompatibilityVerifierFailureAutoConfigurationTests { + + @Rule public OutputCapture outputCapture = new OutputCapture(); + + @Test + public void contextFailsToLoad() { + try { + SpringApplication.run(TestConfiguration.class, + "--spring.cloud.compatibility-verifier.compatible-boot-versions=1.2.x,1.3.x"); + BDDAssertions.fail("should throw exception"); + } catch (BeanCreationException ex) { + Throwable cause = NestedExceptionUtils.getRootCause(ex); + BDDAssertions.then(((CompatibilityNotMetException) cause).results).hasSize(1); + } + } + + @Configuration + @EnableAutoConfiguration + static class TestConfiguration { + } +} + diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/configuration/CompatibilityVerifierTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/configuration/CompatibilityVerifierTests.java new file mode 100644 index 00000000..23487d7e --- /dev/null +++ b/spring-cloud-commons/src/test/java/org/springframework/cloud/configuration/CompatibilityVerifierTests.java @@ -0,0 +1,65 @@ +/* + * Copyright 2002-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.cloud.configuration; + +import java.util.ArrayList; +import java.util.List; + +import org.assertj.core.api.BDDAssertions; +import org.junit.Rule; +import org.junit.Test; + +import org.springframework.boot.test.rule.OutputCapture; + +/** + * @author Marcin Grzejszczak + */ +public class CompatibilityVerifierTests { + + @Rule public OutputCapture outputCapture = new OutputCapture(); + + @Test + public void should_not_print_the_report_when_no_errors_were_found() { + CompositeCompatibilityVerifier verifier = new CompositeCompatibilityVerifier(new ArrayList()); + + verifier.verifyDependencies(); + + BDDAssertions.then(outputCapture.toString()).doesNotContain("SPRING CLOUD VERIFICATION FAILED"); + } + + @Test + public void should_print_the_report_when_errors_were_found() { + List list = new ArrayList<>(); + list.add(new CompatibilityVerifier() { + @Override + public VerificationResult verify() { + return VerificationResult.notCompatible("Wrong Boot version", "Use Boot version 1.2"); + } + }); + list.add(new CompatibilityVerifier() { + @Override + public VerificationResult verify() { + return VerificationResult.notCompatible("Wrong JDK version", "Use JDK 25"); + } + }); + CompositeCompatibilityVerifier verifier = new CompositeCompatibilityVerifier(list); + + try { + verifier.verifyDependencies(); + BDDAssertions.fail("should fail"); + } catch (CompatibilityNotMetException ex) { + BDDAssertions.then(ex.results).hasSize(2); + } + } + +} \ No newline at end of file diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/configuration/SpringBootDependencyTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/configuration/SpringBootDependencyTests.java new file mode 100644 index 00000000..92ffb579 --- /dev/null +++ b/spring-cloud-commons/src/test/java/org/springframework/cloud/configuration/SpringBootDependencyTests.java @@ -0,0 +1,209 @@ +/* + * Copyright 2002-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.cloud.configuration; + +import java.util.Collections; +import java.util.List; + +import org.assertj.core.api.BDDAssertions; +import org.junit.Test; + +/** + * @author Marcin Grzejszczak + */ +public class SpringBootDependencyTests { + + @Test + public void should_read_concrete_version_from_manifest() { + List acceptedVersions = Collections.singletonList("2.0.3.RELEASE"); + SpringBootVersionVerifier + versionVerifier = new SpringBootVersionVerifier(acceptedVersions) { + @Override + String getVersionFromManifest() { + return "2.0.3.RELEASE"; + } + }; + versionVerifier.ACCEPTED_VERSIONS.clear(); + + VerificationResult verificationResult = versionVerifier.verify(); + + BDDAssertions.then(verificationResult.description).isEmpty(); + BDDAssertions.then(verificationResult.action).isEmpty(); + } + + @Test + public void should_read_concrete_version_from_manifest_and_return_false_when_version_is_not_matched() { + List acceptedVersions = Collections.singletonList("2.0.9.RELEASE"); + SpringBootVersionVerifier + versionVerifier = new SpringBootVersionVerifier(acceptedVersions) { + @Override + String getVersionFromManifest() { + return "2.0.3.RELEASE"; + } + }; + versionVerifier.ACCEPTED_VERSIONS.clear(); + + VerificationResult verificationResult = versionVerifier.verify(); + + BDDAssertions.then(verificationResult.description).isNotEmpty(); + BDDAssertions.then(verificationResult.action).isNotEmpty(); + } + + @Test + public void should_read_concrete_version_from_manifest_and_return_false_when_minor_version_is_not_matched() { + List acceptedVersions = Collections.singletonList("2.0"); + SpringBootVersionVerifier + versionVerifier = new SpringBootVersionVerifier(acceptedVersions) { + @Override + String getVersionFromManifest() { + return "2.1.3.RELEASE"; + } + }; + versionVerifier.ACCEPTED_VERSIONS.clear(); + + VerificationResult verificationResult = versionVerifier.verify(); + + BDDAssertions.then(verificationResult.description).isNotEmpty(); + BDDAssertions.then(verificationResult.action).isNotEmpty(); + } + + @Test + public void should_read_concrete_version_from_manifest_and_match_it_against_minor_version() { + List acceptedVersions = Collections.singletonList("2.0"); + SpringBootVersionVerifier + versionVerifier = new SpringBootVersionVerifier(acceptedVersions) { + @Override + String getVersionFromManifest() { + return "2.0.3.RELEASE"; + } + }; + versionVerifier.ACCEPTED_VERSIONS.clear(); + + VerificationResult verificationResult = versionVerifier.verify(); + + BDDAssertions.then(verificationResult.description).isEmpty(); + BDDAssertions.then(verificationResult.action).isEmpty(); + } + + @Test + public void should_match_against_predicate() { + List acceptedVersions = Collections.singletonList("2.5"); + SpringBootVersionVerifier + versionVerifier = new SpringBootVersionVerifier(acceptedVersions) { + @Override + String getVersionFromManifest() { + return ""; + } + }; + versionVerifier.ACCEPTED_VERSIONS.clear(); + versionVerifier.ACCEPTED_VERSIONS.put("2.5", new CompatibilityPredicate() { + @Override + public boolean isCompatible() { + return true; + } + }); + + VerificationResult verificationResult = versionVerifier.verify(); + + BDDAssertions.then(verificationResult.description).isEmpty(); + BDDAssertions.then(verificationResult.action).isEmpty(); + } + + @Test + public void should_fail_to_match_against_predicate_when_none_is_matching() { + List acceptedVersions = Collections.singletonList("2.5"); + SpringBootVersionVerifier + versionVerifier = new SpringBootVersionVerifier(acceptedVersions) { + @Override + String getVersionFromManifest() { + return ""; + } + }; + versionVerifier.ACCEPTED_VERSIONS.clear(); + + VerificationResult verificationResult = versionVerifier.verify(); + + BDDAssertions.then(verificationResult.description).isNotEmpty(); + BDDAssertions.then(verificationResult.action).isNotEmpty(); + } + + @Test + public void should_match_against_current_manifest() { + List acceptedVersions = Collections.singletonList("1.5"); + SpringBootVersionVerifier + versionVerifier = new SpringBootVersionVerifier(acceptedVersions); + versionVerifier.ACCEPTED_VERSIONS.clear(); + + VerificationResult verificationResult = versionVerifier.verify(); + + BDDAssertions.then(verificationResult.description).isEmpty(); + BDDAssertions.then(verificationResult.action).isEmpty(); + } + + @Test + public void should_match_against_current_predicate() { + List acceptedVersions = Collections.singletonList("1.5"); + SpringBootVersionVerifier + versionVerifier = new SpringBootVersionVerifier(acceptedVersions){ + @Override + String getVersionFromManifest() { + return ""; + } + }; + versionVerifier.ACCEPTED_VERSIONS.clear(); + versionVerifier.ACCEPTED_VERSIONS.put("1.5", versionVerifier.is1_5()); + + VerificationResult verificationResult = versionVerifier.verify(); + + BDDAssertions.then(verificationResult.description).isEmpty(); + BDDAssertions.then(verificationResult.action).isEmpty(); + } + + @Test + public void should_match_against_current_predicate_with_version_ending_with_x() { + List acceptedVersions = Collections.singletonList("1.5.x"); + SpringBootVersionVerifier + versionVerifier = new SpringBootVersionVerifier(acceptedVersions){ + @Override + String getVersionFromManifest() { + return ""; + } + }; + versionVerifier.ACCEPTED_VERSIONS.clear(); + versionVerifier.ACCEPTED_VERSIONS.put("1.5", versionVerifier.is1_5()); + + VerificationResult verificationResult = versionVerifier.verify(); + + BDDAssertions.then(verificationResult.description).isEmpty(); + BDDAssertions.then(verificationResult.action).isEmpty(); + } + + @Test + public void should_fail_to_match_against_predicate_for_non_current_versions() { + List acceptedVersions = Collections.singletonList("1.5"); + SpringBootVersionVerifier + versionVerifier = new SpringBootVersionVerifier(acceptedVersions) { + @Override + String getVersionFromManifest() { + return ""; + } + }; + versionVerifier.ACCEPTED_VERSIONS.remove("1.5"); + + VerificationResult verificationResult = versionVerifier.verify(); + + BDDAssertions.then(verificationResult.description).isNotEmpty(); + BDDAssertions.then(verificationResult.action).isNotEmpty(); + } + +} \ No newline at end of file