diff --git a/.github/workflows/build-pull-request.yml b/.github/workflows/build-pull-request.yml
index c9448b094e89..395ffc395950 100644
--- a/.github/workflows/build-pull-request.yml
+++ b/.github/workflows/build-pull-request.yml
@@ -7,7 +7,7 @@ permissions:
jobs:
build:
name: Build pull request
- runs-on: ubuntu-latest
+ runs-on: ubuntu22-8-32
if: ${{ github.repository == 'spring-projects/spring-boot' }}
steps:
- name: Set up JDK 17
@@ -17,13 +17,13 @@ jobs:
distribution: 'liberica'
- name: Check out code
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
- name: Validate Gradle wrapper
uses: gradle/wrapper-validation-action@v1
- name: Set up Gradle
- uses: gradle/gradle-build-action@bd5760595778326ba7f1441bcf7e88b49de61a25
+ uses: gradle/gradle-build-action@842c587ad8aa4c68eeba24c396e15af4c2e9f30a
- name: Build
env:
@@ -37,6 +37,7 @@ jobs:
- name: Upload build reports
uses: actions/upload-artifact@v3
+ if: failure()
with:
name: build-reports
path: '**/build/reports/'
diff --git a/.github/workflows/gradle-wrapper-validation.yml b/.github/workflows/gradle-wrapper-validation.yml
index c80a7e5278d0..c87c892efbf0 100644
--- a/.github/workflows/gradle-wrapper-validation.yml
+++ b/.github/workflows/gradle-wrapper-validation.yml
@@ -9,5 +9,5 @@ jobs:
name: "Validation"
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- uses: gradle/wrapper-validation-action@v1
diff --git a/.gitignore b/.gitignore
index 6edbdcda3124..a5256ecef4fa 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,7 +12,6 @@
.classpath
.factorypath
.gradle
-.idea
.metadata
.project
.recommenders
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 000000000000..f1e07ef8c39f
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,10 @@
+.name
+*.xml
+/modules/
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
new file mode 100644
index 000000000000..854b5bf05230
--- /dev/null
+++ b/.idea/codeStyles/Project.xml
@@ -0,0 +1,121 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml
new file mode 100644
index 000000000000..79ee123c2b23
--- /dev/null
+++ b/.idea/codeStyles/codeStyleConfig.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/copyright/java.xml b/.idea/copyright/java.xml
new file mode 100644
index 000000000000..f48ffaf6b6e1
--- /dev/null
+++ b/.idea/copyright/java.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml
new file mode 100644
index 000000000000..d278876c98f1
--- /dev/null
+++ b/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 000000000000..df1bf12fd2db
--- /dev/null
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.idea/scopes/java.xml b/.idea/scopes/java.xml
new file mode 100644
index 000000000000..a4576baff901
--- /dev/null
+++ b/.idea/scopes/java.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/.sdkmanrc b/.sdkmanrc
index 93afdeb201db..6dbcaa9337a9 100644
--- a/.sdkmanrc
+++ b/.sdkmanrc
@@ -1,3 +1,3 @@
# Enable auto-env through the sdkman_auto_env config
# Add key=value pairs of SDKs to use below
-java=17.0.7-librca
+java=17.0.9-librca
diff --git a/README.adoc b/README.adoc
index b0e635135a51..b603722e4e25 100755
--- a/README.adoc
+++ b/README.adoc
@@ -1,4 +1,4 @@
-= Spring Boot image:https://ci.spring.io/api/v1/teams/spring-boot/pipelines/spring-boot-3.1.x/jobs/build/badge["Build Status", link="https://ci.spring.io/teams/spring-boot/pipelines/spring-boot-3.1.x?groups=Build"] image:https://badges.gitter.im/Join Chat.svg["Chat",link="https://gitter.im/spring-projects/spring-boot?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge"] image:https://img.shields.io/badge/Revved%20up%20by-Gradle%20Enterprise-06A0CE?logo=Gradle&labelColor=02303A["Revved up by Gradle Enterprise", link="https://ge.spring.io/scans?&search.rootProjectNames=Spring%20Boot%20Build&search.rootProjectNames=spring-boot-build"]
+= Spring Boot image:https://ci.spring.io/api/v1/teams/spring-boot/pipelines/spring-boot-3.2.x/jobs/build/badge["Build Status", link="https://ci.spring.io/teams/spring-boot/pipelines/spring-boot-3.2.x?groups=Build"] image:https://badges.gitter.im/Join Chat.svg["Chat",link="https://gitter.im/spring-projects/spring-boot?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge"] image:https://img.shields.io/badge/Revved%20up%20by-Gradle%20Enterprise-06A0CE?logo=Gradle&labelColor=02303A["Revved up by Gradle Enterprise", link="https://ge.spring.io/scans?&search.rootProjectNames=Spring%20Boot%20Build&search.rootProjectNames=spring-boot-build"]
:docs: https://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference
:github: https://github.com/spring-projects/spring-boot
diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle
index 2968c3e14e79..4970e29102db 100644
--- a/buildSrc/build.gradle
+++ b/buildSrc/build.gradle
@@ -10,49 +10,56 @@ repositories {
gradlePluginPortal()
}
-new File(new File("$projectDir").parentFile, "gradle.properties").withInputStream {
+sourceCompatibility = 17
+targetCompatibility = 17
+
+def versions = [:]
+new File(projectDir.parentFile, "gradle.properties").withInputStream {
def properties = new Properties()
properties.load(it)
- ext.set("kotlinVersion", properties["kotlinVersion"])
- ext.set("springFrameworkVersion", properties["springFrameworkVersion"])
- if (properties["springFrameworkVersion"].contains("-")) {
- repositories {
- maven { url "https://repo.spring.io/milestone" }
- maven { url "https://repo.spring.io/snapshot" }
- }
+ ["assertj", "commonsCodec", "hamcrest", "jackson", "junitJupiter",
+ "kotlin", "maven"].each {
+ versions[it] = properties[it + "Version"]
+ }
+}
+versions["springFramework"] = "6.0.12"
+ext.set("versions", versions)
+if (versions.springFramework.contains("-")) {
+ repositories {
+ maven { url "https://repo.spring.io/milestone" }
+ maven { url "https://repo.spring.io/snapshot" }
}
}
-
-sourceCompatibility = 17
-targetCompatibility = 17
dependencies {
checkstyle "io.spring.javaformat:spring-javaformat-checkstyle:${javaFormatVersion}"
- implementation(platform("org.springframework:spring-framework-bom:${springFrameworkVersion}"))
+ implementation(platform("org.springframework:spring-framework-bom:${versions.springFramework}"))
implementation("com.diffplug.gradle:goomph:3.37.2")
- implementation("com.fasterxml.jackson.core:jackson-databind:2.11.4")
+ implementation("com.fasterxml.jackson.core:jackson-databind:${versions.jackson}")
implementation("com.gradle:gradle-enterprise-gradle-plugin:3.12.1")
implementation("com.tngtech.archunit:archunit:1.0.0")
- implementation("commons-codec:commons-codec:1.13")
+ implementation("commons-codec:commons-codec:${versions.commonsCodec}")
+ implementation("de.undercouch.download:de.undercouch.download.gradle.plugin:5.5.0")
implementation("io.spring.javaformat:spring-javaformat-gradle-plugin:${javaFormatVersion}")
- implementation("org.apache.maven:maven-embedder:3.6.3")
+ implementation("org.apache.maven:maven-embedder:${versions.maven}")
implementation("org.asciidoctor:asciidoctor-gradle-jvm:3.3.2")
- implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:${kotlinVersion}")
- implementation("org.jetbrains.kotlin:kotlin-compiler-embeddable:${kotlinVersion}")
+ implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:${versions.kotlin}")
+ implementation("org.jetbrains.kotlin:kotlin-compiler-embeddable:${versions.kotlin}")
implementation("org.springframework:spring-context")
implementation("org.springframework:spring-core")
implementation("org.springframework:spring-web")
- testImplementation("org.assertj:assertj-core:3.11.1")
- testImplementation("org.apache.logging.log4j:log4j-core:2.17.1")
- testImplementation("org.junit.jupiter:junit-jupiter:5.6.0")
+ testImplementation("org.assertj:assertj-core:${versions.assertj}")
+ testImplementation("org.hamcrest:hamcrest:${versions.hamcrest}")
+ testImplementation("org.junit.jupiter:junit-jupiter:${versions.junitJupiter}")
+ testImplementation("org.springframework:spring-test")
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
}
checkstyle {
- toolVersion = 8.11
+ toolVersion = "10.12.4"
}
gradlePlugin {
@@ -62,8 +69,8 @@ gradlePlugin {
implementationClass = "org.springframework.boot.build.processors.AnnotationProcessorPlugin"
}
architecturePlugin {
- id = "org.springframework.boot.architecture"
- implementationClass = "org.springframework.boot.build.architecture.ArchitecturePlugin"
+ id = "org.springframework.boot.architecture"
+ implementationClass = "org.springframework.boot.build.architecture.ArchitecturePlugin"
}
autoConfigurationPlugin {
id = "org.springframework.boot.auto-configuration"
diff --git a/buildSrc/src/main/java/org/springframework/boot/build/AsciidoctorConventions.java b/buildSrc/src/main/java/org/springframework/boot/build/AsciidoctorConventions.java
index 537ff277f739..339db1c3f766 100644
--- a/buildSrc/src/main/java/org/springframework/boot/build/AsciidoctorConventions.java
+++ b/buildSrc/src/main/java/org/springframework/boot/build/AsciidoctorConventions.java
@@ -134,7 +134,7 @@ private void configureForkOptions(AbstractAsciidoctorTask asciidoctorTask) {
private String determineGitHubTag(Project project) {
String version = "v" + project.getVersion();
- return (version.endsWith("-SNAPSHOT")) ? "3.1.x" : version;
+ return (version.endsWith("-SNAPSHOT")) ? "main" : version;
}
private void configureOptions(AbstractAsciidoctorTask asciidoctorTask) {
diff --git a/buildSrc/src/main/java/org/springframework/boot/build/JavaConventions.java b/buildSrc/src/main/java/org/springframework/boot/build/JavaConventions.java
index 08f7e18aa999..6f13a5fbbac2 100644
--- a/buildSrc/src/main/java/org/springframework/boot/build/JavaConventions.java
+++ b/buildSrc/src/main/java/org/springframework/boot/build/JavaConventions.java
@@ -179,7 +179,7 @@ private void configureTestConventions(Project project) {
private void configureTestRetries(Test test) {
TestRetryExtension testRetry = test.getExtensions().getByType(TestRetryExtension.class);
- testRetry.getFailOnPassedAfterRetry().set(true);
+ testRetry.getFailOnPassedAfterRetry().set(false);
testRetry.getMaxRetries().set(isCi() ? 3 : 0);
}
@@ -239,7 +239,7 @@ private void configureSpringJavaFormat(Project project) {
project.getTasks().withType(Format.class, (Format) -> Format.setEncoding("UTF-8"));
project.getPlugins().apply(CheckstylePlugin.class);
CheckstyleExtension checkstyle = project.getExtensions().getByType(CheckstyleExtension.class);
- checkstyle.setToolVersion("8.45.1");
+ checkstyle.setToolVersion("10.12.4");
checkstyle.getConfigDirectory().set(project.getRootProject().file("src/checkstyle"));
String version = SpringJavaFormatPlugin.class.getPackage().getImplementationVersion();
DependencySet checkstyleDependencies = project.getConfigurations().getByName("checkstyle").getDependencies();
diff --git a/buildSrc/src/main/java/org/springframework/boot/build/bom/BomExtension.java b/buildSrc/src/main/java/org/springframework/boot/build/bom/BomExtension.java
index 57a16796cac0..5291f7190992 100644
--- a/buildSrc/src/main/java/org/springframework/boot/build/bom/BomExtension.java
+++ b/buildSrc/src/main/java/org/springframework/boot/build/bom/BomExtension.java
@@ -113,7 +113,8 @@ public void library(String name, String version, Action action)
LibraryHandler libraryHandler = objects.newInstance(LibraryHandler.class, (version != null) ? version : "");
action.execute(libraryHandler);
LibraryVersion libraryVersion = new LibraryVersion(DependencyVersion.parse(libraryHandler.version));
- addLibrary(new Library(name, libraryVersion, libraryHandler.groups, libraryHandler.prohibitedVersions));
+ addLibrary(new Library(name, libraryHandler.calendarName, libraryVersion, libraryHandler.groups,
+ libraryHandler.prohibitedVersions, libraryHandler.considerSnapshots));
}
public void effectiveBomArtifact() {
@@ -213,8 +214,12 @@ public static class LibraryHandler {
private final List prohibitedVersions = new ArrayList<>();
+ private boolean considerSnapshots = false;
+
private String version;
+ private String calendarName;
+
@Inject
public LibraryHandler(String version) {
this.version = version;
@@ -224,6 +229,14 @@ public void version(String version) {
this.version = version;
}
+ public void considerSnapshots() {
+ this.considerSnapshots = true;
+ }
+
+ public void setCalendarName(String calendarName) {
+ this.calendarName = calendarName;
+ }
+
public void group(String id, Action action) {
GroupHandler groupHandler = new GroupHandler(id);
action.execute(groupHandler);
diff --git a/buildSrc/src/main/java/org/springframework/boot/build/bom/BomPlugin.java b/buildSrc/src/main/java/org/springframework/boot/build/bom/BomPlugin.java
index d6db769e4604..a18d10481d80 100644
--- a/buildSrc/src/main/java/org/springframework/boot/build/bom/BomPlugin.java
+++ b/buildSrc/src/main/java/org/springframework/boot/build/bom/BomPlugin.java
@@ -62,7 +62,8 @@ public void apply(Project project) {
createApiEnforcedConfiguration(project);
BomExtension bom = project.getExtensions()
.create("bom", BomExtension.class, project.getDependencies(), project);
- project.getTasks().create("bomrCheck", CheckBom.class, bom);
+ CheckBom checkBom = project.getTasks().create("bomrCheck", CheckBom.class, bom);
+ project.getTasks().named("check").configure((check) -> check.dependsOn(checkBom));
project.getTasks().create("bomrUpgrade", UpgradeBom.class, bom);
project.getTasks().create("moveToSnapshots", MoveToSnapshots.class, bom);
new PublishingCustomizer(project, bom).customize();
diff --git a/buildSrc/src/main/java/org/springframework/boot/build/bom/CheckBom.java b/buildSrc/src/main/java/org/springframework/boot/build/bom/CheckBom.java
index 3aeaf0161b5c..7c2089e25969 100644
--- a/buildSrc/src/main/java/org/springframework/boot/build/bom/CheckBom.java
+++ b/buildSrc/src/main/java/org/springframework/boot/build/bom/CheckBom.java
@@ -16,18 +16,25 @@
package org.springframework.boot.build.bom;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import java.util.stream.Collectors;
import javax.inject.Inject;
+import org.apache.maven.artifact.versioning.ArtifactVersion;
+import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
+import org.apache.maven.artifact.versioning.Restriction;
+import org.apache.maven.artifact.versioning.VersionRange;
import org.gradle.api.DefaultTask;
-import org.gradle.api.InvalidUserDataException;
+import org.gradle.api.GradleException;
import org.gradle.api.tasks.TaskAction;
import org.springframework.boot.build.bom.Library.Group;
import org.springframework.boot.build.bom.Library.Module;
+import org.springframework.boot.build.bom.Library.ProhibitedVersion;
import org.springframework.boot.build.bom.bomr.version.DependencyVersion;
/**
@@ -46,18 +53,41 @@ public CheckBom(BomExtension bom) {
@TaskAction
void checkBom() {
+ List errors = new ArrayList<>();
for (Library library : this.bom.getLibraries()) {
- for (Group group : library.getGroups()) {
- for (Module module : group.getModules()) {
- if (!module.getExclusions().isEmpty()) {
- checkExclusions(group.getId(), module, library.getVersion().getVersion());
- }
+ checkLibrary(library, errors);
+ }
+ if (!errors.isEmpty()) {
+ System.out.println();
+ errors.forEach(System.out::println);
+ System.out.println();
+ throw new GradleException("Bom check failed. See previous output for details.");
+ }
+ }
+
+ private void checkLibrary(Library library, List errors) {
+ List libraryErrors = new ArrayList<>();
+ checkExclusions(library, libraryErrors);
+ checkProhibitedVersions(library, libraryErrors);
+ if (!libraryErrors.isEmpty()) {
+ errors.add(library.getName());
+ for (String libraryError : libraryErrors) {
+ errors.add(" - " + libraryError);
+ }
+ }
+ }
+
+ private void checkExclusions(Library library, List errors) {
+ for (Group group : library.getGroups()) {
+ for (Module module : group.getModules()) {
+ if (!module.getExclusions().isEmpty()) {
+ checkExclusions(group.getId(), module, library.getVersion().getVersion(), errors);
}
}
}
}
- private void checkExclusions(String groupId, Module module, DependencyVersion version) {
+ private void checkExclusions(String groupId, Module module, DependencyVersion version, List errors) {
Set resolved = getProject().getConfigurations()
.detachedConfiguration(
getProject().getDependencies().create(groupId + ":" + module.getName() + ":" + version))
@@ -87,8 +117,34 @@ private void checkExclusions(String groupId, Module module, DependencyVersion ve
}
exclusions.removeAll(resolved);
if (!unused.isEmpty()) {
- throw new InvalidUserDataException(
- "Unnecessary exclusions on " + groupId + ":" + module.getName() + ": " + exclusions);
+ errors.add("Unnecessary exclusions on " + groupId + ":" + module.getName() + ": " + exclusions);
+ }
+ }
+
+ private void checkProhibitedVersions(Library library, List errors) {
+ ArtifactVersion currentVersion = new DefaultArtifactVersion(library.getVersion().getVersion().toString());
+ for (ProhibitedVersion prohibited : library.getProhibitedVersions()) {
+ if (prohibited.isProhibited(library.getVersion().getVersion().toString())) {
+ errors.add("Current version " + currentVersion + " is prohibited");
+ }
+ else {
+ VersionRange versionRange = prohibited.getRange();
+ if (versionRange != null) {
+ for (Restriction restriction : versionRange.getRestrictions()) {
+ ArtifactVersion upperBound = restriction.getUpperBound();
+ if (upperBound == null) {
+ return;
+ }
+ int comparison = currentVersion.compareTo(upperBound);
+ if ((restriction.isUpperBoundInclusive() && comparison <= 0)
+ || ((!restriction.isUpperBoundInclusive()) && comparison < 0)) {
+ return;
+ }
+ }
+ errors.add("Version range " + versionRange + " is ineffective as the current version, "
+ + currentVersion + ", is greater than its upper bound");
+ }
+ }
}
}
diff --git a/buildSrc/src/main/java/org/springframework/boot/build/bom/Library.java b/buildSrc/src/main/java/org/springframework/boot/build/bom/Library.java
index b51cd42dd52e..a2d6f4517cb9 100644
--- a/buildSrc/src/main/java/org/springframework/boot/build/bom/Library.java
+++ b/buildSrc/src/main/java/org/springframework/boot/build/bom/Library.java
@@ -20,6 +20,7 @@
import java.util.List;
import java.util.Locale;
+import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
import org.apache.maven.artifact.versioning.VersionRange;
import org.springframework.boot.build.bom.bomr.version.DependencyVersion;
@@ -34,6 +35,8 @@ public class Library {
private final String name;
+ private final String calendarName;
+
private final LibraryVersion version;
private final List groups;
@@ -42,28 +45,39 @@ public class Library {
private final List prohibitedVersions;
+ private final boolean considerSnapshots;
+
/**
* Create a new {@code Library} with the given {@code name}, {@code version}, and
* {@code groups}.
* @param name name of the library
+ * @param calendarName name of the library as it appears in the Spring Calendar. May
+ * be {@code null} in which case the {@code name} is used.
* @param version version of the library
* @param groups groups in the library
* @param prohibitedVersions version of the library that are prohibited
+ * @param considerSnapshots whether to consider snapshots
*/
- public Library(String name, LibraryVersion version, List groups,
- List prohibitedVersions) {
+ public Library(String name, String calendarName, LibraryVersion version, List groups,
+ List prohibitedVersions, boolean considerSnapshots) {
this.name = name;
+ this.calendarName = (calendarName != null) ? calendarName : name;
this.version = version;
this.groups = groups;
this.versionProperty = "Spring Boot".equals(name) ? null
: name.toLowerCase(Locale.ENGLISH).replace(' ', '-') + ".version";
this.prohibitedVersions = prohibitedVersions;
+ this.considerSnapshots = considerSnapshots;
}
public String getName() {
return this.name;
}
+ public String getCalendarName() {
+ return this.calendarName;
+ }
+
public LibraryVersion getVersion() {
return this.version;
}
@@ -80,6 +94,10 @@ public List getProhibitedVersions() {
return this.prohibitedVersions;
}
+ public boolean isConsiderSnapshots() {
+ return this.considerSnapshots;
+ }
+
/**
* A version or range of versions that are prohibited from being used in a bom.
*/
@@ -124,6 +142,16 @@ public String getReason() {
return this.reason;
}
+ public boolean isProhibited(String candidate) {
+ boolean result = false;
+ result = result
+ || (this.range != null && this.range.containsVersion(new DefaultArtifactVersion(candidate)));
+ result = result || this.startsWith.stream().anyMatch(candidate::startsWith);
+ result = result || this.endsWith.stream().anyMatch(candidate::endsWith);
+ result = result || this.contains.stream().anyMatch(candidate::contains);
+ return result;
+ }
+
}
public static class LibraryVersion {
diff --git a/buildSrc/src/main/java/org/springframework/boot/build/bom/UpgradePolicy.java b/buildSrc/src/main/java/org/springframework/boot/build/bom/UpgradePolicy.java
index c74bee8223fe..e9d72393965f 100644
--- a/buildSrc/src/main/java/org/springframework/boot/build/bom/UpgradePolicy.java
+++ b/buildSrc/src/main/java/org/springframework/boot/build/bom/UpgradePolicy.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2020 the original author or authors.
+ * Copyright 2012-2023 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.
@@ -28,24 +28,19 @@
public enum UpgradePolicy implements BiPredicate {
/**
- * All versions more recent than the current version will be suggested as possible
- * upgrades.
+ * Any version.
*/
- ANY((candidate, current) -> current.compareTo(candidate) < 0),
+ ANY((candidate, current) -> true),
/**
- * New minor versions of the current major version will be suggested as possible
- * upgrades. For example, if the current version is 1.2.3, all 1.x.y versions after
- * 1.2.3 will be suggested. 2.x versions will not be offered.
+ * Minor versions of the current major version.
*/
- SAME_MAJOR_VERSION(DependencyVersion::isSameMajorAndNewerThan),
+ SAME_MAJOR_VERSION((candidate, current) -> candidate.isSameMajor(current)),
/**
- * New patch versions of the current minor version will be offered as possible
- * upgrades. For example, if the current version is 1.2.3, all 1.2.x versions after
- * 1.2.3 will be suggested. 1.x versions will not be offered.
+ * Patch versions of the current minor version.
*/
- SAME_MINOR_VERSION(DependencyVersion::isSameMinorAndNewerThan);
+ SAME_MINOR_VERSION((candidate, current) -> candidate.isSameMinor(current));
private final BiPredicate delegate;
diff --git a/buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/MoveToSnapshots.java b/buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/MoveToSnapshots.java
index 322ecd5011a7..b47545839378 100644
--- a/buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/MoveToSnapshots.java
+++ b/buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/MoveToSnapshots.java
@@ -17,12 +17,23 @@
package org.springframework.boot.build.bom.bomr;
import java.net.URI;
+import java.time.OffsetDateTime;
+import java.util.List;
+import java.util.Map;
+import java.util.function.BiPredicate;
import javax.inject.Inject;
import org.gradle.api.Task;
+import org.gradle.api.tasks.TaskAction;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.springframework.boot.build.bom.BomExtension;
+import org.springframework.boot.build.bom.Library;
+import org.springframework.boot.build.bom.bomr.ReleaseSchedule.Release;
+import org.springframework.boot.build.bom.bomr.github.Milestone;
+import org.springframework.boot.build.bom.bomr.version.DependencyVersion;
/**
* A {@link Task} to move to snapshot dependencies.
@@ -31,14 +42,22 @@
*/
public abstract class MoveToSnapshots extends UpgradeDependencies {
+ private static final Logger log = LoggerFactory.getLogger(MoveToSnapshots.class);
+
private final URI REPOSITORY_URI = URI.create("https://repo.spring.io/snapshot/");
@Inject
public MoveToSnapshots(BomExtension bom) {
- super(bom);
+ super(bom, true);
getRepositoryUris().add(this.REPOSITORY_URI);
}
+ @Override
+ @TaskAction
+ void upgradeDependencies() {
+ super.upgradeDependencies();
+ }
+
@Override
protected String issueTitle(Upgrade upgrade) {
String snapshotVersion = upgrade.getVersion().toString();
@@ -57,4 +76,33 @@ private String releaseVersion(Upgrade upgrade) {
return snapshotVersion.substring(0, snapshotVersion.length() - "-SNAPSHOT".length());
}
+ @Override
+ protected boolean eligible(Library library) {
+ return library.isConsiderSnapshots() && super.eligible(library);
+ }
+
+ @Override
+ protected List> determineUpdatePredicates(Milestone milestone) {
+ ReleaseSchedule releaseSchedule = new ReleaseSchedule();
+ Map> releases = releaseSchedule.releasesBetween(OffsetDateTime.now(),
+ milestone.getDueOn());
+ List> predicates = super.determineUpdatePredicates(milestone);
+ predicates.add((library, candidate) -> {
+ List releasesForLibrary = releases.get(library.getCalendarName());
+ if (releasesForLibrary != null) {
+ for (Release release : releasesForLibrary) {
+ if (candidate.isSnapshotFor(release.getVersion())) {
+ return true;
+ }
+ }
+ }
+ if (log.isInfoEnabled()) {
+ log.info("Ignoring " + candidate + ". No release of " + library.getName() + " scheduled before "
+ + milestone.getDueOn());
+ }
+ return false;
+ });
+ return predicates;
+ }
+
}
diff --git a/buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/MultithreadedLibraryUpdateResolver.java b/buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/MultithreadedLibraryUpdateResolver.java
index 69239b006ee3..18a5490b631b 100644
--- a/buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/MultithreadedLibraryUpdateResolver.java
+++ b/buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/MultithreadedLibraryUpdateResolver.java
@@ -16,36 +16,39 @@
package org.springframework.boot.build.bom.bomr;
-import java.time.Duration;
-import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
+import java.util.stream.Stream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.build.bom.Library;
-import org.springframework.boot.build.bom.UpgradePolicy;
/**
- * Uses multiple threads to find library updates.
+ * {@link LibraryUpdateResolver} decorator that uses multiple threads to find library
+ * updates.
*
* @author Moritz Halbritter
+ * @author Andy Wilkinson
*/
-class MultithreadedLibraryUpdateResolver extends StandardLibraryUpdateResolver {
+class MultithreadedLibraryUpdateResolver implements LibraryUpdateResolver {
private static final Logger LOGGER = LoggerFactory.getLogger(MultithreadedLibraryUpdateResolver.class);
private final int threads;
- MultithreadedLibraryUpdateResolver(VersionResolver versionResolver, UpgradePolicy upgradePolicy, int threads) {
- super(versionResolver, upgradePolicy);
+ private final LibraryUpdateResolver delegate;
+
+ MultithreadedLibraryUpdateResolver(int threads, LibraryUpdateResolver delegate) {
this.threads = threads;
+ this.delegate = delegate;
}
@Override
@@ -54,34 +57,28 @@ public List findLibraryUpdates(Collection li
LOGGER.info("Looking for updates using {} threads", this.threads);
ExecutorService executorService = Executors.newFixedThreadPool(this.threads);
try {
- List> jobs = new ArrayList<>();
- for (Library library : librariesToUpgrade) {
- if (isLibraryExcluded(library)) {
- continue;
- }
- jobs.add(executorService.submit(() -> {
- LOGGER.info("Looking for updates for {}", library.getName());
- long start = System.nanoTime();
- List versionOptions = getVersionOptions(library, librariesByName);
- LOGGER.info("Found {} updates for {}, took {}", versionOptions.size(), library.getName(),
- Duration.ofNanos(System.nanoTime() - start));
- return new LibraryWithVersionOptions(library, versionOptions);
- }));
- }
- List result = new ArrayList<>();
- for (Future job : jobs) {
- try {
- result.add(job.get());
- }
- catch (InterruptedException | ExecutionException ex) {
- throw new RuntimeException(ex);
- }
- }
- return result;
+ return librariesToUpgrade.stream()
+ .map((library) -> executorService.submit(
+ () -> this.delegate.findLibraryUpdates(Collections.singletonList(library), librariesByName)))
+ .flatMap(this::getResult)
+ .toList();
}
finally {
executorService.shutdownNow();
}
}
+ private Stream getResult(Future> job) {
+ try {
+ return job.get().stream();
+ }
+ catch (InterruptedException ex) {
+ Thread.currentThread().interrupt();
+ throw new RuntimeException(ex);
+ }
+ catch (ExecutionException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
}
diff --git a/buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/ReleaseSchedule.java b/buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/ReleaseSchedule.java
new file mode 100644
index 000000000000..c32518b46246
--- /dev/null
+++ b/buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/ReleaseSchedule.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2023-2023 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.boot.build.bom.bomr;
+
+import java.time.LocalDate;
+import java.time.OffsetDateTime;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.springframework.boot.build.bom.bomr.version.DependencyVersion;
+import org.springframework.http.ResponseEntity;
+import org.springframework.util.LinkedCaseInsensitiveMap;
+import org.springframework.web.client.RestOperations;
+import org.springframework.web.client.RestTemplate;
+
+/**
+ * Release schedule for Spring projects, retrieved from
+ * https://calendar.spring.io .
+ *
+ * @author Andy Wilkinson
+ */
+class ReleaseSchedule {
+
+ private static final Pattern LIBRARY_AND_VERSION = Pattern.compile("([A-Za-z0-9 ]+) ([0-9A-Za-z.-]+)");
+
+ private final RestOperations rest;
+
+ ReleaseSchedule() {
+ this(new RestTemplate());
+ }
+
+ ReleaseSchedule(RestOperations rest) {
+ this.rest = rest;
+ }
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ Map> releasesBetween(OffsetDateTime start, OffsetDateTime end) {
+ ResponseEntity response = this.rest
+ .getForEntity("https://calendar.spring.io/releases?start=" + start + "&end=" + end, List.class);
+ List> body = response.getBody();
+ Map> releasesByLibrary = new LinkedCaseInsensitiveMap<>();
+ body.stream()
+ .map(this::asRelease)
+ .filter(Objects::nonNull)
+ .forEach((release) -> releasesByLibrary.computeIfAbsent(release.getLibraryName(), (l) -> new ArrayList<>())
+ .add(release));
+ return releasesByLibrary;
+ }
+
+ private Release asRelease(Map entry) {
+ LocalDate due = LocalDate.parse(entry.get("start"));
+ String title = entry.get("title");
+ Matcher matcher = LIBRARY_AND_VERSION.matcher(title);
+ if (!matcher.matches()) {
+ return null;
+ }
+ String library = matcher.group(1);
+ String version = matcher.group(2);
+ return new Release(library, DependencyVersion.parse(version), due);
+ }
+
+ static class Release {
+
+ private final String libraryName;
+
+ private final DependencyVersion version;
+
+ private final LocalDate dueOn;
+
+ Release(String libraryName, DependencyVersion version, LocalDate dueOn) {
+ this.libraryName = libraryName;
+ this.version = version;
+ this.dueOn = dueOn;
+ }
+
+ String getLibraryName() {
+ return this.libraryName;
+ }
+
+ DependencyVersion getVersion() {
+ return this.version;
+ }
+
+ LocalDate getDueOn() {
+ return this.dueOn;
+ }
+
+ }
+
+}
diff --git a/buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/StandardLibraryUpdateResolver.java b/buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/StandardLibraryUpdateResolver.java
index bcfb1406c5f5..5bbdd90a62f6 100644
--- a/buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/StandardLibraryUpdateResolver.java
+++ b/buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/StandardLibraryUpdateResolver.java
@@ -19,22 +19,18 @@
import java.time.Duration;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.SortedSet;
-import java.util.stream.Collectors;
+import java.util.function.BiPredicate;
-import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.build.bom.Library;
import org.springframework.boot.build.bom.Library.Group;
import org.springframework.boot.build.bom.Library.Module;
-import org.springframework.boot.build.bom.Library.ProhibitedVersion;
-import org.springframework.boot.build.bom.UpgradePolicy;
import org.springframework.boot.build.bom.bomr.version.DependencyVersion;
/**
@@ -48,11 +44,13 @@ class StandardLibraryUpdateResolver implements LibraryUpdateResolver {
private final VersionResolver versionResolver;
- private final UpgradePolicy upgradePolicy;
+ private final BiPredicate predicate;
- StandardLibraryUpdateResolver(VersionResolver versionResolver, UpgradePolicy upgradePolicy) {
+ StandardLibraryUpdateResolver(VersionResolver versionResolver,
+ List> predicates) {
this.versionResolver = versionResolver;
- this.upgradePolicy = upgradePolicy;
+ this.predicate = (library, dependencyVersion) -> predicates.stream()
+ .allMatch((predicate) -> predicate.test(library, dependencyVersion));
}
@Override
@@ -83,60 +81,27 @@ protected List getVersionOptions(Library library, Map determineResolvedVersionOptions(Library library) {
Map> moduleVersions = new LinkedHashMap<>();
- DependencyVersion libraryVersion = library.getVersion().getVersion();
for (Group group : library.getGroups()) {
for (Module module : group.getModules()) {
moduleVersions.put(group.getId() + ":" + module.getName(),
- getLaterVersionsForModule(group.getId(), module.getName(), libraryVersion));
+ getLaterVersionsForModule(group.getId(), module.getName(), library));
}
for (String bom : group.getBoms()) {
- moduleVersions.put(group.getId() + ":" + bom,
- getLaterVersionsForModule(group.getId(), bom, libraryVersion));
+ moduleVersions.put(group.getId() + ":" + bom, getLaterVersionsForModule(group.getId(), bom, library));
}
for (String plugin : group.getPlugins()) {
moduleVersions.put(group.getId() + ":" + plugin,
- getLaterVersionsForModule(group.getId(), plugin, libraryVersion));
+ getLaterVersionsForModule(group.getId(), plugin, library));
}
}
- List allVersions = moduleVersions.values()
+ return moduleVersions.values()
.stream()
.flatMap(SortedSet::stream)
.distinct()
- .filter((dependencyVersion) -> isPermitted(dependencyVersion, library.getProhibitedVersions()))
- .toList();
- if (allVersions.isEmpty()) {
- return Collections.emptyList();
- }
- return allVersions.stream()
- .map((version) -> new VersionOption.ResolvedVersionOption(version,
+ .filter((dependencyVersion) -> this.predicate.test(library, dependencyVersion))
+ .map((version) -> (VersionOption) new VersionOption.ResolvedVersionOption(version,
getMissingModules(moduleVersions, version)))
- .collect(Collectors.toList());
- }
-
- private boolean isPermitted(DependencyVersion dependencyVersion, List prohibitedVersions) {
- for (ProhibitedVersion prohibitedVersion : prohibitedVersions) {
- String dependencyVersionToString = dependencyVersion.toString();
- if (prohibitedVersion.getRange() != null && prohibitedVersion.getRange()
- .containsVersion(new DefaultArtifactVersion(dependencyVersionToString))) {
- return false;
- }
- for (String startsWith : prohibitedVersion.getStartsWith()) {
- if (dependencyVersionToString.startsWith(startsWith)) {
- return false;
- }
- }
- for (String endsWith : prohibitedVersion.getEndsWith()) {
- if (dependencyVersionToString.endsWith(endsWith)) {
- return false;
- }
- }
- for (String contains : prohibitedVersion.getContains()) {
- if (dependencyVersionToString.contains(contains)) {
- return false;
- }
- }
- }
- return true;
+ .toList();
}
private List getMissingModules(Map> moduleVersions,
@@ -150,11 +115,8 @@ private List getMissingModules(Map>
return missingModules;
}
- private SortedSet getLaterVersionsForModule(String groupId, String artifactId,
- DependencyVersion currentVersion) {
- SortedSet versions = this.versionResolver.resolveVersions(groupId, artifactId);
- versions.removeIf((candidate) -> !this.upgradePolicy.test(candidate, currentVersion));
- return versions;
+ private SortedSet getLaterVersionsForModule(String groupId, String artifactId, Library library) {
+ return this.versionResolver.resolveVersions(groupId, artifactId);
}
}
diff --git a/buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/UpgradeDependencies.java b/buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/UpgradeDependencies.java
index ae2625c0e4a5..81511606b710 100644
--- a/buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/UpgradeDependencies.java
+++ b/buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/UpgradeDependencies.java
@@ -27,6 +27,7 @@
import java.util.List;
import java.util.Properties;
import java.util.Set;
+import java.util.function.BiPredicate;
import java.util.function.Predicate;
import java.util.regex.Pattern;
@@ -49,6 +50,7 @@
import org.springframework.boot.build.bom.bomr.github.GitHubRepository;
import org.springframework.boot.build.bom.bomr.github.Issue;
import org.springframework.boot.build.bom.bomr.github.Milestone;
+import org.springframework.boot.build.bom.bomr.version.DependencyVersion;
import org.springframework.util.StringUtils;
/**
@@ -61,10 +63,17 @@ public abstract class UpgradeDependencies extends DefaultTask {
private final BomExtension bom;
+ private final boolean movingToSnapshots;
+
@Inject
public UpgradeDependencies(BomExtension bom) {
+ this(bom, false);
+ }
+
+ protected UpgradeDependencies(BomExtension bom, boolean movingToSnapshots) {
this.bom = bom;
getThreads().convention(2);
+ this.movingToSnapshots = movingToSnapshots;
}
@Input
@@ -90,7 +99,7 @@ void upgradeDependencies() {
this.bom.getUpgrade().getGitHub().getRepository());
List issueLabels = verifyLabels(repository);
Milestone milestone = determineMilestone(repository);
- List upgrades = resolveUpgrades();
+ List upgrades = resolveUpgrades(milestone);
applyUpgrades(repository, issueLabels, milestone, upgrades);
}
@@ -100,45 +109,31 @@ private void applyUpgrades(GitHubRepository repository, List issueLabels
Path gradleProperties = new File(getProject().getRootProject().getProjectDir(), "gradle.properties").toPath();
UpgradeApplicator upgradeApplicator = new UpgradeApplicator(buildFile, gradleProperties);
List existingUpgradeIssues = repository.findIssues(issueLabels, milestone);
+ System.out.println("Applying upgrades...");
+ System.out.println("");
for (Upgrade upgrade : upgrades) {
+ System.out.println(upgrade.getLibrary().getName() + " " + upgrade.getVersion());
String title = issueTitle(upgrade);
Issue existingUpgradeIssue = findExistingUpgradeIssue(existingUpgradeIssues, upgrade);
- if (existingUpgradeIssue != null) {
- if (existingUpgradeIssue.getState() == Issue.State.CLOSED) {
- System.out.println(title + " (supersedes #" + existingUpgradeIssue.getNumber() + " "
- + existingUpgradeIssue.getTitle() + ")");
- }
- else {
- System.out.println(title + " (completes existing upgrade)");
- }
- }
- else {
- System.out.println(title);
- }
try {
Path modified = upgradeApplicator.apply(upgrade);
- int issueNumber;
- if (existingUpgradeIssue != null && existingUpgradeIssue.getState() == Issue.State.OPEN) {
- issueNumber = existingUpgradeIssue.getNumber();
- }
- else {
- issueNumber = repository.openIssue(title,
- (existingUpgradeIssue != null) ? "Supersedes #" + existingUpgradeIssue.getNumber() : "",
- issueLabels, milestone);
- if (existingUpgradeIssue != null && existingUpgradeIssue.getState() == Issue.State.CLOSED) {
- existingUpgradeIssue.label(Arrays.asList("type: task", "status: superseded"));
- }
+ int issueNumber = getOrOpenUpgradeIssue(repository, issueLabels, milestone, title,
+ existingUpgradeIssue);
+ if (existingUpgradeIssue != null && existingUpgradeIssue.getState() == Issue.State.CLOSED) {
+ existingUpgradeIssue.label(Arrays.asList("type: task", "status: superseded"));
}
+ System.out.println(" Issue: " + issueNumber + " - " + title
+ + getExistingUpgradeIssueMessageDetails(existingUpgradeIssue));
if (new ProcessBuilder().command("git", "add", modified.toFile().getAbsolutePath())
.start()
.waitFor() != 0) {
throw new IllegalStateException("git add failed");
}
- if (new ProcessBuilder().command("git", "commit", "-m", commitMessage(upgrade, issueNumber))
- .start()
- .waitFor() != 0) {
+ String commitMessage = commitMessage(upgrade, issueNumber);
+ if (new ProcessBuilder().command("git", "commit", "-m", commitMessage).start().waitFor() != 0) {
throw new IllegalStateException("git commit failed");
}
+ System.out.println(" Commit: " + commitMessage.substring(0, commitMessage.indexOf('\n')));
}
catch (IOException ex) {
throw new TaskExecutionException(this, ex);
@@ -149,6 +144,25 @@ private void applyUpgrades(GitHubRepository repository, List issueLabels
}
}
+ private int getOrOpenUpgradeIssue(GitHubRepository repository, List issueLabels, Milestone milestone,
+ String title, Issue existingUpgradeIssue) {
+ if (existingUpgradeIssue != null && existingUpgradeIssue.getState() == Issue.State.OPEN) {
+ return existingUpgradeIssue.getNumber();
+ }
+ String body = (existingUpgradeIssue != null) ? "Supersedes #" + existingUpgradeIssue.getNumber() : "";
+ return repository.openIssue(title, body, issueLabels, milestone);
+ }
+
+ private String getExistingUpgradeIssueMessageDetails(Issue existingUpgradeIssue) {
+ if (existingUpgradeIssue == null) {
+ return "";
+ }
+ if (existingUpgradeIssue.getState() != Issue.State.CLOSED) {
+ return " (completes existing upgrade)";
+ }
+ return " (supersedes #" + existingUpgradeIssue.getNumber() + " " + existingUpgradeIssue.getTitle() + ")";
+ }
+
private List verifyLabels(GitHubRepository repository) {
Set availableLabels = repository.getLabels();
List issueLabels = this.bom.getUpgrade().getGitHub().getIssueLabels();
@@ -188,9 +202,12 @@ private Milestone determineMilestone(GitHubRepository repository) {
private Issue findExistingUpgradeIssue(List existingUpgradeIssues, Upgrade upgrade) {
String toMatch = "Upgrade to " + upgrade.getLibrary().getName();
for (Issue existingUpgradeIssue : existingUpgradeIssues) {
- if (existingUpgradeIssue.getTitle()
- .substring(0, existingUpgradeIssue.getTitle().lastIndexOf(' '))
- .equals(toMatch)) {
+ String title = existingUpgradeIssue.getTitle();
+ int lastSpaceIndex = title.lastIndexOf(' ');
+ if (lastSpaceIndex > -1) {
+ title = title.substring(0, lastSpaceIndex);
+ }
+ if (title.equals(toMatch)) {
return existingUpgradeIssue;
}
}
@@ -198,29 +215,54 @@ private Issue findExistingUpgradeIssue(List existingUpgradeIssues, Upgrad
}
@SuppressWarnings("deprecation")
- private List resolveUpgrades() {
+ private List resolveUpgrades(Milestone milestone) {
List upgrades = new InteractiveUpgradeResolver(getServices().get(UserInputHandler.class),
- new MultithreadedLibraryUpdateResolver(new MavenMetadataVersionResolver(getRepositoryUris().get()),
- this.bom.getUpgrade().getPolicy(), getThreads().get()))
- .resolveUpgrades(matchingLibraries(getLibraries().getOrNull()), this.bom.getLibraries());
+ new MultithreadedLibraryUpdateResolver(getThreads().get(),
+ new StandardLibraryUpdateResolver(new MavenMetadataVersionResolver(getRepositoryUris().get()),
+ determineUpdatePredicates(milestone))))
+ .resolveUpgrades(matchingLibraries(), this.bom.getLibraries());
return upgrades;
}
- private List matchingLibraries(String pattern) {
- if (pattern == null) {
- return this.bom.getLibraries();
- }
- Predicate libraryPredicate = Pattern.compile(pattern).asPredicate();
- List matchingLibraries = this.bom.getLibraries()
+ protected List> determineUpdatePredicates(Milestone milestone) {
+ List> updatePredicates = new ArrayList<>();
+ updatePredicates.add(this::compilesWithUpgradePolicy);
+ updatePredicates.add(this::isAnUpgrade);
+ updatePredicates.add(this::isNotProhibited);
+ return updatePredicates;
+ }
+
+ private boolean compilesWithUpgradePolicy(Library library, DependencyVersion candidate) {
+ return this.bom.getUpgrade().getPolicy().test(candidate, library.getVersion().getVersion());
+ }
+
+ private boolean isAnUpgrade(Library library, DependencyVersion candidate) {
+ return library.getVersion().getVersion().isUpgrade(candidate, this.movingToSnapshots);
+ }
+
+ private boolean isNotProhibited(Library library, DependencyVersion candidate) {
+ return !library.getProhibitedVersions()
.stream()
- .filter((library) -> libraryPredicate.test(library.getName()))
- .toList();
+ .anyMatch((prohibited) -> prohibited.isProhibited(candidate.toString()));
+ }
+
+ private List matchingLibraries() {
+ List matchingLibraries = this.bom.getLibraries().stream().filter(this::eligible).toList();
if (matchingLibraries.isEmpty()) {
- throw new InvalidUserDataException("No libraries matched '" + pattern + "'");
+ throw new InvalidUserDataException("No libraries to upgrade");
}
return matchingLibraries;
}
+ protected boolean eligible(Library library) {
+ String pattern = getLibraries().getOrNull();
+ if (pattern == null) {
+ return true;
+ }
+ Predicate libraryPredicate = Pattern.compile(pattern).asPredicate();
+ return libraryPredicate.test(library.getName());
+ }
+
protected abstract String issueTitle(Upgrade upgrade);
protected abstract String commitMessage(Upgrade upgrade, int issueNumber);
diff --git a/buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/github/Milestone.java b/buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/github/Milestone.java
index f50dd28c48dd..38d3f1dd5e27 100644
--- a/buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/github/Milestone.java
+++ b/buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/github/Milestone.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2020 the original author or authors.
+ * Copyright 2012-2023 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.
@@ -16,6 +16,8 @@
package org.springframework.boot.build.bom.bomr.github;
+import java.time.OffsetDateTime;
+
/**
* A milestone in a {@link GitHubRepository GitHub repository}.
*
@@ -27,9 +29,12 @@ public class Milestone {
private final int number;
- Milestone(String name, int number) {
+ private final OffsetDateTime dueOn;
+
+ Milestone(String name, int number, OffsetDateTime dueOn) {
this.name = name;
this.number = number;
+ this.dueOn = dueOn;
}
/**
@@ -48,6 +53,10 @@ public int getNumber() {
return this.number;
}
+ public OffsetDateTime getDueOn() {
+ return this.dueOn;
+ }
+
@Override
public String toString() {
return this.name + " (" + this.number + ")";
diff --git a/buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/github/StandardGitHubRepository.java b/buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/github/StandardGitHubRepository.java
index 28027e2c8852..2a5fb9ba527f 100644
--- a/buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/github/StandardGitHubRepository.java
+++ b/buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/github/StandardGitHubRepository.java
@@ -17,6 +17,7 @@
package org.springframework.boot.build.bom.bomr.github;
import java.time.Duration;
+import java.time.OffsetDateTime;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -75,8 +76,9 @@ public Set getLabels() {
@Override
public List getMilestones() {
- return get("milestones?per_page=100",
- (milestone) -> new Milestone((String) milestone.get("title"), (Integer) milestone.get("number")));
+ return get("milestones?per_page=100", (milestone) -> new Milestone((String) milestone.get("title"),
+ (Integer) milestone.get("number"),
+ (milestone.get("due_on") != null) ? OffsetDateTime.parse((String) milestone.get("due_on")) : null));
}
@Override
diff --git a/buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/version/AbstractDependencyVersion.java b/buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/version/AbstractDependencyVersion.java
index 1a0ef1ce979d..4d17ceefc81f 100644
--- a/buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/version/AbstractDependencyVersion.java
+++ b/buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/version/AbstractDependencyVersion.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2022 the original author or authors.
+ * Copyright 2012-2023 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.
@@ -38,6 +38,14 @@ public int compareTo(DependencyVersion other) {
return this.comparableVersion.compareTo(otherComparable);
}
+ @Override
+ public boolean isUpgrade(DependencyVersion candidate, boolean movingToSnapshots) {
+ ComparableVersion comparableCandidate = (candidate instanceof AbstractDependencyVersion)
+ ? ((AbstractDependencyVersion) candidate).comparableVersion
+ : new ComparableVersion(candidate.toString());
+ return comparableCandidate.compareTo(this.comparableVersion) > 0;
+ }
+
@Override
public boolean equals(Object obj) {
if (this == obj) {
diff --git a/buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/version/ArtifactVersionDependencyVersion.java b/buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/version/ArtifactVersionDependencyVersion.java
index 59eacedd3b11..61e1d761e201 100644
--- a/buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/version/ArtifactVersionDependencyVersion.java
+++ b/buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/version/ArtifactVersionDependencyVersion.java
@@ -23,6 +23,8 @@
import org.apache.maven.artifact.versioning.ComparableVersion;
import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
+import org.springframework.util.StringUtils;
+
/**
* A {@link DependencyVersion} backed by an {@link ArtifactVersion}.
*
@@ -33,47 +35,91 @@ class ArtifactVersionDependencyVersion extends AbstractDependencyVersion {
private final ArtifactVersion artifactVersion;
protected ArtifactVersionDependencyVersion(ArtifactVersion artifactVersion) {
- super(new ComparableVersion(artifactVersion.toString()));
+ super(new ComparableVersion(toNormalizedString(artifactVersion)));
this.artifactVersion = artifactVersion;
}
+ private static String toNormalizedString(ArtifactVersion artifactVersion) {
+ String versionString = artifactVersion.toString();
+ if (versionString.endsWith(".RELEASE")) {
+ return versionString.substring(0, versionString.length() - 8);
+ }
+ if (versionString.endsWith(".BUILD-SNAPSHOT")) {
+ return versionString.substring(0, versionString.length() - 15) + "-SNAPSHOT";
+ }
+ return versionString;
+ }
+
protected ArtifactVersionDependencyVersion(ArtifactVersion artifactVersion, ComparableVersion comparableVersion) {
super(comparableVersion);
this.artifactVersion = artifactVersion;
}
@Override
- public boolean isNewerThan(DependencyVersion other) {
+ public boolean isSameMajor(DependencyVersion other) {
if (other instanceof ReleaseTrainDependencyVersion) {
return false;
}
- return compareTo(other) > 0;
+ return extractArtifactVersionDependencyVersion(other).map(this::isSameMajor).orElse(true);
+ }
+
+ private boolean isSameMajor(ArtifactVersionDependencyVersion other) {
+ return this.artifactVersion.getMajorVersion() == other.artifactVersion.getMajorVersion();
}
@Override
- public boolean isSameMajorAndNewerThan(DependencyVersion other) {
+ public boolean isSameMinor(DependencyVersion other) {
if (other instanceof ReleaseTrainDependencyVersion) {
return false;
}
- return extractArtifactVersionDependencyVersion(other).map(this::isSameMajorAndNewerThan).orElse(true);
+ return extractArtifactVersionDependencyVersion(other).map(this::isSameMinor).orElse(true);
}
- private boolean isSameMajorAndNewerThan(ArtifactVersionDependencyVersion other) {
- return this.artifactVersion.getMajorVersion() == other.artifactVersion.getMajorVersion() && isNewerThan(other);
+ private boolean isSameMinor(ArtifactVersionDependencyVersion other) {
+ return isSameMajor(other) && this.artifactVersion.getMinorVersion() == other.artifactVersion.getMinorVersion();
}
@Override
- public boolean isSameMinorAndNewerThan(DependencyVersion other) {
- if (other instanceof ReleaseTrainDependencyVersion) {
+ public boolean isUpgrade(DependencyVersion candidate, boolean movingToSnapshots) {
+ if (!(candidate instanceof ArtifactVersionDependencyVersion)) {
return false;
}
- return extractArtifactVersionDependencyVersion(other).map(this::isSameMinorAndNewerThan).orElse(true);
+ ArtifactVersion other = ((ArtifactVersionDependencyVersion) candidate).artifactVersion;
+ if (this.artifactVersion.equals(other)) {
+ return false;
+ }
+ if (sameMajorMinorIncremental(other)) {
+ if (!StringUtils.hasLength(this.artifactVersion.getQualifier())
+ || "RELEASE".equals(this.artifactVersion.getQualifier())) {
+ return false;
+ }
+ if (isSnapshot()) {
+ return true;
+ }
+ else if (((ArtifactVersionDependencyVersion) candidate).isSnapshot()) {
+ return movingToSnapshots;
+ }
+ }
+ return super.isUpgrade(candidate, movingToSnapshots);
+ }
+
+ private boolean sameMajorMinorIncremental(ArtifactVersion other) {
+ return this.artifactVersion.getMajorVersion() == other.getMajorVersion()
+ && this.artifactVersion.getMinorVersion() == other.getMinorVersion()
+ && this.artifactVersion.getIncrementalVersion() == other.getIncrementalVersion();
}
- private boolean isSameMinorAndNewerThan(ArtifactVersionDependencyVersion other) {
- return this.artifactVersion.getMajorVersion() == other.artifactVersion.getMajorVersion()
- && this.artifactVersion.getMinorVersion() == other.artifactVersion.getMinorVersion()
- && isNewerThan(other);
+ private boolean isSnapshot() {
+ return "SNAPSHOT".equals(this.artifactVersion.getQualifier())
+ || "BUILD".equals(this.artifactVersion.getQualifier());
+ }
+
+ @Override
+ public boolean isSnapshotFor(DependencyVersion candidate) {
+ if (!isSnapshot() || !(candidate instanceof ArtifactVersionDependencyVersion)) {
+ return false;
+ }
+ return sameMajorMinorIncremental(((ArtifactVersionDependencyVersion) candidate).artifactVersion);
}
@Override
diff --git a/buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/version/CalendarVersionDependencyVersion.java b/buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/version/CalendarVersionDependencyVersion.java
index a237ac3af4c4..475e2149f90b 100644
--- a/buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/version/CalendarVersionDependencyVersion.java
+++ b/buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/version/CalendarVersionDependencyVersion.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2020 the original author or authors.
+ * Copyright 2012-2023 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.
@@ -41,14 +41,6 @@ protected CalendarVersionDependencyVersion(ArtifactVersion artifactVersion, Comp
super(artifactVersion, comparableVersion);
}
- @Override
- public boolean isNewerThan(DependencyVersion other) {
- if (other instanceof ReleaseTrainDependencyVersion) {
- return true;
- }
- return super.isNewerThan(other);
- }
-
static CalendarVersionDependencyVersion parse(String version) {
if (!CALENDAR_VERSION_PATTERN.matcher(version).matches()) {
return null;
diff --git a/buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/version/DependencyVersion.java b/buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/version/DependencyVersion.java
index dde4ff0dbb0a..f4b9b897a1ba 100644
--- a/buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/version/DependencyVersion.java
+++ b/buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/version/DependencyVersion.java
@@ -28,29 +28,38 @@
public interface DependencyVersion extends Comparable {
/**
- * Returns whether this version is newer than the given {@code other} version.
- * @param other version to test
- * @return {@code true} if this version is newer, otherwise {@code false}
+ * Returns whether this version has the same major and minor versions as the
+ * {@code other} version.
+ * @param other the version to test
+ * @return {@code true} if this version has the same major and minor, otherwise
+ * {@code false}
*/
- boolean isNewerThan(DependencyVersion other);
+ boolean isSameMinor(DependencyVersion other);
/**
- * Returns whether this version has the same major versions as the {@code other}
- * version while also being newer.
- * @param other version to test
- * @return {@code true} if this version has the same major and is newer, otherwise
- * {@code false}
+ * Returns whether this version has the same major version as the {@code other}
+ * version.
+ * @param other the version to test
+ * @return {@code true} if this version has the same major, otherwise {@code false}
*/
- boolean isSameMajorAndNewerThan(DependencyVersion other);
+ boolean isSameMajor(DependencyVersion other);
/**
- * Returns whether this version has the same major and minor versions as the
- * {@code other} version while also being newer.
- * @param other version to test
- * @return {@code true} if this version has the same major and minor and is newer,
- * otherwise {@code false}
+ * Returns whether the given {@code candidate} is an upgrade of this version.
+ * @param candidate the version to consider
+ * @param movingToSnapshots whether the upgrade is to be considered as part of moving
+ * to snaphots
+ * @return {@code true} if the candidate is an upgrade, otherwise false
+ */
+ boolean isUpgrade(DependencyVersion candidate, boolean movingToSnapshots);
+
+ /**
+ * Returns whether this version is a snapshot for the given {@code candidate}.
+ * @param candidate the version to consider
+ * @return {@code true} if this version is a snapshot for the candidate, otherwise
+ * false
*/
- boolean isSameMinorAndNewerThan(DependencyVersion other);
+ boolean isSnapshotFor(DependencyVersion candidate);
static DependencyVersion parse(String version) {
List> parsers = Arrays.asList(CalendarVersionDependencyVersion::parse,
diff --git a/buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/version/ReleaseTrainDependencyVersion.java b/buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/version/ReleaseTrainDependencyVersion.java
index 838ba33e8b98..c9c79bcdc69b 100644
--- a/buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/version/ReleaseTrainDependencyVersion.java
+++ b/buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/version/ReleaseTrainDependencyVersion.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2022 the original author or authors.
+ * Copyright 2012-2023 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.
@@ -28,7 +28,8 @@
*/
final class ReleaseTrainDependencyVersion implements DependencyVersion {
- private static final Pattern VERSION_PATTERN = Pattern.compile("([A-Z][a-z]+)-([A-Z]+)([0-9]*)");
+ private static final Pattern VERSION_PATTERN = Pattern
+ .compile("([A-Z][a-z]+)-((BUILD-SNAPSHOT)|([A-Z-]+)([0-9]*))");
private final String releaseTrain;
@@ -62,30 +63,56 @@ public int compareTo(DependencyVersion other) {
}
@Override
- public boolean isNewerThan(DependencyVersion other) {
- if (other instanceof CalendarVersionDependencyVersion) {
- return false;
+ public boolean isUpgrade(DependencyVersion candidate, boolean movingToSnapshots) {
+ if (!(candidate instanceof ReleaseTrainDependencyVersion)) {
+ return true;
}
- if (!(other instanceof ReleaseTrainDependencyVersion otherReleaseTrain)) {
+ ReleaseTrainDependencyVersion candidateReleaseTrain = (ReleaseTrainDependencyVersion) candidate;
+ int comparison = this.releaseTrain.compareTo(candidateReleaseTrain.releaseTrain);
+ if (comparison != 0) {
+ return comparison < 0;
+ }
+ if (movingToSnapshots && !isSnapshot() && candidateReleaseTrain.isSnapshot()) {
return true;
}
- return otherReleaseTrain.compareTo(this) < 0;
+ comparison = this.type.compareTo(candidateReleaseTrain.type);
+ if (comparison != 0) {
+ return comparison < 0;
+ }
+ return Integer.compare(this.version, candidateReleaseTrain.version) < 0;
+ }
+
+ private boolean isSnapshot() {
+ return "BUILD-SNAPSHOT".equals(this.type);
+ }
+
+ @Override
+ public boolean isSnapshotFor(DependencyVersion candidate) {
+ if (!isSnapshot() || !(candidate instanceof ReleaseTrainDependencyVersion)) {
+ return false;
+ }
+ ReleaseTrainDependencyVersion candidateReleaseTrain = (ReleaseTrainDependencyVersion) candidate;
+ return this.releaseTrain.equals(candidateReleaseTrain.releaseTrain);
}
@Override
- public boolean isSameMajorAndNewerThan(DependencyVersion other) {
- return isNewerThan(other);
+ public boolean isSameMajor(DependencyVersion other) {
+ return isSameReleaseTrain(other);
}
@Override
- public boolean isSameMinorAndNewerThan(DependencyVersion other) {
+ public boolean isSameMinor(DependencyVersion other) {
+ return isSameReleaseTrain(other);
+ }
+
+ private boolean isSameReleaseTrain(DependencyVersion other) {
if (other instanceof CalendarVersionDependencyVersion) {
return false;
}
- if (!(other instanceof ReleaseTrainDependencyVersion otherReleaseTrain)) {
- return true;
+ if (other instanceof ReleaseTrainDependencyVersion otherReleaseTrain) {
+ return otherReleaseTrain.releaseTrain.equals(this.releaseTrain);
}
- return otherReleaseTrain.releaseTrain.equals(this.releaseTrain) && isNewerThan(other);
+ return true;
}
@Override
@@ -121,8 +148,9 @@ static ReleaseTrainDependencyVersion parse(String input) {
if (!matcher.matches()) {
return null;
}
- return new ReleaseTrainDependencyVersion(matcher.group(1), matcher.group(2),
- (StringUtils.hasLength(matcher.group(3))) ? Integer.parseInt(matcher.group(3)) : 0, input);
+ return new ReleaseTrainDependencyVersion(matcher.group(1),
+ StringUtils.hasLength(matcher.group(3)) ? matcher.group(3) : matcher.group(4),
+ (StringUtils.hasLength(matcher.group(5))) ? Integer.parseInt(matcher.group(5)) : 0, input);
}
}
diff --git a/buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/version/UnstructuredDependencyVersion.java b/buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/version/UnstructuredDependencyVersion.java
index a39d8a3843fa..5799225958bf 100644
--- a/buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/version/UnstructuredDependencyVersion.java
+++ b/buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/version/UnstructuredDependencyVersion.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2020 the original author or authors.
+ * Copyright 2012-2023 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.
@@ -34,23 +34,23 @@ private UnstructuredDependencyVersion(String version) {
}
@Override
- public boolean isNewerThan(DependencyVersion other) {
- return compareTo(other) > 0;
+ public boolean isSameMajor(DependencyVersion other) {
+ return true;
}
@Override
- public boolean isSameMajorAndNewerThan(DependencyVersion other) {
- return compareTo(other) > 0;
+ public boolean isSameMinor(DependencyVersion other) {
+ return true;
}
@Override
- public boolean isSameMinorAndNewerThan(DependencyVersion other) {
- return compareTo(other) > 0;
+ public String toString() {
+ return this.version;
}
@Override
- public String toString() {
- return this.version;
+ public boolean isSnapshotFor(DependencyVersion candidate) {
+ return false;
}
static UnstructuredDependencyVersion parse(String version) {
diff --git a/buildSrc/src/main/java/org/springframework/boot/build/classpath/CheckClasspathForUnnecessaryExclusions.java b/buildSrc/src/main/java/org/springframework/boot/build/classpath/CheckClasspathForUnnecessaryExclusions.java
index 268ace77791e..511898299957 100644
--- a/buildSrc/src/main/java/org/springframework/boot/build/classpath/CheckClasspathForUnnecessaryExclusions.java
+++ b/buildSrc/src/main/java/org/springframework/boot/build/classpath/CheckClasspathForUnnecessaryExclusions.java
@@ -38,6 +38,8 @@
import org.gradle.api.artifacts.component.ModuleComponentIdentifier;
import org.gradle.api.artifacts.dsl.DependencyHandler;
import org.gradle.api.artifacts.result.ResolvedArtifactResult;
+import org.gradle.api.file.FileCollection;
+import org.gradle.api.tasks.Classpath;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.TaskAction;
@@ -61,6 +63,8 @@ public class CheckClasspathForUnnecessaryExclusions extends DefaultTask {
private final ConfigurationContainer configurations;
+ private Configuration classpath;
+
@Inject
public CheckClasspathForUnnecessaryExclusions(DependencyHandler dependencyHandler,
ConfigurationContainer configurations) {
@@ -72,11 +76,17 @@ public CheckClasspathForUnnecessaryExclusions(DependencyHandler dependencyHandle
}
public void setClasspath(Configuration classpath) {
+ this.classpath = classpath;
this.exclusionsByDependencyId.clear();
this.dependencyById.clear();
classpath.getAllDependencies().all(this::processDependency);
}
+ @Classpath
+ public FileCollection getClasspath() {
+ return this.classpath;
+ }
+
private void processDependency(Dependency dependency) {
if (dependency instanceof ModuleDependency moduleDependency) {
processDependency(moduleDependency);
diff --git a/buildSrc/src/main/java/org/springframework/boot/build/context/properties/CheckAdditionalSpringConfigurationMetadata.java b/buildSrc/src/main/java/org/springframework/boot/build/context/properties/CheckAdditionalSpringConfigurationMetadata.java
index d45b1d4e9299..cc7bdfd87b20 100644
--- a/buildSrc/src/main/java/org/springframework/boot/build/context/properties/CheckAdditionalSpringConfigurationMetadata.java
+++ b/buildSrc/src/main/java/org/springframework/boot/build/context/properties/CheckAdditionalSpringConfigurationMetadata.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2022 the original author or authors.
+ * Copyright 2012-2023 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.
@@ -93,7 +93,7 @@ private Report createReport() throws IOException, JsonParseException, JsonMappin
@SuppressWarnings("unchecked")
private void check(String key, Map json, Analysis analysis) {
- List> groups = (List>) json.get(key);
+ List> groups = (List>) json.getOrDefault(key, Collections.emptyList());
List names = groups.stream().map((group) -> (String) group.get("name")).toList();
List sortedNames = sortedCopy(names);
for (int i = 0; i < names.size(); i++) {
diff --git a/buildSrc/src/main/java/org/springframework/boot/build/context/properties/DocumentConfigurationProperties.java b/buildSrc/src/main/java/org/springframework/boot/build/context/properties/DocumentConfigurationProperties.java
index d7c8710e2cb4..6245d5b9da5e 100644
--- a/buildSrc/src/main/java/org/springframework/boot/build/context/properties/DocumentConfigurationProperties.java
+++ b/buildSrc/src/main/java/org/springframework/boot/build/context/properties/DocumentConfigurationProperties.java
@@ -78,8 +78,10 @@ void documentConfigurationProperties() throws IOException {
snippets.add("application-properties.security", "Security Properties", this::securityPrefixes);
snippets.add("application-properties.rsocket", "RSocket Properties", this::rsocketPrefixes);
snippets.add("application-properties.actuator", "Actuator Properties", this::actuatorPrefixes);
- snippets.add("application-properties.docker-compose", "Docker Compose Properties", this::dockerComposePrefixes);
snippets.add("application-properties.devtools", "Devtools Properties", this::devtoolsPrefixes);
+ snippets.add("application-properties.docker-compose", "Docker Compose Properties", this::dockerComposePrefixes);
+ snippets.add("application-properties.testcontainers", "Testcontainers Properties",
+ this::testcontainersPrefixes);
snippets.add("application-properties.testing", "Testing Properties", this::testingPrefixes);
snippets.writeTo(this.outputDir.toPath());
}
@@ -106,6 +108,7 @@ private void corePrefixes(Config config) {
config.accept("spring.reactor");
config.accept("spring.ssl");
config.accept("spring.task");
+ config.accept("spring.threads");
config.accept("spring.mandatory-file-encoding");
config.accept("info");
config.accept("spring.output.ansi.enabled");
@@ -170,6 +173,7 @@ private void integrationPrefixes(Config prefix) {
prefix.accept("spring.integration");
prefix.accept("spring.jms");
prefix.accept("spring.kafka");
+ prefix.accept("spring.pulsar");
prefix.accept("spring.rabbitmq");
prefix.accept("spring.hazelcast");
prefix.accept("spring.webservices");
@@ -222,7 +226,11 @@ private void devtoolsPrefixes(Config prefix) {
}
private void testingPrefixes(Config prefix) {
- prefix.accept("spring.test");
+ prefix.accept("spring.test.");
+ }
+
+ private void testcontainersPrefixes(Config prefix) {
+ prefix.accept("spring.testcontainers.");
}
}
diff --git a/buildSrc/src/main/java/org/springframework/boot/build/docs/ApplicationRunner.java b/buildSrc/src/main/java/org/springframework/boot/build/docs/ApplicationRunner.java
index 0f95d55d3d67..785be772544b 100644
--- a/buildSrc/src/main/java/org/springframework/boot/build/docs/ApplicationRunner.java
+++ b/buildSrc/src/main/java/org/springframework/boot/build/docs/ApplicationRunner.java
@@ -105,8 +105,8 @@ public Property getApplicationJar() {
}
public void normalizeTomcatPort() {
- this.normalizations.put("(Tomcat started on port\\(s\\): )[\\d]+( \\(http\\))", "$18080$2");
- this.normalizations.put("(Tomcat initialized with port\\(s\\): )[\\d]+( \\(http\\))", "$18080$2");
+ this.normalizations.put("(Tomcat started on port )[\\d]+( \\(http\\))", "$18080$2");
+ this.normalizations.put("(Tomcat initialized with port )[\\d]+( \\(http\\))", "$18080$2");
}
public void normalizeLiveReloadPort() {
diff --git a/buildSrc/src/main/java/org/springframework/boot/build/mavenplugin/DocumentPluginGoals.java b/buildSrc/src/main/java/org/springframework/boot/build/mavenplugin/DocumentPluginGoals.java
index 0419f33496ed..f5256fc17c80 100644
--- a/buildSrc/src/main/java/org/springframework/boot/build/mavenplugin/DocumentPluginGoals.java
+++ b/buildSrc/src/main/java/org/springframework/boot/build/mavenplugin/DocumentPluginGoals.java
@@ -21,9 +21,11 @@
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
+import java.util.Map;
import org.gradle.api.DefaultTask;
import org.gradle.api.Task;
+import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.InputFile;
import org.gradle.api.tasks.OutputDirectory;
import org.gradle.api.tasks.TaskAction;
@@ -45,6 +47,8 @@ public class DocumentPluginGoals extends DefaultTask {
private File outputDir;
+ private Map goalSections;
+
@OutputDirectory
public File getOutputDir() {
return this.outputDir;
@@ -54,6 +58,15 @@ public void setOutputDir(File outputDir) {
this.outputDir = outputDir;
}
+ @Input
+ public Map getGoalSections() {
+ return this.goalSections;
+ }
+
+ public void setGoalSections(Map goalSections) {
+ this.goalSections = goalSections;
+ }
+
@InputFile
public File getPluginXml() {
return this.pluginXml;
@@ -79,7 +92,7 @@ private void writeOverview(Plugin plugin) throws IOException {
writer.println("| Goal | Description");
writer.println();
for (Mojo mojo : plugin.getMojos()) {
- writer.printf("| <>%n", mojo.getGoal(), plugin.getGoalPrefix(), mojo.getGoal());
+ writer.printf("| <<%s,%s:%s>>%n", goalSectionId(mojo), plugin.getGoalPrefix(), mojo.getGoal());
writer.printf("| %s%n", mojo.getDescription());
writer.println();
}
@@ -89,7 +102,7 @@ private void writeOverview(Plugin plugin) throws IOException {
private void documentMojo(Plugin plugin, Mojo mojo) throws IOException {
try (PrintWriter writer = new PrintWriter(new FileWriter(new File(this.outputDir, mojo.getGoal() + ".adoc")))) {
- String sectionId = "goals-" + mojo.getGoal();
+ String sectionId = goalSectionId(mojo);
writer.println();
writer.println();
writer.printf("[[%s]]%n", sectionId);
@@ -99,12 +112,11 @@ private void documentMojo(Plugin plugin, Mojo mojo) throws IOException {
writer.println(mojo.getDescription());
List parameters = mojo.getParameters().stream().filter(Parameter::isEditable).toList();
List requiredParameters = parameters.stream().filter(Parameter::isRequired).toList();
- String parametersSectionId = sectionId + "-parameters";
- String detailsSectionId = parametersSectionId + "-details";
+ String detailsSectionId = sectionId + ".parameter-details";
if (!requiredParameters.isEmpty()) {
writer.println();
writer.println();
- writer.printf("[[%s-required]]%n", parametersSectionId);
+ writer.printf("[[%s.required-parameters]]%n", sectionId);
writer.println("== Required parameters");
writeParametersTable(writer, detailsSectionId, requiredParameters);
}
@@ -114,7 +126,7 @@ private void documentMojo(Plugin plugin, Mojo mojo) throws IOException {
if (!optionalParameters.isEmpty()) {
writer.println();
writer.println();
- writer.printf("[[%s-optional]]%n", parametersSectionId);
+ writer.printf("[[%s.optional-parameters]]%n", sectionId);
writer.println("== Optional parameters");
writeParametersTable(writer, detailsSectionId, optionalParameters);
}
@@ -126,6 +138,15 @@ private void documentMojo(Plugin plugin, Mojo mojo) throws IOException {
}
}
+ private String goalSectionId(Mojo mojo) {
+ String goalSection = this.goalSections.get(mojo.getGoal());
+ if (goalSection == null) {
+ throw new IllegalStateException("Goal '" + mojo.getGoal() + "' has not be assigned to a section");
+ }
+ String sectionId = goalSection + "." + mojo.getGoal() + "-goal";
+ return sectionId;
+ }
+
private void writeParametersTable(PrintWriter writer, String detailsSectionId, List parameters) {
writer.println("[cols=\"3,2,3\"]");
writer.println("|===");
@@ -133,7 +154,7 @@ private void writeParametersTable(PrintWriter writer, String detailsSectionId, L
writer.println();
for (Parameter parameter : parameters) {
String name = parameter.getName();
- writer.printf("| <<%s-%s,%s>>%n", detailsSectionId, name, name);
+ writer.printf("| <<%s.%s,%s>>%n", detailsSectionId, parameterId(name), name);
writer.printf("| `%s`%n", typeNameToJavadocLink(shortTypeName(parameter.getType()), parameter.getType()));
String defaultValue = parameter.getDefaultValue();
if (defaultValue != null) {
@@ -152,7 +173,7 @@ private void writeParameterDetails(PrintWriter writer, List parameter
String name = parameter.getName();
writer.println();
writer.println();
- writer.printf("[[%s-%s]]%n", sectionId, name);
+ writer.printf("[[%s.%s]]%n", sectionId, parameterId(name));
writer.printf("=== `%s`%n", name);
writer.println(parameter.getDescription());
writer.println();
@@ -168,6 +189,20 @@ private void writeParameterDetails(PrintWriter writer, List parameter
}
}
+ private String parameterId(String name) {
+ StringBuilder id = new StringBuilder(name.length() + 4);
+ for (char c : name.toCharArray()) {
+ if (Character.isLowerCase(c)) {
+ id.append(c);
+ }
+ else {
+ id.append("-");
+ id.append(Character.toLowerCase(c));
+ }
+ }
+ return id.toString();
+ }
+
private void writeDetail(PrintWriter writer, String name, String value) {
writer.printf("| %s%n", name);
writer.printf("| `%s`%n", value);
diff --git a/buildSrc/src/test/java/org/springframework/boot/build/ConventionsPluginTests.java b/buildSrc/src/test/java/org/springframework/boot/build/ConventionsPluginTests.java
index 6f7c1d0f76ee..5d60470ee066 100644
--- a/buildSrc/src/test/java/org/springframework/boot/build/ConventionsPluginTests.java
+++ b/buildSrc/src/test/java/org/springframework/boot/build/ConventionsPluginTests.java
@@ -187,7 +187,7 @@ void testRetryIsConfiguredWithThreeRetriesOnCI() throws IOException {
}
assertThat(runGradle(Collections.singletonMap("CI", "true"), "retryConfig", "--stacktrace").getOutput())
.contains("maxRetries: 3")
- .contains("failOnPassedAfterRetry: true");
+ .contains("failOnPassedAfterRetry: false");
}
@Test
@@ -209,7 +209,7 @@ void testRetryIsConfiguredWithZeroRetriesLocally() throws IOException {
}
assertThat(runGradle(Collections.singletonMap("CI", "local"), "retryConfig", "--stacktrace").getOutput())
.contains("maxRetries: 0")
- .contains("failOnPassedAfterRetry: true");
+ .contains("failOnPassedAfterRetry: false");
}
private BuildResult runGradle(String... args) {
diff --git a/buildSrc/src/test/java/org/springframework/boot/build/architecture/ArchitectureCheckTests.java b/buildSrc/src/test/java/org/springframework/boot/build/architecture/ArchitectureCheckTests.java
index d9c70b2b031a..1294d6192975 100644
--- a/buildSrc/src/test/java/org/springframework/boot/build/architecture/ArchitectureCheckTests.java
+++ b/buildSrc/src/test/java/org/springframework/boot/build/architecture/ArchitectureCheckTests.java
@@ -46,7 +46,7 @@ class ArchitectureCheckTests {
void whenPackagesAreTangledTaskFailsAndWritesAReport() throws Exception {
prepareTask("tangled", (architectureCheck) -> {
assertThatExceptionOfType(GradleException.class).isThrownBy(architectureCheck::checkArchitecture);
- assertThat(failureReport(architectureCheck).length()).isGreaterThan(0);
+ assertThat(failureReport(architectureCheck)).isNotEmpty();
});
}
@@ -54,7 +54,7 @@ void whenPackagesAreTangledTaskFailsAndWritesAReport() throws Exception {
void whenPackagesAreNotTangledTaskSucceedsAndWritesAnEmptyReport() throws Exception {
prepareTask("untangled", (architectureCheck) -> {
architectureCheck.checkArchitecture();
- assertThat(failureReport(architectureCheck).length()).isZero();
+ assertThat(failureReport(architectureCheck)).isEmpty();
});
}
@@ -66,7 +66,7 @@ File failureReport(ArchitectureCheck architectureCheck) {
void whenBeanPostProcessorBeanMethodIsNotStaticTaskFailsAndWritesAReport() throws Exception {
prepareTask("bpp/nonstatic", (architectureCheck) -> {
assertThatExceptionOfType(GradleException.class).isThrownBy(architectureCheck::checkArchitecture);
- assertThat(failureReport(architectureCheck).length()).isGreaterThan(0);
+ assertThat(failureReport(architectureCheck)).isNotEmpty();
});
}
@@ -74,7 +74,7 @@ void whenBeanPostProcessorBeanMethodIsNotStaticTaskFailsAndWritesAReport() throw
void whenBeanPostProcessorBeanMethodIsStaticAndHasUnsafeParametersTaskFailsAndWritesAReport() throws Exception {
prepareTask("bpp/unsafeparameters", (architectureCheck) -> {
assertThatExceptionOfType(GradleException.class).isThrownBy(architectureCheck::checkArchitecture);
- assertThat(failureReport(architectureCheck).length()).isGreaterThan(0);
+ assertThat(failureReport(architectureCheck)).isNotEmpty();
});
}
@@ -83,7 +83,7 @@ void whenBeanPostProcessorBeanMethodIsStaticAndHasSafeParametersTaskSucceedsAndW
throws Exception {
prepareTask("bpp/safeparameters", (architectureCheck) -> {
architectureCheck.checkArchitecture();
- assertThat(failureReport(architectureCheck).length()).isZero();
+ assertThat(failureReport(architectureCheck)).isEmpty();
});
}
@@ -92,7 +92,7 @@ void whenBeanPostProcessorBeanMethodIsStaticAndHasNoParametersTaskSucceedsAndWri
throws Exception {
prepareTask("bpp/noparameters", (architectureCheck) -> {
architectureCheck.checkArchitecture();
- assertThat(failureReport(architectureCheck).length()).isZero();
+ assertThat(failureReport(architectureCheck)).isEmpty();
});
}
@@ -100,7 +100,7 @@ void whenBeanPostProcessorBeanMethodIsStaticAndHasNoParametersTaskSucceedsAndWri
void whenBeanFactoryPostProcessorBeanMethodIsNotStaticTaskFailsAndWritesAReport() throws Exception {
prepareTask("bfpp/nonstatic", (architectureCheck) -> {
assertThatExceptionOfType(GradleException.class).isThrownBy(architectureCheck::checkArchitecture);
- assertThat(failureReport(architectureCheck).length()).isGreaterThan(0);
+ assertThat(failureReport(architectureCheck)).isNotEmpty();
});
}
@@ -108,7 +108,7 @@ void whenBeanFactoryPostProcessorBeanMethodIsNotStaticTaskFailsAndWritesAReport(
void whenBeanFactoryPostProcessorBeanMethodIsStaticAndHasParametersTaskFailsAndWritesAReport() throws Exception {
prepareTask("bfpp/parameters", (architectureCheck) -> {
assertThatExceptionOfType(GradleException.class).isThrownBy(architectureCheck::checkArchitecture);
- assertThat(failureReport(architectureCheck).length()).isGreaterThan(0);
+ assertThat(failureReport(architectureCheck)).isNotEmpty();
});
}
@@ -117,7 +117,7 @@ void whenBeanFactoryPostProcessorBeanMethodIsStaticAndHasNoParametersTaskSucceed
throws Exception {
prepareTask("bfpp/noparameters", (architectureCheck) -> {
architectureCheck.checkArchitecture();
- assertThat(failureReport(architectureCheck).length()).isZero();
+ assertThat(failureReport(architectureCheck)).isEmpty();
});
}
diff --git a/buildSrc/src/test/java/org/springframework/boot/build/bom/bomr/ReleaseScheduleTests.java b/buildSrc/src/test/java/org/springframework/boot/build/bom/bomr/ReleaseScheduleTests.java
new file mode 100644
index 000000000000..bbf78521403c
--- /dev/null
+++ b/buildSrc/src/test/java/org/springframework/boot/build/bom/bomr/ReleaseScheduleTests.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2023-2023 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.boot.build.bom.bomr;
+
+import java.time.OffsetDateTime;
+import java.util.List;
+import java.util.Map;
+
+import org.junit.jupiter.api.Test;
+
+import org.springframework.boot.build.bom.bomr.ReleaseSchedule.Release;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.http.MediaType;
+import org.springframework.test.web.client.MockRestServiceServer;
+import org.springframework.web.client.RestTemplate;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo;
+import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess;
+
+/**
+ * Tests for {@link ReleaseSchedule}.
+ *
+ * @author Andy Wilkinson
+ */
+class ReleaseScheduleTests {
+
+ private final RestTemplate rest = new RestTemplate();
+
+ private final ReleaseSchedule releaseSchedule = new ReleaseSchedule(this.rest);
+
+ private final MockRestServiceServer server = MockRestServiceServer.bindTo(this.rest).build();
+
+ @Test
+ void releasesBetween() {
+ this.server
+ .expect(requestTo("https://calendar.spring.io/releases?start=2023-09-01T00:00Z&end=2023-09-21T23:59Z"))
+ .andRespond(withSuccess(new ClassPathResource("releases.json"), MediaType.APPLICATION_JSON));
+ Map> releases = this.releaseSchedule
+ .releasesBetween(OffsetDateTime.parse("2023-09-01T00:00Z"), OffsetDateTime.parse("2023-09-21T23:59Z"));
+ assertThat(releases).hasSize(23);
+ assertThat(releases.get("Spring Framework")).hasSize(3);
+ assertThat(releases.get("Spring Boot")).hasSize(4);
+ assertThat(releases.get("Spring Modulith")).hasSize(1);
+ assertThat(releases.get("spring graphql")).hasSize(3);
+ }
+
+}
diff --git a/buildSrc/src/test/java/org/springframework/boot/build/bom/bomr/UpgradeApplicatorTests.java b/buildSrc/src/test/java/org/springframework/boot/build/bom/bomr/UpgradeApplicatorTests.java
index 6c96ab74ef08..af184a2be532 100644
--- a/buildSrc/src/test/java/org/springframework/boot/build/bom/bomr/UpgradeApplicatorTests.java
+++ b/buildSrc/src/test/java/org/springframework/boot/build/bom/bomr/UpgradeApplicatorTests.java
@@ -51,9 +51,9 @@ void whenUpgradeIsAppliedToLibraryWithVersionThenBomIsUpdated() throws IOExcepti
String originalContents = Files.readString(bom.toPath());
File gradleProperties = new File(this.temp, "gradle.properties");
FileCopyUtils.copy(new File("src/test/resources/gradle.properties"), gradleProperties);
- new UpgradeApplicator(bom.toPath(), gradleProperties.toPath()).apply(
- new Upgrade(new Library("ActiveMQ", new LibraryVersion(DependencyVersion.parse("5.15.11")), null, null),
- DependencyVersion.parse("5.16")));
+ new UpgradeApplicator(bom.toPath(), gradleProperties.toPath())
+ .apply(new Upgrade(new Library("ActiveMQ", null, new LibraryVersion(DependencyVersion.parse("5.15.11")),
+ null, null, false), DependencyVersion.parse("5.16")));
String bomContents = Files.readString(bom.toPath());
assertThat(bomContents).hasSize(originalContents.length() - 3);
}
@@ -64,9 +64,9 @@ void whenUpgradeIsAppliedToLibraryWithVersionPropertyThenGradlePropertiesIsUpdat
FileCopyUtils.copy(new File("src/test/resources/bom.gradle"), bom);
File gradleProperties = new File(this.temp, "gradle.properties");
FileCopyUtils.copy(new File("src/test/resources/gradle.properties"), gradleProperties);
- new UpgradeApplicator(bom.toPath(), gradleProperties.toPath())
- .apply(new Upgrade(new Library("Kotlin", new LibraryVersion(DependencyVersion.parse("1.3.70")), null, null),
- DependencyVersion.parse("1.4")));
+ new UpgradeApplicator(bom.toPath(), gradleProperties.toPath()).apply(new Upgrade(
+ new Library("Kotlin", null, new LibraryVersion(DependencyVersion.parse("1.3.70")), null, null, false),
+ DependencyVersion.parse("1.4")));
Properties properties = new Properties();
try (InputStream in = new FileInputStream(gradleProperties)) {
properties.load(in);
diff --git a/buildSrc/src/test/java/org/springframework/boot/build/bom/bomr/version/ArtifactVersionDependencyVersionTests.java b/buildSrc/src/test/java/org/springframework/boot/build/bom/bomr/version/ArtifactVersionDependencyVersionTests.java
index d0091b3fb1de..a50e6ba016fe 100644
--- a/buildSrc/src/test/java/org/springframework/boot/build/bom/bomr/version/ArtifactVersionDependencyVersionTests.java
+++ b/buildSrc/src/test/java/org/springframework/boot/build/bom/bomr/version/ArtifactVersionDependencyVersionTests.java
@@ -38,83 +38,93 @@ void parseWhenVersionIsAMavenVersionShouldReturnAVersion() {
}
@Test
- void isNewerThanWhenInputIsOlderMajorShouldReturnTrue() {
- assertThat(version("2.1.2").isNewerThan(version("1.9.0"))).isTrue();
+ void isSameMajorWhenSameMajorAndMinorShouldReturnTrue() {
+ assertThat(version("1.10.2").isSameMajor(version("1.10.0"))).isTrue();
}
@Test
- void isNewerThanWhenInputIsOlderMinorShouldReturnTrue() {
- assertThat(version("2.1.2").isNewerThan(version("2.0.2"))).isTrue();
+ void isSameMajorWhenSameMajorShouldReturnTrue() {
+ assertThat(version("1.10.2").isSameMajor(version("1.9.0"))).isTrue();
}
@Test
- void isNewerThanWhenInputIsOlderPatchShouldReturnTrue() {
- assertThat(version("2.1.2").isNewerThan(version("2.1.1"))).isTrue();
+ void isSameMajorWhenDifferentMajorShouldReturnFalse() {
+ assertThat(version("2.0.2").isSameMajor(version("1.9.0"))).isFalse();
}
@Test
- void isNewerThanWhenInputIsNewerMajorShouldReturnFalse() {
- assertThat(version("2.1.2").isNewerThan(version("3.2.1"))).isFalse();
+ void isSameMinorWhenSameMinorShouldReturnTrue() {
+ assertThat(version("1.10.2").isSameMinor(version("1.10.1"))).isTrue();
}
@Test
- void isSameMajorAndNewerThanWhenMinorIsOlderShouldReturnTrue() {
- assertThat(version("1.10.2").isSameMajorAndNewerThan(version("1.9.0"))).isTrue();
+ void isSameMinorWhenDifferentMinorShouldReturnFalse() {
+ assertThat(version("1.10.2").isSameMinor(version("1.9.1"))).isFalse();
}
@Test
- void isSameMajorAndNewerThanWhenMajorIsOlderShouldReturnFalse() {
- assertThat(version("2.0.2").isSameMajorAndNewerThan(version("1.9.0"))).isFalse();
+ void isSnapshotForWhenSnapshotForReleaseShouldReturnTrue() {
+ assertThat(version("1.10.2-SNAPSHOT").isSnapshotFor(version("1.10.2"))).isTrue();
}
@Test
- void isSameMajorAndNewerThanWhenPatchIsNewerShouldReturnTrue() {
- assertThat(version("2.1.2").isSameMajorAndNewerThan(version("2.1.1"))).isTrue();
+ void isSnapshotForWhenBuildSnapshotForReleaseShouldReturnTrue() {
+ assertThat(version("1.10.2.BUILD-SNAPSHOT").isSnapshotFor(version("1.10.2.RELEASE"))).isTrue();
}
@Test
- void isSameMajorAndNewerThanWhenMinorIsNewerShouldReturnFalse() {
- assertThat(version("2.1.2").isSameMajorAndNewerThan(version("2.2.1"))).isFalse();
+ void isSnapshotForWhenSnapshotForReleaseCandidateShouldReturnTrue() {
+ assertThat(version("1.10.2-SNAPSHOT").isSnapshotFor(version("1.10.2-RC2"))).isTrue();
}
@Test
- void isSameMajorAndNewerThanWhenMajorIsNewerShouldReturnFalse() {
- assertThat(version("2.1.2").isSameMajorAndNewerThan(version("3.0.1"))).isFalse();
+ void isSnapshotForWhenBuildSnapshotForReleaseCandidateShouldReturnTrue() {
+ assertThat(version("1.10.2.BUILD-SNAPSHOT").isSnapshotFor(version("1.10.2.RC2"))).isTrue();
}
@Test
- void isSameMinorAndNewerThanWhenPatchIsOlderShouldReturnTrue() {
- assertThat(version("1.10.2").isSameMinorAndNewerThan(version("1.10.1"))).isTrue();
+ void isSnapshotForWhenSnapshotForMilestoneShouldReturnTrue() {
+ assertThat(version("1.10.2-SNAPSHOT").isSnapshotFor(version("1.10.2-M1"))).isTrue();
}
@Test
- void isSameMinorAndNewerThanWhenMinorIsOlderShouldReturnFalse() {
- assertThat(version("2.1.2").isSameMinorAndNewerThan(version("2.0.1"))).isFalse();
+ void isSnapshotForWhenBuildSnapshotForMilestoneShouldReturnTrue() {
+ assertThat(version("1.10.2.BUILD-SNAPSHOT").isSnapshotFor(version("1.10.2.M1"))).isTrue();
}
@Test
- void isSameMinorAndNewerThanWhenVersionsAreTheSameShouldReturnFalse() {
- assertThat(version("2.1.2").isSameMinorAndNewerThan(version("2.1.2"))).isFalse();
+ void isSnapshotForWhenSnapshotForDifferentReleaseShouldReturnFalse() {
+ assertThat(version("1.10.1-SNAPSHOT").isSnapshotFor(version("1.10.2"))).isFalse();
}
@Test
- void isSameMinorAndNewerThanWhenSameSnapshotsShouldReturnFalse() {
- assertThat(version("3.1.2-SNAPSHOT").isSameMinorAndNewerThan(version("3.1.2-SNAPSHOT"))).isFalse();
+ void isSnapshotForWhenBuildSnapshotForDifferentReleaseShouldReturnTrue() {
+ assertThat(version("1.10.1.BUILD-SNAPSHOT").isSnapshotFor(version("1.10.2.RELEASE"))).isFalse();
}
@Test
- void isSameMinorAndNewerThanWhenPatchIsNewerShouldReturnFalse() {
- assertThat(version("2.1.2").isSameMinorAndNewerThan(version("2.1.3"))).isFalse();
+ void isSnapshotForWhenSnapshotForDifferentReleaseCandidateShouldReturnTrue() {
+ assertThat(version("1.10.1-SNAPSHOT").isSnapshotFor(version("1.10.2-RC2"))).isFalse();
}
@Test
- void isSameMinorAndNewerThanWhenMinorIsNewerShouldReturnFalse() {
- assertThat(version("2.1.2").isSameMinorAndNewerThan(version("2.0.1"))).isFalse();
+ void isSnapshotForWhenBuildSnapshotForDifferentReleaseCandidateShouldReturnTrue() {
+ assertThat(version("1.10.1.BUILD-SNAPSHOT").isSnapshotFor(version("1.10.2.RC2"))).isFalse();
}
@Test
- void isSameMinorAndNewerThanWhenMajorIsNewerShouldReturnFalse() {
- assertThat(version("3.1.2").isSameMinorAndNewerThan(version("2.0.1"))).isFalse();
+ void isSnapshotForWhenSnapshotForDifferentMilestoneShouldReturnTrue() {
+ assertThat(version("1.10.1-SNAPSHOT").isSnapshotFor(version("1.10.2-M1"))).isFalse();
+ }
+
+ @Test
+ void isSnapshotForWhenBuildSnapshotForDifferentMilestoneShouldReturnTrue() {
+ assertThat(version("1.10.1.BUILD-SNAPSHOT").isSnapshotFor(version("1.10.2.M1"))).isFalse();
+ }
+
+ @Test
+ void isSnapshotForWhenNotSnapshotShouldReturnFalse() {
+ assertThat(version("1.10.1-M1").isSnapshotFor(version("1.10.1"))).isFalse();
}
private ArtifactVersionDependencyVersion version(String version) {
diff --git a/buildSrc/src/test/java/org/springframework/boot/build/bom/bomr/version/CalendarVersionDependencyVersionTests.java b/buildSrc/src/test/java/org/springframework/boot/build/bom/bomr/version/CalendarVersionDependencyVersionTests.java
index 279016c7af2a..08ebb7dbf98f 100644
--- a/buildSrc/src/test/java/org/springframework/boot/build/bom/bomr/version/CalendarVersionDependencyVersionTests.java
+++ b/buildSrc/src/test/java/org/springframework/boot/build/bom/bomr/version/CalendarVersionDependencyVersionTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2021 the original author or authors.
+ * Copyright 2012-2023 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.
@@ -38,93 +38,38 @@ void parseWhenVersionIsACalendarVersionShouldReturnAVersion() {
}
@Test
- void isNewerThanWhenInputIsEarlierYearShouldReturnTrue() {
- assertThat(version("2020.1.2").isNewerThan(version("2019.9.0"))).isTrue();
+ void isSameMajorWhenSameMajorAndMinorShouldReturnTrue() {
+ assertThat(version("2020.0.0").isSameMajor(version("2020.0.1"))).isTrue();
}
@Test
- void isNewerThanWhenInputIsOlderMinorShouldReturnTrue() {
- assertThat(version("2020.1.2").isNewerThan(version("2020.0.2"))).isTrue();
+ void isSameMajorWhenSameMajorShouldReturnTrue() {
+ assertThat(version("2020.0.0").isSameMajor(version("2020.1.0"))).isTrue();
}
@Test
- void isNewerThanWhenInputIsOlderMicroShouldReturnTrue() {
- assertThat(version("2020.1.2").isNewerThan(version("2020.1.1"))).isTrue();
+ void isSameMajorWhenDifferentMajorShouldReturnFalse() {
+ assertThat(version("2020.0.0").isSameMajor(version("2021.0.0"))).isFalse();
}
@Test
- void isNewerThanWhenInputIsLaterYearShouldReturnFalse() {
- assertThat(version("2020.1.2").isNewerThan(version("2021.2.1"))).isFalse();
+ void isSameMinorWhenSameMinorShouldReturnTrue() {
+ assertThat(version("2020.0.0").isSameMinor(version("2020.0.1"))).isTrue();
}
@Test
- void isSameMajorAndNewerThanWhenMinorIsOlderShouldReturnTrue() {
- assertThat(version("2020.10.2").isSameMajorAndNewerThan(version("2020.9.0"))).isTrue();
- }
-
- @Test
- void isSameMajorAndNewerThanWhenMajorIsOlderShouldReturnFalse() {
- assertThat(version("2020.0.2").isSameMajorAndNewerThan(version("2019.9.0"))).isFalse();
- }
-
- @Test
- void isSameMajorAndNewerThanWhenMicroIsNewerShouldReturnTrue() {
- assertThat(version("2020.1.2").isSameMajorAndNewerThan(version("2020.1.1"))).isTrue();
- }
-
- @Test
- void isSameMajorAndNewerThanWhenMinorIsNewerShouldReturnFalse() {
- assertThat(version("2020.1.2").isSameMajorAndNewerThan(version("2020.2.1"))).isFalse();
- }
-
- @Test
- void isSameMajorAndNewerThanWhenMajorIsNewerShouldReturnFalse() {
- assertThat(version("2019.1.2").isSameMajorAndNewerThan(version("2020.0.1"))).isFalse();
- }
-
- @Test
- void isSameMinorAndNewerThanWhenMicroIsOlderShouldReturnTrue() {
- assertThat(version("2020.10.2").isSameMinorAndNewerThan(version("2020.10.1"))).isTrue();
- }
-
- @Test
- void isSameMinorAndNewerThanWhenMinorIsOlderShouldReturnFalse() {
- assertThat(version("2020.1.2").isSameMinorAndNewerThan(version("2020.0.1"))).isFalse();
- }
-
- @Test
- void isSameMinorAndNewerThanWhenVersionsAreTheSameShouldReturnFalse() {
- assertThat(version("2020.1.2").isSameMinorAndNewerThan(version("2020.1.2"))).isFalse();
- }
-
- @Test
- void isSameMinorAndNewerThanWhenMicroIsNewerShouldReturnFalse() {
- assertThat(version("2020.1.2").isSameMinorAndNewerThan(version("2020.1.3"))).isFalse();
- }
-
- @Test
- void isSameMinorAndNewerThanWhenMinorIsNewerShouldReturnFalse() {
- assertThat(version("2020.1.2").isSameMinorAndNewerThan(version("2020.0.1"))).isFalse();
- }
-
- @Test
- void isSameMinorAndNewerThanWhenMajorIsNewerShouldReturnFalse() {
- assertThat(version("2020.1.2").isSameMinorAndNewerThan(version("2019.0.1"))).isFalse();
- }
-
- @Test
- void calendarVersionIsNewerThanReleaseTrainVersion() {
- assertThat(version("2020.0.0").isNewerThan(releaseTrainVersion("Aluminium-RELEASE"))).isTrue();
+ void isSameMinorWhenDifferentMinorShouldReturnFalse() {
+ assertThat(version("2020.0.0").isSameMinor(version("2020.1.0"))).isFalse();
}
@Test
void calendarVersionIsNotSameMajorAsReleaseTrainVersion() {
- assertThat(version("2020.0.0").isSameMajorAndNewerThan(releaseTrainVersion("Aluminium-RELEASE"))).isFalse();
+ assertThat(version("2020.0.0").isSameMajor(releaseTrainVersion("Aluminium-RELEASE"))).isFalse();
}
@Test
void calendarVersionIsNotSameMinorAsReleaseTrainVersion() {
- assertThat(version("2020.0.0").isSameMinorAndNewerThan(releaseTrainVersion("Aluminium-RELEASE"))).isFalse();
+ assertThat(version("2020.0.0").isSameMinor(releaseTrainVersion("Aluminium-RELEASE"))).isFalse();
}
private ReleaseTrainDependencyVersion releaseTrainVersion(String version) {
diff --git a/buildSrc/src/test/java/org/springframework/boot/build/bom/bomr/version/DependencyVersionTests.java b/buildSrc/src/test/java/org/springframework/boot/build/bom/bomr/version/DependencyVersionTests.java
index 64e5f7b2a328..06dc3e6fb3d2 100644
--- a/buildSrc/src/test/java/org/springframework/boot/build/bom/bomr/version/DependencyVersionTests.java
+++ b/buildSrc/src/test/java/org/springframework/boot/build/bom/bomr/version/DependencyVersionTests.java
@@ -68,9 +68,4 @@ void parseWhenCalendarVersionWithModifierShouldReturnArtifactVersionDependencyVe
assertThat(DependencyVersion.parse("2020.0.0-M1")).isInstanceOf(CalendarVersionDependencyVersion.class);
}
- @Test
- void calendarVersionShouldBeNewerThanAReleaseCalendarVersion() {
-
- }
-
}
diff --git a/buildSrc/src/test/java/org/springframework/boot/build/bom/bomr/version/DependencyVersionUpgradeTests.java b/buildSrc/src/test/java/org/springframework/boot/build/bom/bomr/version/DependencyVersionUpgradeTests.java
new file mode 100644
index 000000000000..404ae42fe89f
--- /dev/null
+++ b/buildSrc/src/test/java/org/springframework/boot/build/bom/bomr/version/DependencyVersionUpgradeTests.java
@@ -0,0 +1,304 @@
+/*
+ * Copyright 2023-2023 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.boot.build.bom.bomr.version;
+
+import java.lang.annotation.Annotation;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Repeatable;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.reflect.Method;
+import java.util.function.Function;
+import java.util.stream.Stream;
+
+import org.junit.jupiter.api.extension.ExtensionContext;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.ArgumentsProvider;
+import org.junit.jupiter.params.provider.ArgumentsSource;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Tests for {@link DependencyVersion#isUpgrade} of {@link DependencyVersion}
+ * implementations.
+ *
+ * @author Andy Wilkinson
+ */
+class DependencyVersionUpgradeTests {
+
+ @ParameterizedTest
+ @ArtifactVersion(current = "1.2.3", candidate = "1.2.3")
+ @ArtifactVersion(current = "1.2.3.RELEASE", candidate = "1.2.3.RELEASE")
+ @CalendarVersion(current = "2023.0.0", candidate = "2023.0.0")
+ @ReleaseTrain(current = "Kay-RELEASE", candidate = "Kay-RELEASE")
+ void isUpgradeWhenSameVersionShouldReturnFalse(DependencyVersion current, DependencyVersion candidate) {
+ assertThat(current.isUpgrade(candidate, false)).isFalse();
+ }
+
+ @ParameterizedTest
+ @ArtifactVersion(current = "1.2.3-SNAPSHOT", candidate = "1.2.3-SNAPSHOT")
+ @ArtifactVersion(current = "1.2.3.BUILD-SNAPSHOT", candidate = "1.2.3.BUILD-SNAPSHOT")
+ @CalendarVersion(current = "2023.0.0-SNAPSHOT", candidate = "2023.0.0-SNAPSHOT")
+ @ReleaseTrain(current = "Kay-BUILD-SNAPSHOT", candidate = "Kay-BUILD-SNAPSHOT")
+ void isUpgradeWhenSameSnapshotVersionShouldReturnFalse(DependencyVersion current, DependencyVersion candidate) {
+ assertThat(current.isUpgrade(candidate, false)).isFalse();
+ }
+
+ @ParameterizedTest
+ @ArtifactVersion(current = "1.2.3-SNAPSHOT", candidate = "1.2.3-SNAPSHOT")
+ @ArtifactVersion(current = "1.2.3.BUILD-SNAPSHOT", candidate = "1.2.3.BUILD-SNAPSHOT")
+ @CalendarVersion(current = "2023.0.0-SNAPSHOT", candidate = "2023.0.0-SNAPSHOT")
+ @ReleaseTrain(current = "Kay-BUILD-SNAPSHOT", candidate = "Kay-BUILD-SNAPSHOT")
+ void isUpgradeWhenSameSnapshotVersionAndMovingToSnapshotsShouldReturnFalse(DependencyVersion current,
+ DependencyVersion candidate) {
+ assertThat(current.isUpgrade(candidate, true)).isFalse();
+ }
+
+ @ParameterizedTest
+ @ArtifactVersion(current = "1.2.3", candidate = "1.2.4")
+ @ArtifactVersion(current = "1.2.3.RELEASE", candidate = "1.2.4.RELEASE")
+ @CalendarVersion(current = "2023.0.0", candidate = "2023.0.1")
+ @ReleaseTrain(current = "Kay-RELEASE", candidate = "Kay-SR1")
+ void isUpgradeWhenLaterPatchReleaseShouldReturnTrue(DependencyVersion current, DependencyVersion candidate) {
+ assertThat(current.isUpgrade(candidate, false)).isTrue();
+ }
+
+ @ParameterizedTest
+ @ArtifactVersion(current = "1.2.3", candidate = "1.2.4-SNAPSHOT")
+ @ArtifactVersion(current = "1.2.3.RELEASE", candidate = "1.2.4.BUILD-SNAPSHOT")
+ @CalendarVersion(current = "2023.0.0", candidate = "2023.0.1-SNAPSHOT")
+ void isUpgradeWhenSnapshotOfLaterPatchReleaseShouldReturnTrue(DependencyVersion current,
+ DependencyVersion candidate) {
+ assertThat(current.isUpgrade(candidate, false)).isTrue();
+ }
+
+ @ParameterizedTest
+ @ArtifactVersion(current = "1.2.3", candidate = "1.2.4-SNAPSHOT")
+ @ArtifactVersion(current = "1.2.3.RELEASE", candidate = "1.2.4.BUILD-SNAPSHOT")
+ @CalendarVersion(current = "2023.0.0", candidate = "2023.0.1-SNAPSHOT")
+ @ReleaseTrain(current = "Kay-RELEASE", candidate = "Kay-BUILD-SNAPSHOT")
+ void isUpgradeWhenSnapshotOfLaterPatchReleaseAndMovingToSnapshotsShouldReturnTrue(DependencyVersion current,
+ DependencyVersion candidate) {
+ assertThat(current.isUpgrade(candidate, true)).isTrue();
+ }
+
+ @ParameterizedTest
+ @ArtifactVersion(current = "1.2.3", candidate = "1.2.3-SNAPSHOT")
+ @ArtifactVersion(current = "1.2.3.RELEASE", candidate = "1.2.3.BUILD-SNAPSHOT")
+ @CalendarVersion(current = "2023.0.0", candidate = "2023.0.0-SNAPSHOT")
+ @ReleaseTrain(current = "Kay-RELEASE", candidate = "Kay-BUILD-SNAPSHOT")
+ void isUpgradeWhenSnapshotOfSameVersionShouldReturnFalse(DependencyVersion current, DependencyVersion candidate) {
+ assertThat(current.isUpgrade(candidate, false)).isFalse();
+ }
+
+ @ParameterizedTest
+ @ArtifactVersion(current = "1.2.3-SNAPSHOT", candidate = "1.2.3-M2")
+ @ArtifactVersion(current = "1.2.3.BUILD-SNAPSHOT", candidate = "1.2.3.M2")
+ @CalendarVersion(current = "2023.0.0-SNAPSHOT", candidate = "2023.0.0-M2")
+ @ReleaseTrain(current = "Kay-BUILD-SNAPSHOT", candidate = "Kay-M2")
+ void isUpgradeWhenSnapshotToMilestoneShouldReturnTrue(DependencyVersion current, DependencyVersion candidate) {
+ assertThat(current.isUpgrade(candidate, false)).isTrue();
+ }
+
+ @ParameterizedTest
+ @ArtifactVersion(current = "1.2.3-SNAPSHOT", candidate = "1.2.3-RC1")
+ @ArtifactVersion(current = "1.2.3.BUILD-SNAPSHOT", candidate = "1.2.3.RC1")
+ @CalendarVersion(current = "2023.0.0-SNAPSHOT", candidate = "2023.0.0-RC1")
+ @ReleaseTrain(current = "Kay-BUILD-SNAPSHOT", candidate = "Kay-RC1")
+ void isUpgradeWhenSnapshotToReleaseCandidateShouldReturnTrue(DependencyVersion current,
+ DependencyVersion candidate) {
+ assertThat(current.isUpgrade(candidate, false)).isTrue();
+ }
+
+ @ParameterizedTest
+ @ArtifactVersion(current = "1.2.3-SNAPSHOT", candidate = "1.2.3")
+ @ArtifactVersion(current = "1.2.3.BUILD-SNAPSHOT", candidate = "1.2.3.RELEASE")
+ @CalendarVersion(current = "2023.0.0-SNAPSHOT", candidate = "2023.0.0")
+ @ReleaseTrain(current = "Kay-BUILD-SNAPSHOT", candidate = "Kay-RELEASE")
+ void isUpgradeWhenSnapshotToReleaseShouldReturnTrue(DependencyVersion current, DependencyVersion candidate) {
+ assertThat(current.isUpgrade(candidate, false)).isTrue();
+ }
+
+ @ParameterizedTest
+ @ArtifactVersion(current = "1.2.3-M1", candidate = "1.2.3-SNAPSHOT")
+ @ArtifactVersion(current = "1.2.3.M1", candidate = "1.2.3.BUILD-SNAPSHOT")
+ @CalendarVersion(current = "2023.0.0-M1", candidate = "2023.0.0-SNAPSHOT")
+ @ReleaseTrain(current = "Kay-M1", candidate = "Kay-BUILD-SNAPSHOT")
+ void isUpgradeWhenMilestoneToSnapshotShouldReturnFalse(DependencyVersion current, DependencyVersion candidate) {
+ assertThat(current.isUpgrade(candidate, false)).isFalse();
+ }
+
+ @ParameterizedTest
+ @ArtifactVersion(current = "1.2.3-RC1", candidate = "1.2.3-SNAPSHOT")
+ @ArtifactVersion(current = "1.2.3.RC1", candidate = "1.2.3.BUILD-SNAPSHOT")
+ @CalendarVersion(current = "2023.0.0-RC1", candidate = "2023.0.0-SNAPSHOT")
+ @ReleaseTrain(current = "Kay-RC1", candidate = "Kay-BUILD-SNAPSHOT")
+ void isUpgradeWhenReleaseCandidateToSnapshotShouldReturnFalse(DependencyVersion current,
+ DependencyVersion candidate) {
+ assertThat(current.isUpgrade(candidate, false)).isFalse();
+ }
+
+ @ParameterizedTest
+ @ArtifactVersion(current = "1.2.3", candidate = "1.2.3-SNAPSHOT")
+ @ArtifactVersion(current = "1.2.3.RELEASE", candidate = "1.2.3.BUILD-SNAPSHOT")
+ @CalendarVersion(current = "2023.0.0", candidate = "2023.0.0-SNAPSHOT")
+ @ReleaseTrain(current = "Kay-RELEASE", candidate = "Kay-BUILD-SNAPSHOT")
+ void isUpgradeWhenReleaseToSnapshotShouldReturnFalse(DependencyVersion current, DependencyVersion candidate) {
+ assertThat(current.isUpgrade(candidate, false)).isFalse();
+ }
+
+ @ParameterizedTest
+ @ArtifactVersion(current = "1.2.3-M1", candidate = "1.2.3-SNAPSHOT")
+ @ArtifactVersion(current = "1.2.3.M1", candidate = "1.2.3.BUILD-SNAPSHOT")
+ @CalendarVersion(current = "2023.0.0-M1", candidate = "2023.0.0-SNAPSHOT")
+ @ReleaseTrain(current = "Kay-M1", candidate = "Kay-BUILD-SNAPSHOT")
+ void isUpgradeWhenMilestoneToSnapshotAndMovingToSnapshotsShouldReturnTrue(DependencyVersion current,
+ DependencyVersion candidate) {
+ assertThat(current.isUpgrade(candidate, true)).isTrue();
+ }
+
+ @ParameterizedTest
+ @ArtifactVersion(current = "1.2.3-RC1", candidate = "1.2.3-SNAPSHOT")
+ @ArtifactVersion(current = "1.2.3.RC1", candidate = "1.2.3.BUILD-SNAPSHOT")
+ @CalendarVersion(current = "2023.0.0-RC1", candidate = "2023.0.0-SNAPSHOT")
+ @ReleaseTrain(current = "Kay-RC1", candidate = "Kay-BUILD-SNAPSHOT")
+ void isUpgradeWhenReleaseCandidateToSnapshotAndMovingToSnapshotsShouldReturnTrue(DependencyVersion current,
+ DependencyVersion candidate) {
+ assertThat(current.isUpgrade(candidate, true)).isTrue();
+ }
+
+ @ParameterizedTest
+ @ArtifactVersion(current = "1.2.3", candidate = "1.2.3-SNAPSHOT")
+ @ArtifactVersion(current = "1.2.3.RELEASE", candidate = "1.2.3.BUILD-SNAPSHOT")
+ @CalendarVersion(current = "2023.0.0", candidate = "2023.0.0-SNAPSHOT")
+ void isUpgradeWhenReleaseToSnapshotAndMovingToSnapshotsShouldReturnFalse(DependencyVersion current,
+ DependencyVersion candidate) {
+ assertThat(current.isUpgrade(candidate, true)).isFalse();
+ }
+
+ @ParameterizedTest
+ @ReleaseTrain(current = "Kay-RELEASE", candidate = "Kay-BUILD-SNAPSHOT")
+ void isUpgradeWhenReleaseTrainToSnapshotAndMovingToSnapshotsShouldReturnTrue(DependencyVersion current,
+ DependencyVersion candidate) {
+ assertThat(current.isUpgrade(candidate, true)).isTrue();
+ }
+
+ @Repeatable(ArtifactVersions.class)
+ @Target(ElementType.METHOD)
+ @Retention(RetentionPolicy.RUNTIME)
+ @ArgumentsSource(InputProvider.class)
+ @interface ArtifactVersion {
+
+ String current();
+
+ String candidate();
+
+ }
+
+ @Target(ElementType.METHOD)
+ @Retention(RetentionPolicy.RUNTIME)
+ @interface ArtifactVersions {
+
+ ArtifactVersion[] value();
+
+ }
+
+ @Target(ElementType.METHOD)
+ @Retention(RetentionPolicy.RUNTIME)
+ @ArgumentsSource(InputProvider.class)
+ @interface ReleaseTrain {
+
+ String current();
+
+ String candidate();
+
+ }
+
+ @Target(ElementType.METHOD)
+ @Retention(RetentionPolicy.RUNTIME)
+ @ArgumentsSource(InputProvider.class)
+ @interface CalendarVersion {
+
+ String current();
+
+ String candidate();
+
+ }
+
+ static class InputProvider implements ArgumentsProvider {
+
+ @Override
+ public Stream extends Arguments> provideArguments(ExtensionContext context) {
+ Method testMethod = context.getRequiredTestMethod();
+ Stream artifactVersions = artifactVersions(testMethod)
+ .map((artifactVersion) -> Arguments.of(VersionType.ARTIFACT_VERSION.parse(artifactVersion.current()),
+ VersionType.ARTIFACT_VERSION.parse(artifactVersion.candidate())));
+ Stream releaseTrains = releaseTrains(testMethod)
+ .map((releaseTrain) -> Arguments.of(VersionType.RELEASE_TRAIN.parse(releaseTrain.current()),
+ VersionType.RELEASE_TRAIN.parse(releaseTrain.candidate())));
+ Stream calendarVersions = calendarVersions(testMethod)
+ .map((calendarVersion) -> Arguments.of(VersionType.CALENDAR_VERSION.parse(calendarVersion.current()),
+ VersionType.CALENDAR_VERSION.parse(calendarVersion.candidate())));
+ return Stream.concat(Stream.concat(artifactVersions, releaseTrains), calendarVersions);
+ }
+
+ private Stream artifactVersions(Method testMethod) {
+ ArtifactVersions artifactVersions = testMethod.getAnnotation(ArtifactVersions.class);
+ if (artifactVersions != null) {
+ return Stream.of(artifactVersions.value());
+ }
+ return versions(testMethod, ArtifactVersion.class);
+ }
+
+ private Stream releaseTrains(Method testMethod) {
+ return versions(testMethod, ReleaseTrain.class);
+ }
+
+ private Stream calendarVersions(Method testMethod) {
+ return versions(testMethod, CalendarVersion.class);
+ }
+
+ private Stream versions(Method testMethod, Class type) {
+ T annotation = testMethod.getAnnotation(type);
+ return (annotation != null) ? Stream.of(annotation) : Stream.empty();
+ }
+
+ }
+
+ enum VersionType {
+
+ ARTIFACT_VERSION(ArtifactVersionDependencyVersion::parse),
+
+ CALENDAR_VERSION(CalendarVersionDependencyVersion::parse),
+
+ RELEASE_TRAIN(ReleaseTrainDependencyVersion::parse);
+
+ private final Function parser;
+
+ VersionType(Function parser) {
+ this.parser = parser;
+ }
+
+ DependencyVersion parse(String version) {
+ return this.parser.apply(version);
+ }
+
+ }
+
+}
diff --git a/buildSrc/src/test/java/org/springframework/boot/build/bom/bomr/version/MultipleComponentsDependencyVersionTests.java b/buildSrc/src/test/java/org/springframework/boot/build/bom/bomr/version/MultipleComponentsDependencyVersionTests.java
index 8602a5982a39..ad8b814cd487 100644
--- a/buildSrc/src/test/java/org/springframework/boot/build/bom/bomr/version/MultipleComponentsDependencyVersionTests.java
+++ b/buildSrc/src/test/java/org/springframework/boot/build/bom/bomr/version/MultipleComponentsDependencyVersionTests.java
@@ -29,43 +29,23 @@
class MultipleComponentsDependencyVersionTests {
@Test
- void isNewerThanOnVersionWithNumericQualifierWhenInputHasNoQualifierShouldReturnTrue() {
- assertThat(version("2.9.9.20190806").isNewerThan(DependencyVersion.parse("2.9.9"))).isTrue();
+ void isSameMajorOfFiveComponentVersionWithSameMajorShouldReturnTrue() {
+ assertThat(version("21.4.0.0.1").isSameMajor(version("21.1.0.0"))).isTrue();
}
@Test
- void isNewerThanOnVersionWithNumericQualifierWhenInputHasOlderQualifierShouldReturnTrue() {
- assertThat(version("2.9.9.20190806").isNewerThan(version("2.9.9.20190805"))).isTrue();
+ void isSameMajorOfFiveComponentVersionWithDifferentMajorShouldReturnFalse() {
+ assertThat(version("21.4.0.0.1").isSameMajor(version("22.1.0.0"))).isFalse();
}
@Test
- void isNewerThanOnVersionWithNumericQualifierWhenInputHasNewerQualifierShouldReturnFalse() {
- assertThat(version("2.9.9.20190806").isNewerThan(version("2.9.9.20190807"))).isFalse();
+ void isSameMinorOfFiveComponentVersionWithSameMinorShouldReturnTrue() {
+ assertThat(version("21.4.0.0.1").isSameMinor(version("21.4.0.0"))).isTrue();
}
@Test
- void isNewerThanOnVersionWithNumericQualifierWhenInputHasSameQualifierShouldReturnFalse() {
- assertThat(version("2.9.9.20190806").isNewerThan(version("2.9.9.20190806"))).isFalse();
- }
-
- @Test
- void isNewerThanWorksWith5Components() {
- assertThat(version("21.4.0.0.1").isNewerThan(version("21.1.0.0"))).isTrue();
- }
-
- @Test
- void isNewerThanWorksWith5ComponentsAndLastComponentIsConsidered() {
- assertThat(version("21.1.0.0.1").isNewerThan(version("21.1.0.0"))).isTrue();
- }
-
- @Test
- void isSameMajorAndNewerThanWorksWith5Components() {
- assertThat(version("21.4.0.0.1").isSameMajorAndNewerThan(version("21.1.0.0"))).isTrue();
- }
-
- @Test
- void isSameMinorAndNewerThanWorksWith5Components() {
- assertThat(version("21.4.0.0.1").isSameMinorAndNewerThan(version("21.1.0.0"))).isFalse();
+ void isSameMinorOfFiveComponentVersionWithDifferentMinorShouldReturnFalse() {
+ assertThat(version("21.4.0.0.1").isSameMinor(version("21.5.0.0"))).isFalse();
}
private MultipleComponentsDependencyVersion version(String version) {
diff --git a/buildSrc/src/test/java/org/springframework/boot/build/bom/bomr/version/ReleaseTrainDependencyVersionTests.java b/buildSrc/src/test/java/org/springframework/boot/build/bom/bomr/version/ReleaseTrainDependencyVersionTests.java
index f7cdde0fcd5c..d9c4541c9157 100644
--- a/buildSrc/src/test/java/org/springframework/boot/build/bom/bomr/version/ReleaseTrainDependencyVersionTests.java
+++ b/buildSrc/src/test/java/org/springframework/boot/build/bom/bomr/version/ReleaseTrainDependencyVersionTests.java
@@ -38,81 +38,73 @@ void parsingOfAReleaseTrainVersionReturnsVersion() {
}
@Test
- void isNewerThanWhenReleaseTrainIsNewerShouldReturnTrue() {
- assertThat(version("Lovelace-RELEASE").isNewerThan(version("Kay-SR5"))).isTrue();
+ void isSameMajorWhenReleaseTrainIsDifferentShouldReturnFalse() {
+ assertThat(version("Lovelace-RELEASE").isSameMajor(version("Kay-SR5"))).isFalse();
}
@Test
- void isNewerThanWhenVersionIsNewerShouldReturnTrue() {
- assertThat(version("Kay-SR10").isNewerThan(version("Kay-SR5"))).isTrue();
+ void isSameMajorWhenReleaseTrainIsTheSameShouldReturnTrue() {
+ assertThat(version("Lovelace-RELEASE").isSameMajor(version("Lovelace-SR5"))).isTrue();
}
@Test
- void isNewerThanWhenVersionIsOlderShouldReturnFalse() {
- assertThat(version("Kay-RELEASE").isNewerThan(version("Kay-SR5"))).isFalse();
+ void isSameMinorWhenReleaseTrainIsDifferentShouldReturnFalse() {
+ assertThat(version("Lovelace-RELEASE").isSameMajor(version("Kay-SR5"))).isFalse();
}
@Test
- void isNewerThanWhenReleaseTrainIsOlderShouldReturnFalse() {
- assertThat(version("Ingalls-RELEASE").isNewerThan(version("Kay-SR5"))).isFalse();
+ void isSameMinorWhenReleaseTrainIsTheSameShouldReturnTrue() {
+ assertThat(version("Lovelace-RELEASE").isSameMajor(version("Lovelace-SR5"))).isTrue();
}
@Test
- void isSameMajorAndNewerWhenWhenReleaseTrainIsNewerShouldReturnTrue() {
- assertThat(version("Lovelace-RELEASE").isSameMajorAndNewerThan(version("Kay-SR5"))).isTrue();
- }
-
- @Test
- void isSameMajorAndNewerThanWhenReleaseTrainIsOlderShouldReturnFalse() {
- assertThat(version("Ingalls-RELEASE").isSameMajorAndNewerThan(version("Kay-SR5"))).isFalse();
+ void releaseTrainVersionIsNotSameMajorAsCalendarTrainVersion() {
+ assertThat(version("Kay-SR6").isSameMajor(calendarVersion("2020.0.0"))).isFalse();
}
@Test
- void isSameMajorAndNewerThanWhenVersionIsNewerShouldReturnTrue() {
- assertThat(version("Kay-SR6").isSameMajorAndNewerThan(version("Kay-SR5"))).isTrue();
+ void releaseTrainVersionIsNotSameMinorAsCalendarVersion() {
+ assertThat(version("Kay-SR6").isSameMinor(calendarVersion("2020.0.0"))).isFalse();
}
@Test
- void isSameMinorAndNewerThanWhenReleaseTrainIsNewerShouldReturnFalse() {
- assertThat(version("Lovelace-RELEASE").isSameMinorAndNewerThan(version("Kay-SR5"))).isFalse();
+ void isSnapshotForWhenSnapshotForServiceReleaseShouldReturnTrue() {
+ assertThat(version("Kay-BUILD-SNAPSHOT").isSnapshotFor(version("Kay-SR2"))).isTrue();
}
@Test
- void isSameMinorAndNewerThanWhenReleaseTrainIsTheSameAndVersionIsNewerShouldReturnTrue() {
- assertThat(version("Kay-SR6").isSameMinorAndNewerThan(version("Kay-SR5"))).isTrue();
+ void isSnapshotForWhenSnapshotForReleaseShouldReturnTrue() {
+ assertThat(version("Kay-BUILD-SNAPSHOT").isSnapshotFor(version("Kay-RELEASE"))).isTrue();
}
@Test
- void isSameMinorAndNewerThanWhenReleaseTrainAndVersionAreTheSameShouldReturnFalse() {
- assertThat(version("Kay-SR6").isSameMinorAndNewerThan(version("Kay-SR6"))).isFalse();
+ void isSnapshotForWhenSnapshotForReleaseCandidateShouldReturnTrue() {
+ assertThat(version("Kay-BUILD-SNAPSHOT").isSnapshotFor(version("Kay-RC1"))).isTrue();
}
@Test
- void isSameMinorAndNewerThanWhenReleaseTrainIsTheSameAndVersionIsOlderShouldReturnFalse() {
- assertThat(version("Kay-SR6").isSameMinorAndNewerThan(version("Kay-SR7"))).isFalse();
+ void isSnapshotForWhenSnapshotForMilestoneShouldReturnTrue() {
+ assertThat(version("Kay-BUILD-SNAPSHOT").isSnapshotFor(version("Kay-M2"))).isTrue();
}
@Test
- void releaseTrainVersionIsNotNewerThanCalendarVersion() {
- assertThat(version("Kay-SR6").isNewerThan(calendarVersion("2020.0.0"))).isFalse();
+ void isSnapshotForWhenSnapshotForDifferentReleaseShouldReturnFalse() {
+ assertThat(version("Kay-BUILD-SNAPSHOT").isSnapshotFor(version("Lovelace-RELEASE"))).isFalse();
}
@Test
- void releaseTrainVersionIsNotSameMajorAsCalendarTrainVersion() {
- assertThat(version("Kay-SR6").isSameMajorAndNewerThan(calendarVersion("2020.0.0"))).isFalse();
+ void isSnapshotForWhenSnapshotForDifferentReleaseCandidateShouldReturnTrue() {
+ assertThat(version("Kay-BUILD-SNAPSHOT").isSnapshotFor(version("Lovelace-RC2"))).isFalse();
}
@Test
- void releaseTrainVersionIsNotSameMinorAsCalendarVersion() {
- assertThat(version("Kay-SR6").isSameMinorAndNewerThan(calendarVersion("2020.0.0"))).isFalse();
+ void isSnapshotForWhenSnapshotForDifferentMilestoneShouldReturnTrue() {
+ assertThat(version("Kay-BUILD-SNAPSHOT").isSnapshotFor(version("Lovelace-M1"))).isFalse();
}
@Test
- void whenComparedWithADifferentDependencyVersionTypeThenTheResultsAreNonZero() {
- DependencyVersion dysprosium = ReleaseTrainDependencyVersion.parse("Dysprosium-SR16");
- DependencyVersion twentyTwenty = ArtifactVersionDependencyVersion.parse("2020.0.0");
- assertThat(dysprosium).isLessThan(twentyTwenty);
- assertThat(twentyTwenty).isGreaterThan(dysprosium);
+ void isSnapshotForWhenNotSnapshotShouldReturnFalse() {
+ assertThat(version("Kay-M1").isSnapshotFor(version("Kay-RELEASE"))).isFalse();
}
private static ReleaseTrainDependencyVersion version(String input) {
diff --git a/buildSrc/src/test/java/org/springframework/boot/build/mavenplugin/PluginXmlParserTests.java b/buildSrc/src/test/java/org/springframework/boot/build/mavenplugin/PluginXmlParserTests.java
index 14755846dffe..fba1d1c5f8a9 100644
--- a/buildSrc/src/test/java/org/springframework/boot/build/mavenplugin/PluginXmlParserTests.java
+++ b/buildSrc/src/test/java/org/springframework/boot/build/mavenplugin/PluginXmlParserTests.java
@@ -24,7 +24,7 @@
import org.springframework.boot.build.mavenplugin.PluginXmlParser.Plugin;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
/**
* Tests for {@link PluginXmlParser}.
@@ -49,9 +49,9 @@ void parseExistingDescriptorReturnPluginDescriptor() {
@Test
void parseNonExistingFileThrowException() {
- assertThatThrownBy(() -> this.parser.parse(new File("src/test/resources/nonexistent.xml")))
- .isInstanceOf(RuntimeException.class)
- .hasCauseInstanceOf(FileNotFoundException.class);
+ assertThatExceptionOfType(RuntimeException.class)
+ .isThrownBy(() -> this.parser.parse(new File("src/test/resources/nonexistent.xml")))
+ .withCauseInstanceOf(FileNotFoundException.class);
}
}
diff --git a/buildSrc/src/test/resources/releases.json b/buildSrc/src/test/resources/releases.json
new file mode 100644
index 000000000000..3c5be29801d4
--- /dev/null
+++ b/buildSrc/src/test/resources/releases.json
@@ -0,0 +1,272 @@
+[
+ {
+ "allDay": true,
+ "start": "2023-09-22",
+ "title": "Spring Modulith 1.0.1",
+ "url": "https://github.com/spring-projects/spring-modulith/milestone/15"
+ },
+ {
+ "allDay": true,
+ "start": "2023-09-22",
+ "title": "Spring Modulith 1.1 M1",
+ "url": "https://github.com/spring-projects/spring-modulith/milestone/16"
+ },
+ {
+ "allDay": true,
+ "start": "2023-09-12",
+ "title": "Reactor 2020.0.36",
+ "url": "https://github.com/reactor/reactor/milestone/51"
+ },
+ {
+ "allDay": true,
+ "start": "2023-09-12",
+ "title": "Reactor 2022.0.11",
+ "url": "https://github.com/reactor/reactor/milestone/52"
+ },
+ {
+ "allDay": true,
+ "start": "2023-09-12",
+ "title": "Reactor 2023.0.0-M3",
+ "url": "https://github.com/reactor/reactor/milestone/53"
+ },
+ {
+ "allDay": true,
+ "start": "2023-09-12",
+ "title": "Reactor Core 3.4.33",
+ "url": "https://github.com/reactor/reactor-core/milestone/158"
+ },
+ {
+ "allDay": true,
+ "start": "2023-09-12",
+ "title": "Reactor Core 3.5.10",
+ "url": "https://github.com/reactor/reactor-core/milestone/159"
+ },
+ {
+ "allDay": true,
+ "start": "2023-09-12",
+ "title": "Reactor Core 3.6.0-M3",
+ "url": "https://github.com/reactor/reactor-core/milestone/160"
+ },
+ {
+ "allDay": true,
+ "start": "2023-09-13",
+ "title": "Sts4 4.20.0.RELEASE",
+ "url": "https://github.com/spring-projects/sts4/milestone/66"
+ },
+ {
+ "allDay": true,
+ "start": "2023-09-20",
+ "title": "Spring Batch 5.1.0-M3",
+ "url": "https://github.com/spring-projects/spring-batch/milestone/150"
+ },
+ {
+ "allDay": true,
+ "start": "2023-09-19",
+ "title": "Spring Integration 6.2.0-M3",
+ "url": "https://github.com/spring-projects/spring-integration/milestone/306"
+ },
+ {
+ "allDay": true,
+ "start": "2023-09-19",
+ "title": "Spring Integration 5.5.19",
+ "url": "https://github.com/spring-projects/spring-integration/milestone/309"
+ },
+ {
+ "allDay": true,
+ "start": "2023-09-19",
+ "title": "Spring Integration 6.1.3",
+ "url": "https://github.com/spring-projects/spring-integration/milestone/310"
+ },
+ {
+ "allDay": true,
+ "start": "2023-09-15",
+ "title": "Spring Data Release 2023.1.0-M3",
+ "url": "https://github.com/spring-projects/spring-data-release/milestone/30"
+ },
+ {
+ "allDay": true,
+ "start": "2023-09-15",
+ "title": "Spring Data Release 2021.2.16",
+ "url": "https://github.com/spring-projects/spring-data-release/milestone/39"
+ },
+ {
+ "allDay": true,
+ "start": "2023-09-15",
+ "title": "Spring Data Release 2022.0.10",
+ "url": "https://github.com/spring-projects/spring-data-release/milestone/40"
+ },
+ {
+ "allDay": true,
+ "start": "2023-09-15",
+ "title": "Spring Data Release 2023.0.4",
+ "url": "https://github.com/spring-projects/spring-data-release/milestone/41"
+ },
+ {
+ "allDay": true,
+ "start": "2023-09-19",
+ "title": "Spring Graphql 1.0.5",
+ "url": "https://github.com/spring-projects/spring-graphql/milestone/27"
+ },
+ {
+ "allDay": true,
+ "start": "2023-09-19",
+ "title": "Spring Graphql 1.1.6",
+ "url": "https://github.com/spring-projects/spring-graphql/milestone/33"
+ },
+ {
+ "allDay": true,
+ "start": "2023-09-19",
+ "title": "Spring Graphql 1.2.3",
+ "url": "https://github.com/spring-projects/spring-graphql/milestone/34"
+ },
+ {
+ "allDay": true,
+ "start": "2023-09-19",
+ "title": "Spring Authorization Server 1.2.0-M1",
+ "url": "https://github.com/spring-projects/spring-authorization-server/milestone/34"
+ },
+ {
+ "allDay": true,
+ "start": "2023-09-18",
+ "title": "Spring Kafka 3.1.0-M1",
+ "url": "https://github.com/spring-projects/spring-kafka/milestone/225"
+ },
+ {
+ "allDay": true,
+ "start": "2023-09-14",
+ "title": "Spring Cloud Dataflow 2.11.0",
+ "url": "https://github.com/spring-cloud/spring-cloud-dataflow/milestone/159"
+ },
+ {
+ "allDay": true,
+ "start": "2023-09-11",
+ "title": "Micrometer 1.9.15",
+ "url": "https://github.com/micrometer-metrics/micrometer/milestone/217"
+ },
+ {
+ "allDay": true,
+ "start": "2023-09-11",
+ "title": "Micrometer 1.10.11",
+ "url": "https://github.com/micrometer-metrics/micrometer/milestone/218"
+ },
+ {
+ "allDay": true,
+ "start": "2023-09-11",
+ "title": "Micrometer 1.11.4",
+ "url": "https://github.com/micrometer-metrics/micrometer/milestone/219"
+ },
+ {
+ "allDay": true,
+ "start": "2023-09-11",
+ "title": "Micrometer 1.12.0-M3",
+ "url": "https://github.com/micrometer-metrics/micrometer/milestone/220"
+ },
+ {
+ "allDay": true,
+ "start": "2023-09-11",
+ "title": "Tracing 1.0.10",
+ "url": "https://github.com/micrometer-metrics/tracing/milestone/33"
+ },
+ {
+ "allDay": true,
+ "start": "2023-09-11",
+ "title": "Tracing 1.1.5",
+ "url": "https://github.com/micrometer-metrics/tracing/milestone/34"
+ },
+ {
+ "allDay": true,
+ "start": "2023-09-26",
+ "title": "Spring Cloud Release 2023.0.0-M2",
+ "url": "https://github.com/spring-cloud/spring-cloud-release/milestone/134"
+ },
+ {
+ "allDay": true,
+ "start": "2023-09-11",
+ "title": "Context Propagation 1.0.6",
+ "url": "https://github.com/micrometer-metrics/context-propagation/milestone/19"
+ },
+ {
+ "allDay": true,
+ "start": "2023-09-14",
+ "title": "Spring Ldap 3.2.0-M3",
+ "url": "https://github.com/spring-projects/spring-ldap/milestone/63"
+ },
+ {
+ "allDay": true,
+ "start": "2023-09-21",
+ "title": "Spring Boot 3.2.0-M3",
+ "url": "https://github.com/spring-projects/spring-boot/milestone/306"
+ },
+ {
+ "allDay": true,
+ "start": "2023-09-21",
+ "title": "Spring Boot 2.7.16",
+ "url": "https://github.com/spring-projects/spring-boot/milestone/315"
+ },
+ {
+ "allDay": true,
+ "start": "2023-09-21",
+ "title": "Spring Boot 3.0.11",
+ "url": "https://github.com/spring-projects/spring-boot/milestone/316"
+ },
+ {
+ "allDay": true,
+ "start": "2023-09-21",
+ "title": "Spring Boot 3.1.4",
+ "url": "https://github.com/spring-projects/spring-boot/milestone/317"
+ },
+ {
+ "allDay": true,
+ "start": "2023-09-14",
+ "title": "Spring Cloud Deployer 2.9.0",
+ "url": "https://github.com/spring-cloud/spring-cloud-deployer/milestone/116"
+ },
+ {
+ "allDay": true,
+ "start": "2023-09-12",
+ "title": "Reactor Kafka 1.3.21",
+ "url": "https://github.com/reactor/reactor-kafka/milestone/38"
+ },
+ {
+ "allDay": true,
+ "start": "2023-09-18",
+ "title": "Spring Security 6.2.0-M3",
+ "url": "https://github.com/spring-projects/spring-security/milestone/308"
+ },
+ {
+ "allDay": true,
+ "start": "2023-09-22",
+ "title": "Stream Applications 4.0.0",
+ "url": "https://github.com/spring-cloud/stream-applications/milestone/7"
+ },
+ {
+ "allDay": true,
+ "start": "2023-09-12",
+ "title": "Reactor Netty 1.1.11",
+ "url": "https://github.com/reactor/reactor-netty/milestone/153"
+ },
+ {
+ "allDay": true,
+ "start": "2023-09-12",
+ "title": "Reactor Netty 1.0.36",
+ "url": "https://github.com/reactor/reactor-netty/milestone/154"
+ },
+ {
+ "allDay": true,
+ "start": "2023-09-14",
+ "title": "Spring Framework 6.0.12",
+ "url": "https://github.com/spring-projects/spring-framework/milestone/331"
+ },
+ {
+ "allDay": true,
+ "start": "2023-09-14",
+ "title": "Spring Framework 5.3.30",
+ "url": "https://github.com/spring-projects/spring-framework/milestone/332"
+ },
+ {
+ "allDay": true,
+ "start": "2023-09-14",
+ "title": "Spring Framework 6.1.0-RC1",
+ "url": "https://github.com/spring-projects/spring-framework/milestone/333"
+ }
+]
\ No newline at end of file
diff --git a/ci/README.adoc b/ci/README.adoc
index 4601e84e0b13..5ef82f3ab88d 100644
--- a/ci/README.adoc
+++ b/ci/README.adoc
@@ -11,7 +11,7 @@ The pipeline can be deployed using the following command:
[source]
----
-$ fly -t spring-boot set-pipeline -p spring-boot-3.1.x -c ci/pipeline.yml -l ci/parameters.yml
+$ fly -t spring-boot set-pipeline -p spring-boot-3.2.x -c ci/pipeline.yml -l ci/parameters.yml
----
NOTE: This assumes that you have credhub integration configured with the appropriate
diff --git a/ci/config/release-scripts.yml b/ci/config/release-scripts.yml
new file mode 100644
index 000000000000..207ae802c063
--- /dev/null
+++ b/ci/config/release-scripts.yml
@@ -0,0 +1,11 @@
+spring:
+ main:
+ banner-mode: off
+sonatype:
+ exclude:
+ - "build-info.json"
+ - "org/springframework/boot/spring-boot-docs/.*"
+sdkman:
+ artifact: "org.springframework.boot:spring-boot-cli:*:zip:bin"
+ broadcast-url: "https://github.com/spring-projects/spring-boot/releases/v%s"
+ candidate: "springboot"
diff --git a/ci/images/build-release-scripts.sh b/ci/images/build-release-scripts.sh
deleted file mode 100755
index 7ba7b4745710..000000000000
--- a/ci/images/build-release-scripts.sh
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/bin/bash
-set -ex
-
-pushd /release-scripts
- ./mvnw clean install
-popd
-cp /release-scripts/target/spring-boot-release-scripts.jar .
\ No newline at end of file
diff --git a/ci/images/ci-image-jdk20/Dockerfile b/ci/images/ci-image-jdk20/Dockerfile
deleted file mode 100644
index bf31873a2bc3..000000000000
--- a/ci/images/ci-image-jdk20/Dockerfile
+++ /dev/null
@@ -1,11 +0,0 @@
-FROM ubuntu:jammy-20230624
-
-ADD setup.sh /setup.sh
-ADD get-jdk-url.sh /get-jdk-url.sh
-ADD get-docker-url.sh /get-docker-url.sh
-ADD get-docker-compose-url.sh /get-docker-compose-url.sh
-RUN ./setup.sh java17 java20
-
-ENV JAVA_HOME /opt/openjdk
-ENV PATH $JAVA_HOME/bin:$PATH
-ADD docker-lib.sh /docker-lib.sh
diff --git a/ci/images/ci-image-jdk21/Dockerfile b/ci/images/ci-image-jdk21/Dockerfile
new file mode 100644
index 000000000000..a56960bf6dd6
--- /dev/null
+++ b/ci/images/ci-image-jdk21/Dockerfile
@@ -0,0 +1,14 @@
+FROM ubuntu:jammy-20231004
+
+ADD setup.sh /setup.sh
+ADD get-jdk-url.sh /get-jdk-url.sh
+ADD get-docker-url.sh /get-docker-url.sh
+ADD get-docker-compose-url.sh /get-docker-compose-url.sh
+RUN ./setup.sh java17 java21
+
+ENV LANG en_US.UTF-8
+ENV LANGUAGE en_US:en
+ENV LC_ALL en_US.UTF-8
+ENV JAVA_HOME /opt/openjdk
+ENV PATH $JAVA_HOME/bin:$PATH
+ADD docker-lib.sh /docker-lib.sh
diff --git a/ci/images/ci-image/Dockerfile b/ci/images/ci-image/Dockerfile
index 4028f53d971e..45b125643abc 100644
--- a/ci/images/ci-image/Dockerfile
+++ b/ci/images/ci-image/Dockerfile
@@ -1,4 +1,4 @@
-FROM ubuntu:jammy-20230624
+FROM ubuntu:jammy-20231004
ADD setup.sh /setup.sh
ADD get-jdk-url.sh /get-jdk-url.sh
@@ -6,10 +6,9 @@ ADD get-docker-url.sh /get-docker-url.sh
ADD get-docker-compose-url.sh /get-docker-compose-url.sh
RUN ./setup.sh java17
+ENV LANG en_US.UTF-8
+ENV LANGUAGE en_US:en
+ENV LC_ALL en_US.UTF-8
ENV JAVA_HOME /opt/openjdk
ENV PATH $JAVA_HOME/bin:$PATH
ADD docker-lib.sh /docker-lib.sh
-
-ADD build-release-scripts.sh /build-release-scripts.sh
-ADD releasescripts /release-scripts
-RUN ./build-release-scripts.sh
diff --git a/ci/images/get-docker-url.sh b/ci/images/get-docker-url.sh
index c6d980229afd..965d738b72cb 100755
--- a/ci/images/get-docker-url.sh
+++ b/ci/images/get-docker-url.sh
@@ -1,5 +1,5 @@
#!/bin/bash
set -e
-version="24.0.4"
+version="24.0.7"
echo "https://download.docker.com/linux/static/stable/x86_64/docker-$version.tgz";
diff --git a/ci/images/get-jdk-url.sh b/ci/images/get-jdk-url.sh
index ec2505e5b13d..db11e34f6094 100755
--- a/ci/images/get-jdk-url.sh
+++ b/ci/images/get-jdk-url.sh
@@ -3,10 +3,10 @@ set -e
case "$1" in
java17)
- echo "https://github.com/bell-sw/Liberica/releases/download/17.0.7+7/bellsoft-jdk17.0.7+7-linux-amd64.tar.gz"
+ echo "https://github.com/bell-sw/Liberica/releases/download/17.0.9+11/bellsoft-jdk17.0.9+11-linux-amd64.tar.gz"
;;
- java20)
- echo "https://github.com/bell-sw/Liberica/releases/download/20.0.1+10/bellsoft-jdk20.0.1+10-linux-amd64.tar.gz"
+ java21)
+ echo "https://github.com/bell-sw/Liberica/releases/download/21.0.1+12/bellsoft-jdk21.0.1+12-linux-amd64.tar.gz"
;;
*)
echo $"Unknown java version"
diff --git a/ci/images/releasescripts/.gitignore b/ci/images/releasescripts/.gitignore
deleted file mode 100644
index a2a3040aa86d..000000000000
--- a/ci/images/releasescripts/.gitignore
+++ /dev/null
@@ -1,31 +0,0 @@
-HELP.md
-target/
-!.mvn/wrapper/maven-wrapper.jar
-!**/src/main/**
-!**/src/test/**
-
-### STS ###
-.apt_generated
-.classpath
-.factorypath
-.project
-.settings
-.springBeans
-.sts4-cache
-
-### IntelliJ IDEA ###
-.idea
-*.iws
-*.iml
-*.ipr
-
-### NetBeans ###
-/nbproject/private/
-/nbbuild/
-/dist/
-/nbdist/
-/.nb-gradle/
-build/
-
-### VS Code ###
-.vscode/
diff --git a/ci/images/releasescripts/.mvn/wrapper/MavenWrapperDownloader.java b/ci/images/releasescripts/.mvn/wrapper/MavenWrapperDownloader.java
deleted file mode 100644
index da7c33969591..000000000000
--- a/ci/images/releasescripts/.mvn/wrapper/MavenWrapperDownloader.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements. See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership. The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License. You may obtain a copy of the License at
-
- https://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing,
-software distributed under the License is distributed on an
-"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, either express or implied. See the License for the
-specific language governing permissions and limitations
-under the License.
-*/
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.net.URL;
-import java.nio.channels.Channels;
-import java.nio.channels.ReadableByteChannel;
-import java.util.Properties;
-
-public class MavenWrapperDownloader {
-
- /**
- * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided.
- */
- private static final String DEFAULT_DOWNLOAD_URL =
- "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar";
-
- /**
- * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to
- * use instead of the default one.
- */
- private static final String MAVEN_WRAPPER_PROPERTIES_PATH =
- ".mvn/wrapper/maven-wrapper.properties";
-
- /**
- * Path where the maven-wrapper.jar will be saved to.
- */
- private static final String MAVEN_WRAPPER_JAR_PATH =
- ".mvn/wrapper/maven-wrapper.jar";
-
- /**
- * Name of the property which should be used to override the default download url for the wrapper.
- */
- private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl";
-
- public static void main(String args[]) {
- System.out.println("- Downloader started");
- File baseDirectory = new File(args[0]);
- System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath());
-
- // If the maven-wrapper.properties exists, read it and check if it contains a custom
- // wrapperUrl parameter.
- File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH);
- String url = DEFAULT_DOWNLOAD_URL;
- if (mavenWrapperPropertyFile.exists()) {
- FileInputStream mavenWrapperPropertyFileInputStream = null;
- try {
- mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile);
- Properties mavenWrapperProperties = new Properties();
- mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream);
- url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url);
- }
- catch (IOException e) {
- System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'");
- }
- finally {
- try {
- if (mavenWrapperPropertyFileInputStream != null) {
- mavenWrapperPropertyFileInputStream.close();
- }
- }
- catch (IOException e) {
- // Ignore ...
- }
- }
- }
- System.out.println("- Downloading from: : " + url);
-
- File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH);
- if (!outputFile.getParentFile().exists()) {
- if (!outputFile.getParentFile().mkdirs()) {
- System.out.println(
- "- ERROR creating output direcrory '" + outputFile.getParentFile().getAbsolutePath() + "'");
- }
- }
- System.out.println("- Downloading to: " + outputFile.getAbsolutePath());
- try {
- downloadFileFromURL(url, outputFile);
- System.out.println("Done");
- System.exit(0);
- }
- catch (Throwable e) {
- System.out.println("- Error downloading");
- e.printStackTrace();
- System.exit(1);
- }
- }
-
- private static void downloadFileFromURL(String urlString, File destination) throws Exception {
- URL website = new URL(urlString);
- ReadableByteChannel rbc;
- rbc = Channels.newChannel(website.openStream());
- FileOutputStream fos = new FileOutputStream(destination);
- fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
- fos.close();
- rbc.close();
- }
-
-}
diff --git a/ci/images/releasescripts/.mvn/wrapper/maven-wrapper.jar b/ci/images/releasescripts/.mvn/wrapper/maven-wrapper.jar
deleted file mode 100644
index 01e67997377a..000000000000
Binary files a/ci/images/releasescripts/.mvn/wrapper/maven-wrapper.jar and /dev/null differ
diff --git a/ci/images/releasescripts/.mvn/wrapper/maven-wrapper.properties b/ci/images/releasescripts/.mvn/wrapper/maven-wrapper.properties
deleted file mode 100644
index f5374227f968..000000000000
--- a/ci/images/releasescripts/.mvn/wrapper/maven-wrapper.properties
+++ /dev/null
@@ -1,17 +0,0 @@
-#
-# Copyright 2012-2019 the original author or authors.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# https://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.0/apache-maven-3.6.0-bin.zip
diff --git a/ci/images/releasescripts/mvnw b/ci/images/releasescripts/mvnw
deleted file mode 100755
index 8b9da3b8b600..000000000000
--- a/ci/images/releasescripts/mvnw
+++ /dev/null
@@ -1,286 +0,0 @@
-#!/bin/sh
-# ----------------------------------------------------------------------------
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# https://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-# ----------------------------------------------------------------------------
-
-# ----------------------------------------------------------------------------
-# Maven2 Start Up Batch script
-#
-# Required ENV vars:
-# ------------------
-# JAVA_HOME - location of a JDK home dir
-#
-# Optional ENV vars
-# -----------------
-# M2_HOME - location of maven2's installed home dir
-# MAVEN_OPTS - parameters passed to the Java VM when running Maven
-# e.g. to debug Maven itself, use
-# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
-# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
-# ----------------------------------------------------------------------------
-
-if [ -z "$MAVEN_SKIP_RC" ] ; then
-
- if [ -f /etc/mavenrc ] ; then
- . /etc/mavenrc
- fi
-
- if [ -f "$HOME/.mavenrc" ] ; then
- . "$HOME/.mavenrc"
- fi
-
-fi
-
-# OS specific support. $var _must_ be set to either true or false.
-cygwin=false;
-darwin=false;
-mingw=false
-case "`uname`" in
- CYGWIN*) cygwin=true ;;
- MINGW*) mingw=true;;
- Darwin*) darwin=true
- # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
- # See https://developer.apple.com/library/mac/qa/qa1170/_index.html
- if [ -z "$JAVA_HOME" ]; then
- if [ -x "/usr/libexec/java_home" ]; then
- export JAVA_HOME="`/usr/libexec/java_home`"
- else
- export JAVA_HOME="/Library/Java/Home"
- fi
- fi
- ;;
-esac
-
-if [ -z "$JAVA_HOME" ] ; then
- if [ -r /etc/gentoo-release ] ; then
- JAVA_HOME=`java-config --jre-home`
- fi
-fi
-
-if [ -z "$M2_HOME" ] ; then
- ## resolve links - $0 may be a link to maven's home
- PRG="$0"
-
- # need this for relative symlinks
- while [ -h "$PRG" ] ; do
- ls=`ls -ld "$PRG"`
- link=`expr "$ls" : '.*-> \(.*\)$'`
- if expr "$link" : '/.*' > /dev/null; then
- PRG="$link"
- else
- PRG="`dirname "$PRG"`/$link"
- fi
- done
-
- saveddir=`pwd`
-
- M2_HOME=`dirname "$PRG"`/..
-
- # make it fully qualified
- M2_HOME=`cd "$M2_HOME" && pwd`
-
- cd "$saveddir"
- # echo Using m2 at $M2_HOME
-fi
-
-# For Cygwin, ensure paths are in UNIX format before anything is touched
-if $cygwin ; then
- [ -n "$M2_HOME" ] &&
- M2_HOME=`cygpath --unix "$M2_HOME"`
- [ -n "$JAVA_HOME" ] &&
- JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
- [ -n "$CLASSPATH" ] &&
- CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
-fi
-
-# For Mingw, ensure paths are in UNIX format before anything is touched
-if $mingw ; then
- [ -n "$M2_HOME" ] &&
- M2_HOME="`(cd "$M2_HOME"; pwd)`"
- [ -n "$JAVA_HOME" ] &&
- JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
- # TODO classpath?
-fi
-
-if [ -z "$JAVA_HOME" ]; then
- javaExecutable="`which javac`"
- if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
- # readlink(1) is not available as standard on Solaris 10.
- readLink=`which readlink`
- if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
- if $darwin ; then
- javaHome="`dirname \"$javaExecutable\"`"
- javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
- else
- javaExecutable="`readlink -f \"$javaExecutable\"`"
- fi
- javaHome="`dirname \"$javaExecutable\"`"
- javaHome=`expr "$javaHome" : '\(.*\)/bin'`
- JAVA_HOME="$javaHome"
- export JAVA_HOME
- fi
- fi
-fi
-
-if [ -z "$JAVACMD" ] ; then
- if [ -n "$JAVA_HOME" ] ; then
- if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
- # IBM's JDK on AIX uses strange locations for the executables
- JAVACMD="$JAVA_HOME/jre/sh/java"
- else
- JAVACMD="$JAVA_HOME/bin/java"
- fi
- else
- JAVACMD="`which java`"
- fi
-fi
-
-if [ ! -x "$JAVACMD" ] ; then
- echo "Error: JAVA_HOME is not defined correctly." >&2
- echo " We cannot execute $JAVACMD" >&2
- exit 1
-fi
-
-if [ -z "$JAVA_HOME" ] ; then
- echo "Warning: JAVA_HOME environment variable is not set."
-fi
-
-CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
-
-# traverses directory structure from process work directory to filesystem root
-# first directory with .mvn subdirectory is considered project base directory
-find_maven_basedir() {
-
- if [ -z "$1" ]
- then
- echo "Path not specified to find_maven_basedir"
- return 1
- fi
-
- basedir="$1"
- wdir="$1"
- while [ "$wdir" != '/' ] ; do
- if [ -d "$wdir"/.mvn ] ; then
- basedir=$wdir
- break
- fi
- # workaround for JBEAP-8937 (on Solaris 10/Sparc)
- if [ -d "${wdir}" ]; then
- wdir=`cd "$wdir/.."; pwd`
- fi
- # end of workaround
- done
- echo "${basedir}"
-}
-
-# concatenates all lines of a file
-concat_lines() {
- if [ -f "$1" ]; then
- echo "$(tr -s '\n' ' ' < "$1")"
- fi
-}
-
-BASE_DIR=`find_maven_basedir "$(pwd)"`
-if [ -z "$BASE_DIR" ]; then
- exit 1;
-fi
-
-##########################################################################################
-# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
-# This allows using the maven wrapper in projects that prohibit checking in binary data.
-##########################################################################################
-if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
- if [ "$MVNW_VERBOSE" = true ]; then
- echo "Found .mvn/wrapper/maven-wrapper.jar"
- fi
-else
- if [ "$MVNW_VERBOSE" = true ]; then
- echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
- fi
- jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar"
- while IFS="=" read key value; do
- case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
- esac
- done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
- if [ "$MVNW_VERBOSE" = true ]; then
- echo "Downloading from: $jarUrl"
- fi
- wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
-
- if command -v wget > /dev/null; then
- if [ "$MVNW_VERBOSE" = true ]; then
- echo "Found wget ... using wget"
- fi
- wget "$jarUrl" -O "$wrapperJarPath"
- elif command -v curl > /dev/null; then
- if [ "$MVNW_VERBOSE" = true ]; then
- echo "Found curl ... using curl"
- fi
- curl -o "$wrapperJarPath" "$jarUrl"
- else
- if [ "$MVNW_VERBOSE" = true ]; then
- echo "Falling back to using Java to download"
- fi
- javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
- if [ -e "$javaClass" ]; then
- if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
- if [ "$MVNW_VERBOSE" = true ]; then
- echo " - Compiling MavenWrapperDownloader.java ..."
- fi
- # Compiling the Java class
- ("$JAVA_HOME/bin/javac" "$javaClass")
- fi
- if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
- # Running the downloader
- if [ "$MVNW_VERBOSE" = true ]; then
- echo " - Running MavenWrapperDownloader.java ..."
- fi
- ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
- fi
- fi
- fi
-fi
-##########################################################################################
-# End of extension
-##########################################################################################
-
-export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
-if [ "$MVNW_VERBOSE" = true ]; then
- echo $MAVEN_PROJECTBASEDIR
-fi
-MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
-
-# For Cygwin, switch paths to Windows format before running java
-if $cygwin; then
- [ -n "$M2_HOME" ] &&
- M2_HOME=`cygpath --path --windows "$M2_HOME"`
- [ -n "$JAVA_HOME" ] &&
- JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
- [ -n "$CLASSPATH" ] &&
- CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
- [ -n "$MAVEN_PROJECTBASEDIR" ] &&
- MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
-fi
-
-WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
-
-exec "$JAVACMD" \
- $MAVEN_OPTS \
- -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
- "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
- ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
diff --git a/ci/images/releasescripts/mvnw.cmd b/ci/images/releasescripts/mvnw.cmd
deleted file mode 100644
index fef5a8f7f988..000000000000
--- a/ci/images/releasescripts/mvnw.cmd
+++ /dev/null
@@ -1,161 +0,0 @@
-@REM ----------------------------------------------------------------------------
-@REM Licensed to the Apache Software Foundation (ASF) under one
-@REM or more contributor license agreements. See the NOTICE file
-@REM distributed with this work for additional information
-@REM regarding copyright ownership. The ASF licenses this file
-@REM to you under the Apache License, Version 2.0 (the
-@REM "License"); you may not use this file except in compliance
-@REM with the License. You may obtain a copy of the License at
-@REM
-@REM https://www.apache.org/licenses/LICENSE-2.0
-@REM
-@REM Unless required by applicable law or agreed to in writing,
-@REM software distributed under the License is distributed on an
-@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-@REM KIND, either express or implied. See the License for the
-@REM specific language governing permissions and limitations
-@REM under the License.
-@REM ----------------------------------------------------------------------------
-
-@REM ----------------------------------------------------------------------------
-@REM Maven2 Start Up Batch script
-@REM
-@REM Required ENV vars:
-@REM JAVA_HOME - location of a JDK home dir
-@REM
-@REM Optional ENV vars
-@REM M2_HOME - location of maven2's installed home dir
-@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
-@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
-@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
-@REM e.g. to debug Maven itself, use
-@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
-@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
-@REM ----------------------------------------------------------------------------
-
-@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
-@echo off
-@REM set title of command window
-title %0
-@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
-@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
-
-@REM set %HOME% to equivalent of $HOME
-if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
-
-@REM Execute a user defined script before this one
-if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
-@REM check for pre script, once with legacy .bat ending and once with .cmd ending
-if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
-if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
-:skipRcPre
-
-@setlocal
-
-set ERROR_CODE=0
-
-@REM To isolate internal variables from possible post scripts, we use another setlocal
-@setlocal
-
-@REM ==== START VALIDATION ====
-if not "%JAVA_HOME%" == "" goto OkJHome
-
-echo.
-echo Error: JAVA_HOME not found in your environment. >&2
-echo Please set the JAVA_HOME variable in your environment to match the >&2
-echo location of your Java installation. >&2
-echo.
-goto error
-
-:OkJHome
-if exist "%JAVA_HOME%\bin\java.exe" goto init
-
-echo.
-echo Error: JAVA_HOME is set to an invalid directory. >&2
-echo JAVA_HOME = "%JAVA_HOME%" >&2
-echo Please set the JAVA_HOME variable in your environment to match the >&2
-echo location of your Java installation. >&2
-echo.
-goto error
-
-@REM ==== END VALIDATION ====
-
-:init
-
-@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
-@REM Fallback to current working directory if not found.
-
-set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
-IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
-
-set EXEC_DIR=%CD%
-set WDIR=%EXEC_DIR%
-:findBaseDir
-IF EXIST "%WDIR%"\.mvn goto baseDirFound
-cd ..
-IF "%WDIR%"=="%CD%" goto baseDirNotFound
-set WDIR=%CD%
-goto findBaseDir
-
-:baseDirFound
-set MAVEN_PROJECTBASEDIR=%WDIR%
-cd "%EXEC_DIR%"
-goto endDetectBaseDir
-
-:baseDirNotFound
-set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
-cd "%EXEC_DIR%"
-
-:endDetectBaseDir
-
-IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
-
-@setlocal EnableExtensions EnableDelayedExpansion
-for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
-@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
-
-:endReadAdditionalConfig
-
-SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
-set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
-set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
-
-set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar"
-FOR /F "tokens=1,2 delims==" %%A IN (%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties) DO (
- IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
-)
-
-@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
-@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
-if exist %WRAPPER_JAR% (
- echo Found %WRAPPER_JAR%
-) else (
- echo Couldn't find %WRAPPER_JAR%, downloading it ...
- echo Downloading from: %DOWNLOAD_URL%
- powershell -Command "(New-Object Net.WebClient).DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"
- echo Finished downloading %WRAPPER_JAR%
-)
-@REM End of extension
-
-%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
-if ERRORLEVEL 1 goto error
-goto end
-
-:error
-set ERROR_CODE=1
-
-:end
-@endlocal & set ERROR_CODE=%ERROR_CODE%
-
-if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
-@REM check for post script, once with legacy .bat ending and once with .cmd ending
-if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
-if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
-:skipRcPost
-
-@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
-if "%MAVEN_BATCH_PAUSE%" == "on" pause
-
-if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
-
-exit /B %ERROR_CODE%
diff --git a/ci/images/releasescripts/pom.xml b/ci/images/releasescripts/pom.xml
deleted file mode 100644
index 48b4efa69b34..000000000000
--- a/ci/images/releasescripts/pom.xml
+++ /dev/null
@@ -1,92 +0,0 @@
-
-
- 4.0.0
-
- org.springframework.boot
- spring-boot-starter-parent
- 2.2.4.RELEASE
-
-
- io.spring.concourse.releasescripts
- release-scripts
- 0.0.1-SNAPSHOT
- releasescripts
- Utility that can be used when releasing Java projects
-
- 1.8
- 0.0.26
-
-
-
- org.bouncycastle
- bcpg-jdk18on
- 1.71
-
-
- org.springframework.boot
- spring-boot-starter
-
-
- org.springframework
- spring-web
-
-
- com.fasterxml.jackson.core
- jackson-databind
-
-
- com.fasterxml.jackson.datatype
- jackson-datatype-jdk8
-
-
- com.fasterxml.jackson.datatype
- jackson-datatype-jsr310
-
-
- com.fasterxml.jackson.module
- jackson-module-parameter-names
-
-
- org.awaitility
- awaitility
-
-
- org.springframework.boot
- spring-boot-starter-test
- test
-
-
- org.junit.vintage
- junit-vintage-engine
-
-
-
-
-
- spring-boot-release-scripts
-
-
- org.springframework.boot
- spring-boot-maven-plugin
-
-
- io.spring.javaformat
- spring-javaformat-maven-plugin
- ${spring-javaformat.version}
-
-
- validate
-
- ${disable.checks}
-
-
- validate
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/Application.java b/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/Application.java
deleted file mode 100644
index 9a4c7cb9d46d..000000000000
--- a/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/Application.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
-* Copyright 2012-2020 the original author or authors.
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* https://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-
-package io.spring.concourse.releasescripts;
-
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
-
-@SpringBootApplication
-@ConfigurationPropertiesScan
-public class Application {
-
- public static void main(String[] args) {
- SpringApplication.run(Application.class, args);
- }
-
-}
diff --git a/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/ReleaseInfo.java b/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/ReleaseInfo.java
deleted file mode 100644
index 34fec8172cbf..000000000000
--- a/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/ReleaseInfo.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright 2012-2019 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.spring.concourse.releasescripts;
-
-import io.spring.concourse.releasescripts.artifactory.payload.BuildInfoResponse;
-
-import org.springframework.boot.context.properties.PropertyMapper;
-import org.springframework.util.StringUtils;
-
-/**
- * Properties corresponding to the release.
- *
- * @author Madhura Bhave
- */
-public class ReleaseInfo {
-
- private String buildName;
-
- private String buildNumber;
-
- private String groupId;
-
- private String version;
-
- public static ReleaseInfo from(BuildInfoResponse.BuildInfo buildInfo) {
- ReleaseInfo info = new ReleaseInfo();
- PropertyMapper propertyMapper = PropertyMapper.get();
- propertyMapper.from(buildInfo.getName()).to(info::setBuildName);
- propertyMapper.from(buildInfo.getNumber()).to(info::setBuildNumber);
- String[] moduleInfo = StringUtils.delimitedListToStringArray(buildInfo.getModules()[0].getId(), ":");
- propertyMapper.from(moduleInfo[0]).to(info::setGroupId);
- propertyMapper.from(moduleInfo[2]).to(info::setVersion);
- return info;
- }
-
- public String getBuildName() {
- return this.buildName;
- }
-
- public void setBuildName(String buildName) {
- this.buildName = buildName;
- }
-
- public String getBuildNumber() {
- return this.buildNumber;
- }
-
- public void setBuildNumber(String buildNumber) {
- this.buildNumber = buildNumber;
- }
-
- public String getGroupId() {
- return this.groupId;
- }
-
- public void setGroupId(String groupId) {
- this.groupId = groupId;
- }
-
- public String getVersion() {
- return this.version;
- }
-
- public void setVersion(String version) {
- this.version = version;
- }
-
-}
diff --git a/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/ReleaseProperties.java b/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/ReleaseProperties.java
deleted file mode 100644
index 4973fedc2777..000000000000
--- a/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/ReleaseProperties.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright 2012-2019 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.spring.concourse.releasescripts;
-
-import org.springframework.boot.context.properties.ConfigurationProperties;
-
-/**
- * {@link ConfigurationProperties @ConfigurationProperties} corresponding to the release.
- *
- * @author Madhura Bhave
- */
-@ConfigurationProperties(prefix = "release")
-public class ReleaseProperties {
-
- private String buildName;
-
- private String buildNumber;
-
- private String groupId;
-
- private String version;
-
- public String getBuildName() {
- return this.buildName;
- }
-
- public void setBuildName(String buildName) {
- this.buildName = buildName;
- }
-
- public String getBuildNumber() {
- return this.buildNumber;
- }
-
- public void setBuildNumber(String buildNumber) {
- this.buildNumber = buildNumber;
- }
-
- public String getGroupId() {
- return this.groupId;
- }
-
- public void setGroupId(String groupId) {
- this.groupId = groupId;
- }
-
- public String getVersion() {
- return this.version;
- }
-
- public void setVersion(String version) {
- this.version = version;
- }
-
-}
diff --git a/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/ReleaseType.java b/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/ReleaseType.java
deleted file mode 100644
index f60295897746..000000000000
--- a/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/ReleaseType.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright 2012-2019 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.spring.concourse.releasescripts;
-
-/**
- * Release type.
- *
- * @author Madhura Bhave
- */
-public enum ReleaseType {
-
- MILESTONE("M", "libs-milestone-local"),
-
- RELEASE_CANDIDATE("RC", "libs-milestone-local"),
-
- RELEASE("RELEASE", "libs-release-local");
-
- private final String identifier;
-
- private final String repo;
-
- ReleaseType(String identifier, String repo) {
- this.identifier = identifier;
- this.repo = repo;
- }
-
- public static ReleaseType from(String releaseType) {
- for (ReleaseType type : ReleaseType.values()) {
- if (type.identifier.equals(releaseType)) {
- return type;
- }
- }
- throw new IllegalArgumentException("Invalid release type");
- }
-
- public String getRepo() {
- return this.repo;
- }
-
-}
diff --git a/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/artifactory/ArtifactoryProperties.java b/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/artifactory/ArtifactoryProperties.java
deleted file mode 100644
index 952271167377..000000000000
--- a/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/artifactory/ArtifactoryProperties.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright 2012-2019 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.spring.concourse.releasescripts.artifactory;
-
-import org.springframework.boot.context.properties.ConfigurationProperties;
-
-/**
- * {@link ConfigurationProperties @ConfigurationProperties} for an Artifactory server.
- *
- * @author Madhura Bhave
- */
-@ConfigurationProperties(prefix = "artifactory")
-public class ArtifactoryProperties {
-
- private String username;
-
- private String password;
-
- public String getUsername() {
- return this.username;
- }
-
- public void setUsername(String username) {
- this.username = username;
- }
-
- public String getPassword() {
- return this.password;
- }
-
- public void setPassword(String password) {
- this.password = password;
- }
-
-}
diff --git a/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/artifactory/ArtifactoryService.java b/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/artifactory/ArtifactoryService.java
deleted file mode 100644
index 2bb2cd7603ed..000000000000
--- a/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/artifactory/ArtifactoryService.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * 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.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.spring.concourse.releasescripts.artifactory;
-
-import java.net.URI;
-
-import io.spring.concourse.releasescripts.ReleaseInfo;
-import io.spring.concourse.releasescripts.artifactory.payload.BuildInfoResponse;
-import io.spring.concourse.releasescripts.artifactory.payload.BuildInfoResponse.Status;
-import io.spring.concourse.releasescripts.artifactory.payload.PromotionRequest;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.springframework.boot.web.client.RestTemplateBuilder;
-import org.springframework.http.MediaType;
-import org.springframework.http.RequestEntity;
-import org.springframework.http.ResponseEntity;
-import org.springframework.stereotype.Component;
-import org.springframework.util.StringUtils;
-import org.springframework.web.client.HttpClientErrorException;
-import org.springframework.web.client.RestTemplate;
-
-/**
- * Central class for interacting with Artifactory's REST API.
- *
- * @author Madhura Bhave
- */
-@Component
-public class ArtifactoryService {
-
- private static final Logger logger = LoggerFactory.getLogger(ArtifactoryService.class);
-
- private static final String ARTIFACTORY_URL = "https://repo.spring.io";
-
- private static final String PROMOTION_URL = ARTIFACTORY_URL + "/api/build/promote/";
-
- private static final String BUILD_INFO_URL = ARTIFACTORY_URL + "/api/build/";
-
- private static final String STAGING_REPO = "libs-staging-local";
-
- private final RestTemplate restTemplate;
-
- public ArtifactoryService(RestTemplateBuilder builder, ArtifactoryProperties artifactoryProperties) {
- String username = artifactoryProperties.getUsername();
- String password = artifactoryProperties.getPassword();
- if (StringUtils.hasLength(username)) {
- builder = builder.basicAuthentication(username, password);
- }
- this.restTemplate = builder.build();
- }
-
- /**
- * Move artifacts to a target repository in Artifactory.
- * @param targetRepo the targetRepo
- * @param releaseInfo the release information
- */
- public void promote(String targetRepo, ReleaseInfo releaseInfo) {
- PromotionRequest request = getPromotionRequest(targetRepo);
- String buildName = releaseInfo.getBuildName();
- String buildNumber = releaseInfo.getBuildNumber();
- logger.info("Promoting " + buildName + "/" + buildNumber + " to " + request.getTargetRepo());
- RequestEntity requestEntity = RequestEntity
- .post(URI.create(PROMOTION_URL + buildName + "/" + buildNumber)).contentType(MediaType.APPLICATION_JSON)
- .body(request);
- try {
- this.restTemplate.exchange(requestEntity, String.class);
- logger.debug("Promotion complete");
- }
- catch (HttpClientErrorException ex) {
- boolean isAlreadyPromoted = isAlreadyPromoted(buildName, buildNumber, request.getTargetRepo());
- if (isAlreadyPromoted) {
- logger.info("Already promoted.");
- }
- else {
- logger.info("Promotion failed.");
- throw ex;
- }
- }
- }
-
- private boolean isAlreadyPromoted(String buildName, String buildNumber, String targetRepo) {
- try {
- logger.debug("Checking if already promoted");
- ResponseEntity entity = this.restTemplate
- .getForEntity(BUILD_INFO_URL + buildName + "/" + buildNumber, BuildInfoResponse.class);
- Status[] statuses = entity.getBody().getBuildInfo().getStatuses();
- BuildInfoResponse.Status status = (statuses != null) ? statuses[0] : null;
- if (status == null) {
- logger.debug("Returned no status object");
- return false;
- }
- logger.debug("Returned repository " + status.getRepository() + " expecting " + targetRepo);
- return status.getRepository().equals(targetRepo);
- }
- catch (HttpClientErrorException ex) {
- logger.debug("Client error, assuming not promoted");
- return false;
- }
- }
-
- private PromotionRequest getPromotionRequest(String targetRepo) {
- return new PromotionRequest("staged", STAGING_REPO, targetRepo);
- }
-
-}
diff --git a/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/artifactory/DistributionTimeoutException.java b/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/artifactory/DistributionTimeoutException.java
deleted file mode 100644
index c5ba1812b4fe..000000000000
--- a/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/artifactory/DistributionTimeoutException.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright 2012-2019 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.spring.concourse.releasescripts.artifactory;
-
-/**
- * Runtime exception if artifact distribution to Bintray fails.
- *
- * @author Madhura Bhave
- */
-public class DistributionTimeoutException extends RuntimeException {
-
- private String message;
-
- DistributionTimeoutException(String message) {
- super(message);
- this.message = message;
- }
-
- @Override
- public String getMessage() {
- return this.message;
- }
-
-}
diff --git a/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/artifactory/payload/BuildInfoResponse.java b/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/artifactory/payload/BuildInfoResponse.java
deleted file mode 100644
index 149d2c56fd5d..000000000000
--- a/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/artifactory/payload/BuildInfoResponse.java
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Copyright 2012-2020 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.spring.concourse.releasescripts.artifactory.payload;
-
-import java.util.Arrays;
-import java.util.Set;
-import java.util.function.Predicate;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-/**
- * Represents the response from Artifactory's buildInfo endpoint.
- *
- * @author Madhura Bhave
- */
-public class BuildInfoResponse {
-
- private BuildInfo buildInfo;
-
- public BuildInfo getBuildInfo() {
- return this.buildInfo;
- }
-
- public void setBuildInfo(BuildInfo buildInfo) {
- this.buildInfo = buildInfo;
- }
-
- public static class BuildInfo {
-
- private String name;
-
- private String number;
-
- private String version;
-
- private Status[] statuses;
-
- private Module[] modules;
-
- public Status[] getStatuses() {
- return this.statuses;
- }
-
- public void setStatuses(Status[] statuses) {
- this.statuses = statuses;
- }
-
- public String getName() {
- return this.name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public String getNumber() {
- return this.number;
- }
-
- public void setNumber(String number) {
- this.number = number;
- }
-
- public Module[] getModules() {
- return this.modules;
- }
-
- public void setModules(Module[] modules) {
- this.modules = modules;
- }
-
- public String getVersion() {
- return this.version;
- }
-
- public void setVersion(String version) {
- this.version = version;
-
- }
-
- public Set getArtifactDigests(Predicate predicate) {
- return Arrays.stream(this.modules).flatMap((module) -> {
- Artifact[] artifacts = module.getArtifacts();
- return (artifacts != null) ? Arrays.stream(artifacts) : Stream.empty();
- }).filter(predicate).map(Artifact::getSha256).collect(Collectors.toSet());
- }
-
- }
-
- public static class Status {
-
- private String repository;
-
- public String getRepository() {
- return this.repository;
- }
-
- public void setRepository(String repository) {
- this.repository = repository;
- }
-
- }
-
- public static class Module {
-
- private String id;
-
- private Artifact[] artifacts;
-
- public String getId() {
- return this.id;
- }
-
- public void setId(String id) {
- this.id = id;
- }
-
- public Artifact[] getArtifacts() {
- return this.artifacts;
- }
-
- public void setArtifacts(Artifact[] artifacts) {
- this.artifacts = artifacts;
- }
-
- }
-
- public static class Artifact {
-
- private String name;
-
- private String sha256;
-
- public String getName() {
- return this.name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public String getSha256() {
- return this.sha256;
- }
-
- public void setSha256(String sha256) {
- this.sha256 = sha256;
- }
-
- }
-
-}
diff --git a/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/artifactory/payload/DistributionRequest.java b/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/artifactory/payload/DistributionRequest.java
deleted file mode 100644
index 241f6a6600aa..000000000000
--- a/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/artifactory/payload/DistributionRequest.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright 2012-2019 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.spring.concourse.releasescripts.artifactory.payload;
-
-/**
- * Represents a request to distribute artifacts from Artifactory to Bintray.
- *
- * @author Madhura Bhave
- */
-public class DistributionRequest {
-
- private final String[] sourceRepos;
-
- private final String targetRepo = "spring-distributions";
-
- private final String async = "true";
-
- public DistributionRequest(String[] sourceRepos) {
- this.sourceRepos = sourceRepos;
- }
-
- public String[] getSourceRepos() {
- return sourceRepos;
- }
-
- public String getTargetRepo() {
- return targetRepo;
- }
-
- public String getAsync() {
- return async;
- }
-
-}
diff --git a/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/artifactory/payload/PromotionRequest.java b/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/artifactory/payload/PromotionRequest.java
deleted file mode 100644
index cf9974c53123..000000000000
--- a/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/artifactory/payload/PromotionRequest.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright 2012-2019 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.spring.concourse.releasescripts.artifactory.payload;
-
-/**
- * Represents a request to promote artifacts from a sourceRepo to a targetRepo.
- *
- * @author Madhura Bhave
- */
-public class PromotionRequest {
-
- private final String status;
-
- private final String sourceRepo;
-
- private final String targetRepo;
-
- public PromotionRequest(String status, String sourceRepo, String targetRepo) {
- this.status = status;
- this.sourceRepo = sourceRepo;
- this.targetRepo = targetRepo;
- }
-
- public String getTargetRepo() {
- return this.targetRepo;
- }
-
- public String getSourceRepo() {
- return this.sourceRepo;
- }
-
- public String getStatus() {
- return this.status;
- }
-
-}
diff --git a/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/command/Command.java b/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/command/Command.java
deleted file mode 100644
index e8541ae12848..000000000000
--- a/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/command/Command.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright 2012-2019 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.spring.concourse.releasescripts.command;
-
-import org.springframework.boot.ApplicationArguments;
-import org.springframework.util.ClassUtils;
-
-/**
- * @author Madhura Bhave
- */
-public interface Command {
-
- default String getName() {
- String name = ClassUtils.getShortName(getClass());
- int lastDot = name.lastIndexOf(".");
- if (lastDot != -1) {
- name = name.substring(lastDot + 1, name.length());
- }
- if (name.endsWith("Command")) {
- name = name.substring(0, name.length() - "Command".length());
- }
- return name.toLowerCase();
- }
-
- void run(ApplicationArguments args) throws Exception;
-
-}
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/command/CommandProcessor.java b/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/command/CommandProcessor.java
deleted file mode 100644
index 50a0b2132a7e..000000000000
--- a/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/command/CommandProcessor.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright 2012-2020 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.spring.concourse.releasescripts.command;
-
-import java.util.Collections;
-import java.util.List;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.springframework.boot.ApplicationArguments;
-import org.springframework.boot.ApplicationRunner;
-import org.springframework.stereotype.Component;
-import org.springframework.util.Assert;
-
-/**
- * {@link ApplicationRunner} to delegate incoming requests to commands.
- *
- * @author Madhura Bhave
- */
-@Component
-public class CommandProcessor implements ApplicationRunner {
-
- private static final Logger logger = LoggerFactory.getLogger(CommandProcessor.class);
-
- private final List commands;
-
- public CommandProcessor(List commands) {
- this.commands = Collections.unmodifiableList(commands);
- }
-
- @Override
- public void run(ApplicationArguments args) throws Exception {
- logger.debug("Running command processor");
- List nonOptionArgs = args.getNonOptionArgs();
- Assert.state(!nonOptionArgs.isEmpty(), "No command argument specified");
- String request = nonOptionArgs.get(0);
- Command command = this.commands.stream().filter((candidate) -> candidate.getName().equals(request)).findFirst()
- .orElseThrow(() -> new IllegalStateException("Unknown command '" + request + "'"));
- logger.debug("Found command " + command.getClass().getName());
- command.run(args);
- }
-
-}
diff --git a/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/command/PromoteCommand.java b/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/command/PromoteCommand.java
deleted file mode 100644
index dc8f80ceba62..000000000000
--- a/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/command/PromoteCommand.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright 2012-2020 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.spring.concourse.releasescripts.command;
-
-import java.io.File;
-import java.nio.file.Files;
-import java.util.List;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-import io.spring.concourse.releasescripts.ReleaseInfo;
-import io.spring.concourse.releasescripts.ReleaseType;
-import io.spring.concourse.releasescripts.artifactory.ArtifactoryService;
-import io.spring.concourse.releasescripts.artifactory.payload.BuildInfoResponse;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.springframework.boot.ApplicationArguments;
-import org.springframework.stereotype.Component;
-import org.springframework.util.Assert;
-
-/**
- * Command used to move the build artifacts to a target repository in Artifactory.
- *
- * @author Madhura Bhave
- */
-@Component
-public class PromoteCommand implements Command {
-
- private static final Logger logger = LoggerFactory.getLogger(PromoteCommand.class);
-
- private final ArtifactoryService service;
-
- private final ObjectMapper objectMapper;
-
- public PromoteCommand(ArtifactoryService service, ObjectMapper objectMapper) {
- this.service = service;
- this.objectMapper = objectMapper;
- }
-
- @Override
- public void run(ApplicationArguments args) throws Exception {
- logger.debug("Running 'promote' command");
- List nonOptionArgs = args.getNonOptionArgs();
- Assert.state(!nonOptionArgs.isEmpty(), "No command argument specified");
- Assert.state(nonOptionArgs.size() == 3, "Release type or build info location not specified");
- String releaseType = nonOptionArgs.get(1);
- ReleaseType type = ReleaseType.from(releaseType);
- String buildInfoLocation = nonOptionArgs.get(2);
- byte[] content = Files.readAllBytes(new File(buildInfoLocation).toPath());
- BuildInfoResponse buildInfoResponse = this.objectMapper.readValue(new String(content), BuildInfoResponse.class);
- ReleaseInfo releaseInfo = ReleaseInfo.from(buildInfoResponse.getBuildInfo());
- this.service.promote(type.getRepo(), releaseInfo);
- }
-
-}
diff --git a/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/command/PublishToCentralCommand.java b/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/command/PublishToCentralCommand.java
deleted file mode 100644
index 2dccc1876e48..000000000000
--- a/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/command/PublishToCentralCommand.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * 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.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.spring.concourse.releasescripts.command;
-
-import java.io.File;
-import java.nio.file.Files;
-import java.util.List;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-import io.spring.concourse.releasescripts.ReleaseInfo;
-import io.spring.concourse.releasescripts.ReleaseType;
-import io.spring.concourse.releasescripts.artifactory.payload.BuildInfoResponse;
-import io.spring.concourse.releasescripts.artifactory.payload.BuildInfoResponse.BuildInfo;
-import io.spring.concourse.releasescripts.sonatype.SonatypeService;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.springframework.boot.ApplicationArguments;
-import org.springframework.stereotype.Component;
-import org.springframework.util.Assert;
-
-/**
- * Command used to publish a release to Maven Central.
- *
- * @author Andy Wilkinson
- */
-@Component
-public class PublishToCentralCommand implements Command {
-
- private static final Logger logger = LoggerFactory.getLogger(PublishToCentralCommand.class);
-
- private final SonatypeService sonatype;
-
- private final ObjectMapper objectMapper;
-
- public PublishToCentralCommand(SonatypeService sonatype, ObjectMapper objectMapper) {
- this.sonatype = sonatype;
- this.objectMapper = objectMapper;
- }
-
- @Override
- public String getName() {
- return "publishToCentral";
- }
-
- @Override
- public void run(ApplicationArguments args) throws Exception {
- List nonOptionArgs = args.getNonOptionArgs();
- Assert.state(nonOptionArgs.size() == 4,
- "Release type, build info location, or artifacts location not specified");
- String releaseType = nonOptionArgs.get(1);
- ReleaseType type = ReleaseType.from(releaseType);
- if (!ReleaseType.RELEASE.equals(type)) {
- return;
- }
- String buildInfoLocation = nonOptionArgs.get(2);
- logger.debug("Loading build-info from " + buildInfoLocation);
- byte[] content = Files.readAllBytes(new File(buildInfoLocation).toPath());
- BuildInfoResponse buildInfoResponse = this.objectMapper.readValue(content, BuildInfoResponse.class);
- BuildInfo buildInfo = buildInfoResponse.getBuildInfo();
- ReleaseInfo releaseInfo = ReleaseInfo.from(buildInfo);
- String artifactsLocation = nonOptionArgs.get(3);
- this.sonatype.publish(releaseInfo, new File(artifactsLocation).toPath());
- }
-
-}
diff --git a/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/command/PublishToSdkmanCommand.java b/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/command/PublishToSdkmanCommand.java
deleted file mode 100644
index 1938610dc0cd..000000000000
--- a/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/command/PublishToSdkmanCommand.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright 2012-2020 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.spring.concourse.releasescripts.command;
-
-import java.util.List;
-
-import io.spring.concourse.releasescripts.ReleaseType;
-import io.spring.concourse.releasescripts.sdkman.SdkmanService;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.springframework.boot.ApplicationArguments;
-import org.springframework.stereotype.Component;
-import org.springframework.util.Assert;
-
-/**
- * Command used to publish to SDKMAN.
- *
- * @author Madhura Bhave
- */
-@Component
-public class PublishToSdkmanCommand implements Command {
-
- private static final Logger logger = LoggerFactory.getLogger(PublishToSdkmanCommand.class);
-
- private static final String PUBLISH_TO_SDKMAN_COMMAND = "publishToSdkman";
-
- private final SdkmanService service;
-
- public PublishToSdkmanCommand(SdkmanService service) {
- this.service = service;
- }
-
- @Override
- public String getName() {
- return PUBLISH_TO_SDKMAN_COMMAND;
- }
-
- @Override
- public void run(ApplicationArguments args) throws Exception {
- logger.debug("Running 'push to SDKMAN' command");
- List nonOptionArgs = args.getNonOptionArgs();
- Assert.state(!nonOptionArgs.isEmpty(), "No command argument specified");
- Assert.state(nonOptionArgs.size() >= 3, "Release type or version not specified");
- String releaseType = nonOptionArgs.get(1);
- ReleaseType type = ReleaseType.from(releaseType);
- if (!ReleaseType.RELEASE.equals(type)) {
- return;
- }
- String version = nonOptionArgs.get(2);
- boolean makeDefault = false;
- if (nonOptionArgs.size() == 4) {
- makeDefault = Boolean.parseBoolean(nonOptionArgs.get(3));
- }
- this.service.publish(version, makeDefault);
- }
-
-}
diff --git a/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/sdkman/SdkmanProperties.java b/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/sdkman/SdkmanProperties.java
deleted file mode 100644
index 575d3cf1b703..000000000000
--- a/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/sdkman/SdkmanProperties.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright 2012-2020 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.spring.concourse.releasescripts.sdkman;
-
-import org.springframework.boot.context.properties.ConfigurationProperties;
-
-/**
- * {@link ConfigurationProperties @ConfigurationProperties} for SDKMAN.
- *
- * @author Madhura Bhave
- */
-@ConfigurationProperties(prefix = "sdkman")
-public class SdkmanProperties {
-
- private String consumerKey;
-
- private String consumerToken;
-
- public String getConsumerKey() {
- return this.consumerKey;
- }
-
- public void setConsumerKey(String consumerKey) {
- this.consumerKey = consumerKey;
- }
-
- public String getConsumerToken() {
- return this.consumerToken;
- }
-
- public void setConsumerToken(String consumerToken) {
- this.consumerToken = consumerToken;
- }
-
-}
diff --git a/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/sdkman/SdkmanService.java b/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/sdkman/SdkmanService.java
deleted file mode 100644
index dc87b9285170..000000000000
--- a/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/sdkman/SdkmanService.java
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright 2012-2023 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.spring.concourse.releasescripts.sdkman;
-
-import java.net.URI;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.springframework.boot.web.client.RestTemplateBuilder;
-import org.springframework.http.MediaType;
-import org.springframework.http.RequestEntity;
-import org.springframework.stereotype.Component;
-import org.springframework.web.client.RestTemplate;
-
-/**
- * Central class for interacting with SDKMAN's API.
- *
- * @author Madhura Bhave
- * @author Moritz Halbritter
- */
-@Component
-public class SdkmanService {
-
- private static final Logger logger = LoggerFactory.getLogger(SdkmanService.class);
-
- private static final String SDKMAN_URL = "https://vendors.sdkman.io/";
-
- private static final String DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/org/springframework/boot/spring-boot-cli/"
- + "%s/spring-boot-cli-%s-bin.zip";
-
- private static final String CHANGELOG_URL = "https://github.com/spring-projects/spring-boot/releases/tag/v%s";
-
- private static final String SPRING_BOOT = "springboot";
-
- private final RestTemplate restTemplate;
-
- private final SdkmanProperties properties;
-
- private final String CONSUMER_KEY_HEADER = "Consumer-Key";
-
- private final String CONSUMER_TOKEN_HEADER = "Consumer-Token";
-
- public SdkmanService(RestTemplateBuilder builder, SdkmanProperties properties) {
- this.restTemplate = builder.build();
- this.properties = properties;
- }
-
- public void publish(String version, boolean makeDefault) {
- release(version);
- if (makeDefault) {
- makeDefault(version);
- }
- broadcast(version);
- }
-
- private void broadcast(String version) {
- BroadcastRequest broadcastRequest = new BroadcastRequest(version, String.format(CHANGELOG_URL, version));
- RequestEntity broadcastEntity = RequestEntity.post(URI.create(SDKMAN_URL + "announce/struct"))
- .header(CONSUMER_KEY_HEADER, this.properties.getConsumerKey())
- .header(CONSUMER_TOKEN_HEADER, this.properties.getConsumerToken())
- .contentType(MediaType.APPLICATION_JSON).body(broadcastRequest);
- this.restTemplate.exchange(broadcastEntity, String.class);
- logger.debug("Broadcast complete");
- }
-
- private void makeDefault(String version) {
- logger.debug("Making this version the default");
- Request request = new Request(version);
- RequestEntity requestEntity = RequestEntity.put(URI.create(SDKMAN_URL + "default"))
- .header(CONSUMER_KEY_HEADER, this.properties.getConsumerKey())
- .header(CONSUMER_TOKEN_HEADER, this.properties.getConsumerToken())
- .contentType(MediaType.APPLICATION_JSON).body(request);
- this.restTemplate.exchange(requestEntity, String.class);
- logger.debug("Make default complete");
- }
-
- private void release(String version) {
- ReleaseRequest releaseRequest = new ReleaseRequest(version, String.format(DOWNLOAD_URL, version, version));
- RequestEntity releaseEntity = RequestEntity.post(URI.create(SDKMAN_URL + "release"))
- .header(CONSUMER_KEY_HEADER, this.properties.getConsumerKey())
- .header(CONSUMER_TOKEN_HEADER, this.properties.getConsumerToken())
- .contentType(MediaType.APPLICATION_JSON).body(releaseRequest);
- this.restTemplate.exchange(releaseEntity, String.class);
- logger.debug("Release complete");
- }
-
- static class Request {
-
- private final String candidate = SPRING_BOOT;
-
- private final String version;
-
- Request(String version) {
- this.version = version;
- }
-
- public String getCandidate() {
- return this.candidate;
- }
-
- public String getVersion() {
- return this.version;
- }
-
- }
-
- static class ReleaseRequest extends Request {
-
- private final String url;
-
- ReleaseRequest(String version, String url) {
- super(version);
- this.url = url;
- }
-
- public String getUrl() {
- return this.url;
- }
-
- }
-
- static class BroadcastRequest extends Request {
-
- private final String hashtag = SPRING_BOOT;
-
- private final String url;
-
- BroadcastRequest(String version, String url) {
- super(version);
- this.url = url;
- }
-
- public String getHashtag() {
- return this.hashtag;
- }
-
- public String getUrl() {
- return url;
- }
-
- }
-
-}
diff --git a/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/sonatype/ArtifactCollector.java b/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/sonatype/ArtifactCollector.java
deleted file mode 100644
index d1d466f5b783..000000000000
--- a/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/sonatype/ArtifactCollector.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * 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.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.spring.concourse.releasescripts.sonatype;
-
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.Collection;
-import java.util.List;
-import java.util.function.Predicate;
-import java.util.regex.Pattern;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-import org.springframework.core.io.PathResource;
-
-/**
- * Collects artifacts to be deployed.
- *
- * @author Andy Wilkinson
- */
-class ArtifactCollector {
-
- private final Predicate excludeFilter;
-
- ArtifactCollector(List exclude) {
- this.excludeFilter = excludeFilter(exclude);
- }
-
- private Predicate excludeFilter(List exclude) {
- Predicate patternFilter = exclude.stream().map(Pattern::compile).map(Pattern::asPredicate)
- .reduce((path) -> false, Predicate::or).negate();
- return (path) -> patternFilter.test(path.toString());
- }
-
- Collection collectArtifacts(Path root) {
- try (Stream artifacts = Files.walk(root)) {
- return artifacts.filter(Files::isRegularFile).filter(this.excludeFilter)
- .map((artifact) -> deployableArtifact(artifact, root)).toList();
- }
- catch (IOException ex) {
- throw new RuntimeException("Could not read artifacts from '" + root + "'");
- }
- }
-
- private DeployableArtifact deployableArtifact(Path artifact, Path root) {
- return new DeployableArtifact(new PathResource(artifact), root.relativize(artifact).toString());
- }
-
-}
diff --git a/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/sonatype/DeployableArtifact.java b/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/sonatype/DeployableArtifact.java
deleted file mode 100644
index 45bfa9c3d242..000000000000
--- a/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/sonatype/DeployableArtifact.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * 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.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.spring.concourse.releasescripts.sonatype;
-
-import org.springframework.core.io.Resource;
-
-/**
- * An artifact that can be deployed.
- *
- * @author Andy Wilkinson
- */
-class DeployableArtifact {
-
- private final Resource resource;
-
- private final String path;
-
- DeployableArtifact(Resource resource, String path) {
- this.resource = resource;
- this.path = path;
- }
-
- Resource getResource() {
- return this.resource;
- }
-
- String getPath() {
- return this.path;
- }
-
-}
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/sonatype/SonatypeProperties.java b/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/sonatype/SonatypeProperties.java
deleted file mode 100644
index 4f9d0a4c5409..000000000000
--- a/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/sonatype/SonatypeProperties.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * 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.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.spring.concourse.releasescripts.sonatype;
-
-import java.time.Duration;
-import java.util.ArrayList;
-import java.util.List;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-import org.springframework.boot.context.properties.ConfigurationProperties;
-
-/**
- * {@link ConfigurationProperties @ConfigurationProperties} for Sonatype.
- *
- * @author Madhura Bhave
- */
-@ConfigurationProperties(prefix = "sonatype")
-public class SonatypeProperties {
-
- @JsonProperty("username")
- private String userToken;
-
- @JsonProperty("password")
- private String passwordToken;
-
- /**
- * URL of the Nexus instance used to publish releases.
- */
- private String url;
-
- /**
- * ID of the staging profile used to publish releases.
- */
- private String stagingProfileId;
-
- /**
- * Time between requests made to determine if the closing of a staging repository has
- * completed.
- */
- private Duration pollingInterval = Duration.ofSeconds(15);
-
- /**
- * Number of threads used to upload artifacts to the staging repository.
- */
- private int uploadThreads = 8;
-
- /**
- * Regular expression patterns of artifacts to exclude
- */
- private List exclude = new ArrayList<>();
-
- public String getUserToken() {
- return this.userToken;
- }
-
- public void setUserToken(String userToken) {
- this.userToken = userToken;
- }
-
- public String getPasswordToken() {
- return this.passwordToken;
- }
-
- public void setPasswordToken(String passwordToken) {
- this.passwordToken = passwordToken;
- }
-
- public String getUrl() {
- return this.url;
- }
-
- public void setUrl(String url) {
- this.url = url;
- }
-
- public String getStagingProfileId() {
- return this.stagingProfileId;
- }
-
- public void setStagingProfileId(String stagingProfileId) {
- this.stagingProfileId = stagingProfileId;
- }
-
- public Duration getPollingInterval() {
- return this.pollingInterval;
- }
-
- public void setPollingInterval(Duration pollingInterval) {
- this.pollingInterval = pollingInterval;
- }
-
- public int getUploadThreads() {
- return this.uploadThreads;
- }
-
- public void setUploadThreads(int uploadThreads) {
- this.uploadThreads = uploadThreads;
- }
-
- public List getExclude() {
- return this.exclude;
- }
-
- public void setExclude(List exclude) {
- this.exclude = exclude;
- }
-
-}
diff --git a/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/sonatype/SonatypeService.java b/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/sonatype/SonatypeService.java
deleted file mode 100644
index ed5703662116..000000000000
--- a/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/sonatype/SonatypeService.java
+++ /dev/null
@@ -1,306 +0,0 @@
-/*
- * 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.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.spring.concourse.releasescripts.sonatype;
-
-import java.nio.file.Path;
-import java.time.Duration;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonCreator.Mode;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import io.spring.concourse.releasescripts.ReleaseInfo;
-import org.apache.logging.log4j.util.Strings;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.springframework.boot.web.client.RestTemplateBuilder;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.stereotype.Component;
-import org.springframework.util.StringUtils;
-import org.springframework.web.client.HttpClientErrorException;
-import org.springframework.web.client.RestTemplate;
-
-/**
- * Central class for interacting with Sonatype.
- *
- * @author Madhura Bhave
- * @author Andy Wilkinson
- */
-@Component
-public class SonatypeService {
-
- private static final Logger logger = LoggerFactory.getLogger(SonatypeService.class);
-
- private static final String NEXUS_REPOSITORY_PATH = "/service/local/repositories/releases/content/org/springframework/boot/spring-boot/";
-
- private static final String NEXUS_STAGING_PATH = "/service/local/staging/";
-
- private final ArtifactCollector artifactCollector;
-
- private final RestTemplate restTemplate;
-
- private final String stagingProfileId;
-
- private final Duration pollingInterval;
-
- private final int threads;
-
- public SonatypeService(RestTemplateBuilder builder, SonatypeProperties sonatypeProperties) {
- String username = sonatypeProperties.getUserToken();
- String password = sonatypeProperties.getPasswordToken();
- if (StringUtils.hasLength(username)) {
- builder = builder.basicAuthentication(username, password);
- }
- this.restTemplate = builder.rootUri(sonatypeProperties.getUrl()).build();
- this.stagingProfileId = sonatypeProperties.getStagingProfileId();
- this.pollingInterval = sonatypeProperties.getPollingInterval();
- this.threads = sonatypeProperties.getUploadThreads();
-
- this.artifactCollector = new ArtifactCollector(sonatypeProperties.getExclude());
- }
-
- /**
- * Publishes the release by creating a staging repository and deploying to it the
- * artifacts at the given {@code artifactsRoot}. The repository is then closed and,
- * upon successfully closure, it is released.
- * @param releaseInfo the release information
- * @param artifactsRoot the root directory of the artifacts to stage
- */
- public void publish(ReleaseInfo releaseInfo, Path artifactsRoot) {
- if (artifactsPublished(releaseInfo)) {
- return;
- }
- logger.info("Creating staging repository");
- String buildId = releaseInfo.getBuildNumber();
- String repositoryId = createStagingRepository(buildId);
- Collection artifacts = this.artifactCollector.collectArtifacts(artifactsRoot);
- logger.info("Staging repository {} created. Deploying {} artifacts", repositoryId, artifacts.size());
- deploy(artifacts, repositoryId);
- logger.info("Deploy complete. Closing staging repository");
- close(repositoryId);
- logger.info("Staging repository closed");
- release(repositoryId, buildId);
- logger.info("Staging repository released");
- }
-
- private boolean artifactsPublished(ReleaseInfo releaseInfo) {
- try {
- ResponseEntity> entity = this.restTemplate
- .getForEntity(String.format(NEXUS_REPOSITORY_PATH + "%s/spring-boot-%s.jar.sha1",
- releaseInfo.getVersion(), releaseInfo.getVersion()), byte[].class);
- if (HttpStatus.OK.equals(entity.getStatusCode())) {
- logger.info("Already published to Sonatype.");
- return true;
- }
- }
- catch (HttpClientErrorException ex) {
-
- }
- return false;
- }
-
- private String createStagingRepository(String buildId) {
- Map body = new HashMap<>();
- body.put("data", Collections.singletonMap("description", buildId));
- PromoteResponse response = this.restTemplate.postForObject(
- String.format(NEXUS_STAGING_PATH + "profiles/%s/start", this.stagingProfileId), body,
- PromoteResponse.class);
- String repositoryId = response.data.stagedRepositoryId;
- return repositoryId;
- }
-
- private void deploy(Collection artifacts, String repositoryId) {
- ExecutorService executor = Executors.newFixedThreadPool(this.threads);
- try {
- CompletableFuture.allOf(artifacts.stream()
- .map((artifact) -> CompletableFuture.runAsync(() -> deploy(artifact, repositoryId), executor))
- .toArray(CompletableFuture[]::new)).get(60, TimeUnit.MINUTES);
- }
- catch (InterruptedException ex) {
- Thread.currentThread().interrupt();
- throw new RuntimeException("Interrupted during artifact deploy");
- }
- catch (ExecutionException ex) {
- throw new RuntimeException("Deploy failed", ex);
- }
- catch (TimeoutException ex) {
- throw new RuntimeException("Deploy timed out", ex);
- }
- finally {
- executor.shutdown();
- }
- }
-
- private void deploy(DeployableArtifact deployableArtifact, String repositoryId) {
- try {
- this.restTemplate.put(
- NEXUS_STAGING_PATH + "deployByRepositoryId/" + repositoryId + "/" + deployableArtifact.getPath(),
- deployableArtifact.getResource());
- logger.info("Deloyed {}", deployableArtifact.getPath());
- }
- catch (HttpClientErrorException ex) {
- logger.error("Failed to deploy {}. Error response: {}", deployableArtifact.getPath(),
- ex.getResponseBodyAsString());
- throw ex;
- }
- }
-
- private void close(String stagedRepositoryId) {
- Map body = new HashMap<>();
- body.put("data", Collections.singletonMap("stagedRepositoryId", stagedRepositoryId));
- this.restTemplate.postForEntity(String.format(NEXUS_STAGING_PATH + "profiles/%s/finish", this.stagingProfileId),
- body, Void.class);
- logger.info("Close requested. Awaiting result");
- while (true) {
- StagingRepository repository = this.restTemplate
- .getForObject(NEXUS_STAGING_PATH + "repository/" + stagedRepositoryId, StagingRepository.class);
- if (!repository.transitioning) {
- if ("open".equals(repository.type)) {
- logFailures(stagedRepositoryId);
- throw new RuntimeException("Close failed");
- }
- return;
- }
- try {
- Thread.sleep(this.pollingInterval.toMillis());
- }
- catch (InterruptedException ex) {
- Thread.currentThread().interrupt();
- throw new RuntimeException("Interrupted while waiting for staging repository to close", ex);
- }
- }
- }
-
- private void logFailures(String stagedRepositoryId) {
- try {
- StagingRepositoryActivity[] activities = this.restTemplate.getForObject(
- NEXUS_STAGING_PATH + "repository/" + stagedRepositoryId + "/activity",
- StagingRepositoryActivity[].class);
- List failureMessages = Stream.of(activities).flatMap((activity) -> activity.events.stream())
- .filter((event) -> event.severity > 0).flatMap((event) -> event.properties.stream())
- .filter((property) -> "failureMessage".equals(property.name))
- .map((property) -> " " + property.value).toList();
- if (failureMessages.isEmpty()) {
- logger.error("Close failed for unknown reasons");
- }
- logger.error("Close failed:\n{}", Strings.join(failureMessages, '\n'));
- }
- catch (Exception ex) {
- logger.error("Failed to determine causes of close failure", ex);
- }
- }
-
- private void release(String stagedRepositoryId, String buildId) {
- Map data = new HashMap<>();
- data.put("stagedRepositoryIds", Arrays.asList(stagedRepositoryId));
- data.put("description", "Releasing " + buildId);
- data.put("autoDropAfterRelease", true);
- Map body = Collections.singletonMap("data", data);
- this.restTemplate.postForEntity(NEXUS_STAGING_PATH + "bulk/promote", body, Void.class);
- }
-
- private static final class PromoteResponse {
-
- private final Data data;
-
- @JsonCreator(mode = Mode.PROPERTIES)
- private PromoteResponse(@JsonProperty("data") Data data) {
- this.data = data;
- }
-
- private static final class Data {
-
- private final String stagedRepositoryId;
-
- @JsonCreator(mode = Mode.PROPERTIES)
- Data(@JsonProperty("stagedRepositoryId") String stagedRepositoryId) {
- this.stagedRepositoryId = stagedRepositoryId;
- }
-
- }
-
- }
-
- private static final class StagingRepository {
-
- private final String type;
-
- private final boolean transitioning;
-
- private StagingRepository(String type, boolean transitioning) {
- this.type = type;
- this.transitioning = transitioning;
- }
-
- }
-
- private static final class StagingRepositoryActivity {
-
- private final List events;
-
- @JsonCreator
- private StagingRepositoryActivity(@JsonProperty("events") List events) {
- this.events = events;
- }
-
- private static class Event {
-
- private final List properties;
-
- private final int severity;
-
- @JsonCreator
- public Event(@JsonProperty("name") String name, @JsonProperty("properties") List properties,
- @JsonProperty("severity") int severity) {
- this.properties = properties;
- this.severity = severity;
- }
-
- private static class Property {
-
- private final String name;
-
- private final String value;
-
- @JsonCreator
- private Property(@JsonProperty("name") String name, @JsonProperty("value") String value) {
- this.name = name;
- this.value = value;
- }
-
- }
-
- }
-
- }
-
-}
diff --git a/ci/images/releasescripts/src/main/resources/application.properties b/ci/images/releasescripts/src/main/resources/application.properties
deleted file mode 100644
index 56dfa61a1909..000000000000
--- a/ci/images/releasescripts/src/main/resources/application.properties
+++ /dev/null
@@ -1,4 +0,0 @@
-spring.main.banner-mode=off
-sonatype.exclude[0]=build-info\\.json
-sonatype.exclude[1]=org/springframework/boot/spring-boot-docs/.*
-logging.level.io.spring.concourse=DEBUG
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/java/io/spring/concourse/releasescripts/artifactory/ArtifactoryServiceTests.java b/ci/images/releasescripts/src/test/java/io/spring/concourse/releasescripts/artifactory/ArtifactoryServiceTests.java
deleted file mode 100644
index 70abda3c3b6e..000000000000
--- a/ci/images/releasescripts/src/test/java/io/spring/concourse/releasescripts/artifactory/ArtifactoryServiceTests.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright 2012-2023 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.spring.concourse.releasescripts.artifactory;
-
-import java.util.Base64;
-
-import io.spring.concourse.releasescripts.ReleaseInfo;
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.Test;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.context.properties.EnableConfigurationProperties;
-import org.springframework.boot.test.autoconfigure.web.client.RestClientTest;
-import org.springframework.core.io.ClassPathResource;
-import org.springframework.http.HttpMethod;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.MediaType;
-import org.springframework.test.web.client.MockRestServiceServer;
-import org.springframework.test.web.client.response.DefaultResponseCreator;
-import org.springframework.web.client.HttpClientErrorException;
-
-import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
-import static org.springframework.test.web.client.match.MockRestRequestMatchers.content;
-import static org.springframework.test.web.client.match.MockRestRequestMatchers.header;
-import static org.springframework.test.web.client.match.MockRestRequestMatchers.method;
-import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo;
-import static org.springframework.test.web.client.response.MockRestResponseCreators.withStatus;
-import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess;
-
-/**
- * Tests for {@link ArtifactoryService}.
- *
- * @author Madhura Bhave
- */
-@RestClientTest(ArtifactoryService.class)
-@EnableConfigurationProperties(ArtifactoryProperties.class)
-class ArtifactoryServiceTests {
-
- @Autowired
- private ArtifactoryService service;
-
- @Autowired
- private ArtifactoryProperties properties;
-
- @Autowired
- private MockRestServiceServer server;
-
- @AfterEach
- void tearDown() {
- this.server.reset();
- }
-
- @Test
- void promoteWhenSuccessful() {
- this.server.expect(requestTo("https://repo.spring.io/api/build/promote/example-build/example-build-1"))
- .andExpect(method(HttpMethod.POST))
- .andExpect(content().json(
- "{\"status\": \"staged\", \"sourceRepo\": \"libs-staging-local\", \"targetRepo\": \"libs-milestone-local\"}"))
- .andExpect(
- header("Authorization",
- "Basic " + Base64.getEncoder()
- .encodeToString(String.format("%s:%s", this.properties.getUsername(),
- this.properties.getPassword()).getBytes())))
- .andExpect(header("Content-Type", MediaType.APPLICATION_JSON.toString())).andRespond(withSuccess());
- this.service.promote("libs-milestone-local", getReleaseInfo());
- this.server.verify();
- }
-
- @Test
- void promoteWhenArtifactsAlreadyPromoted() {
- this.server.expect(requestTo("https://repo.spring.io/api/build/promote/example-build/example-build-1"))
- .andRespond(withStatus(HttpStatus.CONFLICT));
- this.server.expect(requestTo("https://repo.spring.io/api/build/example-build/example-build-1"))
- .andRespond(withJsonFrom("build-info-response.json"));
- this.service.promote("libs-release-local", getReleaseInfo());
- this.server.verify();
- }
-
- @Test
- void promoteWhenCheckForArtifactsAlreadyPromotedFails() {
- this.server.expect(requestTo("https://repo.spring.io/api/build/promote/example-build/example-build-1"))
- .andRespond(withStatus(HttpStatus.CONFLICT));
- this.server.expect(requestTo("https://repo.spring.io/api/build/example-build/example-build-1"))
- .andRespond(withStatus(HttpStatus.FORBIDDEN));
- assertThatExceptionOfType(HttpClientErrorException.class)
- .isThrownBy(() -> this.service.promote("libs-release-local", getReleaseInfo()));
- this.server.verify();
- }
-
- @Test
- void promoteWhenCheckForArtifactsAlreadyPromotedReturnsNoStatus() {
- this.server.expect(requestTo("https://repo.spring.io/api/build/promote/example-build/example-build-1"))
- .andRespond(withStatus(HttpStatus.CONFLICT));
- this.server.expect(requestTo("https://repo.spring.io/api/build/example-build/example-build-1"))
- .andRespond(withJsonFrom("no-status-build-info-response.json"));
- assertThatExceptionOfType(HttpClientErrorException.class)
- .isThrownBy(() -> this.service.promote("libs-milestone-local", getReleaseInfo()));
- this.server.verify();
- }
-
- @Test
- void promoteWhenPromotionFails() {
- this.server.expect(requestTo("https://repo.spring.io/api/build/promote/example-build/example-build-1"))
- .andRespond(withStatus(HttpStatus.CONFLICT));
- this.server.expect(requestTo("https://repo.spring.io/api/build/example-build/example-build-1"))
- .andRespond(withJsonFrom("staged-build-info-response.json"));
- assertThatExceptionOfType(HttpClientErrorException.class)
- .isThrownBy(() -> this.service.promote("libs-release-local", getReleaseInfo()));
- this.server.verify();
- }
-
- private ReleaseInfo getReleaseInfo() {
- ReleaseInfo releaseInfo = new ReleaseInfo();
- releaseInfo.setBuildName("example-build");
- releaseInfo.setBuildNumber("example-build-1");
- return releaseInfo;
- }
-
- private DefaultResponseCreator withJsonFrom(String path) {
- return withSuccess(getClassPathResource(path), MediaType.APPLICATION_JSON);
- }
-
- private ClassPathResource getClassPathResource(String path) {
- return new ClassPathResource(path, getClass());
- }
-
-}
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/java/io/spring/concourse/releasescripts/sdkman/SdkmanServiceTests.java b/ci/images/releasescripts/src/test/java/io/spring/concourse/releasescripts/sdkman/SdkmanServiceTests.java
deleted file mode 100644
index 3a81ecfd3f29..000000000000
--- a/ci/images/releasescripts/src/test/java/io/spring/concourse/releasescripts/sdkman/SdkmanServiceTests.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright 2012-2023 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.spring.concourse.releasescripts.sdkman;
-
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.Test;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.context.properties.EnableConfigurationProperties;
-import org.springframework.boot.test.autoconfigure.web.client.RestClientTest;
-import org.springframework.http.HttpMethod;
-import org.springframework.http.MediaType;
-import org.springframework.test.web.client.MockRestServiceServer;
-
-import static org.springframework.test.web.client.match.MockRestRequestMatchers.content;
-import static org.springframework.test.web.client.match.MockRestRequestMatchers.header;
-import static org.springframework.test.web.client.match.MockRestRequestMatchers.method;
-import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo;
-import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess;
-
-/**
- * Tests for {@link SdkmanService}.
- *
- * @author Madhura Bhave
- */
-@EnableConfigurationProperties(SdkmanProperties.class)
-@RestClientTest(SdkmanService.class)
-class SdkmanServiceTests {
-
- @Autowired
- private SdkmanService service;
-
- @Autowired
- private MockRestServiceServer server;
-
- @AfterEach
- void tearDown() {
- this.server.reset();
- }
-
- @Test
- void publishWhenMakeDefaultTrue() {
- setupExpectation("https://vendors.sdkman.io/release",
- "{\"candidate\": \"springboot\", \"version\": \"1.2.3\", \"url\": \"https://repo.maven.apache.org/maven2/org/springframework/boot/spring-boot-cli/1.2.3/spring-boot-cli-1.2.3-bin.zip\"}");
- setupExpectation("https://vendors.sdkman.io/default", "{\"candidate\": \"springboot\", \"version\": \"1.2.3\"}",
- HttpMethod.PUT);
- setupExpectation("https://vendors.sdkman.io/announce/struct",
- "{\"candidate\": \"springboot\", \"version\": \"1.2.3\", \"hashtag\": \"springboot\", \"url\": \"https://github.com/spring-projects/spring-boot/releases/tag/v1.2.3\"}");
- this.service.publish("1.2.3", true);
- this.server.verify();
- }
-
- @Test
- void publishWhenMakeDefaultFalse() {
- setupExpectation("https://vendors.sdkman.io/release",
- "{\"candidate\": \"springboot\", \"version\": \"1.2.3\", \"url\": \"https://repo.maven.apache.org/maven2/org/springframework/boot/spring-boot-cli/1.2.3/spring-boot-cli-1.2.3-bin.zip\"}");
- setupExpectation("https://vendors.sdkman.io/announce/struct",
- "{\"candidate\": \"springboot\", \"version\": \"1.2.3\", \"hashtag\": \"springboot\", \"url\": \"https://github.com/spring-projects/spring-boot/releases/tag/v1.2.3\"}");
- this.service.publish("1.2.3", false);
- this.server.verify();
- }
-
- private void setupExpectation(String url, String body) {
- setupExpectation(url, body, HttpMethod.POST);
- }
-
- private void setupExpectation(String url, String body, HttpMethod method) {
- this.server.expect(requestTo(url)).andExpect(method(method)).andExpect(content().json(body))
- .andExpect(header("Consumer-Key", "sdkman-consumer-key"))
- .andExpect(header("Consumer-Token", "sdkman-consumer-token"))
- .andExpect(header("Content-Type", MediaType.APPLICATION_JSON.toString())).andRespond(withSuccess());
- }
-
-}
diff --git a/ci/images/releasescripts/src/test/java/io/spring/concourse/releasescripts/sonatype/SonatypeServiceTests.java b/ci/images/releasescripts/src/test/java/io/spring/concourse/releasescripts/sonatype/SonatypeServiceTests.java
deleted file mode 100644
index 6c9133c7c677..000000000000
--- a/ci/images/releasescripts/src/test/java/io/spring/concourse/releasescripts/sonatype/SonatypeServiceTests.java
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * 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.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.spring.concourse.releasescripts.sonatype;
-
-import java.io.File;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Set;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-import io.spring.concourse.releasescripts.ReleaseInfo;
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.Test;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.context.properties.EnableConfigurationProperties;
-import org.springframework.boot.test.autoconfigure.web.client.RestClientTest;
-import org.springframework.core.io.FileSystemResource;
-import org.springframework.http.HttpMethod;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.MediaType;
-import org.springframework.http.client.ClientHttpRequest;
-import org.springframework.test.web.client.ExpectedCount;
-import org.springframework.test.web.client.MockRestServiceServer;
-import org.springframework.test.web.client.RequestMatcher;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
-import static org.hamcrest.Matchers.equalTo;
-import static org.springframework.test.web.client.match.MockRestRequestMatchers.header;
-import static org.springframework.test.web.client.match.MockRestRequestMatchers.jsonPath;
-import static org.springframework.test.web.client.match.MockRestRequestMatchers.method;
-import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo;
-import static org.springframework.test.web.client.response.MockRestResponseCreators.withStatus;
-import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess;
-
-/**
- * Tests for {@link SonatypeService}.
- *
- * @author Madhura Bhave
- */
-@RestClientTest(components = SonatypeService.class, properties = "sonatype.url=https://nexus.example.org")
-@EnableConfigurationProperties(SonatypeProperties.class)
-class SonatypeServiceTests {
-
- @Autowired
- private SonatypeService service;
-
- @Autowired
- private MockRestServiceServer server;
-
- @AfterEach
- void tearDown() {
- this.server.reset();
- }
-
- @Test
- void publishWhenAlreadyPublishedShouldNotPublish() {
- this.server.expect(requestTo(String.format(
- "/service/local/repositories/releases/content/org/springframework/boot/spring-boot/%s/spring-boot-%s.jar.sha1",
- "1.1.0.RELEASE", "1.1.0.RELEASE"))).andExpect(method(HttpMethod.GET))
- .andRespond(withSuccess().body("ce8d8b6838ecceb68962b9150b18682f4237ccf71".getBytes()));
- Path artifactsRoot = new File("src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo")
- .toPath();
- this.service.publish(getReleaseInfo(), artifactsRoot);
- this.server.verify();
- }
-
- @Test
- void publishWithSuccessfulClose() throws IOException {
- this.server.expect(requestTo(String.format(
- "/service/local/repositories/releases/content/org/springframework/boot/spring-boot/%s/spring-boot-%s.jar.sha1",
- "1.1.0.RELEASE", "1.1.0.RELEASE"))).andExpect(method(HttpMethod.GET))
- .andRespond(withStatus(HttpStatus.NOT_FOUND));
- this.server.expect(requestTo("/service/local/staging/profiles/1a2b3c4d/start"))
- .andExpect(method(HttpMethod.POST)).andExpect(header("Content-Type", "application/json"))
- .andExpect(header("Accept", "application/json, application/*+json"))
- .andExpect(jsonPath("$.data.description").value("example-build-1"))
- .andRespond(withStatus(HttpStatus.CREATED).contentType(MediaType.APPLICATION_JSON).body(
- "{\"data\":{\"stagedRepositoryId\":\"example-6789\", \"description\":\"example-build\"}}"));
- Path artifactsRoot = new File("src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo")
- .toPath();
- try (Stream artifacts = Files.walk(artifactsRoot)) {
- Set uploads = artifacts.filter(Files::isRegularFile)
- .map((artifact) -> artifactsRoot.relativize(artifact))
- .filter((artifact) -> !artifact.startsWith("build-info.json"))
- .map((artifact) -> requestTo(
- "/service/local/staging/deployByRepositoryId/example-6789/" + artifact.toString()))
- .collect(Collectors.toCollection(HashSet::new));
- AnyOfRequestMatcher uploadRequestsMatcher = anyOf(uploads);
- assertThat(uploadRequestsMatcher.candidates).hasSize(150);
- this.server.expect(ExpectedCount.times(150), uploadRequestsMatcher).andExpect(method(HttpMethod.PUT))
- .andRespond(withSuccess());
- this.server.expect(requestTo("/service/local/staging/profiles/1a2b3c4d/finish"))
- .andExpect(method(HttpMethod.POST)).andExpect(header("Content-Type", "application/json"))
- .andExpect(header("Accept", "application/json, application/*+json"))
- .andRespond(withStatus(HttpStatus.CREATED));
- this.server.expect(ExpectedCount.times(2), requestTo("/service/local/staging/repository/example-6789"))
- .andExpect(method(HttpMethod.GET))
- .andExpect(header("Accept", "application/json, application/*+json"))
- .andRespond(withSuccess().contentType(MediaType.APPLICATION_JSON)
- .body("{\"type\":\"open\", \"transitioning\":true}"));
- this.server.expect(requestTo("/service/local/staging/repository/example-6789"))
- .andExpect(method(HttpMethod.GET))
- .andExpect(header("Accept", "application/json, application/*+json"))
- .andRespond(withSuccess().contentType(MediaType.APPLICATION_JSON)
- .body("{\"type\":\"closed\", \"transitioning\":false}"));
- this.server.expect(requestTo("/service/local/staging/bulk/promote")).andExpect(method(HttpMethod.POST))
- .andExpect(header("Content-Type", "application/json"))
- .andExpect(header("Accept", "application/json, application/*+json"))
- .andExpect(jsonPath("$.data.description").value("Releasing example-build-1"))
- .andExpect(jsonPath("$.data.autoDropAfterRelease").value(true))
- .andExpect(jsonPath("$.data.stagedRepositoryIds").value(equalTo(Arrays.asList("example-6789"))))
- .andRespond(withSuccess());
- this.service.publish(getReleaseInfo(), artifactsRoot);
- this.server.verify();
- assertThat(uploadRequestsMatcher.candidates).hasSize(0);
- }
- }
-
- @Test
- void publishWithCloseFailureDueToRuleViolations() throws IOException {
- this.server.expect(requestTo(String.format(
- "/service/local/repositories/releases/content/org/springframework/boot/spring-boot/%s/spring-boot-%s.jar.sha1",
- "1.1.0.RELEASE", "1.1.0.RELEASE"))).andExpect(method(HttpMethod.GET))
- .andRespond(withStatus(HttpStatus.NOT_FOUND));
- this.server.expect(requestTo("/service/local/staging/profiles/1a2b3c4d/start"))
- .andExpect(method(HttpMethod.POST)).andExpect(header("Content-Type", "application/json"))
- .andExpect(header("Accept", "application/json, application/*+json"))
- .andExpect(jsonPath("$.data.description").value("example-build-1"))
- .andRespond(withStatus(HttpStatus.CREATED).contentType(MediaType.APPLICATION_JSON).body(
- "{\"data\":{\"stagedRepositoryId\":\"example-6789\", \"description\":\"example-build\"}}"));
- Path artifactsRoot = new File("src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo")
- .toPath();
- try (Stream artifacts = Files.walk(artifactsRoot)) {
- Set uploads = artifacts.filter(Files::isRegularFile)
- .map((artifact) -> artifactsRoot.relativize(artifact))
- .filter((artifact) -> !"build-info.json".equals(artifact.toString()))
- .map((artifact) -> requestTo(
- "/service/local/staging/deployByRepositoryId/example-6789/" + artifact.toString()))
- .collect(Collectors.toCollection(HashSet::new));
- AnyOfRequestMatcher uploadRequestsMatcher = anyOf(uploads);
- assertThat(uploadRequestsMatcher.candidates).hasSize(150);
- this.server.expect(ExpectedCount.times(150), uploadRequestsMatcher).andExpect(method(HttpMethod.PUT))
- .andRespond(withSuccess());
- this.server.expect(requestTo("/service/local/staging/profiles/1a2b3c4d/finish"))
- .andExpect(method(HttpMethod.POST)).andExpect(header("Content-Type", "application/json"))
- .andExpect(header("Accept", "application/json, application/*+json"))
- .andRespond(withStatus(HttpStatus.CREATED));
- this.server.expect(ExpectedCount.times(2), requestTo("/service/local/staging/repository/example-6789"))
- .andExpect(method(HttpMethod.GET))
- .andExpect(header("Accept", "application/json, application/*+json"))
- .andRespond(withSuccess().contentType(MediaType.APPLICATION_JSON)
- .body("{\"type\":\"open\", \"transitioning\":true}"));
- this.server.expect(requestTo("/service/local/staging/repository/example-6789"))
- .andExpect(method(HttpMethod.GET))
- .andExpect(header("Accept", "application/json, application/*+json"))
- .andRespond(withSuccess().contentType(MediaType.APPLICATION_JSON)
- .body("{\"type\":\"open\", \"transitioning\":false}"));
- this.server.expect(requestTo("/service/local/staging/repository/example-6789/activity"))
- .andExpect(method(HttpMethod.GET))
- .andExpect(header("Accept", "application/json, application/*+json"))
- .andRespond(withSuccess().contentType(MediaType.APPLICATION_JSON).body(new FileSystemResource(
- new File("src/test/resources/io/spring/concourse/releasescripts/sonatype/activity.json"))));
- assertThatExceptionOfType(RuntimeException.class)
- .isThrownBy(() -> this.service.publish(getReleaseInfo(), artifactsRoot))
- .withMessage("Close failed");
- this.server.verify();
- assertThat(uploadRequestsMatcher.candidates).hasSize(0);
- }
- }
-
- private ReleaseInfo getReleaseInfo() {
- ReleaseInfo releaseInfo = new ReleaseInfo();
- releaseInfo.setBuildName("example-build");
- releaseInfo.setBuildNumber("example-build-1");
- releaseInfo.setVersion("1.1.0.RELEASE");
- releaseInfo.setGroupId("example");
- return releaseInfo;
- }
-
- private AnyOfRequestMatcher anyOf(Set candidates) {
- return new AnyOfRequestMatcher(candidates);
- }
-
- private static class AnyOfRequestMatcher implements RequestMatcher {
-
- private final Object monitor = new Object();
-
- private final Set candidates;
-
- private AnyOfRequestMatcher(Set candidates) {
- this.candidates = candidates;
- }
-
- @Override
- public void match(ClientHttpRequest request) throws IOException, AssertionError {
- synchronized (this.monitor) {
- Iterator iterator = this.candidates.iterator();
- while (iterator.hasNext()) {
- try {
- iterator.next().match(request);
- iterator.remove();
- return;
- }
- catch (AssertionError ex) {
- // Continue
- }
- }
- throw new AssertionError(
- "No matching request matcher was found for request to '" + request.getURI() + "'");
- }
- }
-
- }
-
-}
diff --git a/ci/images/releasescripts/src/test/resources/application.yml b/ci/images/releasescripts/src/test/resources/application.yml
deleted file mode 100644
index 9c2cbc9d5b25..000000000000
--- a/ci/images/releasescripts/src/test/resources/application.yml
+++ /dev/null
@@ -1,16 +0,0 @@
-artifactory:
- username: user
- password: password
-bintray:
- username: bintray-user
- api-key: bintray-api-key
- repo: test
- subject: jars
-sonatype:
- user-token: sonatype-user
- password-token: sonatype-password
- polling-interval: 1s
- staging-profile-id: 1a2b3c4d
-sdkman:
- consumer-key: sdkman-consumer-key
- consumer-token: sdkman-consumer-token
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/artifactory/build-info-response.json b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/artifactory/build-info-response.json
deleted file mode 100644
index bfe0d3be186b..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/artifactory/build-info-response.json
+++ /dev/null
@@ -1,35 +0,0 @@
-{
- "buildInfo": {
- "version": "1.0.1",
- "name": "example",
- "number": "example-build-1",
- "started": "2019-09-10T12:18:05.430+0000",
- "durationMillis": 0,
- "artifactoryPrincipal": "user",
- "url": "https://my-ci.com",
- "modules": [
- {
- "id": "org.example.demo:demo:2.2.0",
- "artifacts": [
- {
- "type": "jar",
- "sha1": "ayyyya9151a22cb3145538e523dbbaaaaaaaa",
- "sha256": "aaaaaaaaa85f5c5093721f3ed0edda8ff8290yyyyyyyyyy",
- "md5": "aaaaaacddea1724b0b69d8yyyyyyy",
- "name": "demo-2.2.0.jar"
- }
- ]
- }
- ],
- "statuses": [
- {
- "status": "staged",
- "repository": "libs-release-local",
- "timestamp": "2019-09-10T12:42:24.716+0000",
- "user": "user",
- "timestampDate": 1568119344716
- }
- ]
- },
- "uri": "https://my-artifactory-repo.com/api/build/example/example-build-1"
-}
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/artifactory/filtered-build-info-response.json b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/artifactory/filtered-build-info-response.json
deleted file mode 100644
index 9f9935114de5..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/artifactory/filtered-build-info-response.json
+++ /dev/null
@@ -1,59 +0,0 @@
-{
- "buildInfo": {
- "version": "1.0.1",
- "name": "example",
- "number": "example-build-1",
- "started": "2019-09-10T12:18:05.430+0000",
- "durationMillis": 0,
- "artifactoryPrincipal": "user",
- "url": "https://my-ci.com",
- "modules": [
- {
- "id": "org.example.demo:demo:2.2.0",
- "artifacts": [
- {
- "type": "jar",
- "sha1": "ayyyya9151a22cb3145538e523dbbaaaaaaaa",
- "sha256": "aaaaaaaaa85f5c5093721f3ed0edda8ff8290yyyyyyyyyy",
- "md5": "aaaaaacddea1724b0b69d8yyyyyyy",
- "name": "demo-2.2.0.jar"
- }
- ]
- },
- {
- "id": "org.example.demo:demo:2.2.0:zip",
- "artifacts": [
- {
- "type": "zip",
- "sha1": "ayyyya9151a22cb3145538e523dbbaaaaaaab",
- "sha256": "aaaaaaaaa85f5c5093721f3ed0edda8ff8290yyyyyyyyyz",
- "md5": "aaaaaacddea1724b0b69d8yyyyyyz",
- "name": "demo-2.2.0.zip"
- }
- ]
- },
- {
- "id": "org.example.demo:demo:2.2.0:doc",
- "artifacts": [
- {
- "type": "jar",
- "sha1": "ayyyya9151a22cb3145538e523dbbaaaaaaba",
- "sha256": "aaaaaaaaa85f5c5093721f3ed0edda8ff8290yyyyyyyyzy",
- "md5": "aaaaaacddea1724b0b69d8yyyyyzy",
- "name": "demo-2.2.0.doc"
- }
- ]
- }
- ],
- "statuses": [
- {
- "status": "staged",
- "repository": "libs-release-local",
- "timestamp": "2019-09-10T12:42:24.716+0000",
- "user": "user",
- "timestampDate": 1568119344716
- }
- ]
- },
- "uri": "https://my-artifactory-repo.com/api/build/example/example-build-1"
-}
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/artifactory/no-status-build-info-response.json b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/artifactory/no-status-build-info-response.json
deleted file mode 100644
index 6183ca80018c..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/artifactory/no-status-build-info-response.json
+++ /dev/null
@@ -1,26 +0,0 @@
-{
- "buildInfo": {
- "version": "1.0.1",
- "name": "example",
- "number": "example-build-1",
- "started": "2019-09-10T12:18:05.430+0000",
- "durationMillis": 0,
- "artifactoryPrincipal": "user",
- "url": "https://my-ci.com",
- "modules": [
- {
- "id": "org.example.demo:demo:2.2.0",
- "artifacts": [
- {
- "type": "jar",
- "sha1": "ayyyya9151a22cb3145538e523dbbaaaaaaaa",
- "sha256": "aaaaaaaaa85f5c5093721f3ed0edda8ff8290yyyyyyyyyy",
- "md5": "aaaaaacddea1724b0b69d8yyyyyyy",
- "name": "demo-2.2.0.jar"
- }
- ]
- }
- ]
- },
- "uri": "https://my-artifactory-repo.com/api/build/example/example-build-1"
-}
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/artifactory/staged-build-info-response.json b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/artifactory/staged-build-info-response.json
deleted file mode 100644
index 33be7a0ffe23..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/artifactory/staged-build-info-response.json
+++ /dev/null
@@ -1,35 +0,0 @@
-{
- "buildInfo": {
- "version": "1.0.1",
- "name": "example",
- "number": "example-build-1",
- "started": "2019-09-10T12:18:05.430+0000",
- "durationMillis": 0,
- "artifactoryPrincipal": "user",
- "url": "https://my-ci.com",
- "modules": [
- {
- "id": "org.example.demo:demo:2.2.0",
- "artifacts": [
- {
- "type": "jar",
- "sha1": "ayyyya9151a22cb3145538e523dbbaaaaaaaa",
- "sha256": "aaaaaaaaa85f5c5093721f3ed0edda8ff8290yyyyyyyyyy",
- "md5": "aaaaaacddea1724b0b69d8yyyyyyy",
- "name": "demo-2.2.0.jar"
- }
- ]
- }
- ],
- "statuses": [
- {
- "status": "staged",
- "repository": "libs-staging-local",
- "timestamp": "2019-09-10T12:42:24.716+0000",
- "user": "user",
- "timestampDate": 1568119344716
- }
- ]
- },
- "uri": "https://my-artifactory-repo.com/api/build/example/example-build-1"
-}
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/activity.json b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/activity.json
deleted file mode 100644
index 92e0e141371d..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/activity.json
+++ /dev/null
@@ -1,362 +0,0 @@
-[
- {
- "events": [
- {
- "name": "repositoryCreated",
- "properties": [
- {
- "name": "id",
- "value": "orgspringframework-7161"
- },
- {
- "name": "user",
- "value": "user"
- },
- {
- "name": "ip",
- "value": "127.0.0.1"
- }
- ],
- "severity": 0,
- "timestamp": "2021-02-08T14:31:13.523Z"
- }
- ],
- "name": "open",
- "started": "2021-02-08T14:31:00.662Z",
- "stopped": "2021-02-08T14:31:14.855Z"
- },
- {
- "events": [
- {
- "name": "rulesEvaluate",
- "properties": [
- {
- "name": "id",
- "value": "5e9e8e6f8d20a3"
- },
- {
- "name": "rule",
- "value": "no-traversal-paths-in-archive-file"
- },
- {
- "name": "rule",
- "value": "profile-target-matching-staging"
- },
- {
- "name": "rule",
- "value": "sbom-report"
- },
- {
- "name": "rule",
- "value": "checksum-staging"
- },
- {
- "name": "rule",
- "value": "javadoc-staging"
- },
- {
- "name": "rule",
- "value": "pom-staging"
- },
- {
- "name": "rule",
- "value": "signature-staging"
- },
- {
- "name": "rule",
- "value": "sources-staging"
- }
- ],
- "severity": 0,
- "timestamp": "2021-02-08T14:31:37.327Z"
- },
- {
- "name": "ruleEvaluate",
- "properties": [
- {
- "name": "typeId",
- "value": "no-traversal-paths-in-archive-file"
- }
- ],
- "severity": 0,
- "timestamp": "2021-02-08T14:31:41.254Z"
- },
- {
- "name": "rulePassed",
- "properties": [
- {
- "name": "typeId",
- "value": "no-traversal-paths-in-archive-file"
- }
- ],
- "severity": 0,
- "timestamp": "2021-02-08T14:31:47.498Z"
- },
- {
- "name": "ruleEvaluate",
- "properties": [
- {
- "name": "typeId",
- "value": "javadoc-staging"
- }
- ],
- "severity": 0,
- "timestamp": "2021-02-08T14:31:53.438Z"
- },
- {
- "name": "rulePassed",
- "properties": [
- {
- "name": "typeId",
- "value": "javadoc-staging"
- }
- ],
- "severity": 0,
- "timestamp": "2021-02-08T14:31:54.623Z"
- },
- {
- "name": "ruleEvaluate",
- "properties": [
- {
- "name": "typeId",
- "value": "pom-staging"
- }
- ],
- "severity": 0,
- "timestamp": "2021-02-08T14:31:58.091Z"
- },
- {
- "name": "ruleFailed",
- "properties": [
- {
- "name": "typeId",
- "value": "pom-staging"
- },
- {
- "name": "failureMessage",
- "value": "Invalid POM: /org/springframework/example/module-one/1.0.0/module-one-1.0.0.pom: Project name missing, Project description missing, Project URL missing, License information missing, SCM URL missing, Developer information missing"
- },
- {
- "name": "failureMessage",
- "value": "Invalid POM: /org/springframework/example/module-two/1.0.0/module-two-1.0.0.pom: Project name missing, Project description missing, Project URL missing, License information missing, SCM URL missing, Developer information missing"
- },
- {
- "name": "failureMessage",
- "value": "Invalid POM: /org/springframework/example/module-three/1.0.0/module-three-1.0.0.pom: Project name missing, Project description missing, Project URL missing, License information missing, SCM URL missing, Developer information missing"
- }
- ],
- "severity": 1,
- "timestamp": "2021-02-08T14:31:59.403Z"
- },
- {
- "name": "ruleEvaluate",
- "properties": [
- {
- "name": "typeId",
- "value": "profile-target-matching-staging"
- }
- ],
- "severity": 0,
- "timestamp": "2021-02-08T14:32:05.322Z"
- },
- {
- "name": "rulePassed",
- "properties": [
- {
- "name": "typeId",
- "value": "profile-target-matching-staging"
- }
- ],
- "severity": 0,
- "timestamp": "2021-02-08T14:32:06.492Z"
- },
- {
- "name": "ruleEvaluate",
- "properties": [
- {
- "name": "typeId",
- "value": "checksum-staging"
- }
- ],
- "severity": 0,
- "timestamp": "2021-02-08T14:32:12.415Z"
- },
- {
- "name": "rulePassed",
- "properties": [
- {
- "name": "typeId",
- "value": "checksum-staging"
- }
- ],
- "severity": 0,
- "timestamp": "2021-02-08T14:32:13.568Z"
- },
- {
- "name": "ruleEvaluate",
- "properties": [
- {
- "name": "typeId",
- "value": "signature-staging"
- }
- ],
- "severity": 0,
- "timestamp": "2021-02-08T14:32:18.288Z"
- },
- {
- "name": "ruleFailed",
- "properties": [
- {
- "name": "typeId",
- "value": "signature-staging"
- },
- {
- "name": "failureMessage",
- "value": "Missing Signature: '/org/springframework/example/module-one/1.0.0/module-one-1.0.0-javadoc.jar.asc' does not exist for 'module-one-1.0.0-javadoc.jar'."
- },
- {
- "name": "failureMessage",
- "value": "Missing Signature: '/org/springframework/example/module-one/1.0.0/module-one-1.0.0.jar.asc' does not exist for 'module-one-1.0.0.jar'."
- },
- {
- "name": "failureMessage",
- "value": "Missing Signature: '/org/springframework/example/module-one/1.0.0/module-one-1.0.0-sources.jar.asc' does not exist for 'module-one-1.0.0-sources.jar'."
- },
- {
- "name": "failureMessage",
- "value": "Missing Signature: '/org/springframework/example/module-one/1.0.0/module-one-1.0.0.module.asc' does not exist for 'module-one-1.0.0.module'."
- },
- {
- "name": "failureMessage",
- "value": "Missing Signature: '/org/springframework/example/module-one/1.0.0/module-one-1.0.0.pom.asc' does not exist for 'module-one-1.0.0.pom'."
- },
- {
- "name": "failureMessage",
- "value": "Missing Signature: '/org/springframework/example/module-two/1.0.0/module-two-1.0.0.module.asc' does not exist for 'module-two-1.0.0.module'."
- },
- {
- "name": "failureMessage",
- "value": "Missing Signature: '/org/springframework/example/module-two/1.0.0/module-two-1.0.0.pom.asc' does not exist for 'module-two-1.0.0.pom'."
- },
- {
- "name": "failureMessage",
- "value": "Missing Signature: '/org/springframework/example/module-two/1.0.0/module-two-1.0.0-sources.jar.asc' does not exist for 'module-two-1.0.0-sources.jar'."
- },
- {
- "name": "failureMessage",
- "value": "Missing Signature: '/org/springframework/example/module-two/1.0.0/module-two-1.0.0.jar.asc' does not exist for 'module-two-1.0.0.jar'."
- },
- {
- "name": "failureMessage",
- "value": "Missing Signature: '/org/springframework/example/module-two/1.0.0/module-two-1.0.0-javadoc.jar.asc' does not exist for 'module-two-1.0.0-javadoc.jar'."
- },
- {
- "name": "failureMessage",
- "value": "Missing Signature: '/org/springframework/example/module-three/1.0.0/module-three-1.0.0.module.asc' does not exist for 'module-three-1.0.0.module'."
- },
- {
- "name": "failureMessage",
- "value": "Missing Signature: '/org/springframework/example/module-three/1.0.0/module-three-1.0.0-javadoc.jar.asc' does not exist for 'module-three-1.0.0-javadoc.jar'."
- },
- {
- "name": "failureMessage",
- "value": "Missing Signature: '/org/springframework/example/module-three/1.0.0/module-three-1.0.0-sources.jar.asc' does not exist for 'module-three-1.0.0-sources.jar'."
- },
- {
- "name": "failureMessage",
- "value": "Missing Signature: '/org/springframework/example/module-three/1.0.0/module-three-1.0.0.jar.asc' does not exist for 'module-three-1.0.0.jar'."
- },
- {
- "name": "failureMessage",
- "value": "Missing Signature: '/org/springframework/example/module-three/1.0.0/module-three-1.0.0.pom.asc' does not exist for 'module-three-1.0.0.pom'."
- }
- ],
- "severity": 1,
- "timestamp": "2021-02-08T14:32:19.443Z"
- },
- {
- "name": "ruleEvaluate",
- "properties": [
- {
- "name": "typeId",
- "value": "sources-staging"
- }
- ],
- "severity": 0,
- "timestamp": "2021-02-08T14:32:24.175Z"
- },
- {
- "name": "rulePassed",
- "properties": [
- {
- "name": "typeId",
- "value": "sources-staging"
- }
- ],
- "severity": 0,
- "timestamp": "2021-02-08T14:32:28.940Z"
- },
- {
- "name": "ruleEvaluate",
- "properties": [
- {
- "name": "typeId",
- "value": "sbom-report"
- }
- ],
- "severity": 0,
- "timestamp": "2021-02-08T14:32:34.906Z"
- },
- {
- "name": "rulePassed",
- "properties": [
- {
- "name": "typeId",
- "value": "sbom-report"
- },
- {
- "name": "successMessage",
- "value": "Successfully requested SBOM report"
- }
- ],
- "severity": 0,
- "timestamp": "2021-02-08T14:32:36.520Z"
- },
- {
- "name": "rulesFailed",
- "properties": [
- {
- "name": "id",
- "value": "5e9e8e6f8d20a3"
- },
- {
- "name": "failureCount",
- "value": "2"
- }
- ],
- "severity": 1,
- "timestamp": "2021-02-08T14:32:42.068Z"
- },
- {
- "name": "repositoryCloseFailed",
- "properties": [
- {
- "name": "id",
- "value": "orgspringframework-7161"
- },
- {
- "name": "cause",
- "value": "com.sonatype.nexus.staging.StagingRulesFailedException: One or more rules have failed"
- }
- ],
- "severity": 1,
- "timestamp": "2021-02-08T14:32:43.218Z"
- }
- ],
- "name": "close",
- "started": "2021-02-08T14:31:34.943Z",
- "startedByIpAddress": "127.0.0.1",
- "startedByUserId": "user",
- "stopped": "2021-02-08T14:32:47.138Z"
- }
-]
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/build-info.json b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/build-info.json
deleted file mode 100644
index bfe0d3be186b..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/build-info.json
+++ /dev/null
@@ -1,35 +0,0 @@
-{
- "buildInfo": {
- "version": "1.0.1",
- "name": "example",
- "number": "example-build-1",
- "started": "2019-09-10T12:18:05.430+0000",
- "durationMillis": 0,
- "artifactoryPrincipal": "user",
- "url": "https://my-ci.com",
- "modules": [
- {
- "id": "org.example.demo:demo:2.2.0",
- "artifacts": [
- {
- "type": "jar",
- "sha1": "ayyyya9151a22cb3145538e523dbbaaaaaaaa",
- "sha256": "aaaaaaaaa85f5c5093721f3ed0edda8ff8290yyyyyyyyyy",
- "md5": "aaaaaacddea1724b0b69d8yyyyyyy",
- "name": "demo-2.2.0.jar"
- }
- ]
- }
- ],
- "statuses": [
- {
- "status": "staged",
- "repository": "libs-release-local",
- "timestamp": "2019-09-10T12:42:24.716+0000",
- "user": "user",
- "timestampDate": 1568119344716
- }
- ]
- },
- "uri": "https://my-artifactory-repo.com/api/build/example/example-build-1"
-}
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-javadoc.jar b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-javadoc.jar
deleted file mode 100644
index a142d391c0af..000000000000
Binary files a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-javadoc.jar and /dev/null differ
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-javadoc.jar.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-javadoc.jar.asc
deleted file mode 100644
index 85d6a7cb1e5a..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-javadoc.jar.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
-xT3qtgf8CeDvxzi7lPghlrZtmYTTjaic4FZsGRWTPky3H24i4wSRDhG0L5sj4uPK
-eLLlITr5a9j26UCas9HRSthiC8+EgIMAhSN0X482SQhUZHAW67ErIvaHlwL+ixMD
-0T5pmsW8PKN3lV1TFMhNYSEC2GRG/4GF+3yQA8LR+BgeEu/E5nmysIH8vuQMkOD6
-3pKA8VKNBml591j6UTqxoHtPX+rThaziz3Hy3+ekf5iWslllTTGPd2SWqTvnj2Ae
-GvRzsbli+FEM0Aj/v8jUQnQzOz891QSvWR+fMfCqZimiJMc+GBzJ9umbcyQsB5tY
-e26mAoYd9KEpGXMKN4biHbJZNp1GGw==
-=x/MY
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-javadoc.jar.md5 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-javadoc.jar.md5
deleted file mode 100644
index 95fa4af1641f..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-javadoc.jar.md5
+++ /dev/null
@@ -1 +0,0 @@
-e84da489be91de821c95d41b8f0e0a0a
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-javadoc.jar.md5.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-javadoc.jar.md5.asc
deleted file mode 100644
index 1cbf6ccffa07..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-javadoc.jar.md5.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
-xT1PSwf+InTdlh+BVVy3RFszEL5vN7waSPYMImXhgd5EZ1d4Lxd6EeOwtNgWNKpG
-E+Ps/Kw0jZDvoD49WJlcUjzDHBNHcE7C/L3GAWHV6WwklhtQaJ4EegsynWdSXz6k
-fqJY6r58aGKGjpKPutRWAjvfcdC170+ZRsc2oi9xrAgHCpvXzTjq4+O9Ah0t5jwW
-jcZ/Xubcw4vjsw774OucHbtwGsvRN5SDJ3IONOH8WCwhUP5vEEKvA6MYX0KGoTdS
-3wTCyZTzU3qtTWxcbTCpiJIWbYwRR7TzLB/uydWHlAMzuz6coIiBpYsGiO6wkmfg
-W+QvcE7wyW2jtb22pCImLyObyZ21VA==
-=VjDv
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-javadoc.jar.sha1 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-javadoc.jar.sha1
deleted file mode 100644
index 2a2834e1ab41..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-javadoc.jar.sha1
+++ /dev/null
@@ -1 +0,0 @@
-8992b17455ce660da9c5fe47226b7ded9e872637
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-javadoc.jar.sha1.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-javadoc.jar.sha1.asc
deleted file mode 100644
index 4cd212d6e1e9..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-javadoc.jar.sha1.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
-xT2HQgf+MTUEnwzXK4zi76VI7C5cchGan26lIA2Ebq4vtYGKDqNSISOAAdWs9+nT
-U6ZA6OIFo5qdeD6F/45s91IoDbxbhMDMFEsSijKASqiuZN5TZM1U2h2kWFAl/sEl
-EI1RTygn+xDw/ah4V3/duuMFC+jRgvJ/LgemIF4KBvECWaTQKNu0fu5d4dPXMpp+
-jrxMEZPQZsivpOvklzV8O7wAkf/ZQhJdcB2m8uOfSPlJ91a4EEtXF9/GzzkXUi1P
-bzt4NsmOag3227B3mO1Bc6yZdDBNu8wQ9apiJVCpqsxB9Dz0PCL4dHNa1u9g6Xo6
-ElRgneV4HZp+LB125VoNabKuNH00bw==
-=2yDl
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-javadoc.jar.sha256 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-javadoc.jar.sha256
deleted file mode 100644
index 4f27f01046dd..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-javadoc.jar.sha256
+++ /dev/null
@@ -1 +0,0 @@
-10ce8a82f7e53c67f2af8d4dc4b8cdb4d0630d0e1d21818da4d5b3ca2de08385
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-javadoc.jar.sha256.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-javadoc.jar.sha256.asc
deleted file mode 100644
index e29629cbec07..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-javadoc.jar.sha256.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
-xT0ScQf7Bip+quFq1CzDCTDxUhdTTOIpQcCfMKo1Jegpa2Hlm63XuK+6zVI9u6S+
-dBXPdYeneMOqMPQUAaw3M06ZqohaDOt8Ti1EiQFGXCdOvbonTA52Lrd4EEZxwNnK
-BdPuIh/8qCfozm5KbZe1bFyGVRAdNyf27KvzHgfBTirLtI+3MiOdL4bvNZbWRPfh
-J84Ko+Ena8jPFgyz6nJv2Q2U/V3dCooLJAXs2vEG6owwk5J9zvSysWpHaJbXas5v
-KXO9TOBBjf3+vxb1WVQa8ZYUU3+FIFes0RFVgOWghJXIooOcWrwOV2Q8z9qWXwoK
-mMZ2oLS+z/7clXibK45KeRUeCX5DvQ==
-=5oO1
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-javadoc.jar.sha512 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-javadoc.jar.sha512
deleted file mode 100644
index eb02a04a89d2..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-javadoc.jar.sha512
+++ /dev/null
@@ -1 +0,0 @@
-2730ac0859e1c2f450d54647c29ece43d095eb834e2130d4949dd1151317d013c072fa8f96f5f4b49836eff7c19a2eeeb5ca7483e5dac24c368bbcd522c27a00
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-javadoc.jar.sha512.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-javadoc.jar.sha512.asc
deleted file mode 100644
index f35b726baff6..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-javadoc.jar.sha512.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
-xT3d+AgAwQvlwnKQLLuiZADGL+I922/YG317N2Re1EjC6WlMRZUKXH54fckRTyPm
-4ZLyxVHy8LlUD2Q10g69opb7HRd/tV0miBJhn5OU1wIM3hqTgxNp9EFckK4md45k
-osnhQJNDsFToxJL8zPP+KRs/aWPZs+FrRcH6k26lwLl2gTfyBDsaU11HFRVEN9yi
-X41obVyKiVNlc9efSSvlLtRBSVt0VhAFhck+3t61H6D9H09QxaDGAqmduDua3Tg3
-t5eqURuDfv3TfSztYgK3JBmG/6gVMsZodCgyC+8rhDDs6vSoDG30apx5Leg2rPbj
-xuk2wi/WNzc94IgY9tVS3tAfT2k6yQ==
-=6+Cv
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-sources.jar b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-sources.jar
deleted file mode 100644
index a142d391c0af..000000000000
Binary files a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-sources.jar and /dev/null differ
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-sources.jar.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-sources.jar.asc
deleted file mode 100644
index 85d6a7cb1e5a..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-sources.jar.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
-xT3qtgf8CeDvxzi7lPghlrZtmYTTjaic4FZsGRWTPky3H24i4wSRDhG0L5sj4uPK
-eLLlITr5a9j26UCas9HRSthiC8+EgIMAhSN0X482SQhUZHAW67ErIvaHlwL+ixMD
-0T5pmsW8PKN3lV1TFMhNYSEC2GRG/4GF+3yQA8LR+BgeEu/E5nmysIH8vuQMkOD6
-3pKA8VKNBml591j6UTqxoHtPX+rThaziz3Hy3+ekf5iWslllTTGPd2SWqTvnj2Ae
-GvRzsbli+FEM0Aj/v8jUQnQzOz891QSvWR+fMfCqZimiJMc+GBzJ9umbcyQsB5tY
-e26mAoYd9KEpGXMKN4biHbJZNp1GGw==
-=x/MY
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-sources.jar.md5 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-sources.jar.md5
deleted file mode 100644
index 95fa4af1641f..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-sources.jar.md5
+++ /dev/null
@@ -1 +0,0 @@
-e84da489be91de821c95d41b8f0e0a0a
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-sources.jar.md5.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-sources.jar.md5.asc
deleted file mode 100644
index 1cbf6ccffa07..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-sources.jar.md5.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
-xT1PSwf+InTdlh+BVVy3RFszEL5vN7waSPYMImXhgd5EZ1d4Lxd6EeOwtNgWNKpG
-E+Ps/Kw0jZDvoD49WJlcUjzDHBNHcE7C/L3GAWHV6WwklhtQaJ4EegsynWdSXz6k
-fqJY6r58aGKGjpKPutRWAjvfcdC170+ZRsc2oi9xrAgHCpvXzTjq4+O9Ah0t5jwW
-jcZ/Xubcw4vjsw774OucHbtwGsvRN5SDJ3IONOH8WCwhUP5vEEKvA6MYX0KGoTdS
-3wTCyZTzU3qtTWxcbTCpiJIWbYwRR7TzLB/uydWHlAMzuz6coIiBpYsGiO6wkmfg
-W+QvcE7wyW2jtb22pCImLyObyZ21VA==
-=VjDv
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-sources.jar.sha1 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-sources.jar.sha1
deleted file mode 100644
index 2a2834e1ab41..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-sources.jar.sha1
+++ /dev/null
@@ -1 +0,0 @@
-8992b17455ce660da9c5fe47226b7ded9e872637
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-sources.jar.sha1.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-sources.jar.sha1.asc
deleted file mode 100644
index 4cd212d6e1e9..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-sources.jar.sha1.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
-xT2HQgf+MTUEnwzXK4zi76VI7C5cchGan26lIA2Ebq4vtYGKDqNSISOAAdWs9+nT
-U6ZA6OIFo5qdeD6F/45s91IoDbxbhMDMFEsSijKASqiuZN5TZM1U2h2kWFAl/sEl
-EI1RTygn+xDw/ah4V3/duuMFC+jRgvJ/LgemIF4KBvECWaTQKNu0fu5d4dPXMpp+
-jrxMEZPQZsivpOvklzV8O7wAkf/ZQhJdcB2m8uOfSPlJ91a4EEtXF9/GzzkXUi1P
-bzt4NsmOag3227B3mO1Bc6yZdDBNu8wQ9apiJVCpqsxB9Dz0PCL4dHNa1u9g6Xo6
-ElRgneV4HZp+LB125VoNabKuNH00bw==
-=2yDl
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-sources.jar.sha256 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-sources.jar.sha256
deleted file mode 100644
index 4f27f01046dd..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-sources.jar.sha256
+++ /dev/null
@@ -1 +0,0 @@
-10ce8a82f7e53c67f2af8d4dc4b8cdb4d0630d0e1d21818da4d5b3ca2de08385
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-sources.jar.sha256.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-sources.jar.sha256.asc
deleted file mode 100644
index e29629cbec07..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-sources.jar.sha256.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
-xT0ScQf7Bip+quFq1CzDCTDxUhdTTOIpQcCfMKo1Jegpa2Hlm63XuK+6zVI9u6S+
-dBXPdYeneMOqMPQUAaw3M06ZqohaDOt8Ti1EiQFGXCdOvbonTA52Lrd4EEZxwNnK
-BdPuIh/8qCfozm5KbZe1bFyGVRAdNyf27KvzHgfBTirLtI+3MiOdL4bvNZbWRPfh
-J84Ko+Ena8jPFgyz6nJv2Q2U/V3dCooLJAXs2vEG6owwk5J9zvSysWpHaJbXas5v
-KXO9TOBBjf3+vxb1WVQa8ZYUU3+FIFes0RFVgOWghJXIooOcWrwOV2Q8z9qWXwoK
-mMZ2oLS+z/7clXibK45KeRUeCX5DvQ==
-=5oO1
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-sources.jar.sha512 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-sources.jar.sha512
deleted file mode 100644
index eb02a04a89d2..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-sources.jar.sha512
+++ /dev/null
@@ -1 +0,0 @@
-2730ac0859e1c2f450d54647c29ece43d095eb834e2130d4949dd1151317d013c072fa8f96f5f4b49836eff7c19a2eeeb5ca7483e5dac24c368bbcd522c27a00
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-sources.jar.sha512.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-sources.jar.sha512.asc
deleted file mode 100644
index f35b726baff6..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-sources.jar.sha512.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
-xT3d+AgAwQvlwnKQLLuiZADGL+I922/YG317N2Re1EjC6WlMRZUKXH54fckRTyPm
-4ZLyxVHy8LlUD2Q10g69opb7HRd/tV0miBJhn5OU1wIM3hqTgxNp9EFckK4md45k
-osnhQJNDsFToxJL8zPP+KRs/aWPZs+FrRcH6k26lwLl2gTfyBDsaU11HFRVEN9yi
-X41obVyKiVNlc9efSSvlLtRBSVt0VhAFhck+3t61H6D9H09QxaDGAqmduDua3Tg3
-t5eqURuDfv3TfSztYgK3JBmG/6gVMsZodCgyC+8rhDDs6vSoDG30apx5Leg2rPbj
-xuk2wi/WNzc94IgY9tVS3tAfT2k6yQ==
-=6+Cv
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.jar b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.jar
deleted file mode 100644
index a142d391c0af..000000000000
Binary files a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.jar and /dev/null differ
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.jar.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.jar.asc
deleted file mode 100644
index 85d6a7cb1e5a..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.jar.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
-xT3qtgf8CeDvxzi7lPghlrZtmYTTjaic4FZsGRWTPky3H24i4wSRDhG0L5sj4uPK
-eLLlITr5a9j26UCas9HRSthiC8+EgIMAhSN0X482SQhUZHAW67ErIvaHlwL+ixMD
-0T5pmsW8PKN3lV1TFMhNYSEC2GRG/4GF+3yQA8LR+BgeEu/E5nmysIH8vuQMkOD6
-3pKA8VKNBml591j6UTqxoHtPX+rThaziz3Hy3+ekf5iWslllTTGPd2SWqTvnj2Ae
-GvRzsbli+FEM0Aj/v8jUQnQzOz891QSvWR+fMfCqZimiJMc+GBzJ9umbcyQsB5tY
-e26mAoYd9KEpGXMKN4biHbJZNp1GGw==
-=x/MY
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.jar.md5 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.jar.md5
deleted file mode 100644
index 95fa4af1641f..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.jar.md5
+++ /dev/null
@@ -1 +0,0 @@
-e84da489be91de821c95d41b8f0e0a0a
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.jar.md5.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.jar.md5.asc
deleted file mode 100644
index 1cbf6ccffa07..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.jar.md5.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
-xT1PSwf+InTdlh+BVVy3RFszEL5vN7waSPYMImXhgd5EZ1d4Lxd6EeOwtNgWNKpG
-E+Ps/Kw0jZDvoD49WJlcUjzDHBNHcE7C/L3GAWHV6WwklhtQaJ4EegsynWdSXz6k
-fqJY6r58aGKGjpKPutRWAjvfcdC170+ZRsc2oi9xrAgHCpvXzTjq4+O9Ah0t5jwW
-jcZ/Xubcw4vjsw774OucHbtwGsvRN5SDJ3IONOH8WCwhUP5vEEKvA6MYX0KGoTdS
-3wTCyZTzU3qtTWxcbTCpiJIWbYwRR7TzLB/uydWHlAMzuz6coIiBpYsGiO6wkmfg
-W+QvcE7wyW2jtb22pCImLyObyZ21VA==
-=VjDv
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.jar.sha1 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.jar.sha1
deleted file mode 100644
index 2a2834e1ab41..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.jar.sha1
+++ /dev/null
@@ -1 +0,0 @@
-8992b17455ce660da9c5fe47226b7ded9e872637
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.jar.sha1.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.jar.sha1.asc
deleted file mode 100644
index 4cd212d6e1e9..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.jar.sha1.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
-xT2HQgf+MTUEnwzXK4zi76VI7C5cchGan26lIA2Ebq4vtYGKDqNSISOAAdWs9+nT
-U6ZA6OIFo5qdeD6F/45s91IoDbxbhMDMFEsSijKASqiuZN5TZM1U2h2kWFAl/sEl
-EI1RTygn+xDw/ah4V3/duuMFC+jRgvJ/LgemIF4KBvECWaTQKNu0fu5d4dPXMpp+
-jrxMEZPQZsivpOvklzV8O7wAkf/ZQhJdcB2m8uOfSPlJ91a4EEtXF9/GzzkXUi1P
-bzt4NsmOag3227B3mO1Bc6yZdDBNu8wQ9apiJVCpqsxB9Dz0PCL4dHNa1u9g6Xo6
-ElRgneV4HZp+LB125VoNabKuNH00bw==
-=2yDl
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.jar.sha256 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.jar.sha256
deleted file mode 100644
index 4f27f01046dd..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.jar.sha256
+++ /dev/null
@@ -1 +0,0 @@
-10ce8a82f7e53c67f2af8d4dc4b8cdb4d0630d0e1d21818da4d5b3ca2de08385
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.jar.sha256.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.jar.sha256.asc
deleted file mode 100644
index e29629cbec07..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.jar.sha256.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
-xT0ScQf7Bip+quFq1CzDCTDxUhdTTOIpQcCfMKo1Jegpa2Hlm63XuK+6zVI9u6S+
-dBXPdYeneMOqMPQUAaw3M06ZqohaDOt8Ti1EiQFGXCdOvbonTA52Lrd4EEZxwNnK
-BdPuIh/8qCfozm5KbZe1bFyGVRAdNyf27KvzHgfBTirLtI+3MiOdL4bvNZbWRPfh
-J84Ko+Ena8jPFgyz6nJv2Q2U/V3dCooLJAXs2vEG6owwk5J9zvSysWpHaJbXas5v
-KXO9TOBBjf3+vxb1WVQa8ZYUU3+FIFes0RFVgOWghJXIooOcWrwOV2Q8z9qWXwoK
-mMZ2oLS+z/7clXibK45KeRUeCX5DvQ==
-=5oO1
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.jar.sha512 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.jar.sha512
deleted file mode 100644
index eb02a04a89d2..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.jar.sha512
+++ /dev/null
@@ -1 +0,0 @@
-2730ac0859e1c2f450d54647c29ece43d095eb834e2130d4949dd1151317d013c072fa8f96f5f4b49836eff7c19a2eeeb5ca7483e5dac24c368bbcd522c27a00
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.jar.sha512.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.jar.sha512.asc
deleted file mode 100644
index f35b726baff6..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.jar.sha512.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
-xT3d+AgAwQvlwnKQLLuiZADGL+I922/YG317N2Re1EjC6WlMRZUKXH54fckRTyPm
-4ZLyxVHy8LlUD2Q10g69opb7HRd/tV0miBJhn5OU1wIM3hqTgxNp9EFckK4md45k
-osnhQJNDsFToxJL8zPP+KRs/aWPZs+FrRcH6k26lwLl2gTfyBDsaU11HFRVEN9yi
-X41obVyKiVNlc9efSSvlLtRBSVt0VhAFhck+3t61H6D9H09QxaDGAqmduDua3Tg3
-t5eqURuDfv3TfSztYgK3JBmG/6gVMsZodCgyC+8rhDDs6vSoDG30apx5Leg2rPbj
-xuk2wi/WNzc94IgY9tVS3tAfT2k6yQ==
-=6+Cv
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.module b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.module
deleted file mode 100644
index 6a92fa0a1afb..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.module
+++ /dev/null
@@ -1,101 +0,0 @@
-{
- "formatVersion": "1.1",
- "component": {
- "group": "org.springframework.example",
- "module": "module-one",
- "version": "1.0.0",
- "attributes": {
- "org.gradle.status": "release"
- }
- },
- "createdBy": {
- "gradle": {
- "version": "6.5.1",
- "buildId": "mvqepqsdqjcahjl7cii6b6ucoe"
- }
- },
- "variants": [
- {
- "name": "apiElements",
- "attributes": {
- "org.gradle.category": "library",
- "org.gradle.dependency.bundling": "external",
- "org.gradle.jvm.version": 8,
- "org.gradle.libraryelements": "jar",
- "org.gradle.usage": "java-api"
- },
- "files": [
- {
- "name": "module-one-1.0.0.jar",
- "url": "module-one-1.0.0.jar",
- "size": 261,
- "sha512": "2730ac0859e1c2f450d54647c29ece43d095eb834e2130d4949dd1151317d013c072fa8f96f5f4b49836eff7c19a2eeeb5ca7483e5dac24c368bbcd522c27a00",
- "sha256": "10ce8a82f7e53c67f2af8d4dc4b8cdb4d0630d0e1d21818da4d5b3ca2de08385",
- "sha1": "8992b17455ce660da9c5fe47226b7ded9e872637",
- "md5": "e84da489be91de821c95d41b8f0e0a0a"
- }
- ]
- },
- {
- "name": "runtimeElements",
- "attributes": {
- "org.gradle.category": "library",
- "org.gradle.dependency.bundling": "external",
- "org.gradle.jvm.version": 8,
- "org.gradle.libraryelements": "jar",
- "org.gradle.usage": "java-runtime"
- },
- "files": [
- {
- "name": "module-one-1.0.0.jar",
- "url": "module-one-1.0.0.jar",
- "size": 261,
- "sha512": "2730ac0859e1c2f450d54647c29ece43d095eb834e2130d4949dd1151317d013c072fa8f96f5f4b49836eff7c19a2eeeb5ca7483e5dac24c368bbcd522c27a00",
- "sha256": "10ce8a82f7e53c67f2af8d4dc4b8cdb4d0630d0e1d21818da4d5b3ca2de08385",
- "sha1": "8992b17455ce660da9c5fe47226b7ded9e872637",
- "md5": "e84da489be91de821c95d41b8f0e0a0a"
- }
- ]
- },
- {
- "name": "javadocElements",
- "attributes": {
- "org.gradle.category": "documentation",
- "org.gradle.dependency.bundling": "external",
- "org.gradle.docstype": "javadoc",
- "org.gradle.usage": "java-runtime"
- },
- "files": [
- {
- "name": "module-one-1.0.0-javadoc.jar",
- "url": "module-one-1.0.0-javadoc.jar",
- "size": 261,
- "sha512": "2730ac0859e1c2f450d54647c29ece43d095eb834e2130d4949dd1151317d013c072fa8f96f5f4b49836eff7c19a2eeeb5ca7483e5dac24c368bbcd522c27a00",
- "sha256": "10ce8a82f7e53c67f2af8d4dc4b8cdb4d0630d0e1d21818da4d5b3ca2de08385",
- "sha1": "8992b17455ce660da9c5fe47226b7ded9e872637",
- "md5": "e84da489be91de821c95d41b8f0e0a0a"
- }
- ]
- },
- {
- "name": "sourcesElements",
- "attributes": {
- "org.gradle.category": "documentation",
- "org.gradle.dependency.bundling": "external",
- "org.gradle.docstype": "sources",
- "org.gradle.usage": "java-runtime"
- },
- "files": [
- {
- "name": "module-one-1.0.0-sources.jar",
- "url": "module-one-1.0.0-sources.jar",
- "size": 261,
- "sha512": "2730ac0859e1c2f450d54647c29ece43d095eb834e2130d4949dd1151317d013c072fa8f96f5f4b49836eff7c19a2eeeb5ca7483e5dac24c368bbcd522c27a00",
- "sha256": "10ce8a82f7e53c67f2af8d4dc4b8cdb4d0630d0e1d21818da4d5b3ca2de08385",
- "sha1": "8992b17455ce660da9c5fe47226b7ded9e872637",
- "md5": "e84da489be91de821c95d41b8f0e0a0a"
- }
- ]
- }
- ]
-}
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.module.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.module.asc
deleted file mode 100644
index 54d7598382da..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.module.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
-xT1HBQf/fCBHR+fpZjkcgonkAVWcGvRx5kRHlsCISs64XMw90++DTawoKxr9/TvY
-fltQlq/xaf+2O2Xzh9HIymtZBeKp7a4fWQ2AHf/ygkGyIKvy8h+mu3MGDdmHZeA4
-fn9FGjaE0a/wYJmCEHJ1qJ4GaNq47gzRTu76jzZNafnNRlq1rlyVu2txnlks6xDr
-oE8EnRT86Y67Ku8YArjkhZSHhf/tzSSwdTAgBinh6eba5tW5ueRXfsheqgtpJMov
-hiDIVxuAlJoHy2cQ8L9+8geg0OSXLwQ9BXrBsDCLvrDauU735/Hv/NGrWE95kemw
-Ay9jCXhXFWKkzCw2ps3QHTTpTK4aVw==
-=1QME
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.module.md5 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.module.md5
deleted file mode 100644
index 7da5a1024ebb..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.module.md5
+++ /dev/null
@@ -1 +0,0 @@
-b5b2aedb082633674ef9308a2ac21934
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.module.md5.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.module.md5.asc
deleted file mode 100644
index f525064e6acc..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.module.md5.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
-xT1SLQgApB6OWW9cgtaofOu3HwgsVxaxLYPsDf057m2O5pI6uV5Ikyt97B1txjTB
-9EXcy4gsfu7rxwgRHIEPCQkQKhhZioscT1SPFN0yopCwsJEvxrJE018ojyaIem/L
-KVcbtiBVMj3GZCbS0DHpwZNx2u7yblyBqUGhCMKLkYqVL7nUHJKtECECs5jbJnb9
-xXGFe0xlZ/IbkHv5QXyStgUYCah7ayWQDvjN7UJrpJL1lmTD0rjWLilkeKsVu3/k
-11cZb5YdOmrL9a+8ql1jXPkma3HPjoIPRC5LB2BnloduwEPsiiLGG7Cs8UFEJNjQ
-m5w+l4dDd03y5ioaW8fI/meAKpBm4g==
-=gwLM
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.module.sha1 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.module.sha1
deleted file mode 100644
index f4d48063e987..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.module.sha1
+++ /dev/null
@@ -1 +0,0 @@
-b7cb6c2ce7fbb98b8eb502c3ef8fcab0dd4880fc
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.module.sha1.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.module.sha1.asc
deleted file mode 100644
index 0c9e8cb57007..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.module.sha1.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
-xT2y5AgAlI4H5hwDIgVmXtRq/ri7kxEJnC9L9FOv8aE9YasHAruaU1YR5m17Jncl
-4guJHc+gSd3BiSx1rsI6PNxLACabw4Vy56eCRpmiFWeIkoCETBUk8AN25Q/1tzgw
-hHmIRgOkF9PzSBWDTUNsyx/7E9P2QSiJOkMAGGuMKGDpYTR9zmaluzwfY+BI/VoW
-BbZpdzt02OGQosWmA7DlwkXUwip6iBjga79suUFIsyH0hmRW2q/nCeJ04ttzXUog
-NTNkpEwMYpZAzQXE7ks7WJJlAPkVYPWy/j5YCV7xTFb9I/56ux+/wRUaGU5fumSR
-lr3PNoYNToC/4GLX6Kc2OH0e1LXNTQ==
-=s02D
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.module.sha256 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.module.sha256
deleted file mode 100644
index cdc919db3db6..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.module.sha256
+++ /dev/null
@@ -1 +0,0 @@
-4ef7e1ba5fda72b0168c9aab4746ec6ee57fb73020c49fe2f49251187aaab074
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.module.sha256.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.module.sha256.asc
deleted file mode 100644
index 94ab1b8db014..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.module.sha256.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
-xT1/vwgAhUTLKjxmry4W3cVdfX/D/vxDTLAp5OxwJy36CZmJwsVuN9TLjPo4tRqq
-woiopR2oSTaJqld2pe98WlIeDJJRe4ta1Uwvg7k4Sf6YaZXm01Wufk4a835sFUwY
-BTWmnFYX0+dp5mLyXZmZjrAr5Q2bowRuqZd2DAYiNY/E5MH2T7OAJE2hCOHUpCaB
-JVeP7HcbaGYR3NX/mLq0t8+xjTPXQk/OHijuusuLQxfLZvZiaikDoOHUD6l0dlRw
-xcLTghG5+jd1q7noKAbUVgoEOshstfomCHZpPMj11c7KIuG1+3wRMdm+F67lkcJ5
-eDW2fmF+6LYr+WlEi33rDIyTk3GhlQ==
-=mHUe
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.module.sha512 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.module.sha512
deleted file mode 100644
index 76ab9ddba9cd..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.module.sha512
+++ /dev/null
@@ -1 +0,0 @@
-29b1bc06a150e4764826e35e2d2541933b0583ce823f5b00c02effad9f37f02f0d2eef1c81214d69eaf74220e1f77332c5e6a91eb413a3022b5a8a1d7914c4c3
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.module.sha512.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.module.sha512.asc
deleted file mode 100644
index 8041ff51f1f1..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.module.sha512.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
-xT0QLAf/ffTpTfH4IebklGJIKZC8ZjRt4CgwpR431qNeWkY25cHmWFj48x2u9dmS
-ZpxN572d3PPjcMigT/9wM05omiU+4DHxGgHq/Xj6GXN1DNaENcu7uoye96thjKPv
-jz98tPIRMC9hYr3m/K1CJ3+ZG0++7JorCZRpodH/MhklRWXOvNszs81VWtgvMnpd
-h9r0PuoaYBl6bIl19o7E3JJU6dKgwfre4b+a1RSYI+A8bmJOKMgHytAKi+804r0P
-4R2WuQT4q+dSmkMtgp65vJ9giv/xuFrd1bT4n+qcDkwE8pTcWvsB4w1RkDOKs4fK
-/ta5xBQ1hiKAd6nJffke1b0MBrZOrA==
-=ZMpE
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.pom b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.pom
deleted file mode 100644
index d618d6e120e5..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.pom
+++ /dev/null
@@ -1,49 +0,0 @@
-
-
-
-
-
-
-
- 4.0.0
- org.springframework.example
- module-one
- 1.0.0
- module-one
- Example module
- https://spring.io/projects/spring-boot
-
- Spring
- https://spring.io
-
-
-
- Apache License, Version 2.0
- https://www.apache.org/licenses/LICENSE-2.0
-
-
-
-
- Spring
- ask@spring.io
- Spring
- https://www.spring.io
-
-
-
-
- scm:git:git://github.com/spring-projects/spring-boot.git
-
-
- scm:git:ssh://git@github.com/spring-projects/spring-boot.git
-
- https://github.com/spring-projects/spring-boot
-
-
- GitHub
-
- https://github.com/spring-projects/spring-boot/issues
-
-
-
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.pom.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.pom.asc
deleted file mode 100644
index eba13f46b597..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.pom.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
-xT04rwgAwJHic8GGHFZ+UAJYLW/OxJOVyd0ebx4yT5zAyTjyvxnrlKmKZ6GP/NhZ
-htJQnZez85lUKA0TsMvl/6H2iEhKOns6HgqY3PLFkKNRKOq601phtD9HCkxDibWB
-UDT01I0q2xNOljD03lhfytefnSnZ96AaySol2v5DBIZsOKWGir0/8KJCpEQJHjCF
-TwNk8lNF3moGlO4zUfoBbkSZ+J0J8Bq5QI3nIAWFYxHcrZ2YGsAZd48kux8x2V3C
-c6QsYEonmztqxop76a7K8Gv+MDmo/u/vqM8z5C63/WpOoDtRG+F5vtPkhCrR6M5f
-ygubQUy5TL+dWdHE8zgA2O9hZuoHEg==
-=bkxG
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.pom.md5 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.pom.md5
deleted file mode 100644
index d82ed4d3a5d3..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.pom.md5
+++ /dev/null
@@ -1 +0,0 @@
-48776112e8bc3ca36b6392b0e9d6d619
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.pom.md5.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.pom.md5.asc
deleted file mode 100644
index 78c3a0a5f668..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.pom.md5.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
-xT0XEAf+O9a/29MIWBtj1oLxIT1LLdzTU68qt5+qW+58SNQmMxu0MaESW4GZOc3p
-mTV0EJyxUkCLJyoqOY4/GhqBAm33mMZSY8BQtvUZPYxpbJwBo+pE8YfnH3n1v20P
-4pS4oJKekXAhTqShpx5oFjCK4J3chaz+Xc8Ldm1DXakCRc1bc/YYZ+87sy2z+PXk
-PmN3KPcc/XjH4GPjmVUR8vR1TGUjUMQGvbAdrgkjFyaCGNvyreuHLsAFWrFFbIOn
-/mB++enkXhmjWbiyvmvWQvtU0QFA4sRGYww0Lup1GRQ+00IqHF1QRMskqujAwmok
-+TuB3Zc9WuAERPre+Qr1DEevClNwAQ==
-=3beu
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.pom.sha1 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.pom.sha1
deleted file mode 100644
index 28dc2dadd344..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.pom.sha1
+++ /dev/null
@@ -1 +0,0 @@
-a5cc75e17f8eccfc4ac30bfbb09f42d5f34ecbb1
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.pom.sha1.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.pom.sha1.asc
deleted file mode 100644
index 9d1d2ea54f3b..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.pom.sha1.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
-xT2aVAf+MQhSBr1jzcQE5mo1bMOXa4owaRr+dRir5Q4Gr7Fz4NuGoQEIzoL7XP5r
-0zIjebzworxCaw+JNyaIxniHNBeK3sPHTLeW8bCrdJLkhE9RtGdEHLyPYXwPuFin
-xVw3VQHWiA0uPM+JaekgdPDtK5wGFQ/AK3pc6vR108oT0kV4zQEqgRnvLqV9Q5zZ
-UPHBi5kypu1BmCW4upYL1dmjASWPn9Q8cNpHcX/NJPNJ9zW0yxAAtq4wLfh7PQml
-3EaHEYllsf8v1vMv00+zZNhc6O4BBP1qrRiaYHDAJhJjn6ctV9GFhJ2Ttxh/NmSy
-H679tlC2PeRjGMi8bOHBshcikn5KUw==
-=4aJI
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.pom.sha256 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.pom.sha256
deleted file mode 100644
index 8d1625bf07c2..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.pom.sha256
+++ /dev/null
@@ -1 +0,0 @@
-3b31f2abf79368001e2fab02997446ac62db714b9db9cb78c4c542aa962485dc
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.pom.sha256.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.pom.sha256.asc
deleted file mode 100644
index e572b776de94..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.pom.sha256.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
-xT0nDQgAlfchq7/W/wubx3IR3tQs0tKiix3nZIc97zuH6sR8+r+CJe78wbmSE9Oo
-/z96wfzeZYNIKh2v+dBLHF7OfcPGBE7tiX07jfCa6KzjjY3hFBhW+muMP/aBRb+4
-itSs6F3lkZOPW2+hpSdFQ6U8Rm81cAlZv7Zk2XswwTQkJo8GcNL1w/5wAVpNK0yG
-VinZr8YRMFs6OYQxLqGSypDLAmv9rOaJ7aCdaKnQwYES65kC7tbe0SRZGQoDe8n4
-XLzpvC8rM9MXZDEN4qI+ZAANOJNVsXUmDZLDSe4ak48u/cTOokY8I6bR2k/XOhbu
-L+D4W7oKAE9HmzlTMusosyjNOBQAmQ==
-=Wjji
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.pom.sha512 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.pom.sha512
deleted file mode 100644
index 6edd0b3e98f8..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.pom.sha512
+++ /dev/null
@@ -1 +0,0 @@
-05bd8fd394a15b9dcc1bfaece0a63b0fdc2c3625a7e0aa5230fd3b5b75a8f8934a0af550b44437aa1486909058e84703e63fdec6f637d639d565b55bdaf1fa6c
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.pom.sha512.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.pom.sha512.asc
deleted file mode 100644
index 896fc8f31e59..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.pom.sha512.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
-xT19rwf/a6sZxSDNTxN72VvsrKsHq+wMes5UUcQ+L7e5QLjaCTx2ayW2FdHMBaNi
-IDBBE9kxnxa/S6G6nSRARUjXowsEYZGUNLLvUjNZ4Z3g2R9XyGPaz3Ky9yWpRm36
-E0lFqf8aaCLpzwV2z7cfeVNYsd2gnHakphK/UiZzXFz+GYzqby/0m5Kk8Zs7rK6V
-/ji0bYWUi8t1jli8MfTHQtM8EUHG0nXRfEKilyoYkO3UsTEh/UN1VRpJ5DgcRC8L
-Zbd2zPnV15MPUzZvz3kkycUulQdhOqTDjUod9P/WoASwjDuKCG2/kquwOvnoHXJ9
-9Ju+ca0s9y0jbotIygYxJXZVev3EiA==
-=oWIp
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-javadoc.jar b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-javadoc.jar
deleted file mode 100644
index a142d391c0af..000000000000
Binary files a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-javadoc.jar and /dev/null differ
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-javadoc.jar.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-javadoc.jar.asc
deleted file mode 100644
index 85d6a7cb1e5a..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-javadoc.jar.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
-xT3qtgf8CeDvxzi7lPghlrZtmYTTjaic4FZsGRWTPky3H24i4wSRDhG0L5sj4uPK
-eLLlITr5a9j26UCas9HRSthiC8+EgIMAhSN0X482SQhUZHAW67ErIvaHlwL+ixMD
-0T5pmsW8PKN3lV1TFMhNYSEC2GRG/4GF+3yQA8LR+BgeEu/E5nmysIH8vuQMkOD6
-3pKA8VKNBml591j6UTqxoHtPX+rThaziz3Hy3+ekf5iWslllTTGPd2SWqTvnj2Ae
-GvRzsbli+FEM0Aj/v8jUQnQzOz891QSvWR+fMfCqZimiJMc+GBzJ9umbcyQsB5tY
-e26mAoYd9KEpGXMKN4biHbJZNp1GGw==
-=x/MY
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-javadoc.jar.md5 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-javadoc.jar.md5
deleted file mode 100644
index 95fa4af1641f..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-javadoc.jar.md5
+++ /dev/null
@@ -1 +0,0 @@
-e84da489be91de821c95d41b8f0e0a0a
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-javadoc.jar.md5.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-javadoc.jar.md5.asc
deleted file mode 100644
index 1cbf6ccffa07..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-javadoc.jar.md5.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
-xT1PSwf+InTdlh+BVVy3RFszEL5vN7waSPYMImXhgd5EZ1d4Lxd6EeOwtNgWNKpG
-E+Ps/Kw0jZDvoD49WJlcUjzDHBNHcE7C/L3GAWHV6WwklhtQaJ4EegsynWdSXz6k
-fqJY6r58aGKGjpKPutRWAjvfcdC170+ZRsc2oi9xrAgHCpvXzTjq4+O9Ah0t5jwW
-jcZ/Xubcw4vjsw774OucHbtwGsvRN5SDJ3IONOH8WCwhUP5vEEKvA6MYX0KGoTdS
-3wTCyZTzU3qtTWxcbTCpiJIWbYwRR7TzLB/uydWHlAMzuz6coIiBpYsGiO6wkmfg
-W+QvcE7wyW2jtb22pCImLyObyZ21VA==
-=VjDv
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-javadoc.jar.sha1 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-javadoc.jar.sha1
deleted file mode 100644
index 2a2834e1ab41..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-javadoc.jar.sha1
+++ /dev/null
@@ -1 +0,0 @@
-8992b17455ce660da9c5fe47226b7ded9e872637
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-javadoc.jar.sha1.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-javadoc.jar.sha1.asc
deleted file mode 100644
index 4cd212d6e1e9..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-javadoc.jar.sha1.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
-xT2HQgf+MTUEnwzXK4zi76VI7C5cchGan26lIA2Ebq4vtYGKDqNSISOAAdWs9+nT
-U6ZA6OIFo5qdeD6F/45s91IoDbxbhMDMFEsSijKASqiuZN5TZM1U2h2kWFAl/sEl
-EI1RTygn+xDw/ah4V3/duuMFC+jRgvJ/LgemIF4KBvECWaTQKNu0fu5d4dPXMpp+
-jrxMEZPQZsivpOvklzV8O7wAkf/ZQhJdcB2m8uOfSPlJ91a4EEtXF9/GzzkXUi1P
-bzt4NsmOag3227B3mO1Bc6yZdDBNu8wQ9apiJVCpqsxB9Dz0PCL4dHNa1u9g6Xo6
-ElRgneV4HZp+LB125VoNabKuNH00bw==
-=2yDl
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-javadoc.jar.sha256 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-javadoc.jar.sha256
deleted file mode 100644
index 4f27f01046dd..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-javadoc.jar.sha256
+++ /dev/null
@@ -1 +0,0 @@
-10ce8a82f7e53c67f2af8d4dc4b8cdb4d0630d0e1d21818da4d5b3ca2de08385
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-javadoc.jar.sha256.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-javadoc.jar.sha256.asc
deleted file mode 100644
index e29629cbec07..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-javadoc.jar.sha256.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
-xT0ScQf7Bip+quFq1CzDCTDxUhdTTOIpQcCfMKo1Jegpa2Hlm63XuK+6zVI9u6S+
-dBXPdYeneMOqMPQUAaw3M06ZqohaDOt8Ti1EiQFGXCdOvbonTA52Lrd4EEZxwNnK
-BdPuIh/8qCfozm5KbZe1bFyGVRAdNyf27KvzHgfBTirLtI+3MiOdL4bvNZbWRPfh
-J84Ko+Ena8jPFgyz6nJv2Q2U/V3dCooLJAXs2vEG6owwk5J9zvSysWpHaJbXas5v
-KXO9TOBBjf3+vxb1WVQa8ZYUU3+FIFes0RFVgOWghJXIooOcWrwOV2Q8z9qWXwoK
-mMZ2oLS+z/7clXibK45KeRUeCX5DvQ==
-=5oO1
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-javadoc.jar.sha512 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-javadoc.jar.sha512
deleted file mode 100644
index eb02a04a89d2..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-javadoc.jar.sha512
+++ /dev/null
@@ -1 +0,0 @@
-2730ac0859e1c2f450d54647c29ece43d095eb834e2130d4949dd1151317d013c072fa8f96f5f4b49836eff7c19a2eeeb5ca7483e5dac24c368bbcd522c27a00
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-javadoc.jar.sha512.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-javadoc.jar.sha512.asc
deleted file mode 100644
index f35b726baff6..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-javadoc.jar.sha512.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
-xT3d+AgAwQvlwnKQLLuiZADGL+I922/YG317N2Re1EjC6WlMRZUKXH54fckRTyPm
-4ZLyxVHy8LlUD2Q10g69opb7HRd/tV0miBJhn5OU1wIM3hqTgxNp9EFckK4md45k
-osnhQJNDsFToxJL8zPP+KRs/aWPZs+FrRcH6k26lwLl2gTfyBDsaU11HFRVEN9yi
-X41obVyKiVNlc9efSSvlLtRBSVt0VhAFhck+3t61H6D9H09QxaDGAqmduDua3Tg3
-t5eqURuDfv3TfSztYgK3JBmG/6gVMsZodCgyC+8rhDDs6vSoDG30apx5Leg2rPbj
-xuk2wi/WNzc94IgY9tVS3tAfT2k6yQ==
-=6+Cv
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-sources.jar b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-sources.jar
deleted file mode 100644
index a142d391c0af..000000000000
Binary files a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-sources.jar and /dev/null differ
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-sources.jar.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-sources.jar.asc
deleted file mode 100644
index 85d6a7cb1e5a..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-sources.jar.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
-xT3qtgf8CeDvxzi7lPghlrZtmYTTjaic4FZsGRWTPky3H24i4wSRDhG0L5sj4uPK
-eLLlITr5a9j26UCas9HRSthiC8+EgIMAhSN0X482SQhUZHAW67ErIvaHlwL+ixMD
-0T5pmsW8PKN3lV1TFMhNYSEC2GRG/4GF+3yQA8LR+BgeEu/E5nmysIH8vuQMkOD6
-3pKA8VKNBml591j6UTqxoHtPX+rThaziz3Hy3+ekf5iWslllTTGPd2SWqTvnj2Ae
-GvRzsbli+FEM0Aj/v8jUQnQzOz891QSvWR+fMfCqZimiJMc+GBzJ9umbcyQsB5tY
-e26mAoYd9KEpGXMKN4biHbJZNp1GGw==
-=x/MY
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-sources.jar.md5 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-sources.jar.md5
deleted file mode 100644
index 95fa4af1641f..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-sources.jar.md5
+++ /dev/null
@@ -1 +0,0 @@
-e84da489be91de821c95d41b8f0e0a0a
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-sources.jar.md5.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-sources.jar.md5.asc
deleted file mode 100644
index 1cbf6ccffa07..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-sources.jar.md5.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
-xT1PSwf+InTdlh+BVVy3RFszEL5vN7waSPYMImXhgd5EZ1d4Lxd6EeOwtNgWNKpG
-E+Ps/Kw0jZDvoD49WJlcUjzDHBNHcE7C/L3GAWHV6WwklhtQaJ4EegsynWdSXz6k
-fqJY6r58aGKGjpKPutRWAjvfcdC170+ZRsc2oi9xrAgHCpvXzTjq4+O9Ah0t5jwW
-jcZ/Xubcw4vjsw774OucHbtwGsvRN5SDJ3IONOH8WCwhUP5vEEKvA6MYX0KGoTdS
-3wTCyZTzU3qtTWxcbTCpiJIWbYwRR7TzLB/uydWHlAMzuz6coIiBpYsGiO6wkmfg
-W+QvcE7wyW2jtb22pCImLyObyZ21VA==
-=VjDv
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-sources.jar.sha1 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-sources.jar.sha1
deleted file mode 100644
index 2a2834e1ab41..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-sources.jar.sha1
+++ /dev/null
@@ -1 +0,0 @@
-8992b17455ce660da9c5fe47226b7ded9e872637
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-sources.jar.sha1.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-sources.jar.sha1.asc
deleted file mode 100644
index 4cd212d6e1e9..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-sources.jar.sha1.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
-xT2HQgf+MTUEnwzXK4zi76VI7C5cchGan26lIA2Ebq4vtYGKDqNSISOAAdWs9+nT
-U6ZA6OIFo5qdeD6F/45s91IoDbxbhMDMFEsSijKASqiuZN5TZM1U2h2kWFAl/sEl
-EI1RTygn+xDw/ah4V3/duuMFC+jRgvJ/LgemIF4KBvECWaTQKNu0fu5d4dPXMpp+
-jrxMEZPQZsivpOvklzV8O7wAkf/ZQhJdcB2m8uOfSPlJ91a4EEtXF9/GzzkXUi1P
-bzt4NsmOag3227B3mO1Bc6yZdDBNu8wQ9apiJVCpqsxB9Dz0PCL4dHNa1u9g6Xo6
-ElRgneV4HZp+LB125VoNabKuNH00bw==
-=2yDl
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-sources.jar.sha256 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-sources.jar.sha256
deleted file mode 100644
index 4f27f01046dd..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-sources.jar.sha256
+++ /dev/null
@@ -1 +0,0 @@
-10ce8a82f7e53c67f2af8d4dc4b8cdb4d0630d0e1d21818da4d5b3ca2de08385
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-sources.jar.sha256.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-sources.jar.sha256.asc
deleted file mode 100644
index e29629cbec07..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-sources.jar.sha256.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
-xT0ScQf7Bip+quFq1CzDCTDxUhdTTOIpQcCfMKo1Jegpa2Hlm63XuK+6zVI9u6S+
-dBXPdYeneMOqMPQUAaw3M06ZqohaDOt8Ti1EiQFGXCdOvbonTA52Lrd4EEZxwNnK
-BdPuIh/8qCfozm5KbZe1bFyGVRAdNyf27KvzHgfBTirLtI+3MiOdL4bvNZbWRPfh
-J84Ko+Ena8jPFgyz6nJv2Q2U/V3dCooLJAXs2vEG6owwk5J9zvSysWpHaJbXas5v
-KXO9TOBBjf3+vxb1WVQa8ZYUU3+FIFes0RFVgOWghJXIooOcWrwOV2Q8z9qWXwoK
-mMZ2oLS+z/7clXibK45KeRUeCX5DvQ==
-=5oO1
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-sources.jar.sha512 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-sources.jar.sha512
deleted file mode 100644
index eb02a04a89d2..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-sources.jar.sha512
+++ /dev/null
@@ -1 +0,0 @@
-2730ac0859e1c2f450d54647c29ece43d095eb834e2130d4949dd1151317d013c072fa8f96f5f4b49836eff7c19a2eeeb5ca7483e5dac24c368bbcd522c27a00
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-sources.jar.sha512.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-sources.jar.sha512.asc
deleted file mode 100644
index f35b726baff6..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-sources.jar.sha512.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
-xT3d+AgAwQvlwnKQLLuiZADGL+I922/YG317N2Re1EjC6WlMRZUKXH54fckRTyPm
-4ZLyxVHy8LlUD2Q10g69opb7HRd/tV0miBJhn5OU1wIM3hqTgxNp9EFckK4md45k
-osnhQJNDsFToxJL8zPP+KRs/aWPZs+FrRcH6k26lwLl2gTfyBDsaU11HFRVEN9yi
-X41obVyKiVNlc9efSSvlLtRBSVt0VhAFhck+3t61H6D9H09QxaDGAqmduDua3Tg3
-t5eqURuDfv3TfSztYgK3JBmG/6gVMsZodCgyC+8rhDDs6vSoDG30apx5Leg2rPbj
-xuk2wi/WNzc94IgY9tVS3tAfT2k6yQ==
-=6+Cv
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.jar b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.jar
deleted file mode 100644
index a142d391c0af..000000000000
Binary files a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.jar and /dev/null differ
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.jar.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.jar.asc
deleted file mode 100644
index 85d6a7cb1e5a..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.jar.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
-xT3qtgf8CeDvxzi7lPghlrZtmYTTjaic4FZsGRWTPky3H24i4wSRDhG0L5sj4uPK
-eLLlITr5a9j26UCas9HRSthiC8+EgIMAhSN0X482SQhUZHAW67ErIvaHlwL+ixMD
-0T5pmsW8PKN3lV1TFMhNYSEC2GRG/4GF+3yQA8LR+BgeEu/E5nmysIH8vuQMkOD6
-3pKA8VKNBml591j6UTqxoHtPX+rThaziz3Hy3+ekf5iWslllTTGPd2SWqTvnj2Ae
-GvRzsbli+FEM0Aj/v8jUQnQzOz891QSvWR+fMfCqZimiJMc+GBzJ9umbcyQsB5tY
-e26mAoYd9KEpGXMKN4biHbJZNp1GGw==
-=x/MY
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.jar.md5 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.jar.md5
deleted file mode 100644
index 95fa4af1641f..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.jar.md5
+++ /dev/null
@@ -1 +0,0 @@
-e84da489be91de821c95d41b8f0e0a0a
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.jar.md5.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.jar.md5.asc
deleted file mode 100644
index 1cbf6ccffa07..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.jar.md5.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
-xT1PSwf+InTdlh+BVVy3RFszEL5vN7waSPYMImXhgd5EZ1d4Lxd6EeOwtNgWNKpG
-E+Ps/Kw0jZDvoD49WJlcUjzDHBNHcE7C/L3GAWHV6WwklhtQaJ4EegsynWdSXz6k
-fqJY6r58aGKGjpKPutRWAjvfcdC170+ZRsc2oi9xrAgHCpvXzTjq4+O9Ah0t5jwW
-jcZ/Xubcw4vjsw774OucHbtwGsvRN5SDJ3IONOH8WCwhUP5vEEKvA6MYX0KGoTdS
-3wTCyZTzU3qtTWxcbTCpiJIWbYwRR7TzLB/uydWHlAMzuz6coIiBpYsGiO6wkmfg
-W+QvcE7wyW2jtb22pCImLyObyZ21VA==
-=VjDv
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.jar.sha1 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.jar.sha1
deleted file mode 100644
index 2a2834e1ab41..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.jar.sha1
+++ /dev/null
@@ -1 +0,0 @@
-8992b17455ce660da9c5fe47226b7ded9e872637
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.jar.sha1.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.jar.sha1.asc
deleted file mode 100644
index 4cd212d6e1e9..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.jar.sha1.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
-xT2HQgf+MTUEnwzXK4zi76VI7C5cchGan26lIA2Ebq4vtYGKDqNSISOAAdWs9+nT
-U6ZA6OIFo5qdeD6F/45s91IoDbxbhMDMFEsSijKASqiuZN5TZM1U2h2kWFAl/sEl
-EI1RTygn+xDw/ah4V3/duuMFC+jRgvJ/LgemIF4KBvECWaTQKNu0fu5d4dPXMpp+
-jrxMEZPQZsivpOvklzV8O7wAkf/ZQhJdcB2m8uOfSPlJ91a4EEtXF9/GzzkXUi1P
-bzt4NsmOag3227B3mO1Bc6yZdDBNu8wQ9apiJVCpqsxB9Dz0PCL4dHNa1u9g6Xo6
-ElRgneV4HZp+LB125VoNabKuNH00bw==
-=2yDl
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.jar.sha256 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.jar.sha256
deleted file mode 100644
index 4f27f01046dd..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.jar.sha256
+++ /dev/null
@@ -1 +0,0 @@
-10ce8a82f7e53c67f2af8d4dc4b8cdb4d0630d0e1d21818da4d5b3ca2de08385
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.jar.sha256.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.jar.sha256.asc
deleted file mode 100644
index e29629cbec07..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.jar.sha256.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
-xT0ScQf7Bip+quFq1CzDCTDxUhdTTOIpQcCfMKo1Jegpa2Hlm63XuK+6zVI9u6S+
-dBXPdYeneMOqMPQUAaw3M06ZqohaDOt8Ti1EiQFGXCdOvbonTA52Lrd4EEZxwNnK
-BdPuIh/8qCfozm5KbZe1bFyGVRAdNyf27KvzHgfBTirLtI+3MiOdL4bvNZbWRPfh
-J84Ko+Ena8jPFgyz6nJv2Q2U/V3dCooLJAXs2vEG6owwk5J9zvSysWpHaJbXas5v
-KXO9TOBBjf3+vxb1WVQa8ZYUU3+FIFes0RFVgOWghJXIooOcWrwOV2Q8z9qWXwoK
-mMZ2oLS+z/7clXibK45KeRUeCX5DvQ==
-=5oO1
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.jar.sha512 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.jar.sha512
deleted file mode 100644
index eb02a04a89d2..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.jar.sha512
+++ /dev/null
@@ -1 +0,0 @@
-2730ac0859e1c2f450d54647c29ece43d095eb834e2130d4949dd1151317d013c072fa8f96f5f4b49836eff7c19a2eeeb5ca7483e5dac24c368bbcd522c27a00
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.jar.sha512.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.jar.sha512.asc
deleted file mode 100644
index f35b726baff6..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.jar.sha512.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
-xT3d+AgAwQvlwnKQLLuiZADGL+I922/YG317N2Re1EjC6WlMRZUKXH54fckRTyPm
-4ZLyxVHy8LlUD2Q10g69opb7HRd/tV0miBJhn5OU1wIM3hqTgxNp9EFckK4md45k
-osnhQJNDsFToxJL8zPP+KRs/aWPZs+FrRcH6k26lwLl2gTfyBDsaU11HFRVEN9yi
-X41obVyKiVNlc9efSSvlLtRBSVt0VhAFhck+3t61H6D9H09QxaDGAqmduDua3Tg3
-t5eqURuDfv3TfSztYgK3JBmG/6gVMsZodCgyC+8rhDDs6vSoDG30apx5Leg2rPbj
-xuk2wi/WNzc94IgY9tVS3tAfT2k6yQ==
-=6+Cv
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.module b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.module
deleted file mode 100644
index 8618f194c99c..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.module
+++ /dev/null
@@ -1,101 +0,0 @@
-{
- "formatVersion": "1.1",
- "component": {
- "group": "org.springframework.example",
- "module": "module-three",
- "version": "1.0.0",
- "attributes": {
- "org.gradle.status": "release"
- }
- },
- "createdBy": {
- "gradle": {
- "version": "6.5.1",
- "buildId": "mvqepqsdqjcahjl7cii6b6ucoe"
- }
- },
- "variants": [
- {
- "name": "apiElements",
- "attributes": {
- "org.gradle.category": "library",
- "org.gradle.dependency.bundling": "external",
- "org.gradle.jvm.version": 8,
- "org.gradle.libraryelements": "jar",
- "org.gradle.usage": "java-api"
- },
- "files": [
- {
- "name": "module-three-1.0.0.jar",
- "url": "module-three-1.0.0.jar",
- "size": 261,
- "sha512": "2730ac0859e1c2f450d54647c29ece43d095eb834e2130d4949dd1151317d013c072fa8f96f5f4b49836eff7c19a2eeeb5ca7483e5dac24c368bbcd522c27a00",
- "sha256": "10ce8a82f7e53c67f2af8d4dc4b8cdb4d0630d0e1d21818da4d5b3ca2de08385",
- "sha1": "8992b17455ce660da9c5fe47226b7ded9e872637",
- "md5": "e84da489be91de821c95d41b8f0e0a0a"
- }
- ]
- },
- {
- "name": "runtimeElements",
- "attributes": {
- "org.gradle.category": "library",
- "org.gradle.dependency.bundling": "external",
- "org.gradle.jvm.version": 8,
- "org.gradle.libraryelements": "jar",
- "org.gradle.usage": "java-runtime"
- },
- "files": [
- {
- "name": "module-three-1.0.0.jar",
- "url": "module-three-1.0.0.jar",
- "size": 261,
- "sha512": "2730ac0859e1c2f450d54647c29ece43d095eb834e2130d4949dd1151317d013c072fa8f96f5f4b49836eff7c19a2eeeb5ca7483e5dac24c368bbcd522c27a00",
- "sha256": "10ce8a82f7e53c67f2af8d4dc4b8cdb4d0630d0e1d21818da4d5b3ca2de08385",
- "sha1": "8992b17455ce660da9c5fe47226b7ded9e872637",
- "md5": "e84da489be91de821c95d41b8f0e0a0a"
- }
- ]
- },
- {
- "name": "javadocElements",
- "attributes": {
- "org.gradle.category": "documentation",
- "org.gradle.dependency.bundling": "external",
- "org.gradle.docstype": "javadoc",
- "org.gradle.usage": "java-runtime"
- },
- "files": [
- {
- "name": "module-three-1.0.0-javadoc.jar",
- "url": "module-three-1.0.0-javadoc.jar",
- "size": 261,
- "sha512": "2730ac0859e1c2f450d54647c29ece43d095eb834e2130d4949dd1151317d013c072fa8f96f5f4b49836eff7c19a2eeeb5ca7483e5dac24c368bbcd522c27a00",
- "sha256": "10ce8a82f7e53c67f2af8d4dc4b8cdb4d0630d0e1d21818da4d5b3ca2de08385",
- "sha1": "8992b17455ce660da9c5fe47226b7ded9e872637",
- "md5": "e84da489be91de821c95d41b8f0e0a0a"
- }
- ]
- },
- {
- "name": "sourcesElements",
- "attributes": {
- "org.gradle.category": "documentation",
- "org.gradle.dependency.bundling": "external",
- "org.gradle.docstype": "sources",
- "org.gradle.usage": "java-runtime"
- },
- "files": [
- {
- "name": "module-three-1.0.0-sources.jar",
- "url": "module-three-1.0.0-sources.jar",
- "size": 261,
- "sha512": "2730ac0859e1c2f450d54647c29ece43d095eb834e2130d4949dd1151317d013c072fa8f96f5f4b49836eff7c19a2eeeb5ca7483e5dac24c368bbcd522c27a00",
- "sha256": "10ce8a82f7e53c67f2af8d4dc4b8cdb4d0630d0e1d21818da4d5b3ca2de08385",
- "sha1": "8992b17455ce660da9c5fe47226b7ded9e872637",
- "md5": "e84da489be91de821c95d41b8f0e0a0a"
- }
- ]
- }
- ]
-}
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.module.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.module.asc
deleted file mode 100644
index f7112bc8e54a..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.module.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
-xT3OcAf+OJv0t0rhNnJcF656mem5qv3fvcJKkPqyKF9I0TiP33W61/ntrGezdaDX
-tLde1MFRto3HS0/U0t6NqfMNTXYcQ5vH/qqnIRWP7Iv/t7f+mum6pOcYkxJhhXFT
-1pH0l4iqVQOBUiAJhOpUh0utLNWdZcEv+DdxgtFbFyaEDmg46Cpy9YtAH6XKEh5d
-ZZeiX/+XC+Ufx1bReDLHvFjUyQa/Lv8rEthX2eBmAXkoPwJG0LA9xF6X8leB0DI/
-9a1KiNcmRSSUarLpqV/hE6oQggGeMLVoJ+51klunRAfiXw6h2m9gRlnWikLjC+23
-/E2m+7Gb0Kc4izXIdHTqS2fYPMHsyw==
-=h486
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.module.md5 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.module.md5
deleted file mode 100644
index c5a7b486933a..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.module.md5
+++ /dev/null
@@ -1 +0,0 @@
-90fa60dcc829042dd1208c174752caeb
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.module.md5.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.module.md5.asc
deleted file mode 100644
index 83f03d877951..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.module.md5.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
-xT0xjQgAwJcUWVwcl3PI7FhRUoPaPfqaoG3bUPwLePYuf++qPCNUDOmnq0aXtqbr
-Ul9SxQRDy9D7ygCWVCTVXRjg0HHZQT/ZYB7lhaDLxMEpV25q9acJAZ4qzbn8vRAG
-FqlqYaSlIDducapPUGWAOF/xwhf5k8tIGO5p0hY4wdU3b+0YU1w5DavYOetTZ26Z
-jwVagOj/6WFIHnu6PwXGkynqxui8dnsld23eamOZYsfR19weTNh0GT3ncl8y03eP
-Wy6CkFxzN0kvSdze0nAfO9dygpRxh7nNbz/uJhTFP4pDwz5iE8FBiUXZLkxTZ8YJ
-lvIKuS+JnUTEQcd00/nAL4cncMiJIQ==
-=lQP9
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.module.sha1 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.module.sha1
deleted file mode 100644
index 4b25265d7253..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.module.sha1
+++ /dev/null
@@ -1 +0,0 @@
-9090f5fcb4c79a89b3a46f2cb8071381e0787a03
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.module.sha1.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.module.sha1.asc
deleted file mode 100644
index cfa8f7e8880f..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.module.sha1.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
-xT3urQf/W31jKnVjCIckj7XFbeucazmVr0K73LNpg0eQwqqz877KKmBDV8qn8b3o
-MTBDgUn/9LMJzUSWRFV+CkM0cgAG0s8vmzeymtH6RWv+ikHh/3Ky4sYxd9Pa3Ipo
-zeeIqyJk1dysfcLLsP1ml6ayh8VM/DK+DDc4CU9wrEGAUDeVIFiTw7DrMIB7PcdG
-ru7z6J/jcIA55RiJMDvuqhS+Obx/JUrmqDrrK8Npp9stRP+RpZpF1AKGgg1dfLo1
-bKw+KYuMhK7Kq7nIg9GqZvhr46oOKko5NF2l+GfVR14Gdb330/88t/IxwJvsUiCC
-sWQTrGJb062N5oHGtdoZ3mXLo7bnuw==
-=+snH
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.module.sha256 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.module.sha256
deleted file mode 100644
index 346a5ff6e495..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.module.sha256
+++ /dev/null
@@ -1 +0,0 @@
-2e8d3db6ece5719d7be27bcfdefa1f890da9a19f73390c7122797db1081d245b
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.module.sha256.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.module.sha256.asc
deleted file mode 100644
index 41d0ccfe35c6..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.module.sha256.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
-xT14OggAlf9eyYFV3HRC7LoeM1Q9LrkYZUIDIUkukUxDxBTGPLf739qZtHgUl6lC
-yUCQqGswhuuwR8s7ht2MDMp8isjs1j7inpAQA3kYgHOCUMjYlIyhPdIxHtQ8WD+S
-CwW2nHtf7tXFrhKFecqolKyp+qZYWx1anMmbLggyaXWZmiIwhIHLxIogbyjVLdkD
-9qUAKCUpEvyNqogyYYtAjJERRzw9RN4lwnpm/uEkKtFQVoxui2VQr/DEbzooXu8A
-mqKkUBbgf9uxH5s+pUuUgbl+XZnPLGzJV6NcFe/jpsvEzHkUQzAsVnNnCWAPreY8
-RTfj2eGleFWESIiMFUAp6U0an5GoOQ==
-=T+Cv
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.module.sha512 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.module.sha512
deleted file mode 100644
index 1817ab28cb61..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.module.sha512
+++ /dev/null
@@ -1 +0,0 @@
-ac3e2a0dfb3b8ddaa79468f85698ff97e9b88e401849e2e733073b711a1673ba2e37be61d224fd69ec2e1c59ed0342e6b3757bc3931c2e297d24bcae9370fa3b
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.module.sha512.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.module.sha512.asc
deleted file mode 100644
index 1f6bfda96678..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.module.sha512.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
-xT1HGQgAuINmQJ5vpFWWmXbIrEVf5+fTKq72R7gXdJ9XHYgQdSyKoeUUy3FElqfI
-55gyiLk1OMMy6Pd1HKi0bczOUOlz8K34uMXcT+ctm41Lp6243FfLm4iy1x/DWlHb
-IWksIG1TRf7g0b//OiBbbaesjnc5QK1rft6T4KiEPD9NtOi/8ON7vVu0S9oERUGO
-32Zwu/wGZeKztUoXVQ/zZk5UA9hYE/7C5bX3dRBS038luv7YZKe3313PfVj29vdx
-bsfRIcH/qIe//WL3OTTbaOvSgOs8qvJHPN8NmdH70GbZ2W9jTe7KrIlb8FBEaPEj
-BbLov9td9qxXlRxyBhLYRB7MN4rsKw==
-=qIiQ
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.pom b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.pom
deleted file mode 100644
index badff025f688..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.pom
+++ /dev/null
@@ -1,49 +0,0 @@
-
-
-
-
-
-
-
- 4.0.0
- org.springframework.example
- module-three
- 1.0.0
- module-three
- Example module
- https://spring.io/projects/spring-boot
-
- Spring
- https://spring.io
-
-
-
- Apache License, Version 2.0
- https://www.apache.org/licenses/LICENSE-2.0
-
-
-
-
- Spring
- ask@spring.io
- Spring
- https://www.spring.io
-
-
-
-
- scm:git:git://github.com/spring-projects/spring-boot.git
-
-
- scm:git:ssh://git@github.com/spring-projects/spring-boot.git
-
- https://github.com/spring-projects/spring-boot
-
-
- GitHub
-
- https://github.com/spring-projects/spring-boot/issues
-
-
-
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.pom.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.pom.asc
deleted file mode 100644
index eb100ce746aa..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.pom.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
-xT0T5QgAgXfcX/6hkGNWRp4xIbpC0P9wi21WBmlWeM1l1vPjlogcPB5fIQ15tnxL
-dyXVJjhdBXG70m5UkOtR5LbO+6Y7soEsocfuN/wdjNP/JUk2xW4HTj87F16r3EhV
-s1nrydd/nZxsIemTY1irOrCk4yEOWlAO91VOGFI4UoGGE6oeMiTFje6vbNidGT3Y
-RD1VrxbVasI38HHggQ+odrdp+rk8AwAUJq8g96KyRO5d+O6NQCf4cTe6S5+kJKG1
-ETQ0yASHiD5pzcpQiEQu+wclgAunVAzr5Ql/SnOcZEjUoVOLix7Ttcv5KcXjZhY9
-9VQyULZ1MzcrSEoRoOv8k8fT7swvLg==
-=KgwJ
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.pom.md5 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.pom.md5
deleted file mode 100644
index e156ed030237..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.pom.md5
+++ /dev/null
@@ -1 +0,0 @@
-a819cb79241de23f94f3626ae83be12f
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.pom.md5.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.pom.md5.asc
deleted file mode 100644
index f55b2670d4e8..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.pom.md5.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
-xT2Umgf+K57ogLEAGx/40dFOV0yiGmvCXwywMCVbnMXCA85Ceti0TGFY6T0EaJXy
-wF7QQ0SW56svIxX/U58IVocWuaVRJA7tCZF1u9DCvafdYDJeM4iHHVu6GzM1Tng2
-JFYV4q5MtT712rCrcf7ZH3MntYawsGjBiF9IHWwvSNUyf53W7L4VSWcpv0tfPLra
-EeC7ztnnDXgi32FSpXvu27mDPbrQLibihUZBjoZ4uuRU2wB6HICJ90JjoYtK6JoC
-ToEZY4jFLkEmQ8dy0KUa5rhUDWJ+Bq+bYHhwMXl9HQUKZuqjvlmHCRHIsJgdU+Cl
-i5NPJkXhCZOs9tD3hf3NdeD9ef72kQ==
-=PraK
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.pom.sha1 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.pom.sha1
deleted file mode 100644
index 81ed28e231d7..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.pom.sha1
+++ /dev/null
@@ -1 +0,0 @@
-e562eacb5f9cf14ccbb80c8be0396710fc6a546c
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.pom.sha1.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.pom.sha1.asc
deleted file mode 100644
index 53461b47a075..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.pom.sha1.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
-xT2j8QgAiciViDfKLAv2rYMyBJbyQjK29fpG78NMsKw+j3zWwJEPlPuZhIT0/KWQ
-3ipcYbtBoKYrKSG54uzPflGAQoostMYV+XtJ+0fjICsNDpKjfhuDWojaWkxnF1KD
-NcWSiapNO6iX0s62yaL/netVVsHsE5fVr//IG6WDTrJK2GEkOQAoca2W8ixI3G0s
-kTIJEmCMA9ZOUMKBwwtJ0NPEZPxe1N/R6SuGWGdkWlrqPRmA6lnY153zH3vJ6pqF
-RM1Phwpt46l3o20D5wOhqU8jvV7b5HUZ50sHV0sJOMUbwvFyrhIOzJLMixk1WJhR
-lnudbpWPssTJO3Fiv67b/iADaBaIbA==
-=4CYs
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.pom.sha256 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.pom.sha256
deleted file mode 100644
index 381f84d9d480..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.pom.sha256
+++ /dev/null
@@ -1 +0,0 @@
-f043a098eee190d59e2b4b450c2de21dcb3b7fce224abefd89e0e5b44b939fa7
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.pom.sha256.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.pom.sha256.asc
deleted file mode 100644
index b9b35e5371e6..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.pom.sha256.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
-xT3Pwwf+IikjoDdjeMQfmERTN4Gjirx9+fler+Gr5JYC78OxLrB8uq0tn11wEJMQ
-ZDQe83OYjEkFQhPn6yQ5bc9edZTJztQJcGpVe7NkYffS4geo+ahuksaQWMF9opEc
-OqBB5fTWVt18qGFTI2F3CEDIo38muTgkzndFuzmcbVhAcknF5ybcVDIFpZNlnqe/
-xflD6lupXWXQC4nE4n2EVhNnmkiF9nKRJWwEJ1hoy1gwTxSYmnO/BLn8ob4tswnc
-gHnj4Yp7qoV/SnRnfNDHMPQMfzAwq1jucjjPOt3xkw17UIGBnrP1zAxeZFmarCTO
-YjJt5PUNwtqOVHlHzwgn3b3FGRJe3A==
-=AU99
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.pom.sha512 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.pom.sha512
deleted file mode 100644
index fb6a445480ea..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.pom.sha512
+++ /dev/null
@@ -1 +0,0 @@
-67549e36f07c9f4b83cfa9f00fa647705128eabd03dec3df0066177e89940652fc7e13b8c0b60652c811e167c3ffaba0ab95a4f315a10f69572c12e4e944b6e6
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.pom.sha512.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.pom.sha512.asc
deleted file mode 100644
index 71232b747c6f..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.pom.sha512.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
-xT0bBgf+Nm9vooXNKE/z4cNeFqiHwLb+gMxvqlKnl/+03KbuFvlDUwdqSxfnHQZ3
-qfCBtIe6MN/0I5FCNRCcFxiCjCPDqSMAcvRPU5UOG2M2W0uvcqMwKO6KRGBLd65J
-MulDxoe7LrEk6KwNYfecxCtXBvLwzwQd3A10tcQOVl66neF/g+9jEc+MHJPa1xi5
-4pDOo3TQ4EpGfB8eF9Z+7YKc9hPYBFsm+n3P6SYcVAiRUiNBE8gCOvvZE9mOTQAo
-yC80AfDjXe/YBsd3a79hVW+ESQAKfK8S1RzO+c5GhIZCIJFdSJDOeww86O4U0n5g
-6hIXRNWUFUEueAvQ2dYHZujQSBxNig==
-=t5De
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-javadoc.jar b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-javadoc.jar
deleted file mode 100644
index a142d391c0af..000000000000
Binary files a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-javadoc.jar and /dev/null differ
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-javadoc.jar.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-javadoc.jar.asc
deleted file mode 100644
index 624356b34ae0..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-javadoc.jar.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1sACgkQmix6mORX
-xT1IkAf+N8ts9K88PC/dISZMWSrgRbSugd6VRG6pto6jsp9cJBzTzQ6C8psMkXcN
-qX0fnLBn4Zn1dovxRIrA8QeT/vxHMl1X0Foe6SUTMjK34Ofq4V1FVlhuJIi0YZrP
-L7B4cKTkv1ndwSVgE23zkynfaIPiPl1uZOwDmlpArokqnjSiUq9NndtKf87NwekW
-hbf7brgfZddeDj9xhAn5hz2pHUhx/uH9tOX3JlZgE+yATZsGm6Z9BSf4Lur0W85P
-hrJ+MfuYPzZ3n7okuaQdMT3QIqe3FO+dfGZKwakw2NWfgWP3LZsQ5rbyxBlyH7CG
-JA/VAIIqe99ftHcBFRGB6C9hMn4FcA==
-=prNt
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-javadoc.jar.md5 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-javadoc.jar.md5
deleted file mode 100644
index 95fa4af1641f..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-javadoc.jar.md5
+++ /dev/null
@@ -1 +0,0 @@
-e84da489be91de821c95d41b8f0e0a0a
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-javadoc.jar.md5.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-javadoc.jar.md5.asc
deleted file mode 100644
index 333ba4509b3f..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-javadoc.jar.md5.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1sACgkQmix6mORX
-xT3jzQf8DUis2+v7616JWRpUziEnpnvms7+PkgovWttcpbO0RlLr1s0Uno0D0jAt
-7KUGNN4//n8hKsojZ6ZI+7pzsk/0NathOQRNYcdb+AFf71T3yJhef1d5GmXHA7iV
-wA6AfrFTEQ7SaimZXEGGpFXzb3rPsVnryOEbTOXno3B7nNjZTUpjkW/APkvJueUk
-BIFCWH9rL1txRKWhKg8f6YT+l6HQFn+qu1Z3/MoqxCn6HvUxExA1mwNbzfvNaDTt
-l04jNVG6NqZyGhivuDnpyonnmwKySryKVvGrWn6b5SfgPPQYQJTWK3c7npSPjKpO
-ydzWOvISS55vBKLbB7g69g8ah3FHEw==
-=fcEr
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-javadoc.jar.sha1 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-javadoc.jar.sha1
deleted file mode 100644
index 2a2834e1ab41..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-javadoc.jar.sha1
+++ /dev/null
@@ -1 +0,0 @@
-8992b17455ce660da9c5fe47226b7ded9e872637
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-javadoc.jar.sha1.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-javadoc.jar.sha1.asc
deleted file mode 100644
index 66ae31b24c26..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-javadoc.jar.sha1.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1sACgkQmix6mORX
-xT0ovgf/aejEen2MEvJTF1Tjg24rK1jZAYqmgGi8H2b26h7ZEd/le2jWs6VpPmvv
-DX3pyaKFyOZXpU8SOkoPgi021VIt9LLWPlxMgcWlb6EWg8xw70PXISbUFy3IcxRi
-I14uAUXoFgIOT6jPt659kdXLNtYRsS3nQcBgJTIz6axHk2t5tD3TRf4xcLCyuVGv
-/obkTwpLr2jdPBxgTe+oDPjCnOyI6YeN0dKq4aiGBI/xECNpitbzmYQA2FQ+WvsG
-qq+1n/eAZAzAUWumxLna9ov1O0f6cY9d9hxWMTe2L4/a7B6KezF0CPnShFaC6pCV
-98aamE5QxBmSeQtmRdI75WFHJ1h0Vg==
-=0M4U
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-javadoc.jar.sha256 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-javadoc.jar.sha256
deleted file mode 100644
index 4f27f01046dd..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-javadoc.jar.sha256
+++ /dev/null
@@ -1 +0,0 @@
-10ce8a82f7e53c67f2af8d4dc4b8cdb4d0630d0e1d21818da4d5b3ca2de08385
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-javadoc.jar.sha256.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-javadoc.jar.sha256.asc
deleted file mode 100644
index 825ed5de96dd..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-javadoc.jar.sha256.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1sACgkQmix6mORX
-xT104Qf+NG6IUBLo7eTPtPzWyNs9bShrJR759atbY9kBOrRfyoBM/hWrcr6pG4e5
-BmBPULkuBWLVM+Ra52B2S96848oiaLLEuiWlMudWRsWCxyVknjm9EKlMHA3VdQtu
-8grrPKS4mIwSvdzAEEeqR+mwtWXHlz+jc/R9NeQhNmmcNZv1nkyzCuoNCH/HMTl4
-/ei6enpYrYNnMrNz9TOMQ67sCtZEm6TaxlqS+9h/V9TEnq6+1qXEt4c+AsqQdMWH
-3BZREzXHFocQciSEXfL6m07pnNlnvCcjsM2SAqTeTqQupEmqFGkhL2blE1VMdplW
-fDCC/ee5JYVyyUXpzydSjCYwFbO3NQ==
-=gSEv
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-javadoc.jar.sha512 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-javadoc.jar.sha512
deleted file mode 100644
index eb02a04a89d2..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-javadoc.jar.sha512
+++ /dev/null
@@ -1 +0,0 @@
-2730ac0859e1c2f450d54647c29ece43d095eb834e2130d4949dd1151317d013c072fa8f96f5f4b49836eff7c19a2eeeb5ca7483e5dac24c368bbcd522c27a00
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-javadoc.jar.sha512.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-javadoc.jar.sha512.asc
deleted file mode 100644
index 7df8aa894e07..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-javadoc.jar.sha512.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1sACgkQmix6mORX
-xT0XdAf/feMRtW2BUz84x43aYLaERIEPx2TsqMUwVcov6sp5MWaSAJEX2vrscCRB
-K/7x4N3dxnrckc3sBF1hs+zrRwySYU1FyGVIxQxdeURnUWxCva0uOWj91jcUOIkA
-gpmOZZj51b4SkB6GZjtvN/Z3B4xzEPmTPfKFiBZPhuYW4HiC8FHM1JnlW6h2xoj6
-Bja//qoj9ccfRjiMnnI0iPgZNiyR8n8+EJGi0ykizxkiT6cWI84kZ+JQYooDHbCf
-NgPt2NjcGzd6SGrQW8/0td0N+xDRfLpTrbfTmlC5hikXmS0e79BV6W0eYcWcgDni
-r8WjbDmomHHFDhT8p1R+tGtd8p2txg==
-=BHvx
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-sources.jar b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-sources.jar
deleted file mode 100644
index a142d391c0af..000000000000
Binary files a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-sources.jar and /dev/null differ
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-sources.jar.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-sources.jar.asc
deleted file mode 100644
index 624356b34ae0..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-sources.jar.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1sACgkQmix6mORX
-xT1IkAf+N8ts9K88PC/dISZMWSrgRbSugd6VRG6pto6jsp9cJBzTzQ6C8psMkXcN
-qX0fnLBn4Zn1dovxRIrA8QeT/vxHMl1X0Foe6SUTMjK34Ofq4V1FVlhuJIi0YZrP
-L7B4cKTkv1ndwSVgE23zkynfaIPiPl1uZOwDmlpArokqnjSiUq9NndtKf87NwekW
-hbf7brgfZddeDj9xhAn5hz2pHUhx/uH9tOX3JlZgE+yATZsGm6Z9BSf4Lur0W85P
-hrJ+MfuYPzZ3n7okuaQdMT3QIqe3FO+dfGZKwakw2NWfgWP3LZsQ5rbyxBlyH7CG
-JA/VAIIqe99ftHcBFRGB6C9hMn4FcA==
-=prNt
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-sources.jar.md5 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-sources.jar.md5
deleted file mode 100644
index 95fa4af1641f..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-sources.jar.md5
+++ /dev/null
@@ -1 +0,0 @@
-e84da489be91de821c95d41b8f0e0a0a
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-sources.jar.md5.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-sources.jar.md5.asc
deleted file mode 100644
index 1cbf6ccffa07..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-sources.jar.md5.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
-xT1PSwf+InTdlh+BVVy3RFszEL5vN7waSPYMImXhgd5EZ1d4Lxd6EeOwtNgWNKpG
-E+Ps/Kw0jZDvoD49WJlcUjzDHBNHcE7C/L3GAWHV6WwklhtQaJ4EegsynWdSXz6k
-fqJY6r58aGKGjpKPutRWAjvfcdC170+ZRsc2oi9xrAgHCpvXzTjq4+O9Ah0t5jwW
-jcZ/Xubcw4vjsw774OucHbtwGsvRN5SDJ3IONOH8WCwhUP5vEEKvA6MYX0KGoTdS
-3wTCyZTzU3qtTWxcbTCpiJIWbYwRR7TzLB/uydWHlAMzuz6coIiBpYsGiO6wkmfg
-W+QvcE7wyW2jtb22pCImLyObyZ21VA==
-=VjDv
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-sources.jar.sha1 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-sources.jar.sha1
deleted file mode 100644
index 2a2834e1ab41..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-sources.jar.sha1
+++ /dev/null
@@ -1 +0,0 @@
-8992b17455ce660da9c5fe47226b7ded9e872637
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-sources.jar.sha1.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-sources.jar.sha1.asc
deleted file mode 100644
index 4cd212d6e1e9..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-sources.jar.sha1.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
-xT2HQgf+MTUEnwzXK4zi76VI7C5cchGan26lIA2Ebq4vtYGKDqNSISOAAdWs9+nT
-U6ZA6OIFo5qdeD6F/45s91IoDbxbhMDMFEsSijKASqiuZN5TZM1U2h2kWFAl/sEl
-EI1RTygn+xDw/ah4V3/duuMFC+jRgvJ/LgemIF4KBvECWaTQKNu0fu5d4dPXMpp+
-jrxMEZPQZsivpOvklzV8O7wAkf/ZQhJdcB2m8uOfSPlJ91a4EEtXF9/GzzkXUi1P
-bzt4NsmOag3227B3mO1Bc6yZdDBNu8wQ9apiJVCpqsxB9Dz0PCL4dHNa1u9g6Xo6
-ElRgneV4HZp+LB125VoNabKuNH00bw==
-=2yDl
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-sources.jar.sha256 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-sources.jar.sha256
deleted file mode 100644
index 4f27f01046dd..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-sources.jar.sha256
+++ /dev/null
@@ -1 +0,0 @@
-10ce8a82f7e53c67f2af8d4dc4b8cdb4d0630d0e1d21818da4d5b3ca2de08385
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-sources.jar.sha256.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-sources.jar.sha256.asc
deleted file mode 100644
index 825ed5de96dd..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-sources.jar.sha256.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1sACgkQmix6mORX
-xT104Qf+NG6IUBLo7eTPtPzWyNs9bShrJR759atbY9kBOrRfyoBM/hWrcr6pG4e5
-BmBPULkuBWLVM+Ra52B2S96848oiaLLEuiWlMudWRsWCxyVknjm9EKlMHA3VdQtu
-8grrPKS4mIwSvdzAEEeqR+mwtWXHlz+jc/R9NeQhNmmcNZv1nkyzCuoNCH/HMTl4
-/ei6enpYrYNnMrNz9TOMQ67sCtZEm6TaxlqS+9h/V9TEnq6+1qXEt4c+AsqQdMWH
-3BZREzXHFocQciSEXfL6m07pnNlnvCcjsM2SAqTeTqQupEmqFGkhL2blE1VMdplW
-fDCC/ee5JYVyyUXpzydSjCYwFbO3NQ==
-=gSEv
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-sources.jar.sha512 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-sources.jar.sha512
deleted file mode 100644
index eb02a04a89d2..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-sources.jar.sha512
+++ /dev/null
@@ -1 +0,0 @@
-2730ac0859e1c2f450d54647c29ece43d095eb834e2130d4949dd1151317d013c072fa8f96f5f4b49836eff7c19a2eeeb5ca7483e5dac24c368bbcd522c27a00
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-sources.jar.sha512.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-sources.jar.sha512.asc
deleted file mode 100644
index f35b726baff6..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-sources.jar.sha512.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
-xT3d+AgAwQvlwnKQLLuiZADGL+I922/YG317N2Re1EjC6WlMRZUKXH54fckRTyPm
-4ZLyxVHy8LlUD2Q10g69opb7HRd/tV0miBJhn5OU1wIM3hqTgxNp9EFckK4md45k
-osnhQJNDsFToxJL8zPP+KRs/aWPZs+FrRcH6k26lwLl2gTfyBDsaU11HFRVEN9yi
-X41obVyKiVNlc9efSSvlLtRBSVt0VhAFhck+3t61H6D9H09QxaDGAqmduDua3Tg3
-t5eqURuDfv3TfSztYgK3JBmG/6gVMsZodCgyC+8rhDDs6vSoDG30apx5Leg2rPbj
-xuk2wi/WNzc94IgY9tVS3tAfT2k6yQ==
-=6+Cv
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.jar b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.jar
deleted file mode 100644
index a142d391c0af..000000000000
Binary files a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.jar and /dev/null differ
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.jar.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.jar.asc
deleted file mode 100644
index 624356b34ae0..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.jar.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1sACgkQmix6mORX
-xT1IkAf+N8ts9K88PC/dISZMWSrgRbSugd6VRG6pto6jsp9cJBzTzQ6C8psMkXcN
-qX0fnLBn4Zn1dovxRIrA8QeT/vxHMl1X0Foe6SUTMjK34Ofq4V1FVlhuJIi0YZrP
-L7B4cKTkv1ndwSVgE23zkynfaIPiPl1uZOwDmlpArokqnjSiUq9NndtKf87NwekW
-hbf7brgfZddeDj9xhAn5hz2pHUhx/uH9tOX3JlZgE+yATZsGm6Z9BSf4Lur0W85P
-hrJ+MfuYPzZ3n7okuaQdMT3QIqe3FO+dfGZKwakw2NWfgWP3LZsQ5rbyxBlyH7CG
-JA/VAIIqe99ftHcBFRGB6C9hMn4FcA==
-=prNt
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.jar.md5 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.jar.md5
deleted file mode 100644
index 95fa4af1641f..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.jar.md5
+++ /dev/null
@@ -1 +0,0 @@
-e84da489be91de821c95d41b8f0e0a0a
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.jar.md5.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.jar.md5.asc
deleted file mode 100644
index 333ba4509b3f..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.jar.md5.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1sACgkQmix6mORX
-xT3jzQf8DUis2+v7616JWRpUziEnpnvms7+PkgovWttcpbO0RlLr1s0Uno0D0jAt
-7KUGNN4//n8hKsojZ6ZI+7pzsk/0NathOQRNYcdb+AFf71T3yJhef1d5GmXHA7iV
-wA6AfrFTEQ7SaimZXEGGpFXzb3rPsVnryOEbTOXno3B7nNjZTUpjkW/APkvJueUk
-BIFCWH9rL1txRKWhKg8f6YT+l6HQFn+qu1Z3/MoqxCn6HvUxExA1mwNbzfvNaDTt
-l04jNVG6NqZyGhivuDnpyonnmwKySryKVvGrWn6b5SfgPPQYQJTWK3c7npSPjKpO
-ydzWOvISS55vBKLbB7g69g8ah3FHEw==
-=fcEr
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.jar.sha1 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.jar.sha1
deleted file mode 100644
index 2a2834e1ab41..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.jar.sha1
+++ /dev/null
@@ -1 +0,0 @@
-8992b17455ce660da9c5fe47226b7ded9e872637
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.jar.sha1.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.jar.sha1.asc
deleted file mode 100644
index 66ae31b24c26..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.jar.sha1.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1sACgkQmix6mORX
-xT0ovgf/aejEen2MEvJTF1Tjg24rK1jZAYqmgGi8H2b26h7ZEd/le2jWs6VpPmvv
-DX3pyaKFyOZXpU8SOkoPgi021VIt9LLWPlxMgcWlb6EWg8xw70PXISbUFy3IcxRi
-I14uAUXoFgIOT6jPt659kdXLNtYRsS3nQcBgJTIz6axHk2t5tD3TRf4xcLCyuVGv
-/obkTwpLr2jdPBxgTe+oDPjCnOyI6YeN0dKq4aiGBI/xECNpitbzmYQA2FQ+WvsG
-qq+1n/eAZAzAUWumxLna9ov1O0f6cY9d9hxWMTe2L4/a7B6KezF0CPnShFaC6pCV
-98aamE5QxBmSeQtmRdI75WFHJ1h0Vg==
-=0M4U
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.jar.sha256 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.jar.sha256
deleted file mode 100644
index 4f27f01046dd..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.jar.sha256
+++ /dev/null
@@ -1 +0,0 @@
-10ce8a82f7e53c67f2af8d4dc4b8cdb4d0630d0e1d21818da4d5b3ca2de08385
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.jar.sha256.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.jar.sha256.asc
deleted file mode 100644
index 825ed5de96dd..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.jar.sha256.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1sACgkQmix6mORX
-xT104Qf+NG6IUBLo7eTPtPzWyNs9bShrJR759atbY9kBOrRfyoBM/hWrcr6pG4e5
-BmBPULkuBWLVM+Ra52B2S96848oiaLLEuiWlMudWRsWCxyVknjm9EKlMHA3VdQtu
-8grrPKS4mIwSvdzAEEeqR+mwtWXHlz+jc/R9NeQhNmmcNZv1nkyzCuoNCH/HMTl4
-/ei6enpYrYNnMrNz9TOMQ67sCtZEm6TaxlqS+9h/V9TEnq6+1qXEt4c+AsqQdMWH
-3BZREzXHFocQciSEXfL6m07pnNlnvCcjsM2SAqTeTqQupEmqFGkhL2blE1VMdplW
-fDCC/ee5JYVyyUXpzydSjCYwFbO3NQ==
-=gSEv
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.jar.sha512 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.jar.sha512
deleted file mode 100644
index eb02a04a89d2..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.jar.sha512
+++ /dev/null
@@ -1 +0,0 @@
-2730ac0859e1c2f450d54647c29ece43d095eb834e2130d4949dd1151317d013c072fa8f96f5f4b49836eff7c19a2eeeb5ca7483e5dac24c368bbcd522c27a00
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.jar.sha512.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.jar.sha512.asc
deleted file mode 100644
index f35b726baff6..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.jar.sha512.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
-xT3d+AgAwQvlwnKQLLuiZADGL+I922/YG317N2Re1EjC6WlMRZUKXH54fckRTyPm
-4ZLyxVHy8LlUD2Q10g69opb7HRd/tV0miBJhn5OU1wIM3hqTgxNp9EFckK4md45k
-osnhQJNDsFToxJL8zPP+KRs/aWPZs+FrRcH6k26lwLl2gTfyBDsaU11HFRVEN9yi
-X41obVyKiVNlc9efSSvlLtRBSVt0VhAFhck+3t61H6D9H09QxaDGAqmduDua3Tg3
-t5eqURuDfv3TfSztYgK3JBmG/6gVMsZodCgyC+8rhDDs6vSoDG30apx5Leg2rPbj
-xuk2wi/WNzc94IgY9tVS3tAfT2k6yQ==
-=6+Cv
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.module b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.module
deleted file mode 100644
index 23e5ef1229ad..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.module
+++ /dev/null
@@ -1,101 +0,0 @@
-{
- "formatVersion": "1.1",
- "component": {
- "group": "org.springframework.example",
- "module": "module-two",
- "version": "1.0.0",
- "attributes": {
- "org.gradle.status": "release"
- }
- },
- "createdBy": {
- "gradle": {
- "version": "6.5.1",
- "buildId": "mvqepqsdqjcahjl7cii6b6ucoe"
- }
- },
- "variants": [
- {
- "name": "apiElements",
- "attributes": {
- "org.gradle.category": "library",
- "org.gradle.dependency.bundling": "external",
- "org.gradle.jvm.version": 8,
- "org.gradle.libraryelements": "jar",
- "org.gradle.usage": "java-api"
- },
- "files": [
- {
- "name": "module-two-1.0.0.jar",
- "url": "module-two-1.0.0.jar",
- "size": 261,
- "sha512": "2730ac0859e1c2f450d54647c29ece43d095eb834e2130d4949dd1151317d013c072fa8f96f5f4b49836eff7c19a2eeeb5ca7483e5dac24c368bbcd522c27a00",
- "sha256": "10ce8a82f7e53c67f2af8d4dc4b8cdb4d0630d0e1d21818da4d5b3ca2de08385",
- "sha1": "8992b17455ce660da9c5fe47226b7ded9e872637",
- "md5": "e84da489be91de821c95d41b8f0e0a0a"
- }
- ]
- },
- {
- "name": "runtimeElements",
- "attributes": {
- "org.gradle.category": "library",
- "org.gradle.dependency.bundling": "external",
- "org.gradle.jvm.version": 8,
- "org.gradle.libraryelements": "jar",
- "org.gradle.usage": "java-runtime"
- },
- "files": [
- {
- "name": "module-two-1.0.0.jar",
- "url": "module-two-1.0.0.jar",
- "size": 261,
- "sha512": "2730ac0859e1c2f450d54647c29ece43d095eb834e2130d4949dd1151317d013c072fa8f96f5f4b49836eff7c19a2eeeb5ca7483e5dac24c368bbcd522c27a00",
- "sha256": "10ce8a82f7e53c67f2af8d4dc4b8cdb4d0630d0e1d21818da4d5b3ca2de08385",
- "sha1": "8992b17455ce660da9c5fe47226b7ded9e872637",
- "md5": "e84da489be91de821c95d41b8f0e0a0a"
- }
- ]
- },
- {
- "name": "javadocElements",
- "attributes": {
- "org.gradle.category": "documentation",
- "org.gradle.dependency.bundling": "external",
- "org.gradle.docstype": "javadoc",
- "org.gradle.usage": "java-runtime"
- },
- "files": [
- {
- "name": "module-two-1.0.0-javadoc.jar",
- "url": "module-two-1.0.0-javadoc.jar",
- "size": 261,
- "sha512": "2730ac0859e1c2f450d54647c29ece43d095eb834e2130d4949dd1151317d013c072fa8f96f5f4b49836eff7c19a2eeeb5ca7483e5dac24c368bbcd522c27a00",
- "sha256": "10ce8a82f7e53c67f2af8d4dc4b8cdb4d0630d0e1d21818da4d5b3ca2de08385",
- "sha1": "8992b17455ce660da9c5fe47226b7ded9e872637",
- "md5": "e84da489be91de821c95d41b8f0e0a0a"
- }
- ]
- },
- {
- "name": "sourcesElements",
- "attributes": {
- "org.gradle.category": "documentation",
- "org.gradle.dependency.bundling": "external",
- "org.gradle.docstype": "sources",
- "org.gradle.usage": "java-runtime"
- },
- "files": [
- {
- "name": "module-two-1.0.0-sources.jar",
- "url": "module-two-1.0.0-sources.jar",
- "size": 261,
- "sha512": "2730ac0859e1c2f450d54647c29ece43d095eb834e2130d4949dd1151317d013c072fa8f96f5f4b49836eff7c19a2eeeb5ca7483e5dac24c368bbcd522c27a00",
- "sha256": "10ce8a82f7e53c67f2af8d4dc4b8cdb4d0630d0e1d21818da4d5b3ca2de08385",
- "sha1": "8992b17455ce660da9c5fe47226b7ded9e872637",
- "md5": "e84da489be91de821c95d41b8f0e0a0a"
- }
- ]
- }
- ]
-}
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.module.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.module.asc
deleted file mode 100644
index 3cf7219f0929..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.module.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1sACgkQmix6mORX
-xT2SwAf/SDu2XlOfyL+oTidHItm3DmLsRY0xU2d5siCuasxxpzIPG+O5f3o7VeNS
-pKUctb+Vbx7Za+tPYts4ztG+bqVUVZbtn9ERWCXAvuuAnbJMxIl4D7HXahZPJKtl
-UrpKgA+45p2NLB9MK5B9QkmZInxF0ex3IUkc6e3MN8pmcefcjjDpoEvWKlc+ocEA
-/ySwMcH38FRYB6XbwsAjdXm7jiLpA9ZA5MdfZzjmm3nRBDzujBjU/Pv1+PFPH4Lh
-rfAS5+HOvWLQwt5kKyr8w3GzfbWT7FF7z024x0rT6mo0chOMe33Ng/AOYSGFzisJ
-OrJieiEosNjdcFbfuvspQFsI0cRU/A==
-=dgpO
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.module.md5 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.module.md5
deleted file mode 100644
index ef64fa1aa54d..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.module.md5
+++ /dev/null
@@ -1 +0,0 @@
-9a7d415ecef034f2fd4a0b251055ec4b
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.module.md5.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.module.md5.asc
deleted file mode 100644
index a31ae245d37d..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.module.md5.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1sACgkQmix6mORX
-xT375Af+L1KawLLikLiiC6R2BCxufjcLHEzxh0RLjgDHpHXy8s/Bh5GgkTT4x/Hn
-gGJNT3Yz18rzpZaLnvNR/J9wOFEzLxRsgl1rumvTrrwhbIjac774oj3Z8Zv+W1T8
-KN1mtfUSLDZSRbmY0YByvPVtag1+FaIifxmIIFLny+xDzRVD1OZ38gOaxz91nqmd
-pgjR2eVmeYLX3oAIApVopYdKWXNwOMzdBQbNroPRKCOesmTqQi0sjuvgN7r5JoxN
-9vVzF1SFnAKnw/LQqL0KMrRzCBd+ncUk7A6D6RB0MM0V+TB9am9CsatxflRgQY+c
-vzu/BHY8k6lh44TECvAuNuSr01CkPA==
-=awJx
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.module.sha1 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.module.sha1
deleted file mode 100644
index dc6c2e7bcd60..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.module.sha1
+++ /dev/null
@@ -1 +0,0 @@
-9df95def633421b7415f807b0b5848c6975de806
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.module.sha1.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.module.sha1.asc
deleted file mode 100644
index df2673f47c2f..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.module.sha1.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1sACgkQmix6mORX
-xT1ubAgAtWXXzqRDIC+DhAaY3IfHyM/Dmlj58jLhTzta4xKQe9HykEjBlpkPSscp
-9R+O2aL4xfBUmKtVLORKoGN3oUPhdU8a5vfgI2itdDPWLkOfFE64OJtIOZKp4ST4
-i00Jsqd4GFryS3r+i5FL5MCCv+zG/OkylMIfcH1XVxynvwrJVY49Do+TmW4MOIFf
-4uDOd29XmEc8vCJBd3VZu0epHqcXhdiQy0ekdl3NdUimzRuXAckNhGNMoLWYhKaw
-voErlAtfDHMbYU1DebguEaiLi98N6IxX1aO0Lleg3JNveD7pLCjEEf7AW+7TYoz1
-QBvHABpVHzZ7Rg5VhZNIIrQ38zyZdg==
-=kz39
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.module.sha256 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.module.sha256
deleted file mode 100644
index dc5ad0866352..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.module.sha256
+++ /dev/null
@@ -1 +0,0 @@
-773b2d6350eb671af0b79328bd5334fba565f9041ca823fe7b55097dadf3dcf5
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.module.sha256.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.module.sha256.asc
deleted file mode 100644
index 2557a7a64e2f..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.module.sha256.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1sACgkQmix6mORX
-xT3njggAl61MfkbtByxMKX8fQo5Jqp+vtvyZoaDZj+6FKr0xust5Wr4Fi+4+7fkj
-KyXFCTZUTd0xokRNpC8bxeZhhVkeG0pq6DrTr5BTvJLMJwPWVvrtn+bzDN1FvMia
-iZqcOlWtbwTdcosmBxXtxwI1gavwFhHUGudBzrBs85qkMkDz9BH8Egb+z/owFfPh
-lB9NSzezj4axgr745Ov5gYCwZp44iDBTcLZDWSLGMTuC6VdrLTQVsNLxouGI/67E
-0oqLmlaqfWZEJktTMk0LHG5ymy0g40Gm8r2kuxRnFEDVJwXSfJRiTvxifB+YoEHp
-RAcpReQe8+iSStuGEKYmfwmyXTdXAA==
-=759w
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.module.sha512 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.module.sha512
deleted file mode 100644
index 7e12e81cba75..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.module.sha512
+++ /dev/null
@@ -1 +0,0 @@
-6294828fb9ce277d60e92c607d00b739e9266c3ebdca173fb32881c04f2d365d43bf9d77c0a07cf1dbcd09ad302f7458e938197f59ff5614a5d1d4e4146a0cf6
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.module.sha512.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.module.sha512.asc
deleted file mode 100644
index 5c37a3450966..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.module.sha512.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1sACgkQmix6mORX
-xT1H5wgAnmHJRXH+f1cZLlLKqMv7JMbuSFha3XsDPeL/XIEXmD9zj/R8IE7EKmpS
-uwkswZaOeIyc95J4FasxiZm5CExxzRSTQfXtK2lOl/7Gp84D+D6XXI28CUIRnOfo
-SeOyCFk2U3a6uTsRgi1FSnJRvLCs+0tB+bByKuVgGbfQdF0mtQ9rCxlqKKVa/dz6
-ertOXtz1A7fiLV44ovZG27GOciRJbogBmWfmNGPaQ+Ry8b8ICPf3SDdNSpp/nG2i
-YZxzIyX9xabzPGg7M1d4ClhrpJQRjJD1hJRIHCkwC8f8Y544iQ/MuAwd3hNIfjWP
-GJjgOl0iYjO8LPVaRdrHFkBUntVdHQ==
-=tlE4
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.pom b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.pom
deleted file mode 100644
index 31433f629303..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.pom
+++ /dev/null
@@ -1,49 +0,0 @@
-
-
-
-
-
-
-
- 4.0.0
- org.springframework.example
- module-two
- 1.0.0
- module-two
- Example module
- https://spring.io/projects/spring-boot
-
- Spring
- https://spring.io
-
-
-
- Apache License, Version 2.0
- https://www.apache.org/licenses/LICENSE-2.0
-
-
-
-
- Spring
- ask@spring.io
- Spring
- https://www.spring.io
-
-
-
-
- scm:git:git://github.com/spring-projects/spring-boot.git
-
-
- scm:git:ssh://git@github.com/spring-projects/spring-boot.git
-
- https://github.com/spring-projects/spring-boot
-
-
- GitHub
-
- https://github.com/spring-projects/spring-boot/issues
-
-
-
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.pom.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.pom.asc
deleted file mode 100644
index f3703ea391be..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.pom.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
-xT2kvAgAoc2k0ljj7L3Pj4rPz73K1SO3pDHdf+6S6pU7E4ao9FEFZBcB7YJjEmmQ
-U724HqU15PIkaJKI/v4Z612E1gMSMIQ8A0LnsFR9yQdvrsK1Ijv+CdPCdyvZsBfP
-3MgmWaRUOToK3BAAVV5y0dfUNFUyeKKxHNclJd6H0HUK02of8I7LBn/5ULK4QRaQ
-Lm3bUIT3PtjUfND+DK3QlczZ+YgOkIwTkLywYCYxblm9XJjWCRXaZI1MdUlA6SMs
-uEqtglQ9zEJgyue/JtWsIkAlzUbdyjo34Cg5HEZJ6RNzboXlRNFm83fcKyPhSy7V
-0xikP1INbKuZSU1ZE7/rRYIQ7ChK0g==
-=96NH
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.pom.md5 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.pom.md5
deleted file mode 100644
index 463446fec94b..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.pom.md5
+++ /dev/null
@@ -1 +0,0 @@
-057258909d16c0f9ed33c8a83e4ef165
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.pom.md5.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.pom.md5.asc
deleted file mode 100644
index df9d49af1f43..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.pom.md5.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1sACgkQmix6mORX
-xT1eXQgAhIYkhiSoV4lFMPT9GuN4OjkoQC+v9ev8HkmIdq8lpoB+StIYzI35hKLU
-kfm5d2aeVo7ifDdXh642p9oEXRfuDPfaLd9u8SZZBAdo4rolQZr4bl+JaUFzR79i
-nRozXQeJF1UrDUKMi0+YGQxlosTbdx7Romj2UdfEmL2ACetxxR3rQExgZl4O/OUm
-PHJtIrzO1xdbVxtKelILJ4D/PauqEqcqzC2gI5vObZJcRgxDU/wc2CVN9jruv07h
-UW+8IEFV8vexoHo+Kq/F9xaTW2b7oXnvfOJgWRbh3zGpxSluJwVINDyX39/ym/Dr
-FIO6BPWFKQPEUW2cY6C69jj7S+v8Ig==
-=PYoG
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.pom.sha1 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.pom.sha1
deleted file mode 100644
index 2b3f269aad0f..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.pom.sha1
+++ /dev/null
@@ -1 +0,0 @@
-1a742c42aef877b6a2808a1b5c35fbe3189ce274
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.pom.sha1.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.pom.sha1.asc
deleted file mode 100644
index ea7c57f9c6ed..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.pom.sha1.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEyBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1sACgkQmix6mORX
-xT0bmAf4+WOg0xkoyRDXf/1hFOXlimKqyF1K7I6PXx1dFokRr+tvOtfFZucCOf+f
-1hCvnBiPTQwwMPCgll0reTsH2nHfDVUcbugpxVDC3Yza0x3gHudBhPC7yv+osNIu
-sVlnMRYbG1RQGjE6BxHoBk9pdOcwgN7zk2Y4LfAbOKMTo7dhAjZavRx3aShEUwHy
-P9/kfxcWCL0tOSzWg5XpZuxFEdVMWNJvshFvP0j2/Nlr6ZL5o/AwtyZKMiZ8QcUb
-0satLj501JYI6pM2cm8N17T94+jCsQXZic/hUCNteXA4XbRcDBR2wQLd08/Ht0U4
-rHzZQNr5Ft5R5ScshTEVBwjcd/Kx
-=drUj
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.pom.sha256 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.pom.sha256
deleted file mode 100644
index 334afc14508c..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.pom.sha256
+++ /dev/null
@@ -1 +0,0 @@
-7e855e618d4aba3eb4e63bbfc9960e4da319d8bdef0cca213a11e9b2d1991635
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.pom.sha256.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.pom.sha256.asc
deleted file mode 100644
index 433766e66069..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.pom.sha256.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
-xT3w3QgAvHS75cBMEEZGWiCQ+lbwDMWY7rjQBwkpO1Sj6WxpKcWD2F4YmNni1z1k
-L71SDuLP0a+IbYcoDCkss7vxH6hx6Lm53e+2WwhaVGCO1A6N3a56rFyEFlATrn31
-mcRjLrN4wzysqqbeamzSt+R0UoWj7yiihtBuz7tkhjGP+df2qCrXNeuetrhukFOz
-P5RLd4PURYMMUMqqNZ8JNnRhdCVdSVUpfM+BDolNDaswDrvOI3jzjXD/6HCt0fcN
-Pt484kFDqGEx0iXvv+7shiExs31gex+fsn2ta9yOGYluF/8Rc4z+X0/59MewoCgC
-EelPT4oi4zirrIWzGp1bRF+jDi6feA==
-=stbf
------END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.pom.sha512 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.pom.sha512
deleted file mode 100644
index e7b24fdd95be..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.pom.sha512
+++ /dev/null
@@ -1 +0,0 @@
-5b06587734aa146b452e78e34abffb38b8c820abf623975409ae003b5d90aded345fa8f92ed9d7a505a16db324c0649d2e16c7597bad8dc63f0a5c00123789e1
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.pom.sha512.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.pom.sha512.asc
deleted file mode 100644
index d8d2cc73e369..000000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.pom.sha512.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1sACgkQmix6mORX
-xT3p3QgAp5doWrX6eMPD1I09NHMt29LI8wFa/xld7rof8OQLHDN55TLseqOvBU4V
-E82s5cm4Uk0ndnth/VUHqsJK6SsNX8/0N2bvOtWgUWBYdClcy6ZBWXjQIDFfCdqX
-LPqQN4nOT3ZZMrzTZhLsAJkbzvVaOzEtUYZWw1ZAIT8nPkud24stuuxKUtsAxfeD
-QqcgKng/sPx6DS2+NSmmzyCF9eSL70NBcBF6+RJ+4X0YtZRtX+wsic2MnKnVAnyX
-hPejxguJYhwWbn1yRdVWknCdffpiT09IC/7AS/yc8s1DdbS6XEae8uFl0OB5z5dx
-nnaHUvlFrAjDGsrYeW5h1ZkM8VwBxA==
-=2HWi
------END PGP SIGNATURE-----
diff --git a/ci/images/setup.sh b/ci/images/setup.sh
index 48df23b70732..f1d15e5149c0 100755
--- a/ci/images/setup.sh
+++ b/ci/images/setup.sh
@@ -2,12 +2,13 @@
set -ex
###########################################################
-# UTILS
+# OS and UTILS
###########################################################
export DEBIAN_FRONTEND=noninteractive
apt-get update
-apt-get install --no-install-recommends -y tzdata ca-certificates net-tools libxml2-utils git curl libudev1 libxml2-utils iptables iproute2 jq
+apt-get install --no-install-recommends -y locales tzdata ca-certificates net-tools libxml2-utils git curl libudev1 libxml2-utils iptables iproute2 jq
+locale-gen en_US.utf8
ln -fs /usr/share/zoneinfo/UTC /etc/localtime
dpkg-reconfigure --frontend noninteractive tzdata
rm -rf /var/lib/apt/lists/*
@@ -37,6 +38,7 @@ if [[ $# -eq 2 ]]; then
test -f /opt/openjdk-toolchain/bin/javac
fi
+
###########################################################
# DOCKER
###########################################################
@@ -52,6 +54,7 @@ chmod +x entrykit && \
mv entrykit /bin/entrykit && \
entrykit --symlink
+
###########################################################
# DOCKER COMPOSE
###########################################################
@@ -59,9 +62,3 @@ mkdir -p /usr/local/lib/docker/cli-plugins
DOCKER_COMPOSE_URL=$( ./get-docker-compose-url.sh )
curl -L ${DOCKER_COMPOSE_URL} -o /usr/local/lib/docker/cli-plugins/docker-compose
chmod +x /usr/local/lib/docker/cli-plugins/docker-compose
-
-###########################################################
-# GRADLE ENTERPRISE
-###########################################################
-mkdir ~/.gradle
-echo 'systemProp.user.name=concourse' > ~/.gradle/gradle.properties
\ No newline at end of file
diff --git a/ci/parameters.yml b/ci/parameters.yml
index 530398e4dc2c..0aff59284632 100644
--- a/ci/parameters.yml
+++ b/ci/parameters.yml
@@ -1,10 +1,15 @@
-github-repo: "https://github.com/spring-projects/spring-boot.git"
-github-repo-name: "spring-projects/spring-boot"
+github-organization-name: "spring-projects"
+github-repository-name: "spring-boot"
+github-repository-uri: "https://github.com/spring-projects/spring-boot.git"
homebrew-tap-repo: "https://github.com/spring-io/homebrew-tap.git"
docker-hub-organization: "springci"
-artifactory-server: "https://repo.spring.io"
-branch: "3.1.x"
-milestone: "3.1.x"
+docker-hub-repository-prefix: "spring-boot"
+artifactory-snapshot-repository: "libs-snapshot-local"
+artifactory-staging-repository: "libs-staging-local"
+artifactory-url: "https://repo.spring.io"
+branch: "main"
+milestone: "3.2.x"
build-name: "spring-boot"
concourse-url: "https://ci.spring.io"
task-timeout: 2h00m
+final-release: false
diff --git a/ci/pipeline.yml b/ci/pipeline.yml
index 99d016228400..d661686d422c 100644
--- a/ci/pipeline.yml
+++ b/ci/pipeline.yml
@@ -1,6 +1,6 @@
anchors:
git-repo-resource-source: &git-repo-resource-source
- uri: ((github-repo))
+ uri: ((github-repository-uri))
username: ((github-username))
password: ((github-ci-release-token))
branch: ((branch))
@@ -22,18 +22,18 @@ anchors:
DOCKER_HUB_PASSWORD: ((docker-hub-password))
DOCKER_HUB_AUTH: ((docker-hub-auth))
github-task-params: &github-task-params
- GITHUB_REPO: spring-boot
- GITHUB_ORGANIZATION: spring-projects
+ GITHUB_REPO: ((github-repository-name))
+ GITHUB_ORGANIZATION: ((github-organization-name))
GITHUB_PASSWORD: ((github-ci-release-token))
GITHUB_USERNAME: ((github-username))
MILESTONE: ((milestone))
sontatype-task-params: &sonatype-task-params
- SONATYPE_USER_TOKEN: ((sonatype-username))
- SONATYPE_PASSWORD_TOKEN: ((sonatype-password))
+ SONATYPE_USERNAME: ((sonatype-username))
+ SONATYPE_PASSWORD: ((sonatype-password))
SONATYPE_URL: ((sonatype-url))
SONATYPE_STAGING_PROFILE_ID: ((sonatype-staging-profile-id))
artifactory-task-params: &artifactory-task-params
- ARTIFACTORY_SERVER: ((artifactory-server))
+ ARTIFACTORY_URL: ((artifactory-url))
ARTIFACTORY_USERNAME: ((artifactory-username))
ARTIFACTORY_PASSWORD: ((artifactory-password))
sdkman-task-params: &sdkman-task-params
@@ -58,7 +58,7 @@ anchors:
artifactory-repo-put-params: &artifactory-repo-put-params
signing_key: ((signing-key))
signing_passphrase: ((signing-passphrase))
- repo: libs-snapshot-local
+ repo: ((artifactory-snapshot-repository))
folder: distribution-repository
build_uri: "https://ci.spring.io/teams/${BUILD_TEAM_NAME}/pipelines/${BUILD_PIPELINE_NAME}/jobs/${BUILD_JOB_NAME}/builds/${BUILD_NAME}"
build_number: "${BUILD_JOB_NAME}-${BUILD_NAME}"
@@ -143,8 +143,8 @@ resources:
type: github-release
icon: briefcase-download-outline
source:
- owner: spring-projects
- repository: spring-boot
+ owner: ((github-organization-name))
+ repository: ((github-repository-name))
access_token: ((github-ci-release-token))
pre_release: true
release: false
@@ -152,15 +152,15 @@ resources:
type: github-release
icon: briefcase-download
source:
- owner: spring-projects
- repository: spring-boot
+ owner: ((github-organization-name))
+ repository: ((github-repository-name))
access_token: ((github-ci-release-token))
pre_release: false
- name: ci-images-git-repo
type: git
icon: github
source:
- uri: ((github-repo))
+ uri: ((github-repository-uri))
branch: ((branch))
paths: ["ci/images/*"]
- name: ci-image
@@ -168,24 +168,24 @@ resources:
icon: docker
source:
<<: *ci-registry-image-resource-source
- repository: ((docker-hub-organization))/spring-boot-ci
-- name: ci-image-jdk20
+ repository: ((docker-hub-organization))/((docker-hub-repository-prefix))-ci
+- name: ci-image-jdk21
type: registry-image
icon: docker
source:
<<: *ci-registry-image-resource-source
- repository: ((docker-hub-organization))/spring-boot-ci-jdk20
+ repository: ((docker-hub-organization))/((docker-hub-repository-prefix))-ci-jdk21
- name: paketo-builder-base-image
type: registry-image
icon: docker
source:
- repository: paketobuildpacks/builder
- tag: base
+ repository: paketobuildpacks/builder-jammy-base
+ tag: latest
- name: artifactory-repo
type: artifactory-resource
icon: package-variant
source:
- uri: ((artifactory-server))
+ uri: ((artifactory-url))
username: ((artifactory-username))
password: ((artifactory-password))
build_name: ((build-name))
@@ -195,18 +195,18 @@ resources:
type: github-status-resource
icon: eye-check-outline
source:
- repository: ((github-repo-name))
+ repository: ((github-organization-name))/((github-repository-name))
access_token: ((github-ci-status-token))
branch: ((branch))
context: build
-- name: repo-status-jdk20-build
+- name: repo-status-jdk21-build
type: github-status-resource
icon: eye-check-outline
source:
- repository: ((github-repo-name))
+ repository: ((github-organization-name))/((github-repository-name))
access_token: ((github-ci-status-token))
branch: ((branch))
- context: jdk20-build
+ context: jdk21-build
- name: slack-alert
type: slack-notification
icon: slack
@@ -242,20 +242,20 @@ jobs:
image: ci-image
vars:
ci-image-name: ci-image
- - task: build-ci-image-jdk20
+ - task: build-ci-image-jdk21
privileged: true
file: git-repo/ci/tasks/build-ci-image.yml
output_mapping:
- image: ci-image-jdk20
+ image: ci-image-jdk21
vars:
- ci-image-name: ci-image-jdk20
+ ci-image-name: ci-image-jdk21
- in_parallel:
- put: ci-image
params:
image: ci-image/image.tar
- - put: ci-image-jdk20
+ - put: ci-image-jdk21
params:
- image: ci-image-jdk20/image.tar
+ image: ci-image-jdk21/image.tar
- name: detect-jdk-updates
plan:
- get: git-repo
@@ -269,12 +269,12 @@ jobs:
params:
<<: *github-task-params
JDK_VERSION: java17
- - task: detect-jdk20-update
+ - task: detect-jdk21-update
image: ci-image
file: git-repo/ci/tasks/detect-jdk-updates.yml
params:
<<: *github-task-params
- JDK_VERSION: java20
+ JDK_VERSION: java21
- name: detect-ubuntu-image-updates
plan:
- get: git-repo
@@ -334,34 +334,34 @@ jobs:
- put: slack-alert
params:
<<: *slack-success-params
-- name: jdk20-build
+- name: jdk21-build
serial: true
public: true
plan:
- - get: ci-image-jdk20
+ - get: ci-image-jdk21
- get: git-repo
trigger: true
- - put: repo-status-jdk20-build
+ - put: repo-status-jdk21-build
params: { state: "pending", commit: "git-repo" }
- do:
- task: build-project
- image: ci-image-jdk20
+ image: ci-image-jdk21
privileged: true
timeout: ((task-timeout))
file: git-repo/ci/tasks/build-project.yml
params:
BRANCH: ((branch))
- TOOLCHAIN_JAVA_VERSION: 20
+ TOOLCHAIN_JAVA_VERSION: 21
<<: *gradle-enterprise-task-params
<<: *docker-hub-task-params
on_failure:
do:
- - put: repo-status-jdk20-build
+ - put: repo-status-jdk21-build
params: { state: "failure", commit: "git-repo" }
- put: slack-alert
params:
<<: *slack-fail-params
- - put: repo-status-jdk20-build
+ - put: repo-status-jdk21-build
params: { state: "success", commit: "git-repo" }
- put: slack-alert
params:
@@ -402,13 +402,14 @@ jobs:
timeout: ((task-timeout))
file: git-repo/ci/tasks/stage.yml
params:
+ FINAL_RELEASE: ((final-release))
RELEASE_TYPE: M
<<: *gradle-enterprise-task-params
<<: *docker-hub-task-params
- put: artifactory-repo
params:
<<: *artifactory-repo-put-params
- repo: libs-staging-local
+ repo: ((artifactory-staging-repository))
get_params:
threads: 8
- put: git-repo
@@ -425,13 +426,14 @@ jobs:
timeout: ((task-timeout))
file: git-repo/ci/tasks/stage.yml
params:
+ FINAL_RELEASE: ((final-release))
RELEASE_TYPE: RC
<<: *gradle-enterprise-task-params
<<: *docker-hub-task-params
- put: artifactory-repo
params:
<<: *artifactory-repo-put-params
- repo: libs-staging-local
+ repo: ((artifactory-staging-repository))
get_params:
threads: 8
- put: git-repo
@@ -448,13 +450,14 @@ jobs:
timeout: ((task-timeout))
file: git-repo/ci/tasks/stage.yml
params:
+ FINAL_RELEASE: ((final-release))
RELEASE_TYPE: RELEASE
<<: *gradle-enterprise-task-params
<<: *docker-hub-task-params
- put: artifactory-repo
params:
<<: *artifactory-repo-put-params
- repo: libs-staging-local
+ repo: ((artifactory-staging-repository))
get_params:
threads: 8
- put: git-repo
@@ -463,7 +466,6 @@ jobs:
- name: promote-milestone
serial: true
plan:
- - get: ci-image
- get: git-repo
trigger: false
- get: artifactory-repo
@@ -473,7 +475,6 @@ jobs:
download_artifacts: false
save_build_info: true
- task: promote
- image: ci-image
file: git-repo/ci/tasks/promote.yml
params:
RELEASE_TYPE: M
@@ -492,7 +493,6 @@ jobs:
- name: promote-rc
serial: true
plan:
- - get: ci-image
- get: git-repo
trigger: false
- get: artifactory-repo
@@ -502,7 +502,6 @@ jobs:
download_artifacts: false
save_build_info: true
- task: promote
- image: ci-image
file: git-repo/ci/tasks/promote.yml
params:
RELEASE_TYPE: RC
@@ -521,7 +520,6 @@ jobs:
- name: promote-release
serial: true
plan:
- - get: ci-image
- get: git-repo
trigger: false
- get: artifactory-repo
@@ -532,7 +530,6 @@ jobs:
save_build_info: true
threads: 8
- task: promote
- image: ci-image
file: git-repo/ci/tasks/promote.yml
params:
RELEASE_TYPE: RELEASE
@@ -580,7 +577,6 @@ jobs:
- name: publish-to-sdkman
serial: true
plan:
- - get: ci-image
- get: git-repo
- get: artifactory-repo
passed: [create-github-release]
@@ -588,7 +584,6 @@ jobs:
download_artifacts: false
save_build_info: true
- task: publish-to-sdkman
- image: ci-image
file: git-repo/ci/tasks/publish-to-sdkman.yml
params:
<<: *sdkman-task-params
@@ -636,11 +631,11 @@ jobs:
- put: slack-alert
params:
<<: *slack-success-params
-- name: jdk20-run-system-tests
+- name: jdk21-run-system-tests
serial: true
public: true
plan:
- - get: ci-image-jdk20
+ - get: ci-image-jdk21
- get: git-repo
- get: paketo-builder-base-image
trigger: true
@@ -648,13 +643,13 @@ jobs:
trigger: true
- do:
- task: run-system-tests
- image: ci-image-jdk20
+ image: ci-image-jdk21
privileged: true
timeout: ((task-timeout))
file: git-repo/ci/tasks/run-system-tests.yml
params:
BRANCH: ((branch))
- TOOLCHAIN_JAVA_VERSION: 20
+ TOOLCHAIN_JAVA_VERSION: 21
<<: *gradle-enterprise-task-params
<<: *docker-hub-task-params
on_failure:
@@ -667,11 +662,11 @@ jobs:
<<: *slack-success-params
groups:
- name: "builds"
- jobs: ["build", "jdk20-build", "windows-build"]
+ jobs: ["build", "jdk21-build", "windows-build"]
- name: "releases"
jobs: ["stage-milestone", "stage-rc", "stage-release", "promote-milestone", "promote-rc", "promote-release", "create-github-release", "publish-gradle-plugin", "publish-to-sdkman", "update-homebrew-tap"]
- name: "system-tests"
- jobs: ["run-system-tests", "jdk20-run-system-tests"]
+ jobs: ["run-system-tests", "jdk21-run-system-tests"]
- name: "ci-images"
jobs: ["build-ci-images", "detect-docker-updates", "detect-jdk-updates", "detect-ubuntu-image-updates"]
diff --git a/ci/scripts/common.sh b/ci/scripts/common.sh
index 0c0f901c5072..bdc3e2b6075a 100644
--- a/ci/scripts/common.sh
+++ b/ci/scripts/common.sh
@@ -1,8 +1,7 @@
source /opt/concourse-java.sh
setup_symlinks
-if [[ -d $PWD/embedmongo && ! -d $HOME/.embedmongo ]]; then
- ln -s "$PWD/embedmongo" "$HOME/.embedmongo"
-fi
cleanup_maven_repo "org.springframework.boot"
+
+echo 'systemProp.user.name=concourse' > ~/.gradle/gradle.properties
diff --git a/ci/scripts/detect-jdk-updates.sh b/ci/scripts/detect-jdk-updates.sh
index 22dc5dcbd960..e54fc3b8f228 100755
--- a/ci/scripts/detect-jdk-updates.sh
+++ b/ci/scripts/detect-jdk-updates.sh
@@ -12,9 +12,9 @@ case "$JDK_VERSION" in
BASE_URL="https://api.bell-sw.com/v1/liberica/releases?version-feature=17"
ISSUE_TITLE="Upgrade Java 17 version in CI image and .sdkmanrc"
;;
- java20)
- BASE_URL="https://api.bell-sw.com/v1/liberica/releases?version-feature=20"
- ISSUE_TITLE="Upgrade Java 20 version in CI image"
+ java21)
+ BASE_URL="https://api.bell-sw.com/v1/liberica/releases?version-feature=21"
+ ISSUE_TITLE="Upgrade Java 21 version in CI image"
;;
*)
echo $"Unknown java version"
diff --git a/ci/scripts/promote.sh b/ci/scripts/promote.sh
index 14ad9861e6e1..bd1600191a79 100755
--- a/ci/scripts/promote.sh
+++ b/ci/scripts/promote.sh
@@ -1,13 +1,17 @@
#!/bin/bash
-source $(dirname $0)/common.sh
+CONFIG_DIR=git-repo/ci/config
version=$( cat artifactory-repo/build-info.json | jq -r '.buildInfo.modules[0].id' | sed 's/.*:.*:\(.*\)/\1/' )
export BUILD_INFO_LOCATION=$(pwd)/artifactory-repo/build-info.json
-java -jar /spring-boot-release-scripts.jar publishToCentral $RELEASE_TYPE $BUILD_INFO_LOCATION artifactory-repo || { exit 1; }
+java -jar /concourse-release-scripts.jar \
+ --spring.config.location=${CONFIG_DIR}/release-scripts.yml \
+ publishToCentral $RELEASE_TYPE $BUILD_INFO_LOCATION artifactory-repo || { exit 1; }
-java -jar /spring-boot-release-scripts.jar promote $RELEASE_TYPE $BUILD_INFO_LOCATION || { exit 1; }
+java -jar /concourse-release-scripts.jar \
+ --spring.config.location=${CONFIG_DIR}/release-scripts.yml \
+ promote $RELEASE_TYPE $BUILD_INFO_LOCATION || { exit 1; }
echo "Promotion complete"
echo $version > version/version
diff --git a/ci/scripts/publish-to-sdkman.sh b/ci/scripts/publish-to-sdkman.sh
index 00bb6adc26e5..9cf273d2345e 100755
--- a/ci/scripts/publish-to-sdkman.sh
+++ b/ci/scripts/publish-to-sdkman.sh
@@ -1,9 +1,11 @@
#!/bin/bash
-source $(dirname $0)/common.sh
+CONFIG_DIR=git-repo/ci/config
version=$( cat artifactory-repo/build-info.json | jq -r '.buildInfo.modules[0].id' | sed 's/.*:.*:\(.*\)/\1/' )
-java -jar /spring-boot-release-scripts.jar publishToSdkman $RELEASE_TYPE $version $LATEST_GA || { exit 1; }
+java -jar /concourse-release-scripts.jar \
+ --spring.config.location=${CONFIG_DIR}/release-scripts.yml \
+ publishToSdkman $RELEASE_TYPE $version $LATEST_GA || { exit 1; }
echo "Push to SDKMAN complete"
diff --git a/ci/scripts/stage.sh b/ci/scripts/stage.sh
index bfc2690198e5..981aeb2ec7ca 100755
--- a/ci/scripts/stage.sh
+++ b/ci/scripts/stage.sh
@@ -38,7 +38,7 @@ git tag -a "v$stageVersion" -m"Release v$stageVersion" > /dev/null
./gradlew --no-daemon --max-workers=4 -PdeploymentRepository=${repository} build publishAllPublicationsToDeploymentRepository
git reset --hard HEAD^ > /dev/null
-if [[ $nextVersion != $snapshotVersion ]]; then
+if [[ $FINAL_RELEASE != true && $nextVersion != $snapshotVersion ]]; then
echo "Setting next development version (v$nextVersion)"
sed -i "s/version=$snapshotVersion/version=$nextVersion/" gradle.properties
git add gradle.properties > /dev/null
diff --git a/ci/tasks/build-project.yml b/ci/tasks/build-project.yml
index db3003af6e0c..ccc12d032430 100644
--- a/ci/tasks/build-project.yml
+++ b/ci/tasks/build-project.yml
@@ -7,7 +7,7 @@ outputs:
- name: git-repo
caches:
- path: gradle
-- path: embedmongo
+- path: maven
params:
BRANCH:
CI: true
diff --git a/ci/tasks/promote.yml b/ci/tasks/promote.yml
index 2e5f9d36b65b..aa700a1bf11f 100644
--- a/ci/tasks/promote.yml
+++ b/ci/tasks/promote.yml
@@ -1,17 +1,25 @@
---
platform: linux
+image_resource:
+ type: registry-image
+ source:
+ repository: springio/concourse-release-scripts
+ tag: '0.4.0'
+ username: ((docker-hub-username))
+ password: ((docker-hub-password))
inputs:
-- name: git-repo
-- name: artifactory-repo
+ - name: git-repo
+ - name: artifactory-repo
outputs:
-- name: version
+ - name: version
params:
RELEASE_TYPE:
- ARTIFACTORY_SERVER:
+ ARTIFACTORY_URL:
ARTIFACTORY_USERNAME:
ARTIFACTORY_PASSWORD:
- SONATYPE_USER_TOKEN:
- SONATYPE_PASSWORD_TOKEN:
+ SONATYPE_USERNAME:
+ SONATYPE_PASSWORD:
+ SONATYPE_URL:
SONATYPE_STAGING_PROFILE_ID:
run:
path: git-repo/ci/scripts/promote.sh
diff --git a/ci/tasks/publish-to-sdkman.yml b/ci/tasks/publish-to-sdkman.yml
index 0215e2943bee..3b9fa93ebbb4 100755
--- a/ci/tasks/publish-to-sdkman.yml
+++ b/ci/tasks/publish-to-sdkman.yml
@@ -1,8 +1,15 @@
---
platform: linux
+image_resource:
+ type: registry-image
+ source:
+ repository: springio/concourse-release-scripts
+ tag: '0.4.0'
+ username: ((docker-hub-username))
+ password: ((docker-hub-password))
inputs:
- - name: artifactory-repo
- name: git-repo
+ - name: artifactory-repo
params:
RELEASE_TYPE:
BRANCH:
diff --git a/ci/tasks/stage.yml b/ci/tasks/stage.yml
index 3ea8550eb524..feff204848e7 100644
--- a/ci/tasks/stage.yml
+++ b/ci/tasks/stage.yml
@@ -8,6 +8,7 @@ outputs:
params:
RELEASE_TYPE:
CI: true
+ FINAL_RELEASE:
GRADLE_ENTERPRISE_CACHE_URL:
GRADLE_ENTERPRISE_CACHE_USERNAME:
GRADLE_ENTERPRISE_CACHE_PASSWORD:
diff --git a/eclipse/spring-boot-project.setup b/eclipse/spring-boot-project.setup
index 6cd6605e50d8..0e060372d33f 100644
--- a/eclipse/spring-boot-project.setup
+++ b/eclipse/spring-boot-project.setup
@@ -11,8 +11,8 @@
xmlns:setup.workingsets="http://www.eclipse.org/oomph/setup/workingsets/1.0"
xmlns:workingsets="http://www.eclipse.org/oomph/workingsets/1.0"
xsi:schemaLocation="http://www.eclipse.org/oomph/setup/jdt/1.0 http://git.eclipse.org/c/oomph/org.eclipse.oomph.git/plain/setups/models/JDT.ecore http://www.eclipse.org/buildship/oomph/1.0 https://raw.githubusercontent.com/eclipse/buildship/master/org.eclipse.buildship.oomph/model/GradleImport-1.0.ecore http://www.eclipse.org/oomph/predicates/1.0 http://git.eclipse.org/c/oomph/org.eclipse.oomph.git/plain/setups/models/Predicates.ecore http://www.eclipse.org/oomph/setup/workingsets/1.0 http://git.eclipse.org/c/oomph/org.eclipse.oomph.git/plain/setups/models/SetupWorkingSets.ecore http://www.eclipse.org/oomph/workingsets/1.0 http://git.eclipse.org/c/oomph/org.eclipse.oomph.git/plain/setups/models/WorkingSets.ecore"
- name="spring.boot.3.1.x"
- label="Spring Boot 3.1.x">
+ name="spring.boot.3.2.x"
+ label="Spring Boot 3.2.x">
+ pattern="spring-boot-(tools|antlib|configuration-.*|loader|loader-classic|.*-tools|.*-layertools|.*-plugin|autoconfigure-processor|buildpack.*)"/>
diff --git a/git/hooks/prepare-forward-merge b/git/hooks/prepare-forward-merge
index e9f03a32b594..786afcfb312a 100755
--- a/git/hooks/prepare-forward-merge
+++ b/git/hooks/prepare-forward-merge
@@ -4,7 +4,7 @@ require 'net/http'
require 'yaml'
require 'logger'
-$main_branch = "3.1.x"
+$main_branch = "3.2.x"
$log = Logger.new(STDOUT)
$log.level = Logger::WARN
diff --git a/gradle.properties b/gradle.properties
index c49004089b08..2fa85a373d54 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,12 +1,18 @@
-version=3.1.2-SNAPSHOT
+version=3.2.0
org.gradle.caching=true
org.gradle.parallel=true
org.gradle.jvmargs=-Xmx2g -Dfile.encoding=UTF-8
-kotlinVersion=1.8.22
-nativeBuildToolsVersion=0.9.23
-springFrameworkVersion=6.0.11
-tomcatVersion=10.1.11
+assertjVersion=3.24.2
+commonsCodecVersion=1.16.0
+hamcrestVersion=2.2
+jacksonVersion=2.15.3
+junitJupiterVersion=5.10.1
+kotlinVersion=1.9.20
+mavenVersion=3.9.4
+nativeBuildToolsVersion=0.9.28
+springFrameworkVersion=6.1.1
+tomcatVersion=10.1.16
kotlin.stdlib.default.dependency=false
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 4e86b9270786..b1624c473c42 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.2-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-bin.zip
networkTimeout=10000
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
diff --git a/idea/codeStyleConfig.xml b/idea/codeStyleConfig.xml
deleted file mode 100644
index 84141ac28fda..000000000000
--- a/idea/codeStyleConfig.xml
+++ /dev/null
@@ -1,128 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/settings.gradle b/settings.gradle
index 101c44479d93..9dc4ab6ee40d 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -53,11 +53,13 @@ include "spring-boot-project:spring-boot-tools:spring-boot-autoconfigure-process
include "spring-boot-project:spring-boot-tools:spring-boot-buildpack-platform"
include "spring-boot-project:spring-boot-tools:spring-boot-cli"
include "spring-boot-project:spring-boot-tools:spring-boot-configuration-metadata"
+include "spring-boot-project:spring-boot-tools:spring-boot-configuration-metadata-changelog-generator"
include "spring-boot-project:spring-boot-tools:spring-boot-configuration-processor"
include "spring-boot-project:spring-boot-tools:spring-boot-gradle-plugin"
include "spring-boot-project:spring-boot-tools:spring-boot-gradle-test-support"
include "spring-boot-project:spring-boot-tools:spring-boot-jarmode-layertools"
include "spring-boot-project:spring-boot-tools:spring-boot-loader"
+include "spring-boot-project:spring-boot-tools:spring-boot-loader-classic"
include "spring-boot-project:spring-boot-tools:spring-boot-loader-tools"
include "spring-boot-project:spring-boot-tools:spring-boot-maven-plugin"
include "spring-boot-project:spring-boot-tools:spring-boot-properties-migrator"
@@ -75,6 +77,7 @@ include "spring-boot-project:spring-boot-test-autoconfigure"
include "spring-boot-tests:spring-boot-integration-tests:spring-boot-configuration-processor-tests"
include "spring-boot-tests:spring-boot-integration-tests:spring-boot-launch-script-tests"
include "spring-boot-tests:spring-boot-integration-tests:spring-boot-loader-tests"
+include "spring-boot-tests:spring-boot-integration-tests:spring-boot-loader-classic-tests"
include "spring-boot-tests:spring-boot-integration-tests:spring-boot-server-tests"
include "spring-boot-system-tests:spring-boot-deployment-tests"
include "spring-boot-system-tests:spring-boot-image-tests"
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/build.gradle b/spring-boot-project/spring-boot-actuator-autoconfigure/build.gradle
index 078187aff0cd..c901a3fc0af2 100644
--- a/spring-boot-project/spring-boot-actuator-autoconfigure/build.gradle
+++ b/spring-boot-project/spring-boot-actuator-autoconfigure/build.gradle
@@ -37,7 +37,7 @@ dependencies {
optional("io.dropwizard.metrics:metrics-jmx")
optional("io.lettuce:lettuce-core")
optional("io.micrometer:micrometer-observation")
- optional("io.micrometer:micrometer-core")
+ optional("io.micrometer:micrometer-jakarta9")
optional("io.micrometer:micrometer-tracing")
optional("io.micrometer:micrometer-tracing-bridge-brave")
optional("io.micrometer:micrometer-tracing-bridge-otel")
@@ -68,11 +68,13 @@ dependencies {
optional("io.micrometer:micrometer-registry-signalfx")
optional("io.micrometer:micrometer-registry-statsd")
optional("io.micrometer:micrometer-registry-wavefront")
+ optional("io.zipkin.reporter2:zipkin-reporter-brave")
optional("io.zipkin.reporter2:zipkin-sender-urlconnection")
optional("io.opentelemetry:opentelemetry-exporter-zipkin")
optional("io.opentelemetry:opentelemetry-exporter-otlp")
optional("io.projectreactor.netty:reactor-netty-http")
optional("io.r2dbc:r2dbc-pool")
+ optional("io.r2dbc:r2dbc-proxy")
optional("io.r2dbc:r2dbc-spi")
optional("jakarta.jms:jakarta.jms-api")
optional("jakarta.persistence:jakarta.persistence-api")
@@ -159,9 +161,7 @@ dependencies {
testImplementation("org.assertj:assertj-core")
testImplementation("org.awaitility:awaitility")
testImplementation("org.cache2k:cache2k-api")
- testImplementation("org.eclipse.jetty:jetty-webapp") {
- exclude group: "org.eclipse.jetty.toolchain", module: "jetty-jakarta-servlet-api"
- }
+ testImplementation("org.eclipse.jetty.ee10:jetty-ee10-webapp")
testImplementation("org.glassfish.jersey.ext:jersey-spring6")
testImplementation("org.glassfish.jersey.media:jersey-media-json-jackson")
testImplementation("org.hamcrest:hamcrest")
@@ -249,8 +249,12 @@ tasks.withType(org.asciidoctor.gradle.jvm.AbstractAsciidoctorTask) {
dependsOn dependencyVersions
doFirst {
def versionConstraints = dependencyVersions.versionConstraints
+ def toAntoraVersion = version -> {
+ String formatted = version.split("\\.").take(2).join('.')
+ return version.endsWith("-SNAPSHOT") ? formatted + "-SNAPSHOT" : formatted
+ }
def integrationVersion = versionConstraints["org.springframework.integration:spring-integration-core"]
- def integrationDocs = String.format("https://docs.spring.io/spring-integration/docs/%s/reference/html/", integrationVersion)
+ String integrationDocs = String.format("https://docs.spring.io/spring-integration/reference/%s", toAntoraVersion(integrationVersion))
attributes "spring-integration-docs": integrationDocs
}
dependsOn documentationTest
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/asciidoc/endpoints/env.adoc b/spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/asciidoc/endpoints/env.adoc
index ac5f2a7568e2..4e75bfec4f2d 100644
--- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/asciidoc/endpoints/env.adoc
+++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/asciidoc/endpoints/env.adoc
@@ -14,6 +14,7 @@ The resulting response is similar to the following:
include::{snippets}/env/all/http-response.adoc[]
+NOTE: Sanitization of sensitive values has been switched off for this example.
[[env.entire.response-structure]]
@@ -37,7 +38,7 @@ The resulting response is similar to the following:
include::{snippets}/env/single/http-response.adoc[]
-
+NOTE: Sanitization of sensitive values has been switched off for this example.
[[env.single-property.response-structure]]
=== Response Structure
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/asciidoc/endpoints/integrationgraph.adoc b/spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/asciidoc/endpoints/integrationgraph.adoc
index 5709ca935833..dad34a128c32 100644
--- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/asciidoc/endpoints/integrationgraph.adoc
+++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/asciidoc/endpoints/integrationgraph.adoc
@@ -19,7 +19,7 @@ include::{snippets}/integrationgraph/graph/http-response.adoc[]
[[integrationgraph.retrieving.response-structure]]
=== Response Structure
The response contains all Spring Integration components used within the application, as well as the links between them.
-More information about the structure can be found in the {spring-integration-docs}index-single.html#integration-graph[reference documentation].
+More information about the structure can be found in the {spring-integration-docs}/index.html#integration-graph[reference documentation].
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/ReactiveCloudFoundrySecurityService.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/ReactiveCloudFoundrySecurityService.java
index 4add4c094315..d75725e68d6f 100644
--- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/ReactiveCloudFoundrySecurityService.java
+++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/ReactiveCloudFoundrySecurityService.java
@@ -53,8 +53,6 @@ class ReactiveCloudFoundrySecurityService {
private final String cloudControllerUrl;
- private Mono uaaUrl;
-
ReactiveCloudFoundrySecurityService(WebClient.Builder webClientBuilder, String cloudControllerUrl,
boolean skipSslValidation) {
Assert.notNull(webClientBuilder, "WebClient must not be null");
@@ -149,7 +147,7 @@ private Map extractTokenKeys(Map response) {
* @return the UAA url Mono
*/
Mono getUaaUrl() {
- this.uaaUrl = this.webClient.get()
+ return this.webClient.get()
.uri(this.cloudControllerUrl + "/info")
.retrieve()
.bodyToMono(Map.class)
@@ -157,7 +155,6 @@ Mono getUaaUrl() {
.cache()
.onErrorMap((ex) -> new CloudFoundryAuthorizationException(Reason.SERVICE_UNAVAILABLE,
"Unable to fetch token keys from UAA."));
- return this.uaaUrl;
}
}
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/ReactiveTokenValidator.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/ReactiveTokenValidator.java
index e31fc3797aee..e9f6dd5a62a9 100644
--- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/ReactiveTokenValidator.java
+++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/ReactiveTokenValidator.java
@@ -24,9 +24,8 @@
import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
+import java.util.Collections;
import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.TimeUnit;
import reactor.core.publisher.Mono;
@@ -44,7 +43,7 @@ class ReactiveTokenValidator {
private final ReactiveCloudFoundrySecurityService securityService;
- private volatile ConcurrentMap cachedTokenKeys = new ConcurrentHashMap<>();
+ private volatile Map cachedTokenKeys = Collections.emptyMap();
ReactiveTokenValidator(ReactiveCloudFoundrySecurityService securityService) {
this.securityService = securityService;
@@ -92,7 +91,7 @@ private Mono getTokenKey(Token token) {
}
private void cacheTokenKeys(Map tokenKeys) {
- this.cachedTokenKeys = new ConcurrentHashMap<>(tokenKeys);
+ this.cachedTokenKeys = Map.copyOf(tokenKeys);
}
private boolean hasValidSignature(Token token, String key) {
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryActuatorAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryActuatorAutoConfiguration.java
index 35ba2cab29e9..08a688c53bef 100644
--- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryActuatorAutoConfiguration.java
+++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryActuatorAutoConfiguration.java
@@ -67,7 +67,6 @@
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.OrRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;
-import org.springframework.util.CollectionUtils;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.servlet.DispatcherServlet;
@@ -125,8 +124,8 @@ public CloudFoundryWebEndpointServletHandlerMapping cloudFoundryWebEndpointServl
allEndpoints.addAll(webEndpoints);
allEndpoints.addAll(servletEndpointsSupplier.getEndpoints());
allEndpoints.addAll(controllerEndpointsSupplier.getEndpoints());
- return new CloudFoundryWebEndpointServletHandlerMapping(new EndpointMapping("/cloudfoundryapplication"),
- webEndpoints, endpointMediaTypes, getCorsConfiguration(), securityInterceptor, allEndpoints);
+ return new CloudFoundryWebEndpointServletHandlerMapping(new EndpointMapping(BASE_PATH), webEndpoints,
+ endpointMediaTypes, getCorsConfiguration(), securityInterceptor, allEndpoints);
}
private CloudFoundrySecurityInterceptor getSecurityInterceptor(RestTemplateBuilder restTemplateBuilder,
@@ -189,9 +188,7 @@ public void customize(WebSecurity web) {
.forEach((path) -> requestMatchers.add(new AntPathRequestMatcher(path + "/**")));
requestMatchers.add(new AntPathRequestMatcher(BASE_PATH));
requestMatchers.add(new AntPathRequestMatcher(BASE_PATH + "/"));
- if (!CollectionUtils.isEmpty(requestMatchers)) {
- web.ignoring().requestMatchers(new OrRequestMatcher(requestMatchers));
- }
+ web.ignoring().requestMatchers(new OrRequestMatcher(requestMatchers));
}
}
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundrySecurityInterceptor.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundrySecurityInterceptor.java
index 01eafcf65125..c5c4b2c8e4d2 100644
--- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundrySecurityInterceptor.java
+++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundrySecurityInterceptor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2022 the original author or authors.
+ * Copyright 2012-2023 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.
@@ -86,7 +86,7 @@ SecurityResponse preHandle(HttpServletRequest request, EndpointId endpointId) {
return SecurityResponse.success();
}
- private void check(HttpServletRequest request, EndpointId endpointId) throws Exception {
+ private void check(HttpServletRequest request, EndpointId endpointId) {
Token token = getToken(request);
this.tokenValidator.validate(token);
AccessLevel accessLevel = this.cloudFoundrySecurityService.getAccessLevel(token.toString(), this.applicationId);
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/condition/OnAvailableEndpointCondition.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/condition/OnAvailableEndpointCondition.java
index 4478b0ed9426..a485aa2a4a10 100644
--- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/condition/OnAvailableEndpointCondition.java
+++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/condition/OnAvailableEndpointCondition.java
@@ -143,11 +143,8 @@ private ConditionOutcome getEnablementOutcome(Environment environment,
}
private Boolean isEnabledByDefault(Environment environment) {
- Optional enabledByDefault = enabledByDefaultCache.get(environment);
- if (enabledByDefault == null) {
- enabledByDefault = Optional.ofNullable(environment.getProperty(ENABLED_BY_DEFAULT_KEY, Boolean.class));
- enabledByDefaultCache.put(environment, enabledByDefault);
- }
+ Optional enabledByDefault = enabledByDefaultCache.computeIfAbsent(environment,
+ (ignore) -> Optional.ofNullable(environment.getProperty(ENABLED_BY_DEFAULT_KEY, Boolean.class)));
return enabledByDefault.orElse(null);
}
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/expose/IncludeExcludeEndpointFilter.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/expose/IncludeExcludeEndpointFilter.java
index d2c738b5e2ec..00affa4cfff3 100644
--- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/expose/IncludeExcludeEndpointFilter.java
+++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/expose/IncludeExcludeEndpointFilter.java
@@ -150,7 +150,7 @@ private static class EndpointPatterns {
private final Set endpointIds;
EndpointPatterns(String[] patterns) {
- this((patterns != null) ? Arrays.asList(patterns) : (Collection) null);
+ this((patterns != null) ? Arrays.asList(patterns) : null);
}
EndpointPatterns(Collection patterns) {
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/jersey/JerseyWebEndpointManagementContextConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/jersey/JerseyWebEndpointManagementContextConfiguration.java
index 24736e2647d0..dd7a8668ca4c 100644
--- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/jersey/JerseyWebEndpointManagementContextConfiguration.java
+++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/jersey/JerseyWebEndpointManagementContextConfiguration.java
@@ -103,7 +103,8 @@ JerseyAdditionalHealthEndpointPathsManagementResourcesRegistrar jerseyDifferentP
ExposableWebEndpoint health = webEndpoints.stream()
.filter((endpoint) -> endpoint.getEndpointId().equals(HEALTH_ENDPOINT_ID))
.findFirst()
- .get();
+ .orElseThrow(
+ () -> new IllegalStateException("No endpoint with id '%s' found".formatted(HEALTH_ENDPOINT_ID)));
return new JerseyAdditionalHealthEndpointPathsManagementResourcesRegistrar(health, healthEndpointGroups);
}
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/reactive/WebFluxEndpointManagementContextConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/reactive/WebFluxEndpointManagementContextConfiguration.java
index 9e117dd3b7c9..94ea4766f50f 100644
--- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/reactive/WebFluxEndpointManagementContextConfiguration.java
+++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/reactive/WebFluxEndpointManagementContextConfiguration.java
@@ -120,7 +120,8 @@ public AdditionalHealthEndpointPathsWebFluxHandlerMapping managementHealthEndpoi
ExposableWebEndpoint health = webEndpoints.stream()
.filter((endpoint) -> endpoint.getEndpointId().equals(HealthEndpoint.ID))
.findFirst()
- .get();
+ .orElseThrow(
+ () -> new IllegalStateException("No endpoint with id '%s' found".formatted(HealthEndpoint.ID)));
return new AdditionalHealthEndpointPathsWebFluxHandlerMapping(new EndpointMapping(""), health,
groups.getAllWithAdditionalPath(WebServerNamespace.MANAGEMENT));
}
@@ -162,16 +163,16 @@ static class ServerCodecConfigurerEndpointObjectMapperBeanPostProcessor implemen
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
- if (bean instanceof ServerCodecConfigurer) {
- process((ServerCodecConfigurer) bean);
+ if (bean instanceof ServerCodecConfigurer serverCodecConfigurer) {
+ process(serverCodecConfigurer);
}
return bean;
}
private void process(ServerCodecConfigurer configurer) {
for (HttpMessageWriter> writer : configurer.getWriters()) {
- if (writer instanceof EncoderHttpMessageWriter) {
- process(((EncoderHttpMessageWriter>) writer).getEncoder());
+ if (writer instanceof EncoderHttpMessageWriter> encoderHttpMessageWriter) {
+ process((encoderHttpMessageWriter).getEncoder());
}
}
}
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/servlet/WebMvcEndpointManagementContextConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/servlet/WebMvcEndpointManagementContextConfiguration.java
index f271c663ab95..451e08b61396 100644
--- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/servlet/WebMvcEndpointManagementContextConfiguration.java
+++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/servlet/WebMvcEndpointManagementContextConfiguration.java
@@ -115,7 +115,8 @@ public AdditionalHealthEndpointPathsWebMvcHandlerMapping managementHealthEndpoin
ExposableWebEndpoint health = webEndpoints.stream()
.filter((endpoint) -> endpoint.getEndpointId().equals(HealthEndpoint.ID))
.findFirst()
- .get();
+ .orElseThrow(
+ () -> new IllegalStateException("No endpoint with id '%s' found".formatted(HealthEndpoint.ID)));
return new AdditionalHealthEndpointPathsWebMvcHandlerMapping(health,
groups.getAllWithAdditionalPath(WebServerNamespace.MANAGEMENT));
}
@@ -157,8 +158,8 @@ static class EndpointObjectMapperWebMvcConfigurer implements WebMvcConfigurer {
@Override
public void configureMessageConverters(List> converters) {
for (HttpMessageConverter> converter : converters) {
- if (converter instanceof MappingJackson2HttpMessageConverter) {
- configure((MappingJackson2HttpMessageConverter) converter);
+ if (converter instanceof MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter) {
+ configure(mappingJackson2HttpMessageConverter);
}
}
}
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/AbstractCompositeHealthContributorConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/AbstractCompositeHealthContributorConfiguration.java
index 5a7454b08a50..3b5aeda866da 100644
--- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/AbstractCompositeHealthContributorConfiguration.java
+++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/AbstractCompositeHealthContributorConfiguration.java
@@ -16,12 +16,9 @@
package org.springframework.boot.actuate.autoconfigure.health;
-import java.lang.reflect.Constructor;
import java.util.Map;
import java.util.function.Function;
-import org.springframework.beans.BeanUtils;
-import org.springframework.core.ResolvableType;
import org.springframework.util.Assert;
/**
@@ -39,18 +36,6 @@ public abstract class AbstractCompositeHealthContributorConfiguration indicatorFactory;
- /**
- * Creates a {@code AbstractCompositeHealthContributorConfiguration} that will use
- * reflection to create health indicator instances.
- * @deprecated since 3.0.0 in favor of
- * {@link #AbstractCompositeHealthContributorConfiguration(Function)}
- */
- @Deprecated(since = "3.0.0", forRemoval = true)
- protected AbstractCompositeHealthContributorConfiguration() {
- this.indicatorFactory = new ReflectionIndicatorFactory(
- ResolvableType.forClass(AbstractCompositeHealthContributorConfiguration.class, getClass()));
- }
-
/**
* Creates a {@code AbstractCompositeHealthContributorConfiguration} that will use the
* given {@code indicatorFactory} to create health indicator instances.
@@ -75,34 +60,4 @@ protected I createIndicator(B bean) {
return this.indicatorFactory.apply(bean);
}
- private class ReflectionIndicatorFactory implements Function {
-
- private final Class> indicatorType;
-
- private final Class> beanType;
-
- ReflectionIndicatorFactory(ResolvableType type) {
- this.indicatorType = type.resolveGeneric(1);
- this.beanType = type.resolveGeneric(2);
- }
-
- @Override
- public I apply(B bean) {
- try {
- return BeanUtils.instantiateClass(getConstructor(), bean);
- }
- catch (Exception ex) {
- throw new IllegalStateException("Unable to create health indicator %s for bean type %s"
- .formatted(this.indicatorType, this.beanType), ex);
- }
-
- }
-
- @SuppressWarnings("unchecked")
- private Constructor getConstructor() throws NoSuchMethodException {
- return (Constructor) this.indicatorType.getDeclaredConstructor(this.beanType);
- }
-
- }
-
}
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/CompositeHealthContributorConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/CompositeHealthContributorConfiguration.java
index 7901e1307552..4b979e94d19e 100644
--- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/CompositeHealthContributorConfiguration.java
+++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/CompositeHealthContributorConfiguration.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2022 the original author or authors.
+ * Copyright 2012-2023 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.
@@ -36,18 +36,6 @@
public abstract class CompositeHealthContributorConfiguration
extends AbstractCompositeHealthContributorConfiguration {
- /**
- * Creates a {@code CompositeHealthContributorConfiguration} that will use reflection
- * to create {@link HealthIndicator} instances.
- * @deprecated since 3.0.0 in favor of
- * {@link #CompositeHealthContributorConfiguration(Function)}
- */
- @SuppressWarnings("removal")
- @Deprecated(since = "3.0.0", forRemoval = true)
- public CompositeHealthContributorConfiguration() {
- super();
- }
-
/**
* Creates a {@code CompositeHealthContributorConfiguration} that will use the given
* {@code indicatorFactory} to create {@link HealthIndicator} instances.
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/CompositeReactiveHealthContributorConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/CompositeReactiveHealthContributorConfiguration.java
index 57b45ff1a10f..12c4ff22a88e 100644
--- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/CompositeReactiveHealthContributorConfiguration.java
+++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/CompositeReactiveHealthContributorConfiguration.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2022 the original author or authors.
+ * Copyright 2012-2023 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.
@@ -36,18 +36,6 @@
public abstract class CompositeReactiveHealthContributorConfiguration
extends AbstractCompositeHealthContributorConfiguration {
- /**
- * Creates a {@code CompositeReactiveHealthContributorConfiguration} that will use
- * reflection to create {@link ReactiveHealthIndicator} instances.
- * @deprecated since 3.0.0 in favor of
- * {@link #CompositeReactiveHealthContributorConfiguration(Function)}
- */
- @SuppressWarnings("removal")
- @Deprecated(since = "3.0.0", forRemoval = true)
- public CompositeReactiveHealthContributorConfiguration() {
- super();
- }
-
/**
* Creates a {@code CompositeReactiveHealthContributorConfiguration} that will use the
* given {@code indicatorFactory} to create {@link ReactiveHealthIndicator} instances.
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/HealthEndpointReactiveWebExtensionConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/HealthEndpointReactiveWebExtensionConfiguration.java
index 6e80745fa7e7..4a8d814ebd4e 100644
--- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/HealthEndpointReactiveWebExtensionConfiguration.java
+++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/HealthEndpointReactiveWebExtensionConfiguration.java
@@ -70,7 +70,8 @@ AdditionalHealthEndpointPathsWebFluxHandlerMapping healthEndpointWebFluxHandlerM
ExposableWebEndpoint health = webEndpoints.stream()
.filter((endpoint) -> endpoint.getEndpointId().equals(HealthEndpoint.ID))
.findFirst()
- .get();
+ .orElseThrow(
+ () -> new IllegalStateException("No endpoint with id '%s' found".formatted(HealthEndpoint.ID)));
return new AdditionalHealthEndpointPathsWebFluxHandlerMapping(new EndpointMapping(""), health,
groups.getAllWithAdditionalPath(WebServerNamespace.SERVER));
}
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/HealthEndpointWebExtensionConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/HealthEndpointWebExtensionConfiguration.java
index b0924d928018..a973b2f0fa4c 100644
--- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/HealthEndpointWebExtensionConfiguration.java
+++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/HealthEndpointWebExtensionConfiguration.java
@@ -81,7 +81,8 @@ private static ExposableWebEndpoint getHealthEndpoint(WebEndpointsSupplier webEn
return webEndpoints.stream()
.filter((endpoint) -> endpoint.getEndpointId().equals(HealthEndpoint.ID))
.findFirst()
- .get();
+ .orElseThrow(
+ () -> new IllegalStateException("No endpoint with id '%s' found".formatted(HealthEndpoint.ID)));
}
@ConditionalOnBean(DispatcherServlet.class)
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/NoSuchHealthContributorFailureAnalyzer.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/NoSuchHealthContributorFailureAnalyzer.java
new file mode 100644
index 000000000000..b3ea8f0165e8
--- /dev/null
+++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/NoSuchHealthContributorFailureAnalyzer.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2012-2023 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.boot.actuate.autoconfigure.health;
+
+import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointConfiguration.HealthEndpointGroupMembershipValidator.NoSuchHealthContributorException;
+import org.springframework.boot.diagnostics.AbstractFailureAnalyzer;
+import org.springframework.boot.diagnostics.FailureAnalysis;
+
+/**
+ * An {@link AbstractFailureAnalyzer} that performs analysis of failures caused by a
+ * {@link NoSuchHealthContributorException}.
+ *
+ * @author Moritz Halbritter
+ */
+class NoSuchHealthContributorFailureAnalyzer extends AbstractFailureAnalyzer {
+
+ @Override
+ protected FailureAnalysis analyze(Throwable rootFailure, NoSuchHealthContributorException cause) {
+ return new FailureAnalysis(cause.getMessage(), "Update your application to correct the invalid configuration.\n"
+ + "You can also set 'management.endpoint.health.validate-group-membership' to false to disable the validation.",
+ cause);
+ }
+
+}
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/influx/InfluxDbHealthContributorAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/influx/InfluxDbHealthContributorAutoConfiguration.java
index 7f93279fde82..2a9b13603f90 100644
--- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/influx/InfluxDbHealthContributorAutoConfiguration.java
+++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/influx/InfluxDbHealthContributorAutoConfiguration.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2022 the original author or authors.
+ * Copyright 2012-2023 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.
@@ -37,11 +37,16 @@
*
* @author EddĂș MelĂ©ndez
* @since 2.0.0
+ * @deprecated since 3.2.0 for removal in 3.4.0 in favor of the
+ * new client and its own
+ * Spring Boot integration.
*/
+@SuppressWarnings("removal")
@AutoConfiguration(after = InfluxDbAutoConfiguration.class)
@ConditionalOnClass(InfluxDB.class)
@ConditionalOnBean(InfluxDB.class)
@ConditionalOnEnabledHealthIndicator("influxdb")
+@Deprecated(since = "3.2.0", forRemoval = true)
public class InfluxDbHealthContributorAutoConfiguration
extends CompositeHealthContributorConfiguration {
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAspectsAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAspectsAutoConfiguration.java
new file mode 100644
index 000000000000..dbeeb8b27d6e
--- /dev/null
+++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAspectsAutoConfiguration.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2012-2023 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.boot.actuate.autoconfigure.metrics;
+
+import io.micrometer.core.aop.CountedAspect;
+import io.micrometer.core.aop.MeterTagAnnotationHandler;
+import io.micrometer.core.aop.TimedAspect;
+import io.micrometer.core.instrument.MeterRegistry;
+import org.aspectj.weaver.Advice;
+
+import org.springframework.beans.factory.ObjectProvider;
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.context.annotation.Bean;
+
+/**
+ * {@link EnableAutoConfiguration Auto-configuration} for Micrometer-based metrics
+ * aspects.
+ *
+ * @author Jonatan Ivanov
+ * @since 3.2.0
+ */
+@AutoConfiguration(after = { MetricsAutoConfiguration.class, CompositeMeterRegistryAutoConfiguration.class })
+@ConditionalOnClass({ MeterRegistry.class, Advice.class })
+@ConditionalOnBean(MeterRegistry.class)
+public class MetricsAspectsAutoConfiguration {
+
+ @Bean
+ @ConditionalOnMissingBean
+ CountedAspect countedAspect(MeterRegistry registry) {
+ return new CountedAspect(registry);
+ }
+
+ @Bean
+ @ConditionalOnMissingBean
+ TimedAspect timedAspect(MeterRegistry registry,
+ ObjectProvider meterTagAnnotationHandler) {
+ TimedAspect timedAspect = new TimedAspect(registry);
+ meterTagAnnotationHandler.ifAvailable(timedAspect::setMeterTagAnnotationHandler);
+ return timedAspect;
+ }
+
+}
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAutoConfiguration.java
index 16eaab791d98..dfb7e73a5f61 100644
--- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAutoConfiguration.java
+++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAutoConfiguration.java
@@ -16,8 +16,11 @@
package org.springframework.boot.actuate.autoconfigure.metrics;
+import java.util.List;
+
import io.micrometer.core.annotation.Timed;
import io.micrometer.core.instrument.Clock;
+import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.binder.MeterBinder;
import io.micrometer.core.instrument.config.MeterFilter;
@@ -28,7 +31,9 @@
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Bean;
+import org.springframework.context.event.ContextClosedEvent;
import org.springframework.core.annotation.Order;
/**
@@ -36,6 +41,7 @@
*
* @author Jon Schneider
* @author Stephane Nicoll
+ * @author Moritz Halbritter
* @since 2.0.0
*/
@AutoConfiguration(before = CompositeMeterRegistryAutoConfiguration.class)
@@ -64,4 +70,32 @@ public PropertiesMeterFilter propertiesMeterFilter(MetricsProperties properties)
return new PropertiesMeterFilter(properties);
}
+ @Bean
+ MeterRegistryCloser meterRegistryCloser(ObjectProvider meterRegistries) {
+ return new MeterRegistryCloser(meterRegistries.orderedStream().toList());
+ }
+
+ /**
+ * Ensures that {@link MeterRegistry meter registries} are closed early in the
+ * shutdown process.
+ */
+ static class MeterRegistryCloser implements ApplicationListener {
+
+ private final List meterRegistries;
+
+ MeterRegistryCloser(List meterRegistries) {
+ this.meterRegistries = meterRegistries;
+ }
+
+ @Override
+ public void onApplicationEvent(ContextClosedEvent event) {
+ for (MeterRegistry meterRegistry : this.meterRegistries) {
+ if (!meterRegistry.isClosed()) {
+ meterRegistry.close();
+ }
+ }
+ }
+
+ }
+
}
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsProperties.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsProperties.java
index f06176bb95dc..2bafe29923f2 100644
--- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsProperties.java
+++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsProperties.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2022 the original author or authors.
+ * Copyright 2012-2023 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.
@@ -79,6 +79,8 @@ public Map getEnable() {
return this.enable;
}
+ @Deprecated(since = "3.2.0", forRemoval = true)
+ @DeprecatedConfigurationProperty(replacement = "management.observations.key-values", since = "3.2.0")
public Map getTags() {
return this.tags;
}
@@ -115,8 +117,6 @@ public Server getServer() {
public static class Client {
- private final ClientRequest request = new ClientRequest();
-
/**
* Maximum number of unique URI tag values allowed. After the max number of
* tag values is reached, metrics with additional tag values are denied by
@@ -124,10 +124,6 @@ public static class Client {
*/
private int maxUriTags = 100;
- public ClientRequest getRequest() {
- return this.request;
- }
-
public int getMaxUriTags() {
return this.maxUriTags;
}
@@ -136,32 +132,10 @@ public void setMaxUriTags(int maxUriTags) {
this.maxUriTags = maxUriTags;
}
- public static class ClientRequest {
-
- /**
- * Name of the metric for sent requests.
- */
- private String metricName = "http.client.requests";
-
- @Deprecated(since = "3.0.0", forRemoval = true)
- @DeprecatedConfigurationProperty(replacement = "management.observations.http.client.requests.name")
- public String getMetricName() {
- return this.metricName;
- }
-
- @Deprecated(since = "3.0.0", forRemoval = true)
- public void setMetricName(String metricName) {
- this.metricName = metricName;
- }
-
- }
-
}
public static class Server {
- private final ServerRequest request = new ServerRequest();
-
/**
* Maximum number of unique URI tag values allowed. After the max number of
* tag values is reached, metrics with additional tag values are denied by
@@ -169,10 +143,6 @@ public static class Server {
*/
private int maxUriTags = 100;
- public ServerRequest getRequest() {
- return this.request;
- }
-
public int getMaxUriTags() {
return this.maxUriTags;
}
@@ -181,27 +151,6 @@ public void setMaxUriTags(int maxUriTags) {
this.maxUriTags = maxUriTags;
}
- public static class ServerRequest {
-
- /**
- * Name of the metric for received requests.
- */
- private String metricName = "http.server.requests";
-
- @Deprecated(since = "3.0.0", forRemoval = true)
- @DeprecatedConfigurationProperty(replacement = "management.observations.http.server.requests.name")
- public String getMetricName() {
- return this.metricName;
- }
-
- @Deprecated(since = "3.0.0", forRemoval = true)
- @DeprecatedConfigurationProperty(replacement = "management.observations.http.server.requests.name")
- public void setMetricName(String metricName) {
- this.metricName = metricName;
- }
-
- }
-
}
}
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/PropertiesMeterFilter.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/PropertiesMeterFilter.java
index bf506756478a..6293056f58a4 100644
--- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/PropertiesMeterFilter.java
+++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/PropertiesMeterFilter.java
@@ -50,6 +50,7 @@ public class PropertiesMeterFilter implements MeterFilter {
private final MeterFilter mapFilter;
+ @SuppressWarnings("removal")
public PropertiesMeterFilter(MetricsProperties properties) {
Assert.notNull(properties, "Properties must not be null");
this.properties = properties;
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/atlas/AtlasProperties.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/atlas/AtlasProperties.java
index f6fcfcce3595..1d476f0790ad 100644
--- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/atlas/AtlasProperties.java
+++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/atlas/AtlasProperties.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2022 the original author or authors.
+ * Copyright 2012-2023 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.
@@ -78,6 +78,21 @@ public class AtlasProperties {
*/
private boolean lwcEnabled;
+ /**
+ * Step size (reporting frequency) to use for streaming to Atlas LWC. This is the
+ * highest supported resolution for getting an on-demand stream of the data. It must
+ * be less than or equal to management.metrics.export.atlas.step and
+ * management.metrics.export.atlas.step should be an even multiple of this value.
+ */
+ private Duration lwcStep = Duration.ofSeconds(5);
+
+ /**
+ * Whether expressions with the same step size as Atlas publishing should be ignored
+ * for streaming. Used for cases where data being published to Atlas is also sent into
+ * streaming from the backend.
+ */
+ private boolean lwcIgnorePublishStep = true;
+
/**
* Frequency for refreshing config settings from the LWC service.
*/
@@ -170,6 +185,22 @@ public void setLwcEnabled(boolean lwcEnabled) {
this.lwcEnabled = lwcEnabled;
}
+ public Duration getLwcStep() {
+ return this.lwcStep;
+ }
+
+ public void setLwcStep(Duration lwcStep) {
+ this.lwcStep = lwcStep;
+ }
+
+ public boolean isLwcIgnorePublishStep() {
+ return this.lwcIgnorePublishStep;
+ }
+
+ public void setLwcIgnorePublishStep(boolean lwcIgnorePublishStep) {
+ this.lwcIgnorePublishStep = lwcIgnorePublishStep;
+ }
+
public Duration getConfigRefreshFrequency() {
return this.configRefreshFrequency;
}
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/atlas/AtlasPropertiesConfigAdapter.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/atlas/AtlasPropertiesConfigAdapter.java
index a79323f1174a..32458682b987 100644
--- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/atlas/AtlasPropertiesConfigAdapter.java
+++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/atlas/AtlasPropertiesConfigAdapter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2019 the original author or authors.
+ * Copyright 2012-2023 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.
@@ -84,6 +84,16 @@ public boolean lwcEnabled() {
return get(AtlasProperties::isLwcEnabled, AtlasConfig.super::lwcEnabled);
}
+ @Override
+ public Duration lwcStep() {
+ return get(AtlasProperties::getLwcStep, AtlasConfig.super::lwcStep);
+ }
+
+ @Override
+ public boolean lwcIgnorePublishStep() {
+ return get(AtlasProperties::isLwcIgnorePublishStep, AtlasConfig.super::lwcIgnorePublishStep);
+ }
+
@Override
public Duration configRefreshFrequency() {
return get(AtlasProperties::getConfigRefreshFrequency, AtlasConfig.super::configRefreshFrequency);
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/dynatrace/DynatraceProperties.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/dynatrace/DynatraceProperties.java
index 91c710100843..189ef09a86b5 100644
--- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/dynatrace/DynatraceProperties.java
+++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/dynatrace/DynatraceProperties.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2022 the original author or authors.
+ * Copyright 2012-2023 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.
@@ -140,6 +140,12 @@ public static class V2 {
*/
private boolean useDynatraceSummaryInstruments = true;
+ /**
+ * Whether to export meter metadata (unit and description) to the Dynatrace
+ * backend.
+ */
+ private boolean exportMeterMetadata = true;
+
public Map getDefaultDimensions() {
return this.defaultDimensions;
}
@@ -172,6 +178,14 @@ public void setUseDynatraceSummaryInstruments(boolean useDynatraceSummaryInstrum
this.useDynatraceSummaryInstruments = useDynatraceSummaryInstruments;
}
+ public boolean isExportMeterMetadata() {
+ return this.exportMeterMetadata;
+ }
+
+ public void setExportMeterMetadata(boolean exportMeterMetadata) {
+ this.exportMeterMetadata = exportMeterMetadata;
+ }
+
}
}
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/dynatrace/DynatracePropertiesConfigAdapter.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/dynatrace/DynatracePropertiesConfigAdapter.java
index 82135f989860..bbdc14db563a 100644
--- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/dynatrace/DynatracePropertiesConfigAdapter.java
+++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/dynatrace/DynatracePropertiesConfigAdapter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2022 the original author or authors.
+ * Copyright 2012-2023 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.
@@ -95,6 +95,11 @@ public boolean useDynatraceSummaryInstruments() {
return get(v2(V2::isUseDynatraceSummaryInstruments), DynatraceConfig.super::useDynatraceSummaryInstruments);
}
+ @Override
+ public boolean exportMeterMetadata() {
+ return get(v2(V2::isExportMeterMetadata), DynatraceConfig.super::exportMeterMetadata);
+ }
+
private Function v1(Function getter) {
return (properties) -> getter.apply(properties.getV1());
}
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/otlp/OtlpMetricsConnectionDetails.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/otlp/OtlpMetricsConnectionDetails.java
new file mode 100644
index 000000000000..eeef0ae685bc
--- /dev/null
+++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/otlp/OtlpMetricsConnectionDetails.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2012-2023 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.boot.actuate.autoconfigure.metrics.export.otlp;
+
+import org.springframework.boot.autoconfigure.service.connection.ConnectionDetails;
+
+/**
+ * Details required to establish a connection to an OpenTelemetry Collector service.
+ *
+ * @author EddĂș MelĂ©ndez
+ * @since 3.2.0
+ */
+public interface OtlpMetricsConnectionDetails extends ConnectionDetails {
+
+ /**
+ * Address to where metrics will be published.
+ * @return the address to where metrics will be published
+ */
+ String getUrl();
+
+}
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/otlp/OtlpMetricsExportAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/otlp/OtlpMetricsExportAutoConfiguration.java
index 29e89c29e50a..c7da21f488d1 100644
--- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/otlp/OtlpMetricsExportAutoConfiguration.java
+++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/otlp/OtlpMetricsExportAutoConfiguration.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2022 the original author or authors.
+ * Copyright 2012-2023 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.
@@ -24,6 +24,7 @@
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.metrics.export.ConditionalOnEnabledMetricsExport;
import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration;
+import org.springframework.boot.actuate.autoconfigure.opentelemetry.OpenTelemetryProperties;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
@@ -31,11 +32,13 @@
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
+import org.springframework.core.env.Environment;
/**
* {@link EnableAutoConfiguration Auto-configuration} for exporting metrics to OTLP.
*
* @author EddĂș MelĂ©ndez
+ * @author Moritz Halbritter
* @since 3.0.0
*/
@AutoConfiguration(
@@ -44,19 +47,27 @@
@ConditionalOnBean(Clock.class)
@ConditionalOnClass(OtlpMeterRegistry.class)
@ConditionalOnEnabledMetricsExport("otlp")
-@EnableConfigurationProperties(OtlpProperties.class)
+@EnableConfigurationProperties({ OtlpProperties.class, OpenTelemetryProperties.class })
public class OtlpMetricsExportAutoConfiguration {
private final OtlpProperties properties;
- public OtlpMetricsExportAutoConfiguration(OtlpProperties properties) {
+ OtlpMetricsExportAutoConfiguration(OtlpProperties properties) {
this.properties = properties;
}
@Bean
@ConditionalOnMissingBean
- public OtlpConfig otlpConfig() {
- return new OtlpPropertiesConfigAdapter(this.properties);
+ OtlpMetricsConnectionDetails otlpMetricsConnectionDetails() {
+ return new PropertiesOtlpMetricsConnectionDetails(this.properties);
+ }
+
+ @Bean
+ @ConditionalOnMissingBean
+ OtlpConfig otlpConfig(OpenTelemetryProperties openTelemetryProperties,
+ OtlpMetricsConnectionDetails connectionDetails, Environment environment) {
+ return new OtlpPropertiesConfigAdapter(this.properties, openTelemetryProperties, connectionDetails,
+ environment);
}
@Bean
@@ -65,4 +76,22 @@ public OtlpMeterRegistry otlpMeterRegistry(OtlpConfig otlpConfig, Clock clock) {
return new OtlpMeterRegistry(otlpConfig, clock);
}
+ /**
+ * Adapts {@link OtlpProperties} to {@link OtlpMetricsConnectionDetails}.
+ */
+ static class PropertiesOtlpMetricsConnectionDetails implements OtlpMetricsConnectionDetails {
+
+ private final OtlpProperties properties;
+
+ PropertiesOtlpMetricsConnectionDetails(OtlpProperties properties) {
+ this.properties = properties;
+ }
+
+ @Override
+ public String getUrl() {
+ return this.properties.getUrl();
+ }
+
+ }
+
}
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/otlp/OtlpProperties.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/otlp/OtlpProperties.java
index 701d45c30896..e9a038d3e664 100644
--- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/otlp/OtlpProperties.java
+++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/otlp/OtlpProperties.java
@@ -17,11 +17,13 @@
package org.springframework.boot.actuate.autoconfigure.metrics.export.otlp;
import java.util.Map;
+import java.util.concurrent.TimeUnit;
import io.micrometer.registry.otlp.AggregationTemporality;
import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.StepRegistryProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.boot.context.properties.DeprecatedConfigurationProperty;
/**
* {@link ConfigurationProperties @ConfigurationProperties} for configuring OTLP metrics
@@ -55,6 +57,11 @@ public class OtlpProperties extends StepRegistryProperties {
*/
private Map headers;
+ /**
+ * Time unit for exported metrics.
+ */
+ private TimeUnit baseTimeUnit = TimeUnit.MILLISECONDS;
+
public String getUrl() {
return this.url;
}
@@ -71,10 +78,13 @@ public void setAggregationTemporality(AggregationTemporality aggregationTemporal
this.aggregationTemporality = aggregationTemporality;
}
+ @Deprecated(since = "3.2.0", forRemoval = true)
+ @DeprecatedConfigurationProperty(replacement = "management.opentelemetry.resource-attributes", since = "3.2.0")
public Map getResourceAttributes() {
return this.resourceAttributes;
}
+ @Deprecated(since = "3.2.0", forRemoval = true)
public void setResourceAttributes(Map resourceAttributes) {
this.resourceAttributes = resourceAttributes;
}
@@ -87,4 +97,12 @@ public void setHeaders(Map headers) {
this.headers = headers;
}
+ public TimeUnit getBaseTimeUnit() {
+ return this.baseTimeUnit;
+ }
+
+ public void setBaseTimeUnit(TimeUnit baseTimeUnit) {
+ this.baseTimeUnit = baseTimeUnit;
+ }
+
}
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/otlp/OtlpPropertiesConfigAdapter.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/otlp/OtlpPropertiesConfigAdapter.java
index 814298d364e3..f329d7bf17ae 100644
--- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/otlp/OtlpPropertiesConfigAdapter.java
+++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/otlp/OtlpPropertiesConfigAdapter.java
@@ -16,23 +16,45 @@
package org.springframework.boot.actuate.autoconfigure.metrics.export.otlp;
+import java.util.Collections;
+import java.util.HashMap;
import java.util.Map;
+import java.util.concurrent.TimeUnit;
import io.micrometer.registry.otlp.AggregationTemporality;
import io.micrometer.registry.otlp.OtlpConfig;
import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.StepRegistryPropertiesConfigAdapter;
+import org.springframework.boot.actuate.autoconfigure.opentelemetry.OpenTelemetryProperties;
+import org.springframework.core.env.Environment;
+import org.springframework.util.CollectionUtils;
/**
* Adapter to convert {@link OtlpProperties} to an {@link OtlpConfig}.
*
* @author EddĂș MelĂ©ndez
* @author Jonatan Ivanov
+ * @author Moritz Halbritter
*/
class OtlpPropertiesConfigAdapter extends StepRegistryPropertiesConfigAdapter implements OtlpConfig {
- OtlpPropertiesConfigAdapter(OtlpProperties properties) {
+ /**
+ * Default value for application name if {@code spring.application.name} is not set.
+ */
+ private static final String DEFAULT_APPLICATION_NAME = "application";
+
+ private final OpenTelemetryProperties openTelemetryProperties;
+
+ private final OtlpMetricsConnectionDetails connectionDetails;
+
+ private final Environment environment;
+
+ OtlpPropertiesConfigAdapter(OtlpProperties properties, OpenTelemetryProperties openTelemetryProperties,
+ OtlpMetricsConnectionDetails connectionDetails, Environment environment) {
super(properties);
+ this.connectionDetails = connectionDetails;
+ this.openTelemetryProperties = openTelemetryProperties;
+ this.environment = environment;
}
@Override
@@ -42,7 +64,7 @@ public String prefix() {
@Override
public String url() {
- return get(OtlpProperties::getUrl, OtlpConfig.super::url);
+ return get((properties) -> this.connectionDetails.getUrl(), OtlpConfig.super::url);
}
@Override
@@ -51,8 +73,17 @@ public AggregationTemporality aggregationTemporality() {
}
@Override
+ @SuppressWarnings("removal")
public Map resourceAttributes() {
- return get(OtlpProperties::getResourceAttributes, OtlpConfig.super::resourceAttributes);
+ Map resourceAttributes = this.openTelemetryProperties.getResourceAttributes();
+ Map result = new HashMap<>((!CollectionUtils.isEmpty(resourceAttributes)) ? resourceAttributes
+ : get(OtlpProperties::getResourceAttributes, OtlpConfig.super::resourceAttributes));
+ result.computeIfAbsent("service.name", (key) -> getApplicationName());
+ return Collections.unmodifiableMap(result);
+ }
+
+ private String getApplicationName() {
+ return this.environment.getProperty("spring.application.name", DEFAULT_APPLICATION_NAME);
}
@Override
@@ -60,4 +91,9 @@ public Map headers() {
return get(OtlpProperties::getHeaders, OtlpConfig.super::headers);
}
+ @Override
+ public TimeUnit baseTimeUnit() {
+ return get(OtlpProperties::getBaseTimeUnit, OtlpConfig.super::baseTimeUnit);
+ }
+
}
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/signalfx/SignalFxProperties.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/signalfx/SignalFxProperties.java
index efd953395cb2..3a5735537a3f 100644
--- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/signalfx/SignalFxProperties.java
+++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/signalfx/SignalFxProperties.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2022 the original author or authors.
+ * Copyright 2012-2023 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.
@@ -54,6 +54,11 @@ public class SignalFxProperties extends StepRegistryProperties {
*/
private String source;
+ /**
+ * Type of histogram to publish.
+ */
+ private HistogramType publishedHistogramType = HistogramType.DEFAULT;
+
@Override
public Duration getStep() {
return this.step;
@@ -88,4 +93,31 @@ public void setSource(String source) {
this.source = source;
}
+ public HistogramType getPublishedHistogramType() {
+ return this.publishedHistogramType;
+ }
+
+ public void setPublishedHistogramType(HistogramType publishedHistogramType) {
+ this.publishedHistogramType = publishedHistogramType;
+ }
+
+ public enum HistogramType {
+
+ /**
+ * Default, time-based histogram.
+ */
+ DEFAULT,
+
+ /**
+ * Cumulative histogram.
+ */
+ CUMULATIVE,
+
+ /**
+ * Delta histogram.
+ */
+ DELTA;
+
+ }
+
}
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/signalfx/SignalFxPropertiesConfigAdapter.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/signalfx/SignalFxPropertiesConfigAdapter.java
index d5d16d32bf05..754e3cb7c4df 100644
--- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/signalfx/SignalFxPropertiesConfigAdapter.java
+++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/signalfx/SignalFxPropertiesConfigAdapter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2022 the original author or authors.
+ * Copyright 2012-2023 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.
@@ -19,6 +19,7 @@
import io.micrometer.signalfx.SignalFxConfig;
import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.StepRegistryPropertiesConfigAdapter;
+import org.springframework.boot.actuate.autoconfigure.metrics.export.signalfx.SignalFxProperties.HistogramType;
/**
* Adapter to convert {@link SignalFxProperties} to a {@link SignalFxConfig}.
@@ -54,4 +55,22 @@ public String source() {
return get(SignalFxProperties::getSource, SignalFxConfig.super::source);
}
+ @Override
+ public boolean publishCumulativeHistogram() {
+ return get(this::isPublishCumulativeHistogram, SignalFxConfig.super::publishCumulativeHistogram);
+ }
+
+ private boolean isPublishCumulativeHistogram(SignalFxProperties properties) {
+ return HistogramType.CUMULATIVE == properties.getPublishedHistogramType();
+ }
+
+ @Override
+ public boolean publishDeltaHistogram() {
+ return get(this::isPublishDeltaHistogram, SignalFxConfig.super::publishDeltaHistogram);
+ }
+
+ private boolean isPublishDeltaHistogram(SignalFxProperties properties) {
+ return HistogramType.DELTA == properties.getPublishedHistogramType();
+ }
+
}
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/stackdriver/StackdriverProperties.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/stackdriver/StackdriverProperties.java
index b16b83f81a0c..4557f3f5390c 100644
--- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/stackdriver/StackdriverProperties.java
+++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/stackdriver/StackdriverProperties.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2022 the original author or authors.
+ * Copyright 2012-2023 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.
@@ -54,6 +54,12 @@ public class StackdriverProperties extends StepRegistryProperties {
*/
private boolean useSemanticMetricTypes = false;
+ /**
+ * Prefix for metric type. Valid prefixes are described in the Google Cloud
+ * documentation (https://cloud.google.com/monitoring/custom-metrics#identifier).
+ */
+ private String metricTypePrefix = "custom.googleapis.com/";
+
public String getProjectId() {
return this.projectId;
}
@@ -86,4 +92,12 @@ public void setUseSemanticMetricTypes(boolean useSemanticMetricTypes) {
this.useSemanticMetricTypes = useSemanticMetricTypes;
}
+ public String getMetricTypePrefix() {
+ return this.metricTypePrefix;
+ }
+
+ public void setMetricTypePrefix(String metricTypePrefix) {
+ this.metricTypePrefix = metricTypePrefix;
+ }
+
}
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/stackdriver/StackdriverPropertiesConfigAdapter.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/stackdriver/StackdriverPropertiesConfigAdapter.java
index e762b6da8745..b4334c741465 100644
--- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/stackdriver/StackdriverPropertiesConfigAdapter.java
+++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/stackdriver/StackdriverPropertiesConfigAdapter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2022 the original author or authors.
+ * Copyright 2012-2023 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.
@@ -60,4 +60,9 @@ public boolean useSemanticMetricTypes() {
return get(StackdriverProperties::isUseSemanticMetricTypes, StackdriverConfig.super::useSemanticMetricTypes);
}
+ @Override
+ public String metricTypePrefix() {
+ return get(StackdriverProperties::getMetricTypePrefix, StackdriverConfig.super::metricTypePrefix);
+ }
+
}
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/wavefront/WavefrontPropertiesConfigAdapter.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/wavefront/WavefrontPropertiesConfigAdapter.java
index 6baf69378f8e..bd898ddad050 100644
--- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/wavefront/WavefrontPropertiesConfigAdapter.java
+++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/wavefront/WavefrontPropertiesConfigAdapter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2022 the original author or authors.
+ * Copyright 2012-2023 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.
@@ -16,6 +16,7 @@
package org.springframework.boot.actuate.autoconfigure.metrics.export.wavefront;
+import com.wavefront.sdk.common.clients.service.token.TokenService.Type;
import io.micrometer.wavefront.WavefrontConfig;
import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.PushRegistryPropertiesConfigAdapter;
@@ -69,4 +70,24 @@ public String globalPrefix() {
return get(Export::getGlobalPrefix, WavefrontConfig.super::globalPrefix);
}
+ @Override
+ public boolean reportMinuteDistribution() {
+ return get(Export::isReportMinuteDistribution, WavefrontConfig.super::reportMinuteDistribution);
+ }
+
+ @Override
+ public boolean reportHourDistribution() {
+ return get(Export::isReportHourDistribution, WavefrontConfig.super::reportHourDistribution);
+ }
+
+ @Override
+ public boolean reportDayDistribution() {
+ return get(Export::isReportDayDistribution, WavefrontConfig.super::reportDayDistribution);
+ }
+
+ @Override
+ public Type apiTokenType() {
+ return this.properties.getWavefrontApiTokenType();
+ }
+
}
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/jersey/JerseyServerMetricsAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/jersey/JerseyServerMetricsAutoConfiguration.java
index fdb018f2276d..2fc5de48dd3f 100644
--- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/jersey/JerseyServerMetricsAutoConfiguration.java
+++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/jersey/JerseyServerMetricsAutoConfiguration.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2022 the original author or authors.
+ * Copyright 2012-2023 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.
@@ -29,9 +29,9 @@
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsProperties;
-import org.springframework.boot.actuate.autoconfigure.metrics.MetricsProperties.Web.Server;
import org.springframework.boot.actuate.autoconfigure.metrics.OnlyOnceLoggingDenyMeterFilter;
import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration;
+import org.springframework.boot.actuate.autoconfigure.observation.ObservationProperties;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
@@ -57,13 +57,12 @@
@ConditionalOnClass({ ResourceConfig.class, MetricsApplicationEventListener.class })
@ConditionalOnBean({ MeterRegistry.class, ResourceConfig.class })
@EnableConfigurationProperties(MetricsProperties.class)
-@SuppressWarnings("removal")
public class JerseyServerMetricsAutoConfiguration {
- private final MetricsProperties properties;
+ private final ObservationProperties observationProperties;
- public JerseyServerMetricsAutoConfiguration(MetricsProperties properties) {
- this.properties = properties;
+ public JerseyServerMetricsAutoConfiguration(ObservationProperties observationProperties) {
+ this.observationProperties = observationProperties;
}
@Bean
@@ -75,19 +74,19 @@ public DefaultJerseyTagsProvider jerseyTagsProvider() {
@Bean
public ResourceConfigCustomizer jerseyServerMetricsResourceConfigCustomizer(MeterRegistry meterRegistry,
JerseyTagsProvider tagsProvider) {
- Server server = this.properties.getWeb().getServer();
- return (config) -> config.register(new MetricsApplicationEventListener(meterRegistry, tagsProvider,
- server.getRequest().getMetricName(), true, new AnnotationUtilsAnnotationFinder()));
+ String metricName = this.observationProperties.getHttp().getServer().getRequests().getName();
+ return (config) -> config.register(new MetricsApplicationEventListener(meterRegistry, tagsProvider, metricName,
+ true, new AnnotationUtilsAnnotationFinder()));
}
@Bean
@Order(0)
- public MeterFilter jerseyMetricsUriTagFilter() {
- String metricName = this.properties.getWeb().getServer().getRequest().getMetricName();
+ public MeterFilter jerseyMetricsUriTagFilter(MetricsProperties metricsProperties) {
+ String metricName = this.observationProperties.getHttp().getServer().getRequests().getName();
MeterFilter filter = new OnlyOnceLoggingDenyMeterFilter(
() -> String.format("Reached the maximum number of URI tags for '%s'.", metricName));
- return MeterFilter.maximumAllowableTags(metricName, "uri", this.properties.getWeb().getServer().getMaxUriTags(),
- filter);
+ return MeterFilter.maximumAllowableTags(metricName, "uri",
+ metricsProperties.getWeb().getServer().getMaxUriTags(), filter);
}
/**
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/task/TaskExecutorMetricsAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/task/TaskExecutorMetricsAutoConfiguration.java
index 8f6dcfdaf9f2..10c880d898ed 100644
--- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/task/TaskExecutorMetricsAutoConfiguration.java
+++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/task/TaskExecutorMetricsAutoConfiguration.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2022 the original author or authors.
+ * Copyright 2012-2023 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.
@@ -25,6 +25,7 @@
import io.micrometer.core.instrument.binder.jvm.ExecutorServiceMetrics;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.LazyInitializationExcludeFilter;
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration;
import org.springframework.boot.autoconfigure.AutoConfiguration;
@@ -33,6 +34,7 @@
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration;
import org.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfiguration;
+import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
@@ -63,6 +65,11 @@ else if (executor instanceof ThreadPoolTaskScheduler threadPoolTaskScheduler) {
});
}
+ @Bean
+ static LazyInitializationExcludeFilter eagerTaskExecutorMetrics() {
+ return LazyInitializationExcludeFilter.forBeanTypes(TaskExecutorMetricsAutoConfiguration.class);
+ }
+
private void monitor(MeterRegistry registry, ThreadPoolExecutor threadPoolExecutor, String name) {
if (threadPoolExecutor != null) {
new ExecutorServiceMetrics(threadPoolExecutor, name, Collections.emptyList()).bindTo(registry);
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationAutoConfiguration.java
index 216bc4262408..b9230b45dd12 100644
--- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationAutoConfiguration.java
+++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationAutoConfiguration.java
@@ -27,9 +27,11 @@
import io.micrometer.observation.ObservationHandler;
import io.micrometer.observation.ObservationPredicate;
import io.micrometer.observation.ObservationRegistry;
+import io.micrometer.observation.aop.ObservedAspect;
import io.micrometer.tracing.Tracer;
import io.micrometer.tracing.handler.TracingAwareMeterObservationHandler;
import io.micrometer.tracing.handler.TracingObservationHandler;
+import org.aspectj.weaver.Advice;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration;
@@ -43,6 +45,7 @@
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
+import org.springframework.core.annotation.Order;
/**
* {@link EnableAutoConfiguration Auto-configuration} for the Micrometer Observation API.
@@ -50,6 +53,7 @@
* @author Moritz Halbritter
* @author Brian Clozel
* @author Jonatan Ivanov
+ * @author Vedran Pavic
* @since 3.0.0
*/
@AutoConfiguration(after = { CompositeMeterRegistryAutoConfiguration.class, MicrometerTracingAutoConfiguration.class })
@@ -75,6 +79,12 @@ ObservationRegistry observationRegistry() {
return ObservationRegistry.create();
}
+ @Bean
+ @Order(0)
+ PropertiesObservationFilterPredicate propertiesObservationFilter(ObservationProperties properties) {
+ return new PropertiesObservationFilterPredicate(properties);
+ }
+
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(MeterRegistry.class)
@ConditionalOnMissingClass("io.micrometer.tracing.Tracer")
@@ -142,4 +152,16 @@ TracingAwareMeterObservationHandler tracingAwareMeterObserv
}
+ @Configuration(proxyBeanMethods = false)
+ @ConditionalOnClass(Advice.class)
+ static class ObservedAspectConfiguration {
+
+ @Bean
+ @ConditionalOnMissingBean
+ ObservedAspect observedAspect(ObservationRegistry observationRegistry) {
+ return new ObservedAspect(observationRegistry);
+ }
+
+ }
+
}
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationHandlerGrouping.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationHandlerGrouping.java
index 163186947e8a..df964c813366 100644
--- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationHandlerGrouping.java
+++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationHandlerGrouping.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2022 the original author or authors.
+ * Copyright 2012-2023 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.
@@ -16,6 +16,7 @@
package org.springframework.boot.actuate.autoconfigure.observation;
+import java.util.ArrayList;
import java.util.List;
import io.micrometer.observation.ObservationHandler;
@@ -30,6 +31,7 @@
* Groups {@link ObservationHandler ObservationHandlers} by type.
*
* @author Andy Wilkinson
+ * @author Moritz Halbritter
*/
@SuppressWarnings("rawtypes")
class ObservationHandlerGrouping {
@@ -46,13 +48,14 @@ class ObservationHandlerGrouping {
void apply(List> handlers, ObservationConfig config) {
MultiValueMap, ObservationHandler>> groupings = new LinkedMultiValueMap<>();
+ List> handlersWithoutCategory = new ArrayList<>();
for (ObservationHandler> handler : handlers) {
Class extends ObservationHandler> category = findCategory(handler);
if (category != null) {
groupings.add(category, handler);
}
else {
- config.observationHandler(handler);
+ handlersWithoutCategory.add(handler);
}
}
for (Class extends ObservationHandler> category : this.categories) {
@@ -61,6 +64,9 @@ void apply(List> handlers, ObservationConfig config) {
config.observationHandler(new FirstMatchingCompositeObservationHandler(handlerGroup));
}
}
+ for (ObservationHandler> observationHandler : handlersWithoutCategory) {
+ config.observationHandler(observationHandler);
+ }
}
private Class extends ObservationHandler> findCategory(ObservationHandler> handler) {
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationProperties.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationProperties.java
index e4668d7f4b59..08de1a01c104 100644
--- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationProperties.java
+++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationProperties.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2022 the original author or authors.
+ * Copyright 2012-2023 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.
@@ -16,6 +16,9 @@
package org.springframework.boot.actuate.autoconfigure.observation;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
@@ -23,6 +26,7 @@
* observations.
*
* @author Brian Clozel
+ * @author Moritz Halbritter
* @since 3.0.0
*/
@ConfigurationProperties("management.observations")
@@ -30,10 +34,37 @@ public class ObservationProperties {
private final Http http = new Http();
+ /**
+ * Common key-values that are applied to every observation.
+ */
+ private Map keyValues = new LinkedHashMap<>();
+
+ /**
+ * Whether observations starting with the specified name should be enabled. The
+ * longest match wins, the key 'all' can also be used to configure all observations.
+ */
+ private Map enable = new LinkedHashMap<>();
+
+ public Map getEnable() {
+ return this.enable;
+ }
+
+ public void setEnable(Map enable) {
+ this.enable = enable;
+ }
+
public Http getHttp() {
return this.http;
}
+ public Map getKeyValues() {
+ return this.keyValues;
+ }
+
+ public void setKeyValues(Map keyValues) {
+ this.keyValues = keyValues;
+ }
+
public static class Http {
private final Client client = new Client();
@@ -59,10 +90,9 @@ public ClientRequests getRequests() {
public static class ClientRequests {
/**
- * Name of the observation for client requests. If empty, will use the
- * default "http.client.requests".
+ * Name of the observation for client requests.
*/
- private String name;
+ private String name = "http.client.requests";
public String getName() {
return this.name;
@@ -87,10 +117,9 @@ public ServerRequests getRequests() {
public static class ServerRequests {
/**
- * Name of the observation for server requests. If empty, will use the
- * default "http.server.requests".
+ * Name of the observation for server requests.
*/
- private String name;
+ private String name = "http.server.requests";
public String getName() {
return this.name;
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/PropertiesObservationFilterPredicate.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/PropertiesObservationFilterPredicate.java
new file mode 100644
index 000000000000..1154668798af
--- /dev/null
+++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/PropertiesObservationFilterPredicate.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2012-2023 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.boot.actuate.autoconfigure.observation;
+
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.function.Supplier;
+
+import io.micrometer.common.KeyValues;
+import io.micrometer.observation.Observation.Context;
+import io.micrometer.observation.ObservationFilter;
+import io.micrometer.observation.ObservationPredicate;
+
+import org.springframework.util.StringUtils;
+
+/**
+ * {@link ObservationFilter} to apply settings from {@link ObservationProperties}.
+ *
+ * @author Moritz Halbritter
+ */
+class PropertiesObservationFilterPredicate implements ObservationFilter, ObservationPredicate {
+
+ private final ObservationFilter commonKeyValuesFilter;
+
+ private final ObservationProperties properties;
+
+ PropertiesObservationFilterPredicate(ObservationProperties properties) {
+ this.properties = properties;
+ this.commonKeyValuesFilter = createCommonKeyValuesFilter(properties);
+ }
+
+ @Override
+ public Context map(Context context) {
+ return this.commonKeyValuesFilter.map(context);
+ }
+
+ @Override
+ public boolean test(String name, Context context) {
+ return lookupWithFallbackToAll(this.properties.getEnable(), name, true);
+ }
+
+ private static T lookupWithFallbackToAll(Map values, String name, T defaultValue) {
+ if (values.isEmpty()) {
+ return defaultValue;
+ }
+ return doLookup(values, name, () -> values.getOrDefault("all", defaultValue));
+ }
+
+ private static T doLookup(Map values, String name, Supplier defaultValue) {
+ while (StringUtils.hasLength(name)) {
+ T result = values.get(name);
+ if (result != null) {
+ return result;
+ }
+ int lastDot = name.lastIndexOf('.');
+ name = (lastDot != -1) ? name.substring(0, lastDot) : "";
+ }
+ return defaultValue.get();
+ }
+
+ private static ObservationFilter createCommonKeyValuesFilter(ObservationProperties properties) {
+ if (properties.getKeyValues().isEmpty()) {
+ return (context) -> context;
+ }
+ KeyValues keyValues = KeyValues.of(properties.getKeyValues().entrySet(), Entry::getKey, Entry::getValue);
+ return (context) -> context.addLowCardinalityKeyValues(keyValues);
+ }
+
+}
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/graphql/GraphQlObservationAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/graphql/GraphQlObservationAutoConfiguration.java
index 5c447db00fba..86b5ed0aee35 100644
--- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/graphql/GraphQlObservationAutoConfiguration.java
+++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/graphql/GraphQlObservationAutoConfiguration.java
@@ -43,7 +43,6 @@
@AutoConfiguration(after = ObservationAutoConfiguration.class)
@ConditionalOnBean(ObservationRegistry.class)
@ConditionalOnClass({ GraphQL.class, GraphQlSource.class, Observation.class })
-@SuppressWarnings("removal")
public class GraphQlObservationAutoConfiguration {
@Bean
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/jms/JmsTemplateObservationAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/jms/JmsTemplateObservationAutoConfiguration.java
new file mode 100644
index 000000000000..9629468e6051
--- /dev/null
+++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/jms/JmsTemplateObservationAutoConfiguration.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2012-2023 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.boot.actuate.autoconfigure.observation.jms;
+
+import io.micrometer.jakarta9.instrument.jms.JmsPublishObservationContext;
+import io.micrometer.observation.Observation;
+import io.micrometer.observation.ObservationRegistry;
+import jakarta.jms.Message;
+
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.ObjectProvider;
+import org.springframework.beans.factory.config.BeanPostProcessor;
+import org.springframework.boot.actuate.autoconfigure.observation.ObservationAutoConfiguration;
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.jms.core.JmsTemplate;
+
+/**
+ * {@link EnableAutoConfiguration Auto-configuration} for instrumenting
+ * {@link JmsTemplate} beans for Observability.
+ *
+ * @author Brian Clozel
+ * @since 3.2.0
+ */
+@AutoConfiguration(after = { JmsAutoConfiguration.class, ObservationAutoConfiguration.class })
+@ConditionalOnBean({ ObservationRegistry.class, JmsTemplate.class })
+@ConditionalOnClass({ Observation.class, Message.class, JmsTemplate.class, JmsPublishObservationContext.class })
+public class JmsTemplateObservationAutoConfiguration {
+
+ @Bean
+ static JmsTemplateObservationPostProcessor jmsTemplateObservationPostProcessor(
+ ObjectProvider observationRegistry) {
+ return new JmsTemplateObservationPostProcessor(observationRegistry);
+ }
+
+ static class JmsTemplateObservationPostProcessor implements BeanPostProcessor {
+
+ private final ObjectProvider observationRegistry;
+
+ JmsTemplateObservationPostProcessor(ObjectProvider observationRegistry) {
+ this.observationRegistry = observationRegistry;
+ }
+
+ @Override
+ public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
+ if (bean instanceof JmsTemplate jmsTemplate) {
+ this.observationRegistry.ifAvailable(jmsTemplate::setObservationRegistry);
+ }
+ return bean;
+ }
+
+ }
+
+}
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/jms/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/jms/package-info.java
new file mode 100644
index 000000000000..417a73aed67f
--- /dev/null
+++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/jms/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2012-2023 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Auto-configuration for JMS observations.
+ */
+package org.springframework.boot.actuate.autoconfigure.observation.jms;
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/client/ClientHttpObservationConventionAdapter.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/client/ClientHttpObservationConventionAdapter.java
deleted file mode 100644
index 87205527f5e2..000000000000
--- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/client/ClientHttpObservationConventionAdapter.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright 2012-2022 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.boot.actuate.autoconfigure.observation.web.client;
-
-import io.micrometer.common.KeyValues;
-import io.micrometer.core.instrument.Tag;
-
-import org.springframework.boot.actuate.metrics.web.client.RestTemplateExchangeTagsProvider;
-import org.springframework.http.client.observation.ClientRequestObservationContext;
-import org.springframework.http.client.observation.ClientRequestObservationConvention;
-
-/**
- * Adapter class that applies {@link RestTemplateExchangeTagsProvider} tags as a
- * {@link ClientRequestObservationConvention}.
- *
- * @author Brian Clozel
- */
-@SuppressWarnings({ "removal" })
-class ClientHttpObservationConventionAdapter implements ClientRequestObservationConvention {
-
- private final String metricName;
-
- private final RestTemplateExchangeTagsProvider tagsProvider;
-
- ClientHttpObservationConventionAdapter(String metricName, RestTemplateExchangeTagsProvider tagsProvider) {
- this.metricName = metricName;
- this.tagsProvider = tagsProvider;
- }
-
- @Override
- @SuppressWarnings("deprecation")
- public KeyValues getLowCardinalityKeyValues(ClientRequestObservationContext context) {
- Iterable tags = this.tagsProvider.getTags(context.getUriTemplate(), context.getCarrier(),
- context.getResponse());
- return KeyValues.of(tags, Tag::getKey, Tag::getValue);
- }
-
- @Override
- public KeyValues getHighCardinalityKeyValues(ClientRequestObservationContext context) {
- return KeyValues.empty();
- }
-
- @Override
- public String getName() {
- return this.metricName;
- }
-
-}
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/client/ClientObservationConventionAdapter.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/client/ClientObservationConventionAdapter.java
deleted file mode 100644
index 0f3230a5bf8a..000000000000
--- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/client/ClientObservationConventionAdapter.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright 2012-2022 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.boot.actuate.autoconfigure.observation.web.client;
-
-import io.micrometer.common.KeyValues;
-import io.micrometer.core.instrument.Tag;
-import io.micrometer.observation.Observation;
-
-import org.springframework.boot.actuate.metrics.web.reactive.client.WebClientExchangeTagsProvider;
-import org.springframework.core.Conventions;
-import org.springframework.web.reactive.function.client.ClientRequest;
-import org.springframework.web.reactive.function.client.ClientRequestObservationContext;
-import org.springframework.web.reactive.function.client.ClientRequestObservationConvention;
-import org.springframework.web.reactive.function.client.WebClient;
-
-/**
- * Adapter class that applies {@link WebClientExchangeTagsProvider} tags as a
- * {@link ClientRequestObservationConvention}.
- *
- * @author Brian Clozel
- */
-@SuppressWarnings("removal")
-class ClientObservationConventionAdapter implements ClientRequestObservationConvention {
-
- private static final String URI_TEMPLATE_ATTRIBUTE = Conventions.getQualifiedAttributeName(WebClient.class,
- "uriTemplate");
-
- private final String metricName;
-
- private final WebClientExchangeTagsProvider tagsProvider;
-
- ClientObservationConventionAdapter(String metricName, WebClientExchangeTagsProvider tagsProvider) {
- this.metricName = metricName;
- this.tagsProvider = tagsProvider;
- }
-
- @Override
- public boolean supportsContext(Observation.Context context) {
- return context instanceof ClientRequestObservationContext;
- }
-
- @Override
- public KeyValues getLowCardinalityKeyValues(ClientRequestObservationContext context) {
- ClientRequest request = context.getRequest();
- if (request == null) {
- request = context.getCarrier().attribute(URI_TEMPLATE_ATTRIBUTE, context.getUriTemplate()).build();
- }
- Iterable tags = this.tagsProvider.tags(request, context.getResponse(), context.getError());
- return KeyValues.of(tags, Tag::getKey, Tag::getValue);
- }
-
- @Override
- public KeyValues getHighCardinalityKeyValues(ClientRequestObservationContext context) {
- return KeyValues.empty();
- }
-
- @Override
- public String getName() {
- return this.metricName;
- }
-
-}
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/client/HttpClientObservationsAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/client/HttpClientObservationsAutoConfiguration.java
index 23323d25238c..60595014ef39 100644
--- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/client/HttpClientObservationsAutoConfiguration.java
+++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/client/HttpClientObservationsAutoConfiguration.java
@@ -31,6 +31,7 @@
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.web.client.RestClientAutoConfiguration;
import org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration;
import org.springframework.boot.autoconfigure.web.reactive.function.client.WebClientAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
@@ -48,13 +49,15 @@
* @author Stephane Nicoll
* @author Raheela Aslam
* @author Brian Clozel
+ * @author Moritz Halbritter
* @since 3.0.0
*/
@AutoConfiguration(after = { ObservationAutoConfiguration.class, CompositeMeterRegistryAutoConfiguration.class,
- RestTemplateAutoConfiguration.class, WebClientAutoConfiguration.class })
+ RestTemplateAutoConfiguration.class, WebClientAutoConfiguration.class, RestClientAutoConfiguration.class })
@ConditionalOnClass(Observation.class)
@ConditionalOnBean(ObservationRegistry.class)
-@Import({ RestTemplateObservationConfiguration.class, WebClientObservationConfiguration.class })
+@Import({ RestTemplateObservationConfiguration.class, WebClientObservationConfiguration.class,
+ RestClientObservationConfiguration.class })
@EnableConfigurationProperties({ MetricsProperties.class, ObservationProperties.class })
public class HttpClientObservationsAutoConfiguration {
@@ -65,13 +68,10 @@ static class MeterFilterConfiguration {
@Bean
@Order(0)
- @SuppressWarnings("removal")
MeterFilter metricsHttpClientUriTagFilter(ObservationProperties observationProperties,
MetricsProperties metricsProperties) {
Client clientProperties = metricsProperties.getWeb().getClient();
- String metricName = clientProperties.getRequest().getMetricName();
- String observationName = observationProperties.getHttp().getClient().getRequests().getName();
- String name = (observationName != null) ? observationName : metricName;
+ String name = observationProperties.getHttp().getClient().getRequests().getName();
MeterFilter denyFilter = new OnlyOnceLoggingDenyMeterFilter(
() -> "Reached the maximum number of URI tags for '%s'. Are you using 'uriVariables'?"
.formatted(name));
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/client/RestClientObservationConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/client/RestClientObservationConfiguration.java
new file mode 100644
index 000000000000..6b97d6c65e51
--- /dev/null
+++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/client/RestClientObservationConfiguration.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2012-2023 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.boot.actuate.autoconfigure.observation.web.client;
+
+import io.micrometer.observation.ObservationRegistry;
+
+import org.springframework.beans.factory.ObjectProvider;
+import org.springframework.boot.actuate.autoconfigure.observation.ObservationProperties;
+import org.springframework.boot.actuate.metrics.web.client.ObservationRestClientCustomizer;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.web.client.RestClientCustomizer;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.client.observation.ClientRequestObservationConvention;
+import org.springframework.http.client.observation.DefaultClientRequestObservationConvention;
+import org.springframework.web.client.RestClient;
+
+/**
+ * Configure the instrumentation of {@link RestClient}.
+ *
+ * @author Moritz Halbritter
+ */
+@Configuration(proxyBeanMethods = false)
+@ConditionalOnClass(RestClient.class)
+@ConditionalOnBean(RestClient.Builder.class)
+class RestClientObservationConfiguration {
+
+ @Bean
+ RestClientCustomizer observationRestClientCustomizer(ObservationRegistry observationRegistry,
+ ObjectProvider customConvention,
+ ObservationProperties observationProperties) {
+ String name = observationProperties.getHttp().getClient().getRequests().getName();
+ ClientRequestObservationConvention observationConvention = customConvention
+ .getIfAvailable(() -> new DefaultClientRequestObservationConvention(name));
+ return new ObservationRestClientCustomizer(observationRegistry, observationConvention);
+ }
+
+}
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/client/RestTemplateObservationConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/client/RestTemplateObservationConfiguration.java
index 0f62f2849b19..81fb154a230a 100644
--- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/client/RestTemplateObservationConfiguration.java
+++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/client/RestTemplateObservationConfiguration.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2022 the original author or authors.
+ * Copyright 2012-2023 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.
@@ -19,10 +19,8 @@
import io.micrometer.observation.ObservationRegistry;
import org.springframework.beans.factory.ObjectProvider;
-import org.springframework.boot.actuate.autoconfigure.metrics.MetricsProperties;
import org.springframework.boot.actuate.autoconfigure.observation.ObservationProperties;
import org.springframework.boot.actuate.metrics.web.client.ObservationRestTemplateCustomizer;
-import org.springframework.boot.actuate.metrics.web.client.RestTemplateExchangeTagsProvider;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.web.client.RestTemplateBuilder;
@@ -40,39 +38,16 @@
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(RestTemplate.class)
@ConditionalOnBean(RestTemplateBuilder.class)
-@SuppressWarnings("removal")
class RestTemplateObservationConfiguration {
@Bean
ObservationRestTemplateCustomizer observationRestTemplateCustomizer(ObservationRegistry observationRegistry,
ObjectProvider customConvention,
- ObservationProperties observationProperties, MetricsProperties metricsProperties,
- ObjectProvider optionalTagsProvider) {
- String name = observationName(observationProperties, metricsProperties);
- ClientRequestObservationConvention observationConvention = createConvention(customConvention.getIfAvailable(),
- name, optionalTagsProvider.getIfAvailable());
+ ObservationProperties observationProperties) {
+ String name = observationProperties.getHttp().getClient().getRequests().getName();
+ ClientRequestObservationConvention observationConvention = customConvention
+ .getIfAvailable(() -> new DefaultClientRequestObservationConvention(name));
return new ObservationRestTemplateCustomizer(observationRegistry, observationConvention);
}
- private static String observationName(ObservationProperties observationProperties,
- MetricsProperties metricsProperties) {
- String metricName = metricsProperties.getWeb().getClient().getRequest().getMetricName();
- String observationName = observationProperties.getHttp().getClient().getRequests().getName();
- return (observationName != null) ? observationName : metricName;
- }
-
- private static ClientRequestObservationConvention createConvention(
- ClientRequestObservationConvention customConvention, String name,
- RestTemplateExchangeTagsProvider tagsProvider) {
- if (customConvention != null) {
- return customConvention;
- }
- else if (tagsProvider != null) {
- return new ClientHttpObservationConventionAdapter(name, tagsProvider);
- }
- else {
- return new DefaultClientRequestObservationConvention(name);
- }
- }
-
}
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/client/WebClientObservationConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/client/WebClientObservationConfiguration.java
index ce531912e1dc..2df9c4bf9104 100644
--- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/client/WebClientObservationConfiguration.java
+++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/client/WebClientObservationConfiguration.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2022 the original author or authors.
+ * Copyright 2012-2023 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.
@@ -22,7 +22,6 @@
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsProperties;
import org.springframework.boot.actuate.autoconfigure.observation.ObservationProperties;
import org.springframework.boot.actuate.metrics.web.reactive.client.ObservationWebClientCustomizer;
-import org.springframework.boot.actuate.metrics.web.reactive.client.WebClientExchangeTagsProvider;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -37,39 +36,16 @@
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(WebClient.class)
-@SuppressWarnings("removal")
class WebClientObservationConfiguration {
@Bean
ObservationWebClientCustomizer observationWebClientCustomizer(ObservationRegistry observationRegistry,
ObjectProvider customConvention,
- ObservationProperties observationProperties, ObjectProvider tagsProvider,
- MetricsProperties metricsProperties) {
- String name = observationName(observationProperties, metricsProperties);
- ClientRequestObservationConvention observationConvention = createConvention(customConvention.getIfAvailable(),
- tagsProvider.getIfAvailable(), name);
+ ObservationProperties observationProperties, MetricsProperties metricsProperties) {
+ String name = observationProperties.getHttp().getClient().getRequests().getName();
+ ClientRequestObservationConvention observationConvention = customConvention
+ .getIfAvailable(() -> new DefaultClientRequestObservationConvention(name));
return new ObservationWebClientCustomizer(observationRegistry, observationConvention);
}
- private static ClientRequestObservationConvention createConvention(
- ClientRequestObservationConvention customConvention, WebClientExchangeTagsProvider tagsProvider,
- String name) {
- if (customConvention != null) {
- return customConvention;
- }
- else if (tagsProvider != null) {
- return new ClientObservationConventionAdapter(name, tagsProvider);
- }
- else {
- return new DefaultClientRequestObservationConvention(name);
- }
- }
-
- private static String observationName(ObservationProperties observationProperties,
- MetricsProperties metricsProperties) {
- String metricName = metricsProperties.getWeb().getClient().getRequest().getMetricName();
- String observationName = observationProperties.getHttp().getClient().getRequests().getName();
- return (observationName != null) ? observationName : metricName;
- }
-
}
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/reactive/ServerRequestObservationConventionAdapter.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/reactive/ServerRequestObservationConventionAdapter.java
deleted file mode 100644
index 43689a962a05..000000000000
--- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/reactive/ServerRequestObservationConventionAdapter.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright 2012-2022 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.boot.actuate.autoconfigure.observation.web.reactive;
-
-import java.util.List;
-
-import io.micrometer.common.KeyValues;
-import io.micrometer.core.instrument.Tag;
-
-import org.springframework.boot.actuate.metrics.web.reactive.server.DefaultWebFluxTagsProvider;
-import org.springframework.boot.actuate.metrics.web.reactive.server.WebFluxTagsContributor;
-import org.springframework.boot.actuate.metrics.web.reactive.server.WebFluxTagsProvider;
-import org.springframework.http.codec.ServerCodecConfigurer;
-import org.springframework.http.server.reactive.observation.ServerRequestObservationContext;
-import org.springframework.http.server.reactive.observation.ServerRequestObservationConvention;
-import org.springframework.web.server.adapter.DefaultServerWebExchange;
-import org.springframework.web.server.i18n.AcceptHeaderLocaleContextResolver;
-import org.springframework.web.server.i18n.LocaleContextResolver;
-import org.springframework.web.server.session.DefaultWebSessionManager;
-import org.springframework.web.server.session.WebSessionManager;
-
-/**
- * Adapter class that applies {@link WebFluxTagsProvider} tags as a
- * {@link ServerRequestObservationConvention}.
- *
- * @author Brian Clozel
- */
-@SuppressWarnings("removal")
-@Deprecated(since = "3.0.0", forRemoval = true)
-class ServerRequestObservationConventionAdapter implements ServerRequestObservationConvention {
-
- private final WebSessionManager webSessionManager = new DefaultWebSessionManager();
-
- private final ServerCodecConfigurer serverCodecConfigurer = ServerCodecConfigurer.create();
-
- private final LocaleContextResolver localeContextResolver = new AcceptHeaderLocaleContextResolver();
-
- private final String name;
-
- private final WebFluxTagsProvider tagsProvider;
-
- ServerRequestObservationConventionAdapter(String name, WebFluxTagsProvider tagsProvider) {
- this.name = name;
- this.tagsProvider = tagsProvider;
- }
-
- ServerRequestObservationConventionAdapter(String name, List contributors) {
- this(name, new DefaultWebFluxTagsProvider(contributors));
- }
-
- @Override
- public String getName() {
- return this.name;
- }
-
- @Override
- public KeyValues getLowCardinalityKeyValues(ServerRequestObservationContext context) {
- DefaultServerWebExchange serverWebExchange = new DefaultServerWebExchange(context.getCarrier(),
- context.getResponse(), this.webSessionManager, this.serverCodecConfigurer, this.localeContextResolver);
- serverWebExchange.getAttributes().putAll(context.getAttributes());
- Iterable tags = this.tagsProvider.httpRequestTags(serverWebExchange, context.getError());
- return KeyValues.of(tags, Tag::getKey, Tag::getValue);
- }
-
-}
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/reactive/WebFluxObservationAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/reactive/WebFluxObservationAutoConfiguration.java
index a998e6b5d24b..0ccb94d55b5c 100644
--- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/reactive/WebFluxObservationAutoConfiguration.java
+++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/reactive/WebFluxObservationAutoConfiguration.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2022 the original author or authors.
+ * Copyright 2012-2023 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.
@@ -16,37 +16,24 @@
package org.springframework.boot.actuate.autoconfigure.observation.web.reactive;
-import java.util.List;
-
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.config.MeterFilter;
import io.micrometer.observation.Observation;
import io.micrometer.observation.ObservationRegistry;
-import org.springframework.beans.factory.ObjectProvider;
-import org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration;
-import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsProperties;
import org.springframework.boot.actuate.autoconfigure.metrics.OnlyOnceLoggingDenyMeterFilter;
import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.observation.ObservationAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.observation.ObservationProperties;
-import org.springframework.boot.actuate.metrics.web.reactive.server.WebFluxTagsContributor;
-import org.springframework.boot.actuate.metrics.web.reactive.server.WebFluxTagsProvider;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
-import org.springframework.http.server.reactive.observation.DefaultServerRequestObservationConvention;
-import org.springframework.http.server.reactive.observation.ServerRequestObservationConvention;
-import org.springframework.web.filter.reactive.ServerHttpObservationFilter;
/**
* {@link EnableAutoConfiguration Auto-configuration} for instrumentation of Spring
@@ -57,75 +44,22 @@
* @author Dmytro Nosan
* @since 3.0.0
*/
-@AutoConfiguration(after = { MetricsAutoConfiguration.class, CompositeMeterRegistryAutoConfiguration.class,
- SimpleMetricsExportAutoConfiguration.class, ObservationAutoConfiguration.class })
-@ConditionalOnClass(Observation.class)
-@ConditionalOnBean(ObservationRegistry.class)
+@AutoConfiguration(after = { SimpleMetricsExportAutoConfiguration.class, ObservationAutoConfiguration.class })
+@ConditionalOnClass({ Observation.class, MeterRegistry.class })
+@ConditionalOnBean({ ObservationRegistry.class, MeterRegistry.class })
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE)
@EnableConfigurationProperties({ MetricsProperties.class, ObservationProperties.class })
-@SuppressWarnings("removal")
public class WebFluxObservationAutoConfiguration {
- private final MetricsProperties metricsProperties;
-
- private final ObservationProperties observationProperties;
-
- public WebFluxObservationAutoConfiguration(MetricsProperties metricsProperties,
- ObservationProperties observationProperties) {
- this.metricsProperties = metricsProperties;
- this.observationProperties = observationProperties;
- }
-
@Bean
- @ConditionalOnMissingBean
- @Order(Ordered.HIGHEST_PRECEDENCE + 1)
- public ServerHttpObservationFilter webfluxObservationFilter(ObservationRegistry registry,
- ObjectProvider customConvention,
- ObjectProvider tagConfigurer,
- ObjectProvider contributorsProvider) {
- String observationName = this.observationProperties.getHttp().getServer().getRequests().getName();
- String metricName = this.metricsProperties.getWeb().getServer().getRequest().getMetricName();
- String name = (observationName != null) ? observationName : metricName;
- WebFluxTagsProvider tagsProvider = tagConfigurer.getIfAvailable();
- List tagsContributors = contributorsProvider.orderedStream().toList();
- ServerRequestObservationConvention convention = createConvention(customConvention.getIfAvailable(), name,
- tagsProvider, tagsContributors);
- return new ServerHttpObservationFilter(registry, convention);
- }
-
- private static ServerRequestObservationConvention createConvention(
- ServerRequestObservationConvention customConvention, String name, WebFluxTagsProvider tagsProvider,
- List tagsContributors) {
- if (customConvention != null) {
- return customConvention;
- }
- if (tagsProvider != null) {
- return new ServerRequestObservationConventionAdapter(name, tagsProvider);
- }
- if (!tagsContributors.isEmpty()) {
- return new ServerRequestObservationConventionAdapter(name, tagsContributors);
- }
- return new DefaultServerRequestObservationConvention(name);
- }
-
- @Configuration(proxyBeanMethods = false)
- @ConditionalOnClass(MeterRegistry.class)
- @ConditionalOnBean(MeterRegistry.class)
- static class MeterFilterConfiguration {
-
- @Bean
- @Order(0)
- MeterFilter metricsHttpServerUriTagFilter(MetricsProperties metricsProperties,
- ObservationProperties observationProperties) {
- String observationName = observationProperties.getHttp().getServer().getRequests().getName();
- String name = (observationName != null) ? observationName
- : metricsProperties.getWeb().getServer().getRequest().getMetricName();
- MeterFilter filter = new OnlyOnceLoggingDenyMeterFilter(
- () -> "Reached the maximum number of URI tags for '%s'.".formatted(name));
- return MeterFilter.maximumAllowableTags(name, "uri", metricsProperties.getWeb().getServer().getMaxUriTags(),
- filter);
- }
-
+ @Order(0)
+ MeterFilter metricsHttpServerUriTagFilter(MetricsProperties metricsProperties,
+ ObservationProperties observationProperties) {
+ String name = observationProperties.getHttp().getServer().getRequests().getName();
+ MeterFilter filter = new OnlyOnceLoggingDenyMeterFilter(
+ () -> "Reached the maximum number of URI tags for '%s'.".formatted(name));
+ return MeterFilter.maximumAllowableTags(name, "uri", metricsProperties.getWeb().getServer().getMaxUriTags(),
+ filter);
}
}
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/servlet/ServerRequestObservationConventionAdapter.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/servlet/ServerRequestObservationConventionAdapter.java
deleted file mode 100644
index df52cbca7407..000000000000
--- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/servlet/ServerRequestObservationConventionAdapter.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright 2012-2022 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.boot.actuate.autoconfigure.observation.web.servlet;
-
-import java.util.List;
-
-import io.micrometer.common.KeyValues;
-import io.micrometer.core.instrument.Tag;
-import io.micrometer.observation.Observation;
-
-import org.springframework.boot.actuate.metrics.web.servlet.DefaultWebMvcTagsProvider;
-import org.springframework.boot.actuate.metrics.web.servlet.WebMvcTagsContributor;
-import org.springframework.boot.actuate.metrics.web.servlet.WebMvcTagsProvider;
-import org.springframework.http.server.observation.ServerRequestObservationContext;
-import org.springframework.http.server.observation.ServerRequestObservationConvention;
-import org.springframework.util.Assert;
-import org.springframework.web.servlet.HandlerMapping;
-
-/**
- * Adapter class that applies {@link WebMvcTagsProvider} tags as a
- * {@link ServerRequestObservationConvention}.
- *
- * @author Brian Clozel
- */
-@SuppressWarnings("removal")
-@Deprecated(since = "3.0.0", forRemoval = true)
-class ServerRequestObservationConventionAdapter implements ServerRequestObservationConvention {
-
- private final String observationName;
-
- private final WebMvcTagsProvider tagsProvider;
-
- ServerRequestObservationConventionAdapter(String observationName, WebMvcTagsProvider tagsProvider,
- List contributors) {
- Assert.state((tagsProvider != null) || (contributors != null),
- "adapter should adapt to a WebMvcTagsProvider or a list of contributors");
- this.observationName = observationName;
- this.tagsProvider = (tagsProvider != null) ? tagsProvider : new DefaultWebMvcTagsProvider(contributors);
- }
-
- @Override
- public String getName() {
- return this.observationName;
- }
-
- @Override
- public boolean supportsContext(Observation.Context context) {
- return context instanceof ServerRequestObservationContext;
- }
-
- @Override
- public KeyValues getLowCardinalityKeyValues(ServerRequestObservationContext context) {
- Iterable tags = this.tagsProvider.getTags(context.getCarrier(), context.getResponse(), getHandler(context),
- context.getError());
- return KeyValues.of(tags, Tag::getKey, Tag::getValue);
- }
-
- private Object getHandler(ServerRequestObservationContext context) {
- return context.getCarrier().getAttribute(HandlerMapping.BEST_MATCHING_HANDLER_ATTRIBUTE);
- }
-
-}
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/servlet/WebMvcObservationAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/servlet/WebMvcObservationAutoConfiguration.java
index 5a70728ac125..2b4aa96c3933 100644
--- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/servlet/WebMvcObservationAutoConfiguration.java
+++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/servlet/WebMvcObservationAutoConfiguration.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2022 the original author or authors.
+ * Copyright 2012-2023 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.
@@ -16,8 +16,6 @@
package org.springframework.boot.actuate.autoconfigure.observation.web.servlet;
-import java.util.List;
-
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.config.MeterFilter;
import io.micrometer.observation.Observation;
@@ -32,8 +30,6 @@
import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.observation.ObservationAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.observation.ObservationProperties;
-import org.springframework.boot.actuate.metrics.web.servlet.WebMvcTagsContributor;
-import org.springframework.boot.actuate.metrics.web.servlet.WebMvcTagsProvider;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
@@ -66,28 +62,16 @@
@ConditionalOnClass({ DispatcherServlet.class, Observation.class })
@ConditionalOnBean(ObservationRegistry.class)
@EnableConfigurationProperties({ MetricsProperties.class, ObservationProperties.class })
-@SuppressWarnings("removal")
public class WebMvcObservationAutoConfiguration {
- private final MetricsProperties metricsProperties;
-
- private final ObservationProperties observationProperties;
-
- public WebMvcObservationAutoConfiguration(ObservationProperties observationProperties,
- MetricsProperties metricsProperties) {
- this.observationProperties = observationProperties;
- this.metricsProperties = metricsProperties;
- }
-
@Bean
@ConditionalOnMissingFilterBean
public FilterRegistrationBean webMvcObservationFilter(ObservationRegistry registry,
ObjectProvider customConvention,
- ObjectProvider customTagsProvider,
- ObjectProvider contributorsProvider) {
- String name = httpRequestsMetricName(this.observationProperties, this.metricsProperties);
- ServerRequestObservationConvention convention = createConvention(customConvention.getIfAvailable(), name,
- customTagsProvider.getIfAvailable(), contributorsProvider.orderedStream().toList());
+ ObservationProperties observationProperties) {
+ String name = observationProperties.getHttp().getServer().getRequests().getName();
+ ServerRequestObservationConvention convention = customConvention
+ .getIfAvailable(() -> new DefaultServerRequestObservationConvention(name));
ServerHttpObservationFilter filter = new ServerHttpObservationFilter(registry, convention);
FilterRegistrationBean registration = new FilterRegistrationBean<>(filter);
registration.setOrder(Ordered.HIGHEST_PRECEDENCE + 1);
@@ -95,27 +79,6 @@ public FilterRegistrationBean webMvcObservationFilt
return registration;
}
- private static ServerRequestObservationConvention createConvention(
- ServerRequestObservationConvention customConvention, String name, WebMvcTagsProvider tagsProvider,
- List contributors) {
- if (customConvention != null) {
- return customConvention;
- }
- else if (tagsProvider != null || contributors.size() > 0) {
- return new ServerRequestObservationConventionAdapter(name, tagsProvider, contributors);
- }
- else {
- return new DefaultServerRequestObservationConvention(name);
- }
- }
-
- private static String httpRequestsMetricName(ObservationProperties observationProperties,
- MetricsProperties metricsProperties) {
- String observationName = observationProperties.getHttp().getServer().getRequests().getName();
- return (observationName != null) ? observationName
- : metricsProperties.getWeb().getServer().getRequest().getMetricName();
- }
-
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(MeterRegistry.class)
@ConditionalOnBean(MeterRegistry.class)
@@ -123,9 +86,9 @@ static class MeterFilterConfiguration {
@Bean
@Order(0)
- MeterFilter metricsHttpServerUriTagFilter(MetricsProperties metricsProperties,
- ObservationProperties observationProperties) {
- String name = httpRequestsMetricName(observationProperties, metricsProperties);
+ MeterFilter metricsHttpServerUriTagFilter(ObservationProperties observationProperties,
+ MetricsProperties metricsProperties) {
+ String name = observationProperties.getHttp().getServer().getRequests().getName();
MeterFilter filter = new OnlyOnceLoggingDenyMeterFilter(
() -> String.format("Reached the maximum number of URI tags for '%s'.", name));
return MeterFilter.maximumAllowableTags(name, "uri", metricsProperties.getWeb().getServer().getMaxUriTags(),
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/opentelemetry/OpenTelemetryAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/opentelemetry/OpenTelemetryAutoConfiguration.java
new file mode 100644
index 000000000000..f87bfa6548dd
--- /dev/null
+++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/opentelemetry/OpenTelemetryAutoConfiguration.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2012-2023 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.boot.actuate.autoconfigure.opentelemetry;
+
+import io.opentelemetry.api.OpenTelemetry;
+import io.opentelemetry.api.common.AttributeKey;
+import io.opentelemetry.api.common.Attributes;
+import io.opentelemetry.context.propagation.ContextPropagators;
+import io.opentelemetry.sdk.OpenTelemetrySdk;
+import io.opentelemetry.sdk.OpenTelemetrySdkBuilder;
+import io.opentelemetry.sdk.logs.SdkLoggerProvider;
+import io.opentelemetry.sdk.metrics.SdkMeterProvider;
+import io.opentelemetry.sdk.resources.Resource;
+import io.opentelemetry.sdk.resources.ResourceBuilder;
+import io.opentelemetry.sdk.trace.SdkTracerProvider;
+
+import org.springframework.beans.factory.ObjectProvider;
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.core.env.Environment;
+
+/**
+ * {@link EnableAutoConfiguration Auto-configuration} for OpenTelemetry.
+ *
+ * @author Moritz Halbritter
+ * @since 3.2.0
+ */
+@AutoConfiguration
+@ConditionalOnClass(OpenTelemetrySdk.class)
+@EnableConfigurationProperties(OpenTelemetryProperties.class)
+public class OpenTelemetryAutoConfiguration {
+
+ /**
+ * Default value for application name if {@code spring.application.name} is not set.
+ */
+ private static final String DEFAULT_APPLICATION_NAME = "application";
+
+ private static final AttributeKey ATTRIBUTE_KEY_SERVICE_NAME = AttributeKey.stringKey("service.name");
+
+ @Bean
+ @ConditionalOnMissingBean(OpenTelemetry.class)
+ OpenTelemetrySdk openTelemetry(ObjectProvider tracerProvider,
+ ObjectProvider propagators, ObjectProvider loggerProvider,
+ ObjectProvider meterProvider) {
+ OpenTelemetrySdkBuilder builder = OpenTelemetrySdk.builder();
+ tracerProvider.ifAvailable(builder::setTracerProvider);
+ propagators.ifAvailable(builder::setPropagators);
+ loggerProvider.ifAvailable(builder::setLoggerProvider);
+ meterProvider.ifAvailable(builder::setMeterProvider);
+ return builder.build();
+ }
+
+ @Bean
+ @ConditionalOnMissingBean
+ Resource openTelemetryResource(Environment environment, OpenTelemetryProperties properties) {
+ String applicationName = environment.getProperty("spring.application.name", DEFAULT_APPLICATION_NAME);
+ return Resource.getDefault()
+ .merge(Resource.create(Attributes.of(ATTRIBUTE_KEY_SERVICE_NAME, applicationName)))
+ .merge(toResource(properties));
+ }
+
+ private static Resource toResource(OpenTelemetryProperties properties) {
+ ResourceBuilder builder = Resource.builder();
+ properties.getResourceAttributes().forEach(builder::put);
+ return builder.build();
+ }
+
+}
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/opentelemetry/OpenTelemetryProperties.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/opentelemetry/OpenTelemetryProperties.java
new file mode 100644
index 000000000000..4c973ecf578b
--- /dev/null
+++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/opentelemetry/OpenTelemetryProperties.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2012-2023 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.boot.actuate.autoconfigure.opentelemetry;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+/**
+ * Configuration properties for OpenTelemetry.
+ *
+ * @author Moritz Halbritter
+ * @since 3.2.0
+ */
+@ConfigurationProperties(prefix = "management.opentelemetry")
+public class OpenTelemetryProperties {
+
+ /**
+ * Resource attributes.
+ */
+ private Map resourceAttributes = new HashMap<>();
+
+ public Map getResourceAttributes() {
+ return this.resourceAttributes;
+ }
+
+ public void setResourceAttributes(Map resourceAttributes) {
+ this.resourceAttributes = resourceAttributes;
+ }
+
+}
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/opentelemetry/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/opentelemetry/package-info.java
new file mode 100644
index 000000000000..c1aab18823c6
--- /dev/null
+++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/opentelemetry/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2012-2023 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Auto-configuration for OpenTelemetry.
+ */
+package org.springframework.boot.actuate.autoconfigure.opentelemetry;
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/r2dbc/R2dbcObservationAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/r2dbc/R2dbcObservationAutoConfiguration.java
new file mode 100644
index 000000000000..75f619c1bdfe
--- /dev/null
+++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/r2dbc/R2dbcObservationAutoConfiguration.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2012-2023 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.boot.actuate.autoconfigure.r2dbc;
+
+import io.micrometer.observation.ObservationRegistry;
+import io.r2dbc.proxy.ProxyConnectionFactory;
+import io.r2dbc.proxy.observation.ObservationProxyExecutionListener;
+import io.r2dbc.proxy.observation.QueryObservationConvention;
+import io.r2dbc.proxy.observation.QueryParametersTagProvider;
+import io.r2dbc.spi.ConnectionFactory;
+import io.r2dbc.spi.ConnectionFactoryOptions;
+
+import org.springframework.beans.factory.ObjectProvider;
+import org.springframework.boot.actuate.autoconfigure.observation.ObservationAutoConfiguration;
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.boot.r2dbc.ConnectionFactoryDecorator;
+import org.springframework.boot.r2dbc.OptionsCapableConnectionFactory;
+import org.springframework.context.annotation.Bean;
+
+/**
+ * {@link EnableAutoConfiguration Auto-configuration} for R2DBC observability support.
+ *
+ * @author Moritz Halbritter
+ * @since 3.2.0
+ */
+@AutoConfiguration(after = ObservationAutoConfiguration.class)
+@ConditionalOnClass({ ConnectionFactory.class, ProxyConnectionFactory.class })
+@EnableConfigurationProperties(R2dbcObservationProperties.class)
+public class R2dbcObservationAutoConfiguration {
+
+ @Bean
+ @ConditionalOnBean(ObservationRegistry.class)
+ ConnectionFactoryDecorator connectionFactoryDecorator(R2dbcObservationProperties properties,
+ ObservationRegistry observationRegistry,
+ ObjectProvider queryObservationConvention,
+ ObjectProvider queryParametersTagProvider) {
+ return (connectionFactory) -> {
+ HostAndPort hostAndPort = extractHostAndPort(connectionFactory);
+ ObservationProxyExecutionListener listener = new ObservationProxyExecutionListener(observationRegistry,
+ connectionFactory, hostAndPort.host(), hostAndPort.port());
+ listener.setIncludeParameterValues(properties.isIncludeParameterValues());
+ queryObservationConvention.ifAvailable(listener::setQueryObservationConvention);
+ queryParametersTagProvider.ifAvailable(listener::setQueryParametersTagProvider);
+ return ProxyConnectionFactory.builder(connectionFactory).listener(listener).build();
+ };
+ }
+
+ private HostAndPort extractHostAndPort(ConnectionFactory connectionFactory) {
+ OptionsCapableConnectionFactory optionsCapableConnectionFactory = OptionsCapableConnectionFactory
+ .unwrapFrom(connectionFactory);
+ if (optionsCapableConnectionFactory == null) {
+ return HostAndPort.empty();
+ }
+ ConnectionFactoryOptions options = optionsCapableConnectionFactory.getOptions();
+ Object host = options.getValue(ConnectionFactoryOptions.HOST);
+ Object port = options.getValue(ConnectionFactoryOptions.PORT);
+ if (!(host instanceof String hostAsString) || !(port instanceof Integer portAsInt)) {
+ return HostAndPort.empty();
+ }
+ return new HostAndPort(hostAsString, portAsInt);
+ }
+
+ private record HostAndPort(String host, Integer port) {
+ static HostAndPort empty() {
+ return new HostAndPort(null, null);
+ }
+ }
+
+}
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/r2dbc/R2dbcObservationProperties.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/r2dbc/R2dbcObservationProperties.java
new file mode 100644
index 000000000000..4eedf3e12282
--- /dev/null
+++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/r2dbc/R2dbcObservationProperties.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2012-2023 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.boot.actuate.autoconfigure.r2dbc;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+/**
+ * Configuration properties for R2DBC observability.
+ *
+ * @author Moritz Halbritter
+ * @since 3.2.0
+ */
+@ConfigurationProperties("management.observations.r2dbc")
+public class R2dbcObservationProperties {
+
+ /**
+ * Whether to tag actual query parameter values.
+ */
+ private boolean includeParameterValues;
+
+ public boolean isIncludeParameterValues() {
+ return this.includeParameterValues;
+ }
+
+ public void setIncludeParameterValues(boolean includeParameterValues) {
+ this.includeParameterValues = includeParameterValues;
+ }
+
+}
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/scheduling/ScheduledTasksObservabilityAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/scheduling/ScheduledTasksObservabilityAutoConfiguration.java
new file mode 100644
index 000000000000..a4014d2d3eb5
--- /dev/null
+++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/scheduling/ScheduledTasksObservabilityAutoConfiguration.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2012-2023 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.boot.actuate.autoconfigure.scheduling;
+
+import io.micrometer.observation.ObservationRegistry;
+
+import org.springframework.boot.actuate.autoconfigure.observation.ObservationAutoConfiguration;
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.context.annotation.Bean;
+import org.springframework.scheduling.annotation.SchedulingConfigurer;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
+import org.springframework.scheduling.config.ScheduledTaskRegistrar;
+
+/**
+ * {@link EnableAutoConfiguration Auto-configuration} to enable observability for
+ * scheduled tasks.
+ *
+ * @author Moritz Halbritter
+ * @since 3.2.0
+ */
+@AutoConfiguration(after = ObservationAutoConfiguration.class)
+@ConditionalOnBean(ObservationRegistry.class)
+@ConditionalOnClass(ThreadPoolTaskScheduler.class)
+public class ScheduledTasksObservabilityAutoConfiguration {
+
+ @Bean
+ ObservabilitySchedulingConfigurer observabilitySchedulingConfigurer(ObservationRegistry observationRegistry) {
+ return new ObservabilitySchedulingConfigurer(observationRegistry);
+ }
+
+ static final class ObservabilitySchedulingConfigurer implements SchedulingConfigurer {
+
+ private final ObservationRegistry observationRegistry;
+
+ ObservabilitySchedulingConfigurer(ObservationRegistry observationRegistry) {
+ this.observationRegistry = observationRegistry;
+ }
+
+ @Override
+ public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
+ taskRegistrar.setObservationRegistry(this.observationRegistry);
+ }
+
+ }
+
+}
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/BraveAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/BraveAutoConfiguration.java
index b0e25e91495b..47d65fe69cbc 100644
--- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/BraveAutoConfiguration.java
+++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/BraveAutoConfiguration.java
@@ -37,7 +37,9 @@
import brave.propagation.CurrentTraceContext;
import brave.propagation.CurrentTraceContext.ScopeDecorator;
import brave.propagation.CurrentTraceContextCustomizer;
+import brave.propagation.Propagation;
import brave.propagation.Propagation.Factory;
+import brave.propagation.Propagation.KeyFactory;
import brave.propagation.ThreadLocalCurrentTraceContext;
import brave.sampler.Sampler;
import io.micrometer.tracing.brave.bridge.BraveBaggageManager;
@@ -77,7 +79,6 @@
@AutoConfiguration(before = MicrometerTracingAutoConfiguration.class)
@ConditionalOnClass({ Tracer.class, BraveTracer.class })
@EnableConfigurationProperties(TracingProperties.class)
-@ConditionalOnEnabledTracing
public class BraveAutoConfiguration {
private static final BraveBaggageManager BRAVE_BAGGAGE_MANAGER = new BraveBaggageManager();
@@ -188,7 +189,7 @@ static class BraveNoBaggageConfiguration {
@Bean
@ConditionalOnMissingBean
Factory propagationFactory(TracingProperties properties) {
- return CompositePropagationFactory.create(properties.getPropagation(), null);
+ return CompositePropagationFactory.create(properties.getPropagation());
}
}
@@ -207,13 +208,33 @@ static class BraveBaggageConfiguration {
@ConditionalOnMissingBean
BaggagePropagation.FactoryBuilder propagationFactoryBuilder(
ObjectProvider baggagePropagationCustomizers) {
- CompositePropagationFactory factory = CompositePropagationFactory
- .create(this.tracingProperties.getPropagation(), BRAVE_BAGGAGE_MANAGER);
- FactoryBuilder builder = BaggagePropagation.newFactoryBuilder(factory);
- baggagePropagationCustomizers.orderedStream().forEach((customizer) -> customizer.customize(builder));
+ // There's a chicken-and-egg problem here: to create a builder, we need a
+ // factory. But the CompositePropagationFactory needs data from the builder.
+ // We create a throw-away builder with a throw-away factory, and then copy the
+ // config to the real builder.
+ FactoryBuilder throwAwayBuilder = BaggagePropagation.newFactoryBuilder(createThrowAwayFactory());
+ baggagePropagationCustomizers.orderedStream()
+ .forEach((customizer) -> customizer.customize(throwAwayBuilder));
+ CompositePropagationFactory propagationFactory = CompositePropagationFactory.create(
+ this.tracingProperties.getPropagation(), BRAVE_BAGGAGE_MANAGER,
+ LocalBaggageFields.extractFrom(throwAwayBuilder));
+ FactoryBuilder builder = BaggagePropagation.newFactoryBuilder(propagationFactory);
+ throwAwayBuilder.configs().forEach(builder::add);
return builder;
}
+ @SuppressWarnings("deprecation")
+ private Factory createThrowAwayFactory() {
+ return new Factory() {
+
+ @Override
+ public Propagation create(KeyFactory keyFactory) {
+ return null;
+ }
+
+ };
+ }
+
@Bean
@Order(0)
BaggagePropagationCustomizer remoteFieldsBaggagePropagationCustomizer() {
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/CompositePropagationFactory.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/CompositePropagationFactory.java
index 0ec3db30c2b7..4e3b09b1e915 100644
--- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/CompositePropagationFactory.java
+++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/CompositePropagationFactory.java
@@ -17,7 +17,6 @@
package org.springframework.boot.actuate.autoconfigure.tracing;
import java.util.Collection;
-import java.util.Collections;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Stream;
@@ -86,14 +85,24 @@ public TraceContext decorate(TraceContext context) {
}
/**
- * Creates a new {@link CompositePropagationFactory}, which uses the given
- * {@code injectionTypes} for injection and {@code extractionTypes} for extraction.
+ * Creates a new {@link CompositePropagationFactory}.
+ * @param properties the propagation properties
+ * @return the {@link CompositePropagationFactory}
+ */
+ static CompositePropagationFactory create(TracingProperties.Propagation properties) {
+ return create(properties, null, null);
+ }
+
+ /**
+ * Creates a new {@link CompositePropagationFactory}.
* @param properties the propagation properties
* @param baggageManager the baggage manager to use, or {@code null}
+ * @param localFields the local fields, or {@code null}
* @return the {@link CompositePropagationFactory}
*/
- static CompositePropagationFactory create(TracingProperties.Propagation properties, BaggageManager baggageManager) {
- PropagationFactoryMapper mapper = new PropagationFactoryMapper(baggageManager);
+ static CompositePropagationFactory create(TracingProperties.Propagation properties, BaggageManager baggageManager,
+ LocalBaggageFields localFields) {
+ PropagationFactoryMapper mapper = new PropagationFactoryMapper(baggageManager, localFields);
List injectors = properties.getEffectiveProducedTypes().stream().map(mapper::map).toList();
List extractors = properties.getEffectiveConsumedTypes().stream().map(mapper::map).toList();
return new CompositePropagationFactory(injectors, extractors);
@@ -107,8 +116,11 @@ private static class PropagationFactoryMapper {
private final BaggageManager baggageManager;
- PropagationFactoryMapper(BaggageManager baggageManager) {
+ private final LocalBaggageFields localFields;
+
+ PropagationFactoryMapper(BaggageManager baggageManager, LocalBaggageFields localFields) {
this.baggageManager = baggageManager;
+ this.localFields = (localFields != null) ? localFields : LocalBaggageFields.empty();
}
Propagation.Factory map(PropagationType type) {
@@ -124,7 +136,7 @@ Propagation.Factory map(PropagationType type) {
* @return the B3 propagation factory
*/
private Propagation.Factory b3Single() {
- return B3Propagation.newFactoryBuilder().injectFormat(B3Propagation.Format.SINGLE_NO_PARENT).build();
+ return B3Propagation.newFactoryBuilder().injectFormat(B3Propagation.Format.SINGLE).build();
}
/**
@@ -140,8 +152,10 @@ private Propagation.Factory b3Multi() {
* @return the W3C propagation factory
*/
private Propagation.Factory w3c() {
- return (this.baggageManager != null) ? new W3CPropagation(this.baggageManager, Collections.emptyList())
- : new W3CPropagation();
+ if (this.baggageManager == null) {
+ return new W3CPropagation();
+ }
+ return new W3CPropagation(this.baggageManager, this.localFields.asList());
}
}
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/CompositeTextMapPropagator.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/CompositeTextMapPropagator.java
index 5db4f629a0ea..aef0a11f01a3 100644
--- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/CompositeTextMapPropagator.java
+++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/CompositeTextMapPropagator.java
@@ -40,6 +40,7 @@
* configure different formats for injecting and for extracting.
*
* @author Moritz Halbritter
+ * @author Scott Frederick
*/
class CompositeTextMapPropagator implements TextMapPropagator {
@@ -81,6 +82,10 @@ Collection getInjectors() {
return this.injectors;
}
+ Collection