Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

QUARKUS-1490: Use BuildItem to enable use of TestContainers shared network #21863

Merged
merged 1 commit into from
Dec 3, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,41 @@

import io.quarkus.builder.BuildChainBuilder;
import io.quarkus.builder.BuildStepBuilder;
import io.quarkus.builder.item.SimpleBuildItem;
import io.quarkus.builder.item.BuildItem;
import io.quarkus.builder.item.MultiBuildItem;
import io.quarkus.deployment.pkg.builditem.ProcessInheritIODisabled;

/**
* A marker build item that if present during the build, then the containers started by DevServices
* will use a shared network.
* A marker build item that, if any instances are provided during the build, the containers started by DevServices
* will use a shared network and be accessible across the Docker network. The default is that containers started by
* DevServices will only be accessible from the Docker host.
* This is mainly useful in integration tests where the application container needs to be able
* to communicate with the services containers
*/
public final class DevServicesSharedNetworkBuildItem extends SimpleBuildItem {
public final class DevServicesSharedNetworkBuildItem extends MultiBuildItem {
gastaldi marked this conversation as resolved.
Show resolved Hide resolved

private boolean exposeOnDockerHost;

/**
* Construct the {@link BuildItem} exposing services only on the shared network.
*/
public DevServicesSharedNetworkBuildItem() {
this(false);
}

/**
* Construct the {@link BuildItem} exposing services on both the shared network and Docker host.
* This is mainly used by {@see DevServicesKafkaProcessor}.
*
* @param exposeOnDockerHost
*/
public DevServicesSharedNetworkBuildItem(boolean exposeOnDockerHost) {
this.exposeOnDockerHost = exposeOnDockerHost;
}

public boolean isExposedOnDockerHost() {
return exposeOnDockerHost;
}

/**
* Generates a {@link List<Consumer<BuildChainBuilder>> build chain builder} which creates a build step
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
package io.quarkus.apicurio.registry.avro;

import java.time.Duration;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

import org.eclipse.microprofile.config.Config;
import org.eclipse.microprofile.config.ConfigProvider;
import org.jboss.logging.Logger;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.Network;
import org.testcontainers.utility.Base58;
import org.testcontainers.utility.DockerImageName;

import io.quarkus.deployment.IsDockerWorking;
Expand All @@ -25,6 +23,7 @@
import io.quarkus.deployment.console.StartupLogCompressor;
import io.quarkus.deployment.dev.devservices.GlobalDevServicesConfig;
import io.quarkus.deployment.logging.LoggingSetupBuildItem;
import io.quarkus.devservices.common.ConfigureUtil;
import io.quarkus.devservices.common.ContainerLocator;
import io.quarkus.runtime.LaunchMode;
import io.quarkus.runtime.configuration.ConfigUtils;
Expand Down Expand Up @@ -60,7 +59,7 @@ public class DevServicesApicurioRegistryProcessor {
@BuildStep(onlyIfNot = IsNormal.class, onlyIf = GlobalDevServicesConfig.Enabled.class)
public void startApicurioRegistryDevService(LaunchModeBuildItem launchMode,
ApicurioRegistryDevServicesBuildTimeConfig apicurioRegistryDevServices,
Optional<DevServicesSharedNetworkBuildItem> devServicesSharedNetworkBuildItem,
List<DevServicesSharedNetworkBuildItem> devServicesSharedNetworkBuildItem,
BuildProducer<DevServicesConfigResultBuildItem> devServicesConfiguration,
Optional<ConsoleInstalledBuildItem> consoleInstalledBuildItem,
CuratedApplicationShutdownBuildItem closeBuildItem,
Expand All @@ -82,7 +81,7 @@ public void startApicurioRegistryDevService(LaunchModeBuildItem launchMode,
consoleInstalledBuildItem, loggingSetupBuildItem);
try {
apicurioRegistry = startApicurioRegistry(configuration, launchMode,
devServicesSharedNetworkBuildItem.isPresent(), devServicesConfig.timeout);
!devServicesSharedNetworkBuildItem.isEmpty(), devServicesConfig.timeout);
if (apicurioRegistry == null) {
compressor.close();
return;
Expand Down Expand Up @@ -254,23 +253,17 @@ public int hashCode() {
}

private static final class ApicurioRegistryContainer extends GenericContainer<ApicurioRegistryContainer> {
private final int port;
private final int fixedExposedPort;
private final boolean useSharedNetwork;

private String hostName = null;

private ApicurioRegistryContainer(DockerImageName dockerImageName, int fixedExposedPort, String serviceName,
boolean useSharedNetwork) {
super(dockerImageName);
this.port = fixedExposedPort;
this.fixedExposedPort = fixedExposedPort;
this.useSharedNetwork = useSharedNetwork;
withNetwork(Network.SHARED);
Copy link
Contributor

@geoand geoand Dec 7, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coming back to this after encountering a different problem: Why was this call removed? Do you remember?
It seems wrong to me...
Same thing for the other dev services where the same change was made.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was made consistent with the other DevServices and enabled here if useSharedNetwork is enabled.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apicurio was always on the shared network; even if useSharedNetwork was false... perhaps it needed to be that way, perhaps it did not.. but there was nothing to suggest either way.. so yes use of useSharedNetwork was made "consistent" across all DevServices..... like I said yesterday, looking Quarkus is both fun and dangerous!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But that part doesn't call withNetwork or setNetworkAliases unless I am mistaken. Am I missing something?

Copy link
Contributor

@geoand geoand Dec 7, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah sorry, my bad - I see where the call was moved to.

False alarm :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it's a "nice" method call isn't it... took me a while before I stepped into it too!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍🏼

if (useSharedNetwork) {
hostName = "kafka-" + Base58.randomString(5);
setNetworkAliases(Collections.singletonList(hostName));
} else {
withExposedPorts(APICURIO_REGISTRY_PORT);
}

if (serviceName != null) { // Only adds the label in dev mode.
withLabel(DEV_SERVICE_LABEL, serviceName);
}
Expand All @@ -283,8 +276,16 @@ private ApicurioRegistryContainer(DockerImageName dockerImageName, int fixedExpo
@Override
protected void configure() {
super.configure();
if (port > 0 && !useSharedNetwork) {
addFixedExposedPort(port, APICURIO_REGISTRY_PORT);

if (useSharedNetwork) {
hostName = ConfigureUtil.configureSharedNetwork(this, "kafka");
return;
}

if (fixedExposedPort > 0) {
addFixedExposedPort(fixedExposedPort, APICURIO_REGISTRY_PORT);
} else {
addExposedPorts(APICURIO_REGISTRY_PORT);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@ public interface DevServicesDatasourceProvider {
RunningDevServicesDatasource startDatabase(Optional<String> username, Optional<String> password,
Optional<String> datasourceName,
Optional<String> imageName, Map<String, String> additionalProperties,
OptionalInt port, LaunchMode launchMode, Optional<Duration> startupTimeout,
boolean useTestContainersSharedNetwork);
OptionalInt port, LaunchMode launchMode, Optional<Duration> startupTimeout);

default boolean isDockerRequired() {
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -267,8 +267,7 @@ private DevServicesDatasourceResultBuildItem.DbResult startDevDb(String dbName,
ConfigProvider.getConfig().getOptionalValue(prefix + "password", String.class),
Optional.ofNullable(dbName), dataSourceBuildTimeConfig.devservices.imageName,
dataSourceBuildTimeConfig.devservices.properties,
dataSourceBuildTimeConfig.devservices.port, launchMode, globalDevServicesConfig.timeout,
dataSourceBuildTimeConfig.devservices.useTestContainersSharedNetwork);
dataSourceBuildTimeConfig.devservices.port, launchMode, globalDevServicesConfig.timeout);
closeableList.add(datasource.getCloseTask());

propertiesMap.put(prefix + "db-kind", dataSourceBuildTimeConfig.dbKind.orElse(null));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,4 @@ public class DevServicesBuildTimeConfig {
@ConfigItem
public OptionalInt port;

/**
* Whether this particular data source's container should join TestContainers Shared Network.
* <p>
* By default, the data source container will join Docker's default network.
*/
@ConfigItem(defaultValue = "false")
public boolean useTestContainersSharedNetwork;

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
import java.io.Closeable;
import java.io.IOException;
import java.time.Duration;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.OptionalInt;

import org.jboss.logging.Logger;
import org.testcontainers.containers.Db2Container;
import org.testcontainers.containers.Network;
import org.testcontainers.utility.DockerImageName;

import io.quarkus.datasource.common.runtime.DatabaseKind;
Expand All @@ -31,15 +31,14 @@ public class DB2DevServicesProcessor {

@BuildStep
DevServicesDatasourceProviderBuildItem setupDB2(
Optional<DevServicesSharedNetworkBuildItem> devServicesSharedNetworkBuildItem) {
List<DevServicesSharedNetworkBuildItem> devServicesSharedNetworkBuildItem) {
return new DevServicesDatasourceProviderBuildItem(DatabaseKind.DB2, new DevServicesDatasourceProvider() {
@Override
public RunningDevServicesDatasource startDatabase(Optional<String> username, Optional<String> password,
Optional<String> datasourceName, Optional<String> imageName, Map<String, String> additionalProperties,
OptionalInt fixedExposedPort, LaunchMode launchMode, Optional<Duration> startupTimeout,
boolean useTestContainersSharedNetwork) {
OptionalInt fixedExposedPort, LaunchMode launchMode, Optional<Duration> startupTimeout) {
QuarkusDb2Container container = new QuarkusDb2Container(imageName, fixedExposedPort,
devServicesSharedNetworkBuildItem.isPresent(), useTestContainersSharedNetwork);
!devServicesSharedNetworkBuildItem.isEmpty());
startupTimeout.ifPresent(container::withStartupTimeout);
container.withPassword(password.orElse("quarkus"))
.withUsername(username.orElse("quarkus"))
Expand Down Expand Up @@ -69,15 +68,11 @@ private static class QuarkusDb2Container extends Db2Container {

private String hostName = null;

public QuarkusDb2Container(Optional<String> imageName, OptionalInt fixedExposedPort, boolean useSharedNetwork,
boolean useTestContainersSharedNetwork) {
public QuarkusDb2Container(Optional<String> imageName, OptionalInt fixedExposedPort, boolean useSharedNetwork) {
super(DockerImageName.parse(imageName.orElse("ibmcom/db2:" + DB2DevServicesProcessor.TAG))
.asCompatibleSubstituteFor(DockerImageName.parse("ibmcom/db2")));
this.fixedExposedPort = fixedExposedPort;
this.useSharedNetwork = useSharedNetwork;
if (useTestContainersSharedNetwork) {
withNetwork(Network.SHARED);
}
}

@Override
Expand All @@ -91,6 +86,8 @@ protected void configure() {

if (fixedExposedPort.isPresent()) {
addFixedExposedPort(fixedExposedPort.getAsInt(), DB2_PORT);
} else {
addExposedPorts(DB2_PORT);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@ DevServicesDatasourceProviderBuildItem setupDerby() {
@Override
public RunningDevServicesDatasource startDatabase(Optional<String> username, Optional<String> password,
Optional<String> datasourceName, Optional<String> imageName, Map<String, String> additionalProperties,
OptionalInt fixedExposedPort, LaunchMode launchMode, Optional<Duration> startupTimeout,
boolean useTestContainersSharedNetwork) {
OptionalInt fixedExposedPort, LaunchMode launchMode, Optional<Duration> startupTimeout) {
try {
int port = fixedExposedPort.isPresent() ? fixedExposedPort.getAsInt()
: 1527 + (launchMode == LaunchMode.TEST ? 0 : 1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,7 @@ DevServicesDatasourceProviderBuildItem setupH2() {
@Override
public RunningDevServicesDatasource startDatabase(Optional<String> username, Optional<String> password,
Optional<String> datasourceName, Optional<String> imageName, Map<String, String> additionalProperties,
OptionalInt port, LaunchMode launchMode, Optional<Duration> startupTimeout,
boolean useTestContainersSharedNetwork) {
OptionalInt port, LaunchMode launchMode, Optional<Duration> startupTimeout) {
try {
final Server tcpServer = Server.createTcpServer("-tcpPort",
port.isPresent() ? String.valueOf(port.getAsInt()) : "0");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
import java.io.Closeable;
import java.io.IOException;
import java.time.Duration;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.OptionalInt;

import org.jboss.logging.Logger;
import org.testcontainers.containers.MariaDBContainer;
import org.testcontainers.containers.Network;
import org.testcontainers.utility.DockerImageName;

import io.quarkus.datasource.common.runtime.DatabaseKind;
Expand All @@ -29,15 +29,14 @@ public class MariaDBDevServicesProcessor {

@BuildStep
DevServicesDatasourceProviderBuildItem setupMariaDB(
Optional<DevServicesSharedNetworkBuildItem> devServicesSharedNetworkBuildItem) {
List<DevServicesSharedNetworkBuildItem> devServicesSharedNetworkBuildItem) {
return new DevServicesDatasourceProviderBuildItem(DatabaseKind.MARIADB, new DevServicesDatasourceProvider() {
@Override
public RunningDevServicesDatasource startDatabase(Optional<String> username, Optional<String> password,
Optional<String> datasourceName, Optional<String> imageName, Map<String, String> additionalProperties,
OptionalInt fixedExposedPort, LaunchMode launchMode, Optional<Duration> startupTimeout,
boolean useTestContainersSharedNetwork) {
OptionalInt fixedExposedPort, LaunchMode launchMode, Optional<Duration> startupTimeout) {
QuarkusMariaDBContainer container = new QuarkusMariaDBContainer(imageName, fixedExposedPort,
devServicesSharedNetworkBuildItem.isPresent(), useTestContainersSharedNetwork);
!devServicesSharedNetworkBuildItem.isEmpty());
startupTimeout.ifPresent(container::withStartupTimeout);
container.withPassword(password.orElse("quarkus"))
.withUsername(username.orElse("quarkus"))
Expand Down Expand Up @@ -67,15 +66,11 @@ private static class QuarkusMariaDBContainer extends MariaDBContainer {

private String hostName = null;

public QuarkusMariaDBContainer(Optional<String> imageName, OptionalInt fixedExposedPort, boolean useSharedNetwork,
boolean useTestContainersSharedNetwork) {
public QuarkusMariaDBContainer(Optional<String> imageName, OptionalInt fixedExposedPort, boolean useSharedNetwork) {
super(DockerImageName.parse(imageName.orElse(MariaDBContainer.IMAGE + ":" + MariaDBDevServicesProcessor.TAG))
.asCompatibleSubstituteFor(DockerImageName.parse(MariaDBContainer.IMAGE)));
this.fixedExposedPort = fixedExposedPort;
this.useSharedNetwork = useSharedNetwork;
if (useTestContainersSharedNetwork) {
withNetwork(Network.SHARED);
}
}

@Override
Expand All @@ -89,6 +84,8 @@ protected void configure() {

if (fixedExposedPort.isPresent()) {
addFixedExposedPort(fixedExposedPort.getAsInt(), PORT);
} else {
addExposedPort(PORT);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
import java.io.Closeable;
import java.io.IOException;
import java.time.Duration;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.OptionalInt;

import org.jboss.logging.Logger;
import org.testcontainers.containers.MSSQLServerContainer;
import org.testcontainers.containers.Network;
import org.testcontainers.utility.DockerImageName;

import io.quarkus.datasource.common.runtime.DatabaseKind;
Expand All @@ -31,15 +31,14 @@ public class MSSQLDevServicesProcessor {

@BuildStep
DevServicesDatasourceProviderBuildItem setupMSSQL(
Optional<DevServicesSharedNetworkBuildItem> devServicesSharedNetworkBuildItem) {
List<DevServicesSharedNetworkBuildItem> devServicesSharedNetworkBuildItem) {
return new DevServicesDatasourceProviderBuildItem(DatabaseKind.MSSQL, new DevServicesDatasourceProvider() {
@Override
public RunningDevServicesDatasource startDatabase(Optional<String> username, Optional<String> password,
Optional<String> datasourceName, Optional<String> imageName, Map<String, String> additionalProperties,
OptionalInt fixedExposedPort, LaunchMode launchMode, Optional<Duration> startupTimeout,
boolean useTestContainersSharedNetwork) {
OptionalInt fixedExposedPort, LaunchMode launchMode, Optional<Duration> startupTimeout) {
QuarkusMSSQLServerContainer container = new QuarkusMSSQLServerContainer(imageName, fixedExposedPort,
devServicesSharedNetworkBuildItem.isPresent(), useTestContainersSharedNetwork);
!devServicesSharedNetworkBuildItem.isEmpty());
startupTimeout.ifPresent(container::withStartupTimeout);
container.withPassword(password.orElse("Quarkuspassword1"));
additionalProperties.forEach(container::withUrlParam);
Expand Down Expand Up @@ -67,16 +66,12 @@ private static class QuarkusMSSQLServerContainer extends MSSQLServerContainer {

private String hostName = null;

public QuarkusMSSQLServerContainer(Optional<String> imageName, OptionalInt fixedExposedPort, boolean useSharedNetwork,
boolean useTestContainersSharedNetwork) {
public QuarkusMSSQLServerContainer(Optional<String> imageName, OptionalInt fixedExposedPort, boolean useSharedNetwork) {
super(DockerImageName
.parse(imageName.orElse(MSSQLServerContainer.IMAGE + ":" + MSSQLDevServicesProcessor.TAG))
.asCompatibleSubstituteFor(MSSQLServerContainer.IMAGE));
this.fixedExposedPort = fixedExposedPort;
this.useSharedNetwork = useSharedNetwork;
if (useTestContainersSharedNetwork) {
withNetwork(Network.SHARED);
}
}

@Override
Expand All @@ -90,6 +85,8 @@ protected void configure() {

if (fixedExposedPort.isPresent()) {
addFixedExposedPort(fixedExposedPort.getAsInt(), MSSQLServerContainer.MS_SQL_SERVER_PORT);
} else {
addExposedPort(MS_SQL_SERVER_PORT);
}
}

Expand Down