From 0412d9fe8cabdd9061c4ea6069742831b515500c Mon Sep 17 00:00:00 2001 From: John Blum Date: Sat, 13 May 2023 13:47:35 -0700 Subject: [PATCH] Fix bug in VmwHarborProxyImageNameSubstitutor when resolving Spring-managed Docker Images in VMware Harbor Proxy. --- .../VmwHarborProxyImageNameSubstitutor.java | 88 ++++++++++++------- ...borProxyImageNameSubstitutorUnitTests.java | 42 +++++++-- 2 files changed, 91 insertions(+), 39 deletions(-) diff --git a/spring-geode-project/spring-geode/src/test/java/example/app/crm/config/testcontainers/VmwHarborProxyImageNameSubstitutor.java b/spring-geode-project/spring-geode/src/test/java/example/app/crm/config/testcontainers/VmwHarborProxyImageNameSubstitutor.java index 7fda636c..beb6e23d 100644 --- a/spring-geode-project/spring-geode/src/test/java/example/app/crm/config/testcontainers/VmwHarborProxyImageNameSubstitutor.java +++ b/spring-geode-project/spring-geode/src/test/java/example/app/crm/config/testcontainers/VmwHarborProxyImageNameSubstitutor.java @@ -15,6 +15,10 @@ */ package example.app.crm.config.testcontainers; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; + import org.springframework.lang.NonNull; import org.slf4j.Logger; @@ -28,6 +32,7 @@ import org.testcontainers.utility.ImageNameSubstitutor; * @author John Blum * @see org.testcontainers.utility.DockerImageName * @see org.testcontainers.utility.ImageNameSubstitutor + * @see Image name substitution * @see Image Name Substitution not applied for DockerComposeContainers * @since 1.7.6 */ @@ -50,47 +55,53 @@ public class VmwHarborProxyImageNameSubstitutor extends ImageNameSubstitutor { protected static final String TESTCONTAINERS_SPRINGCI_HUB_IMAGE_NAME_TEMPLATE = TESTCONTAINERS_SPRINGCI_HUB_IMAGE_NAME_PREFIX.concat("%s"); - private static final String SPRING_JAVA_VERSION = + protected static final String SPRING_JAVA_VERSION = System.getProperty("spring.java.version", "17.0.6_10-jdk-focal"); - private static final String SPRING_DATA_CASSANDRA_DOCKER_IMAGE_NAME = + protected static final String SPRING_DATA_CASSANDRA_DOCKER_IMAGE_NAME = String.format("spring-data-with-cassandra-3.11:%s", SPRING_JAVA_VERSION); + protected static final String DOCKER_IMAGE_NAME_WITH_VERSION_TEMPLATE = "%1$s:%2$s"; + + private static final Map springManagedDockerImages = new ConcurrentHashMap<>(); + + static { + springManagedDockerImages.put("cassandra", SPRING_DATA_CASSANDRA_DOCKER_IMAGE_NAME); + } + private final Logger logger = LoggerFactory.getLogger(getClass()); @Override - public @NonNull DockerImageName apply(@NonNull DockerImageName original) { + public @NonNull DockerImageName apply(@NonNull DockerImageName originalDockerImageName) { - String originalDockerImageName = original.asCanonicalNameString(); - String resolvedDockerImageName = resolveDockerImageName(originalDockerImageName);; + DockerImageName resolvedDockerImageName = resolveDockerImageName(originalDockerImageName); - logInfo("Original Docker Image Name [%s]", originalDockerImageName); - logInfo("Resolved Docker Image Name [{}]", resolvedDockerImageName); + logInfo("Original Docker Image Name [{}]", originalDockerImageName.asCanonicalNameString()); + logInfo("Resolved Docker Image Name [{}]", resolvedDockerImageName.asCanonicalNameString()); - DockerImageName dockerImageName = DockerImageName.parse(resolvedDockerImageName); + return resolveCompatibleSubstituteFor(resolvedDockerImageName); + } - return dockerImageName.asCanonicalNameString().contains(CASSANDRA_KEYWORD) + protected boolean isJenkinsEnvironment() { + return Boolean.TRUE.equals(Boolean.getBoolean(JENKINS_KEYWORD)); + } + + protected boolean isVMwareHarborProxyAvailable(DockerImageName dockerImageName) { + return dockerImageName.getRegistry().contains(VMWARE_HARBOR_PROXY_URL) || isJenkinsEnvironment(); + } + + protected DockerImageName resolveCompatibleSubstituteFor(DockerImageName dockerImageName) { + + return springManagedDockerImages.containsKey(dockerImageName.getUnversionedPart()) ? dockerImageName.asCompatibleSubstituteFor(CASSANDRA_KEYWORD) : dockerImageName; } - private boolean isJenkinsEnvironment() { - return Boolean.TRUE.equals(Boolean.getBoolean(JENKINS_KEYWORD)); - } - - private boolean isSpringDockerImageName(String dockerImageName) { - return dockerImageName.contains("spring"); - } - - private boolean isVMwareHarborProxyAvailable(String dockerImageName) { - return dockerImageName.contains(VMWARE_HARBOR_PROXY_URL) || isJenkinsEnvironment(); - } - - private String resolveDockerImageName(String originalDockerImageName) { + protected DockerImageName resolveDockerImageName(DockerImageName originalDockerImageName) { logInfo("Is Jenkins Environment [{}]", isJenkinsEnvironment()); - String resolvedDockerImageName = originalDockerImageName; + DockerImageName resolvedDockerImageName = originalDockerImageName; if (isVMwareHarborProxyAvailable(originalDockerImageName)) { logInfo("VMware Harbor Proxy detected [{}]", originalDockerImageName); @@ -101,22 +112,31 @@ public class VmwHarborProxyImageNameSubstitutor extends ImageNameSubstitutor { return resolvedDockerImageName; } - private String doResolveDockerImageName(String originalDockerImageName) { + DockerImageName doResolveDockerImageName(DockerImageName originalDockerImageName) { - return isSpringDockerImageName(originalDockerImageName) - ? String.format(TESTCONTAINERS_SPRINGCI_HUB_IMAGE_NAME_TEMPLATE, substituteCassandraDockerImageName(originalDockerImageName)) - : String.format(TESTCONTAINERS_HUB_IMAGE_NAME_TEMPLATE, originalDockerImageName); + return Optional.ofNullable(originalDockerImageName) + .filter(dockerImageName -> springManagedDockerImages.containsKey(dockerImageName.getUnversionedPart())) + .map(dockerImageName -> springManagedDockerImages.get(dockerImageName.getUnversionedPart())) + .map(springManagedDockerImageName -> String.format(TESTCONTAINERS_SPRINGCI_HUB_IMAGE_NAME_TEMPLATE, springManagedDockerImageName)) + .map(DockerImageName::parse) + .orElseGet(() -> DockerImageName.parse(String.format(TESTCONTAINERS_HUB_IMAGE_NAME_TEMPLATE, originalDockerImageName))); } - private String substituteCassandraDockerImageName(String originalDockerImageName) { + DockerImageName toUnqualifiedDockerImageName(DockerImageName dockerImageName) { - return originalDockerImageName.contains("cassandra") - ? SPRING_DATA_CASSANDRA_DOCKER_IMAGE_NAME - : originalDockerImageName; - } + String name = dockerImageName.getUnversionedPart(); + String registry = dockerImageName.getRegistry(); + String repository = dockerImageName.getRepository(); + String version = dockerImageName.getVersionPart(); - String toUnqualifiedDockerImageName(String dockerImageName) { - return dockerImageName.replace(TESTCONTAINERS_HUB_IMAGE_NAME_PREFIX, ""); + /* + return DockerImageName.parse(dockerImageName.asCanonicalNameString() + .replace(TESTCONTAINERS_HUB_IMAGE_NAME_PREFIX, "")); + */ + + return DockerImageName.parse(String.format(DOCKER_IMAGE_NAME_WITH_VERSION_TEMPLATE, + name.replace(TESTCONTAINERS_HUB_IMAGE_NAME_PREFIX, ""), + version)); } @Override diff --git a/spring-geode-project/spring-geode/src/test/java/example/app/crm/config/testcontainers/VmwHarborProxyImageNameSubstitutorUnitTests.java b/spring-geode-project/spring-geode/src/test/java/example/app/crm/config/testcontainers/VmwHarborProxyImageNameSubstitutorUnitTests.java index 3af539fb..c306b92d 100644 --- a/spring-geode-project/spring-geode/src/test/java/example/app/crm/config/testcontainers/VmwHarborProxyImageNameSubstitutorUnitTests.java +++ b/spring-geode-project/spring-geode/src/test/java/example/app/crm/config/testcontainers/VmwHarborProxyImageNameSubstitutorUnitTests.java @@ -19,6 +19,8 @@ import static org.assertj.core.api.Assertions.assertThat; import org.junit.jupiter.api.Test; +import org.testcontainers.utility.DockerImageName; + /** * Unit Tests for {@link VmwHarborProxyImageNameSubstitutor}. * @@ -30,23 +32,53 @@ import org.junit.jupiter.api.Test; public class VmwHarborProxyImageNameSubstitutorUnitTests { @Test - public void toUnqualifiedDockerImageNameFromQualifiedName() { + public void doResolveDockerImageNameForSpringManagedDockerImage() { + + DockerImageName cassandraDockerImage = DockerImageName.parse("cassandra:3.11.14"); VmwHarborProxyImageNameSubstitutor imageNameSubstitutor = new VmwHarborProxyImageNameSubstitutor(); - String qualifiedDockerImageName = String.format(VmwHarborProxyImageNameSubstitutor - .TESTCONTAINERS_HUB_IMAGE_NAME_TEMPLATE, "testcontainers/ryuk:0.4.0"); + assertThat(imageNameSubstitutor.doResolveDockerImageName(cassandraDockerImage) + .asCanonicalNameString()) + .isEqualTo(String.format(VmwHarborProxyImageNameSubstitutor.TESTCONTAINERS_SPRINGCI_HUB_IMAGE_NAME_TEMPLATE, + VmwHarborProxyImageNameSubstitutor.SPRING_DATA_CASSANDRA_DOCKER_IMAGE_NAME)); + } - assertThat(imageNameSubstitutor.toUnqualifiedDockerImageName(qualifiedDockerImageName)) + @Test + public void doResolveDockerImageNameForNonSpringManagedDockerImage() { + + DockerImageName cassandraDockerImage = DockerImageName.parse("testcontainers/ryuk:0.4.0"); + + VmwHarborProxyImageNameSubstitutor imageNameSubstitutor = new VmwHarborProxyImageNameSubstitutor(); + + assertThat(imageNameSubstitutor.doResolveDockerImageName(cassandraDockerImage) + .asCanonicalNameString()) + .isEqualTo(String.format(VmwHarborProxyImageNameSubstitutor.TESTCONTAINERS_HUB_IMAGE_NAME_TEMPLATE, + "testcontainers/ryuk:0.4.0")); + } + + @Test + public void toUnqualifiedDockerImageNameFromQualifiedName() { + + DockerImageName qualifiedDockerImageName = DockerImageName.parse(String.format( + VmwHarborProxyImageNameSubstitutor.TESTCONTAINERS_HUB_IMAGE_NAME_TEMPLATE, "testcontainers/ryuk:0.4.0")); + + VmwHarborProxyImageNameSubstitutor imageNameSubstitutor = new VmwHarborProxyImageNameSubstitutor(); + + assertThat(imageNameSubstitutor.toUnqualifiedDockerImageName(qualifiedDockerImageName) + .asCanonicalNameString()) .isEqualTo("testcontainers/ryuk:0.4.0"); } @Test public void toUnqualifiedDockerImageNameFromUnqualifiedName() { + DockerImageName unqualifiedDockerImageName = DockerImageName.parse("testcontainers/ryuk:0.4.0"); + VmwHarborProxyImageNameSubstitutor imageNameSubstitutor = new VmwHarborProxyImageNameSubstitutor(); - assertThat(imageNameSubstitutor.toUnqualifiedDockerImageName("testcontainers/ryuk:0.4.0")) + assertThat(imageNameSubstitutor.toUnqualifiedDockerImageName(unqualifiedDockerImageName) + .asCanonicalNameString()) .isEqualTo("testcontainers/ryuk:0.4.0"); } }