-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
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
Add optional OkHttp transport (instead of Netty) #710
Changes from all commits
455b8b3
8edcf85
a0bde0c
85a84c2
d6a59bf
ebd4920
7727b3c
788543f
0166126
e1021b1
360efb6
b905ecf
ff8a1a2
5fe2dee
086c4db
f64be0f
da52424
7cc4c78
23fdb7f
65aa80f
3a82fac
d9c6db7
32ac15d
40b47c2
6386bd4
d005f08
6ed7479
c5eda4f
8cabd49
9a0e302
c6f962b
5cf871b
d384b16
2e1bc26
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,6 +13,7 @@ | |
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
import org.testcontainers.dockerclient.transport.TestcontainersDockerCmdExecFactory; | ||
import org.testcontainers.dockerclient.transport.okhttp.OkHttpDockerCmdExecFactory; | ||
import org.testcontainers.utility.TestcontainersConfiguration; | ||
|
||
import java.util.ArrayList; | ||
|
@@ -164,10 +165,23 @@ public DockerClient getClient() { | |
} | ||
|
||
protected DockerClient getClientForConfig(DockerClientConfig config) { | ||
return DockerClientBuilder | ||
.getInstance(config) | ||
.withDockerCmdExecFactory(new TestcontainersDockerCmdExecFactory()) | ||
.build(); | ||
DockerClientBuilder clientBuilder = DockerClientBuilder | ||
.getInstance(config); | ||
|
||
String transportType = TestcontainersConfiguration.getInstance().getTransportType(); | ||
if ("okhttp".equals(transportType)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nitpicky, but constants for transport types. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does it really makes sense to use constants for single-use things? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. IMO yes, but that's a question of personal taste 😉 |
||
clientBuilder | ||
.withDockerCmdExecFactory(new OkHttpDockerCmdExecFactory()); | ||
} else if ("netty".equals(transportType)) { | ||
clientBuilder | ||
.withDockerCmdExecFactory(new TestcontainersDockerCmdExecFactory()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. maybe the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We plan to switch to okhttp by default and keep Netty as a fallback for a few releases unless we 100% that okhttp works for everyone. Once it happen, we will delete our Netty factory completely. There is also one in |
||
} else { | ||
throw new IllegalArgumentException("Unknown transport type: " + transportType); | ||
} | ||
|
||
LOGGER.info("Will use '{}' transport", transportType); | ||
|
||
return clientBuilder.build(); | ||
} | ||
|
||
protected void ping(DockerClient client, int timeoutInSeconds) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
package org.testcontainers.dockerclient; | ||
|
||
import com.github.dockerjava.core.DefaultDockerClientConfig; | ||
import com.github.dockerjava.core.DockerClientConfig; | ||
import lombok.RequiredArgsConstructor; | ||
import lombok.experimental.Delegate; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.apache.commons.lang.SystemUtils; | ||
import org.jetbrains.annotations.NotNull; | ||
|
||
import java.net.URI; | ||
|
||
@Slf4j | ||
public class NpipeSocketClientProviderStrategy extends DockerClientProviderStrategy { | ||
|
||
protected static final String DOCKER_SOCK_PATH = "//./pipe/docker_engine"; | ||
private static final String SOCKET_LOCATION = "npipe://" + DOCKER_SOCK_PATH; | ||
|
||
private static final String PING_TIMEOUT_DEFAULT = "10"; | ||
private static final String PING_TIMEOUT_PROPERTY_NAME = "testcontainers.npipesocketprovider.timeout"; | ||
|
||
public static final int PRIORITY = EnvironmentAndSystemPropertyClientProviderStrategy.PRIORITY - 20; | ||
|
||
@Override | ||
protected boolean isApplicable() { | ||
return SystemUtils.IS_OS_WINDOWS; | ||
} | ||
|
||
@Override | ||
public void test() throws InvalidConfigurationException { | ||
try { | ||
config = tryConfiguration(); | ||
log.info("Accessing docker with {}", getDescription()); | ||
} catch (Exception | UnsatisfiedLinkError e) { | ||
throw new InvalidConfigurationException("ping failed", e); | ||
} | ||
} | ||
|
||
@NotNull | ||
private DockerClientConfig tryConfiguration() { | ||
URI dockerHost = URI.create(SOCKET_LOCATION); | ||
|
||
config = new DelegatingDockerClientConfig( | ||
DefaultDockerClientConfig.createDefaultConfigBuilder() | ||
.withDockerHost("tcp://localhost:0") | ||
.withDockerTlsVerify(false) | ||
.build() | ||
) { | ||
@Override | ||
public URI getDockerHost() { | ||
return dockerHost; | ||
} | ||
}; | ||
client = getClientForConfig(config); | ||
|
||
final int timeout = Integer.parseInt(System.getProperty(PING_TIMEOUT_PROPERTY_NAME, PING_TIMEOUT_DEFAULT)); | ||
ping(client, timeout); | ||
|
||
return config; | ||
} | ||
|
||
@Override | ||
public String getDescription() { | ||
return "local Npipe socket (" + SOCKET_LOCATION + ")"; | ||
} | ||
|
||
@Override | ||
protected int getPriority() { | ||
return PRIORITY; | ||
} | ||
|
||
@RequiredArgsConstructor | ||
private static class DelegatingDockerClientConfig implements DockerClientConfig { | ||
|
||
@Delegate | ||
final DockerClientConfig dockerClientConfig; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
package org.testcontainers.dockerclient.transport.okhttp; | ||
|
||
import lombok.SneakyThrows; | ||
import lombok.Value; | ||
import org.scalasbt.ipcsocket.Win32NamedPipeSocket; | ||
|
||
import javax.net.SocketFactory; | ||
import java.io.FilterInputStream; | ||
import java.io.FilterOutputStream; | ||
import java.io.IOException; | ||
import java.io.InputStream; | ||
import java.io.OutputStream; | ||
import java.net.InetAddress; | ||
import java.net.Socket; | ||
import java.net.SocketAddress; | ||
|
||
@Value | ||
public class NamedPipeSocketFactory extends SocketFactory { | ||
|
||
String socketPath; | ||
|
||
@Override | ||
@SneakyThrows | ||
public Socket createSocket() { | ||
return new Win32NamedPipeSocket(socketPath.replace("/", "\\")) { | ||
|
||
@Override | ||
public void connect(SocketAddress endpoint, int timeout) throws IOException { | ||
// Do nothing since it's not "connectable" | ||
} | ||
|
||
@Override | ||
public InputStream getInputStream() { | ||
return new FilterInputStream(super.getInputStream()) { | ||
@Override | ||
public void close() throws IOException { | ||
shutdownInput(); | ||
} | ||
}; | ||
} | ||
|
||
@Override | ||
public OutputStream getOutputStream() { | ||
return new FilterOutputStream(super.getOutputStream()) { | ||
|
||
@Override | ||
public void write(byte[] b, int off, int len) throws IOException { | ||
out.write(b, off, len); | ||
} | ||
|
||
@Override | ||
public void close() throws IOException { | ||
shutdownOutput(); | ||
} | ||
}; | ||
} | ||
}; | ||
} | ||
|
||
@Override | ||
public Socket createSocket(String s, int i) { | ||
throw new UnsupportedOperationException(); | ||
} | ||
|
||
@Override | ||
public Socket createSocket(String s, int i, InetAddress inetAddress, int i1) { | ||
throw new UnsupportedOperationException(); | ||
} | ||
|
||
@Override | ||
public Socket createSocket(InetAddress inetAddress, int i) { | ||
throw new UnsupportedOperationException(); | ||
} | ||
|
||
@Override | ||
public Socket createSocket(InetAddress inetAddress, int i, InetAddress inetAddress1, int i1) { | ||
throw new UnsupportedOperationException(); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
docker-java
shades it without the relocation o_O we're not using it anyways