Support Testcontainer Redis with custom image names

Update `RedisContainerConnectionDetailsFactory` so that it can also
support `RedisContainer` with a custom name.

Closes gh-41450
This commit is contained in:
Phillip Webb
2024-08-29 19:23:21 -07:00
parent e7faca3bbb
commit fa686bb593
5 changed files with 138 additions and 9 deletions

View File

@@ -104,12 +104,10 @@ public abstract class ContainerConnectionDetailsFactory<C extends Container<?>,
}
try {
Class<?>[] generics = resolveGenerics();
Class<?> containerType = generics[0];
Class<?> connectionDetailsType = generics[1];
for (String connectionName : this.connectionNames) {
if (source.accepts(connectionName, containerType, connectionDetailsType)) {
return getContainerConnectionDetails(source);
}
Class<?> requiredContainerType = generics[0];
Class<?> requiredConnectionDetailsType = generics[1];
if (sourceAccepts(source, requiredContainerType, requiredConnectionDetailsType)) {
return getContainerConnectionDetails(source);
}
}
catch (NoClassDefFoundError ex) {
@@ -118,6 +116,25 @@ public abstract class ContainerConnectionDetailsFactory<C extends Container<?>,
return null;
}
/**
* Return if the give source accepts the connection. By default this method checks
* each connection name.
* @param source the container connection source
* @param requiredContainerType the required container type
* @param requiredConnectionDetailsType the required connection details type
* @return if the source accepts the connection
* @since 3.4.0
*/
protected boolean sourceAccepts(ContainerConnectionSource<C> source, Class<?> requiredContainerType,
Class<?> requiredConnectionDetailsType) {
for (String requiredConnectionName : this.connectionNames) {
if (source.accepts(requiredConnectionName, requiredContainerType, requiredConnectionDetailsType)) {
return true;
}
}
return false;
}
private boolean hasRequiredClasses() {
return ObjectUtils.isEmpty(this.requiredClassNames) || Arrays.stream(this.requiredClassNames)
.allMatch((requiredClassName) -> ClassUtils.isPresent(requiredClassName, null));

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 the original author or authors.
* Copyright 2012-2024 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.
@@ -90,7 +90,15 @@ public final class ContainerConnectionSource<C extends Container<?>> implements
return null;
}
boolean accepts(String requiredConnectionName, Class<?> requiredContainerType,
/**
* Return is this source accepts the given connection.
* @param requiredConnectionName the required connection name or {@code null}
* @param requiredContainerType the required container type
* @param requiredConnectionDetailsType the required connection details type
* @return if the connection is accepted by this source
* @since 3.4.0
*/
public boolean accepts(String requiredConnectionName, Class<?> requiredContainerType,
Class<?> requiredConnectionDetailsType) {
if (StringUtils.hasText(requiredConnectionName)
&& !requiredConnectionName.equalsIgnoreCase(this.connectionName)) {

View File

@@ -18,6 +18,7 @@ package org.springframework.boot.testcontainers.service.connection.redis;
import java.util.List;
import com.redis.testcontainers.RedisContainer;
import org.testcontainers.containers.Container;
import org.testcontainers.containers.GenericContainer;
@@ -49,7 +50,14 @@ class RedisContainerConnectionDetailsFactory
}
@Override
public RedisConnectionDetails getContainerConnectionDetails(ContainerConnectionSource<Container<?>> source) {
protected boolean sourceAccepts(ContainerConnectionSource<Container<?>> source, Class<?> requiredContainerType,
Class<?> requiredConnectionDetailsType) {
return super.sourceAccepts(source, requiredContainerType, requiredConnectionDetailsType)
|| source.accepts(ANY_CONNECTION_NAME, RedisContainer.class, requiredConnectionDetailsType);
}
@Override
protected RedisConnectionDetails getContainerConnectionDetails(ContainerConnectionSource<Container<?>> source) {
return new RedisContainerConnectionDetails(source);
}