Fix bug in VmwHarborProxyImageNameSubstitutor when resolving Spring-managed Docker Images in VMware Harbor Proxy.

This commit is contained in:
John Blum
2023-05-13 13:47:35 -07:00
parent 441d3a4bcf
commit 0412d9fe8c
2 changed files with 91 additions and 39 deletions

View File

@@ -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 <a href="https://www.testcontainers.org/features/image_name_substitution/">Image name substitution</a>
* @see <a href="https://github.com/testcontainers/testcontainers-java/issues/4605">Image Name Substitution not applied for DockerComposeContainers</a>
* @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<String, String> 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

View File

@@ -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");
}
}