diff --git a/messaging/infinispan-grpc-kafka/src/test/java/io/quarkus/ts/messaging/infinispan/grpc/kafka/InfinispanKafkaSaslIT.java b/messaging/infinispan-grpc-kafka/src/test/java/io/quarkus/ts/messaging/infinispan/grpc/kafka/InfinispanKafkaSaslIT.java index a564e9987..1dc99b225 100644 --- a/messaging/infinispan-grpc-kafka/src/test/java/io/quarkus/ts/messaging/infinispan/grpc/kafka/InfinispanKafkaSaslIT.java +++ b/messaging/infinispan-grpc-kafka/src/test/java/io/quarkus/ts/messaging/infinispan/grpc/kafka/InfinispanKafkaSaslIT.java @@ -22,17 +22,13 @@ // TODO https://github.com/quarkusio/quarkus/issues/25136 @Tag("fips-incompatible") public class InfinispanKafkaSaslIT { - /** - * We can't rename this file to use the default SSL settings part of KafkaService. - */ - private static final String BOOK_TITLE = "testBook"; - @Container(image = "${infinispan.image}", expectedLog = "${infinispan.expected-log}", port = 11222, command = "-c /infinispan-config.xml") + @Container(image = "${infinispan.image}", expectedLog = "${infinispan.expected-log}", port = 11222, command = "-c /infinispan-config.xml", builder = LocalHostInfinispanManagedResourceBuilder.class) static final InfinispanService infinispan = new InfinispanService() .withConfigFile("infinispan-config.xml") .withSecretFiles("keystore.jks"); - @KafkaContainer(vendor = KafkaVendor.STRIMZI, protocol = KafkaProtocol.SASL) + @KafkaContainer(vendor = KafkaVendor.STRIMZI, protocol = KafkaProtocol.SASL, builder = LocalHostKafkaContainerManagedResourceBuilder.class) static final KafkaService kafkasasl = new KafkaService(); @QuarkusApplication diff --git a/messaging/infinispan-grpc-kafka/src/test/java/io/quarkus/ts/messaging/infinispan/grpc/kafka/LocalHostInfinispanManagedResourceBuilder.java b/messaging/infinispan-grpc-kafka/src/test/java/io/quarkus/ts/messaging/infinispan/grpc/kafka/LocalHostInfinispanManagedResourceBuilder.java new file mode 100644 index 000000000..f3f9bb68b --- /dev/null +++ b/messaging/infinispan-grpc-kafka/src/test/java/io/quarkus/ts/messaging/infinispan/grpc/kafka/LocalHostInfinispanManagedResourceBuilder.java @@ -0,0 +1,14 @@ +package io.quarkus.ts.messaging.infinispan.grpc.kafka; + +import static io.quarkus.ts.messaging.infinispan.grpc.kafka.LocalHostManagedResourceUtil.wrapWithLocalhostManagedResource; + +import io.quarkus.test.bootstrap.ManagedResource; +import io.quarkus.test.bootstrap.ServiceContext; +import io.quarkus.test.services.containers.ContainerManagedResourceBuilder; + +public class LocalHostInfinispanManagedResourceBuilder extends ContainerManagedResourceBuilder { + @Override + public ManagedResource build(ServiceContext context) { + return wrapWithLocalhostManagedResource(super.build(context)); + } +} diff --git a/messaging/infinispan-grpc-kafka/src/test/java/io/quarkus/ts/messaging/infinispan/grpc/kafka/LocalHostKafkaContainerManagedResourceBuilder.java b/messaging/infinispan-grpc-kafka/src/test/java/io/quarkus/ts/messaging/infinispan/grpc/kafka/LocalHostKafkaContainerManagedResourceBuilder.java new file mode 100644 index 000000000..205a997b1 --- /dev/null +++ b/messaging/infinispan-grpc-kafka/src/test/java/io/quarkus/ts/messaging/infinispan/grpc/kafka/LocalHostKafkaContainerManagedResourceBuilder.java @@ -0,0 +1,14 @@ +package io.quarkus.ts.messaging.infinispan.grpc.kafka; + +import static io.quarkus.ts.messaging.infinispan.grpc.kafka.LocalHostManagedResourceUtil.wrapWithLocalhostManagedResource; + +import io.quarkus.test.bootstrap.ManagedResource; +import io.quarkus.test.bootstrap.ServiceContext; +import io.quarkus.test.services.containers.KafkaContainerManagedResourceBuilder; + +public class LocalHostKafkaContainerManagedResourceBuilder extends KafkaContainerManagedResourceBuilder { + @Override + public ManagedResource build(ServiceContext context) { + return wrapWithLocalhostManagedResource(super.build(context)); + } +} diff --git a/messaging/infinispan-grpc-kafka/src/test/java/io/quarkus/ts/messaging/infinispan/grpc/kafka/LocalHostManagedResourceUtil.java b/messaging/infinispan-grpc-kafka/src/test/java/io/quarkus/ts/messaging/infinispan/grpc/kafka/LocalHostManagedResourceUtil.java new file mode 100644 index 000000000..205395fe3 --- /dev/null +++ b/messaging/infinispan-grpc-kafka/src/test/java/io/quarkus/ts/messaging/infinispan/grpc/kafka/LocalHostManagedResourceUtil.java @@ -0,0 +1,117 @@ +package io.quarkus.ts.messaging.infinispan.grpc.kafka; + +import java.io.IOException; +import java.util.List; + +import org.junit.jupiter.api.condition.OS; + +import io.quarkus.test.bootstrap.ManagedResource; +import io.quarkus.test.bootstrap.Protocol; +import io.quarkus.test.services.URILike; +import io.quarkus.test.utils.Command; + +class LocalHostManagedResourceUtil { + + /** + * Our Linux bare-metal instances use Docker on localhost. + */ + private static final boolean forwardPort = OS.current() == OS.WINDOWS; + + /** + * Forward Docker ports from localhost to Docker host on Windows. This works around issue when + * certificates are only generated for localhost. + */ + static ManagedResource wrapWithLocalhostManagedResource(ManagedResource delegate) { + return new ManagedResource() { + + @Override + public String getDisplayName() { + return delegate.getDisplayName(); + } + + @Override + public void stop() { + if (forwardPort) { + try { + // stop port proxy + new Command("netsh", "interface", "portproxy", "delete", "v4tov4", + "listenport=" + getExposedPort(), "listenaddress=127.0.0.1").runAndWait(); + } catch (IOException | InterruptedException e) { + throw new RuntimeException( + "Failed delete port proxy for Infinispan container port " + getExposedPort(), e); + } + } + delegate.stop(); + } + + @Override + public void start() { + delegate.start(); + if (forwardPort) { + try { + // forward localhost:somePort to dockerIp:somePort + new Command("netsh", "interface", "portproxy", "add", "v4tov4", "listenport=" + getExposedPort(), + "listenaddress=127.0.0.1", "connectport=" + getExposedPort(), + "connectaddress=" + getDockerHost()).runAndWait(); + } catch (IOException | InterruptedException e) { + throw new RuntimeException( + "Failed to setup forwarding for Infinispan container port " + getExposedPort(), e); + } + } + } + + @Override + public URILike getURI(Protocol protocol) { + var uriLike = delegate.getURI(protocol); + if (forwardPort) { + // replace Docker IP with local host + uriLike = new URILike(uriLike.getScheme(), "localhost", uriLike.getPort(), uriLike.getPath()); + } + return uriLike; + } + + private String getDockerHost() { + return delegate.getURI(Protocol.NONE).getHost(); + } + + private int getExposedPort() { + return delegate.getURI(Protocol.NONE).getPort(); + } + + @Override + public boolean isRunning() { + return delegate.isRunning(); + } + + @Override + public boolean isFailed() { + return delegate.isFailed(); + } + + @Override + public List logs() { + return delegate.logs(); + } + + @Override + public void restart() { + delegate.restart(); + } + + @Override + public void validate() { + delegate.validate(); + } + + @Override + public void afterStart() { + delegate.afterStart(); + } + + @Override + public URILike createURI(String scheme, String host, int port) { + return delegate.createURI(scheme, host, port); + } + }; + } +}