From 6a5e6a74392c003f0eae651b6083bd4e764a9261 Mon Sep 17 00:00:00 2001 From: Maximilian Zellhofer Date: Wed, 4 Mar 2026 12:23:31 +0100 Subject: [PATCH] get rid of docker link --- .../containers/ComposeDelegate.java | 9 +- .../testcontainers/containers/Container.java | 25 +----- .../containers/ContainerState.java | 7 ++ .../containers/FutureContainer.java | 13 --- .../containers/GenericContainer.java | 84 ------------------- .../containers/traits/LinkableContainer.java | 11 --- .../containers/JdbcDatabaseContainer.java | 5 +- .../containers/NginxContainer.java | 5 +- .../containers/BrowserWebDriverContainer.java | 19 +---- 9 files changed, 14 insertions(+), 164 deletions(-) delete mode 100644 core/src/main/java/org/testcontainers/containers/FutureContainer.java delete mode 100644 core/src/main/java/org/testcontainers/containers/traits/LinkableContainer.java diff --git a/core/src/main/java/org/testcontainers/containers/ComposeDelegate.java b/core/src/main/java/org/testcontainers/containers/ComposeDelegate.java index 3365a0b0681..0dc1b448527 100644 --- a/core/src/main/java/org/testcontainers/containers/ComposeDelegate.java +++ b/core/src/main/java/org/testcontainers/containers/ComposeDelegate.java @@ -282,8 +282,8 @@ public void withExposedService(String serviceName, int servicePort, @NonNull Wai /* * For every service/port pair that needs to be exposed, we register a target on an 'ambassador container'. * - * The ambassador container's role is to link (within the Docker network) to one of the - * compose services, and proxy TCP network I/O out to a port that the ambassador container + * The ambassador container's role is to be on the same Docker network as the compose + * services, and proxy TCP network I/O out to a port that the ambassador container * exposes. * * This avoids the need for the docker compose file to explicitly expose ports on all the @@ -299,10 +299,7 @@ public void withExposedService(String serviceName, int servicePort, @NonNull Wai .computeIfAbsent(serviceInstanceName, __ -> new ConcurrentHashMap<>()) .put(servicePort, ambassadorPort); ambassadorContainer.withTarget(ambassadorPort, serviceInstanceName, servicePort); - ambassadorContainer.addLink( - new FutureContainer(this.project + this.composeSeparator + serviceInstanceName), - serviceInstanceName - ); + ambassadorContainer.withNetworkMode(this.project + "_default"); addWaitStrategy(serviceInstanceName, waitStrategy); } diff --git a/core/src/main/java/org/testcontainers/containers/Container.java b/core/src/main/java/org/testcontainers/containers/Container.java index abea7fef576..1f3d39ee9ca 100644 --- a/core/src/main/java/org/testcontainers/containers/Container.java +++ b/core/src/main/java/org/testcontainers/containers/Container.java @@ -7,7 +7,6 @@ import lombok.Value; import org.testcontainers.containers.output.OutputFrame; import org.testcontainers.containers.startupcheck.StartupCheckStrategy; -import org.testcontainers.containers.traits.LinkableContainer; import org.testcontainers.containers.wait.strategy.WaitStrategy; import org.testcontainers.images.ImagePullPolicy; import org.testcontainers.images.builder.Transferable; @@ -22,7 +21,7 @@ import java.util.function.Consumer; import java.util.function.Function; -public interface Container> extends LinkableContainer, ContainerState { +public interface Container> extends ContainerState { /** * @return a reference to this container instance, cast to the expected generic type. */ @@ -97,16 +96,6 @@ default void addFileSystemBind(final String hostPath, final String containerPath @Deprecated void addFileSystemBind(String hostPath, String containerPath, BindMode mode, SelinuxContext selinuxContext); - /** - * Add a link to another container. - * - * @param otherContainer the other container object to link to - * @param alias the alias (for the other container) that this container should be able to use - * @deprecated Links are deprecated (see #465). Please use {@link Network} features instead. - */ - @Deprecated - void addLink(LinkableContainer otherContainer, String alias); - /** * Add an exposed port. Consider using {@link #withExposedPorts(Integer...)} * for building a container in a fluent style. @@ -453,12 +442,6 @@ default void followOutput(Consumer consumer, OutputFrame.OutputType List getBinds(); - /** - * @deprecated Links are deprecated (see #465). Please use {@link Network} features instead. - */ - @Deprecated - Map getLinkedContainers(); - void setExposedPorts(List exposedPorts); void setPortBindings(List portBindings); @@ -473,11 +456,5 @@ default void followOutput(Consumer consumer, OutputFrame.OutputType void setBinds(List binds); - /** - * @deprecated Links are deprecated (see #465). Please use {@link Network} features instead. - */ - @Deprecated - void setLinkedContainers(Map linkedContainers); - void setWaitStrategy(WaitStrategy waitStrategy); } diff --git a/core/src/main/java/org/testcontainers/containers/ContainerState.java b/core/src/main/java/org/testcontainers/containers/ContainerState.java index e19f7a85310..f28b195ae2d 100644 --- a/core/src/main/java/org/testcontainers/containers/ContainerState.java +++ b/core/src/main/java/org/testcontainers/containers/ContainerState.java @@ -233,6 +233,13 @@ default String getContainerId() { return getContainerInfo().getId(); } + /** + * @return the name of the container + */ + default String getContainerName() { + return getContainerInfo().getName(); + } + /** * Returns the container inspect response. The response might be cached/outdated. * diff --git a/core/src/main/java/org/testcontainers/containers/FutureContainer.java b/core/src/main/java/org/testcontainers/containers/FutureContainer.java deleted file mode 100644 index 28cfbfff6c9..00000000000 --- a/core/src/main/java/org/testcontainers/containers/FutureContainer.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.testcontainers.containers; - -import lombok.Data; -import org.testcontainers.containers.traits.LinkableContainer; - -/** - * A container that may not have been launched yet. - */ -@Data -public class FutureContainer implements LinkableContainer { - - private final String containerName; -} diff --git a/core/src/main/java/org/testcontainers/containers/GenericContainer.java b/core/src/main/java/org/testcontainers/containers/GenericContainer.java index 0fe944433ae..89081969883 100644 --- a/core/src/main/java/org/testcontainers/containers/GenericContainer.java +++ b/core/src/main/java/org/testcontainers/containers/GenericContainer.java @@ -11,7 +11,6 @@ import com.github.dockerjava.api.model.ContainerNetwork; import com.github.dockerjava.api.model.ExposedPort; import com.github.dockerjava.api.model.HostConfig; -import com.github.dockerjava.api.model.Link; import com.github.dockerjava.api.model.PortBinding; import com.github.dockerjava.api.model.Ports; import com.github.dockerjava.api.model.Volume; @@ -40,7 +39,6 @@ import org.testcontainers.containers.startupcheck.IsRunningStartupCheckStrategy; import org.testcontainers.containers.startupcheck.MinimumDurationRunningStartupCheckStrategy; import org.testcontainers.containers.startupcheck.StartupCheckStrategy; -import org.testcontainers.containers.traits.LinkableContainer; import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.containers.wait.strategy.WaitStrategy; import org.testcontainers.containers.wait.strategy.WaitStrategyTarget; @@ -72,7 +70,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; -import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashMap; @@ -124,13 +121,6 @@ public class GenericContainer> @NonNull private List volumesFroms = new ArrayList<>(); - /** - * @deprecated Links are deprecated (see #465). Please use {@link Network} features instead. - */ - @NonNull - @Deprecated - private Map linkedContainers = new HashMap<>(); - private StartupCheckStrategy startupCheckStrategy = new IsRunningStartupCheckStrategy(); private int startupAttempts = 1; @@ -781,45 +771,6 @@ private void applyConfiguration(CreateContainerCmd createCommand) { VolumesFrom[] volumesFromsArray = volumesFroms.stream().toArray(VolumesFrom[]::new); createCommand.withVolumesFrom(volumesFromsArray); - Set allLinks = new HashSet<>(); - Set allLinkedContainerNetworks = new HashSet<>(); - for (Entry linkEntries : linkedContainers.entrySet()) { - String alias = linkEntries.getKey(); - LinkableContainer linkableContainer = linkEntries.getValue(); - - Set links = findLinksFromThisContainer(alias, linkableContainer); - allLinks.addAll(links); - - if (allLinks.size() == 0) { - throw new ContainerLaunchException( - "Aborting attempt to link to container " + - linkableContainer.getContainerName() + - " as it is not running" - ); - } - - Set linkedContainerNetworks = findAllNetworksForLinkedContainers(linkableContainer); - allLinkedContainerNetworks.addAll(linkedContainerNetworks); - } - - createCommand.withLinks(allLinks.toArray(new Link[allLinks.size()])); - - allLinkedContainerNetworks.remove("bridge"); - if (allLinkedContainerNetworks.size() > 1) { - logger() - .warn( - "Container needs to be on more than one custom network to link to other " + - "containers - this is not currently supported. Required networks are: {}", - allLinkedContainerNetworks - ); - } - - Optional networkForLinks = allLinkedContainerNetworks.stream().findFirst(); - if (networkForLinks.isPresent()) { - logger().debug("Associating container with network: {}", networkForLinks.get()); - createCommand.withNetworkMode(networkForLinks.get()); - } - if (hostAccessible) { PortForwardingContainer.INSTANCE.start(); } @@ -841,32 +792,6 @@ private void applyConfiguration(CreateContainerCmd createCommand) { } } - private Set findLinksFromThisContainer(String alias, LinkableContainer linkableContainer) { - return dockerClient - .listContainersCmd() - .withStatusFilter(Arrays.asList("running")) - .exec() - .stream() - .flatMap(container -> Stream.of(container.getNames())) - .filter(name -> name.endsWith(linkableContainer.getContainerName())) - .map(name -> new Link(name, alias)) - .collect(Collectors.toSet()); - } - - private Set findAllNetworksForLinkedContainers(LinkableContainer linkableContainer) { - return dockerClient - .listContainersCmd() - .exec() - .stream() - .filter(container -> container.getNames()[0].endsWith(linkableContainer.getContainerName())) - .filter(container -> { - return container.getNetworkSettings() != null && container.getNetworkSettings().getNetworks() != null; - }) - .flatMap(container -> container.getNetworkSettings().getNetworks().keySet().stream()) - .distinct() - .collect(Collectors.toSet()); - } - /** * {@inheritDoc} */ @@ -1029,15 +954,6 @@ private void addVolumesFrom(Container container, BindMode mode) { volumesFroms.add(new VolumesFrom(container.getContainerName(), mode.accessMode)); } - /** - * @deprecated Links are deprecated (see #465). Please use {@link Network} features instead. - */ - @Deprecated - @Override - public void addLink(LinkableContainer otherContainer, String alias) { - this.linkedContainers.put(alias, otherContainer); - } - @Override public void addExposedPort(Integer port) { this.containerDef.addExposedTcpPort(port); diff --git a/core/src/main/java/org/testcontainers/containers/traits/LinkableContainer.java b/core/src/main/java/org/testcontainers/containers/traits/LinkableContainer.java deleted file mode 100644 index 4973c4dc9c1..00000000000 --- a/core/src/main/java/org/testcontainers/containers/traits/LinkableContainer.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.testcontainers.containers.traits; - -/** - * A container which can be linked to by other containers. - * - * @deprecated Links are deprecated (see #465). Please use {@link org.testcontainers.containers.Network} features instead. - */ -@Deprecated -public interface LinkableContainer { - String getContainerName(); -} diff --git a/modules/jdbc/src/main/java/org/testcontainers/containers/JdbcDatabaseContainer.java b/modules/jdbc/src/main/java/org/testcontainers/containers/JdbcDatabaseContainer.java index cf6c995528f..ef536e55d02 100644 --- a/modules/jdbc/src/main/java/org/testcontainers/containers/JdbcDatabaseContainer.java +++ b/modules/jdbc/src/main/java/org/testcontainers/containers/JdbcDatabaseContainer.java @@ -6,7 +6,6 @@ import org.apache.commons.lang3.StringUtils; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.testcontainers.containers.traits.LinkableContainer; import org.testcontainers.delegate.DatabaseDelegate; import org.testcontainers.ext.ScriptUtils; import org.testcontainers.jdbc.JdbcDatabaseDelegate; @@ -31,9 +30,7 @@ /** * Base class for containers that expose a JDBC connection */ -public abstract class JdbcDatabaseContainer> - extends GenericContainer - implements LinkableContainer { +public abstract class JdbcDatabaseContainer> extends GenericContainer { private static final Object DRIVER_LOAD_MUTEX = new Object(); diff --git a/modules/nginx/src/main/java/org/testcontainers/containers/NginxContainer.java b/modules/nginx/src/main/java/org/testcontainers/containers/NginxContainer.java index c66149d2417..6f8048ce78a 100644 --- a/modules/nginx/src/main/java/org/testcontainers/containers/NginxContainer.java +++ b/modules/nginx/src/main/java/org/testcontainers/containers/NginxContainer.java @@ -1,7 +1,6 @@ package org.testcontainers.containers; import org.jetbrains.annotations.NotNull; -import org.testcontainers.containers.traits.LinkableContainer; import org.testcontainers.utility.DockerImageName; import java.net.MalformedURLException; @@ -12,9 +11,7 @@ * @deprecated use {@link org.testcontainers.nginx.NginxContainer} instead. */ @Deprecated -public class NginxContainer> - extends GenericContainer - implements LinkableContainer { +public class NginxContainer> extends GenericContainer { private static final int NGINX_DEFAULT_PORT = 80; diff --git a/modules/selenium/src/main/java/org/testcontainers/containers/BrowserWebDriverContainer.java b/modules/selenium/src/main/java/org/testcontainers/containers/BrowserWebDriverContainer.java index 53ee8ba5577..871ecabb2b2 100644 --- a/modules/selenium/src/main/java/org/testcontainers/containers/BrowserWebDriverContainer.java +++ b/modules/selenium/src/main/java/org/testcontainers/containers/BrowserWebDriverContainer.java @@ -18,7 +18,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.testcontainers.containers.VncRecordingContainer.VncRecordingFormat; -import org.testcontainers.containers.traits.LinkableContainer; import org.testcontainers.containers.wait.strategy.HostPortWaitStrategy; import org.testcontainers.containers.wait.strategy.LogMessageWaitStrategy; import org.testcontainers.containers.wait.strategy.WaitAllStrategy; @@ -52,7 +51,7 @@ @Deprecated public class BrowserWebDriverContainer> extends GenericContainer - implements LinkableContainer, TestLifecycleAware { + implements TestLifecycleAware { private static final DockerImageName CHROME_IMAGE = DockerImageName.parse("selenium/standalone-chrome"); @@ -400,22 +399,6 @@ private void retainRecordingIfNeeded(String prefix, boolean succeeded) { } } - /** - * Remember any other containers this needs to link to. We have to pass these down to the container so that - * the other containers will be initialized before linking occurs. - * - * @param otherContainer the container rule to link to - * @param alias the alias (hostname) that this other container should be referred to by - * @return this - * - * @deprecated Links are deprecated (see #465). Please use {@link Network} features instead. - */ - @Deprecated - public SELF withLinkToContainer(LinkableContainer otherContainer, String alias) { - addLink(otherContainer, alias); - return self(); - } - public SELF withRecordingMode(VncRecordingMode recordingMode, File vncRecordingDirectory) { return withRecordingMode(recordingMode, vncRecordingDirectory, null); }