From cd93223e06ac059cc34ed35a29cf83ccf4412187 Mon Sep 17 00:00:00 2001 From: Dimitris Mandalidis <dimitris.mandalidis@gmail.com> Date: Mon, 28 Oct 2019 23:05:03 +0200 Subject: [PATCH] Drop guava (fixes #74) - Remove workaround for JERSEY-2878 --- CHANGELOG.md | 1 + pom.xml | 3 +- .../docker/client/AnsiProgressHandler.java | 9 +- .../docker/client/CompressedDirectory.java | 29 ++-- .../docker/client/DefaultDockerClient.java | 154 ++++++++---------- .../docker/client/DefaultLogStream.java | 17 +- .../docker/client/DockerCertificates.java | 18 +- .../mandas/docker/client/DockerClient.java | 10 +- .../docker/client/DockerConfigReader.java | 15 +- .../docker/client/DockerCredentialHelper.java | 7 +- .../org/mandas/docker/client/DockerHost.java | 39 ++--- .../org/mandas/docker/client/EventStream.java | 5 - .../org/mandas/docker/client/ImageRef.java | 12 +- .../org/mandas/docker/client/LogMessage.java | 8 +- .../org/mandas/docker/client/LogReader.java | 37 +++-- .../docker/client/ObjectMapperProvider.java | 15 +- .../mandas/docker/client/ProgressStream.java | 20 +-- .../SystemCredentialHelperDelegate.java | 6 +- .../auth/MultiRegistryAuthSupplier.java | 15 +- .../gcr/ContainerRegistryAuthSupplier.java | 34 ++-- .../docker/client/messages/HostConfig.java | 16 +- .../client/messages/RegistryConfigs.java | 32 ++-- .../client/DefaultDockerClientTest.java | 77 +++++---- .../client/DefaultDockerClientUnitTest.java | 115 ++++++------- .../docker/client/DockerCertificatesTest.java | 3 +- .../mandas/docker/client/ImageRefTest.java | 1 - .../ConfigFileRegistryAuthSupplierTest.java | 13 +- .../auth/MultiRegistryAuthSupplierTest.java | 42 ++--- .../docker/client/messages/EventTest.java | 14 +- .../docker/client/messages/IpamTest.java | 10 +- .../client/messages/swarm/DriverTest.java | 16 +- .../java/org/mandas/docker/it/PushPullIT.java | 43 ++--- 32 files changed, 415 insertions(+), 421 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7e1c891e8..52dad9b53 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ * `RegistryConfigs.Builder#addConfig` does not ignore null `RegistryAuth` values anymore * `HostConfig.Builder#appendBinds*` methods removed * `HostConfig.Builder#binds(final Bind... binds)` method does not ignore null binds anymore +* `Immutable*` types removed from public getters and builders ## 2.0.2 diff --git a/pom.xml b/pom.xml index ec323b5ab..69f89ddc6 100644 --- a/pom.xml +++ b/pom.xml @@ -237,7 +237,7 @@ <configuration> <includeTestSourceDirectory>true</includeTestSourceDirectory> <violationSeverity>warning</violationSeverity> - <excludes>**\/AutoValue_*.java</excludes> + <excludes>**\/Immutable*.java</excludes> </configuration> </plugin> <plugin> @@ -415,7 +415,6 @@ <configuration> <excludes> <exclude>org/mandas/**/Immutable*</exclude> - <exclude>org/mandas/**/AutoValue*</exclude> </excludes> </configuration> <executions> diff --git a/src/main/java/org/mandas/docker/client/AnsiProgressHandler.java b/src/main/java/org/mandas/docker/client/AnsiProgressHandler.java index c8034a0d7..cac621085 100644 --- a/src/main/java/org/mandas/docker/client/AnsiProgressHandler.java +++ b/src/main/java/org/mandas/docker/client/AnsiProgressHandler.java @@ -20,14 +20,13 @@ package org.mandas.docker.client; -import com.google.common.collect.Maps; +import java.io.PrintStream; +import java.util.HashMap; +import java.util.Map; import org.mandas.docker.client.exceptions.DockerException; import org.mandas.docker.client.messages.ProgressMessage; -import java.io.PrintStream; -import java.util.Map; - /** * Parses ProgressMessage objects and writes the output to a PrintStream. The output includes ANSI * escape characters to move the cursor around to nicely print progress bars. @@ -46,7 +45,7 @@ public AnsiProgressHandler() { public AnsiProgressHandler(PrintStream out) { this.out = out; - idsToLines = Maps.newHashMap(); + idsToLines = new HashMap<>(); } @Override diff --git a/src/main/java/org/mandas/docker/client/CompressedDirectory.java b/src/main/java/org/mandas/docker/client/CompressedDirectory.java index ad2d5a99e..636ade240 100644 --- a/src/main/java/org/mandas/docker/client/CompressedDirectory.java +++ b/src/main/java/org/mandas/docker/client/CompressedDirectory.java @@ -20,13 +20,11 @@ package org.mandas.docker.client; -import static com.google.common.base.Strings.isNullOrEmpty; +import static java.util.Collections.reverse; +import static java.util.Collections.unmodifiableList; import static org.apache.commons.compress.archivers.tar.TarArchiveOutputStream.BIGNUMBER_POSIX; import static org.apache.commons.compress.archivers.tar.TarArchiveOutputStream.LONGFILE_POSIX; -import com.google.common.annotations.VisibleForTesting; -import com.google.common.collect.ImmutableList; - import java.io.Closeable; import java.io.IOException; import java.io.OutputStream; @@ -44,7 +42,9 @@ import java.nio.file.attribute.PosixFileAttributes; import java.nio.file.attribute.PosixFilePermission; import java.text.MessageFormat; +import java.util.ArrayList; import java.util.EnumSet; +import java.util.List; import java.util.Set; import java.util.regex.Pattern; @@ -104,8 +104,7 @@ public static CompressedDirectory create(final Path directory) throws IOExceptio final Path file = Files.createTempFile("docker-client-", ".tar.gz"); final Path dockerIgnorePath = directory.resolve(".dockerignore"); - final ImmutableList<DockerIgnorePathMatcher> ignoreMatchers = - parseDockerIgnore(dockerIgnorePath); + final List<DockerIgnorePathMatcher> ignoreMatchers = parseDockerIgnore(dockerIgnorePath); try (final OutputStream fileOut = Files.newOutputStream(file); final GzipCompressorOutputStream gzipOut = new GzipCompressorOutputStream(fileOut); @@ -137,14 +136,14 @@ public void close() throws IOException { Files.delete(file); } - static ImmutableList<DockerIgnorePathMatcher> parseDockerIgnore(Path dockerIgnorePath) + static List<DockerIgnorePathMatcher> parseDockerIgnore(Path dockerIgnorePath) throws IOException { - final ImmutableList.Builder<DockerIgnorePathMatcher> matchersBuilder = ImmutableList.builder(); + final List<DockerIgnorePathMatcher> matchersBuilder = new ArrayList<>(); if (Files.isReadable(dockerIgnorePath) && Files.isRegularFile(dockerIgnorePath)) { for (final String line : Files.readAllLines(dockerIgnorePath, StandardCharsets.UTF_8)) { final String pattern = createPattern(line); - if (isNullOrEmpty(pattern)) { + if (pattern == null || "".equals(pattern.trim())) { log.debug("Will skip '{}' - because it's empty after trimming or it's a comment", line); continue; } @@ -158,7 +157,7 @@ static ImmutableList<DockerIgnorePathMatcher> parseDockerIgnore(Path dockerIgnor } } - return matchersBuilder.build(); + return unmodifiableList(matchersBuilder); } private static String createPattern(String line) { @@ -172,7 +171,6 @@ private static String createPattern(String line) { return pattern.replace("/", "\\\\"); } - @VisibleForTesting static PathMatcher goPathMatcher(FileSystem fs, String pattern) { // Supposed to work the same way as Go's path.filepath.match.Match: // http://golang.org/src/path/filepath/match.go#L34 @@ -253,15 +251,16 @@ private static String getNotSeparatorPattern(String separator) { private static class Visitor extends SimpleFileVisitor<Path> { private final Path root; - private final ImmutableList<DockerIgnorePathMatcher> ignoreMatchers; + private final List<DockerIgnorePathMatcher> ignoreMatchers; private final TarArchiveOutputStream tarStream; - private Visitor(final Path root, ImmutableList<DockerIgnorePathMatcher> ignoreMatchers, + private Visitor(final Path root, List<DockerIgnorePathMatcher> ignoreMatchers, final TarArchiveOutputStream tarStream) { this.root = root; // .dockerignore matchers need to be read from the bottom of the file, // so the given list should be reversed before using it. - this.ignoreMatchers = ignoreMatchers.reverse(); + this.ignoreMatchers = new ArrayList<>(ignoreMatchers); + reverse(this.ignoreMatchers); this.tarStream = tarStream; } @@ -312,7 +311,7 @@ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IO * @param path the path to match * @return <code>true</code> if the given path should be excluded, <code>false</code> otherwise */ - private static boolean exclude(ImmutableList<DockerIgnorePathMatcher> matchers, Path path) { + private static boolean exclude(List<DockerIgnorePathMatcher> matchers, Path path) { for (final DockerIgnorePathMatcher matcher : matchers) { if (matcher.matches(path)) { return matcher.isExclude(); diff --git a/src/main/java/org/mandas/docker/client/DefaultDockerClient.java b/src/main/java/org/mandas/docker/client/DefaultDockerClient.java index 7aeaf6a74..bae105950 100644 --- a/src/main/java/org/mandas/docker/client/DefaultDockerClient.java +++ b/src/main/java/org/mandas/docker/client/DefaultDockerClient.java @@ -23,14 +23,11 @@ package org.mandas.docker.client; -import static com.google.common.base.Optional.fromNullable; -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Strings.isNullOrEmpty; -import static com.google.common.collect.Maps.newHashMap; -import static org.mandas.docker.client.ObjectMapperProvider.objectMapper; -import static org.mandas.docker.client.VersionCompare.compareVersion; import static java.nio.charset.StandardCharsets.UTF_8; +import static java.util.Arrays.asList; +import static java.util.Collections.unmodifiableSet; +import static java.util.Objects.requireNonNull; +import static java.util.Optional.ofNullable; import static java.util.concurrent.TimeUnit.SECONDS; import static javax.ws.rs.HttpMethod.DELETE; import static javax.ws.rs.HttpMethod.GET; @@ -40,11 +37,15 @@ import static javax.ws.rs.core.MediaType.APPLICATION_OCTET_STREAM; import static javax.ws.rs.core.MediaType.APPLICATION_OCTET_STREAM_TYPE; import static javax.ws.rs.core.MediaType.TEXT_PLAIN_TYPE; +import static org.mandas.docker.client.DockerHost.certPathFromEnv; +import static org.mandas.docker.client.DockerHost.configPathFromEnv; +import static org.mandas.docker.client.DockerHost.defaultCertPath; +import static org.mandas.docker.client.ObjectMapperProvider.objectMapper; +import static org.mandas.docker.client.VersionCompare.compareVersion; import java.io.Closeable; import java.io.IOException; import java.io.InputStream; -import java.io.InputStreamReader; import java.io.InterruptedIOException; import java.io.StringWriter; import java.io.UnsupportedEncodingException; @@ -56,7 +57,6 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; @@ -64,6 +64,8 @@ import java.util.Locale; import java.util.Map; import java.util.Map.Entry; +import java.util.NoSuchElementException; +import java.util.Optional; import java.util.Set; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; @@ -109,21 +111,6 @@ import org.glassfish.jersey.client.ClientProperties; import org.glassfish.jersey.client.RequestEntityProcessing; import org.glassfish.jersey.jackson.JacksonFeature; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.google.common.base.Optional; -import com.google.common.base.Preconditions; -import com.google.common.base.Predicates; -import com.google.common.base.Strings; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Iterables; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.io.CharStreams; -import com.google.common.net.HostAndPort; import org.mandas.docker.client.auth.ConfigFileRegistryAuthSupplier; import org.mandas.docker.client.auth.FixedRegistryAuthSupplier; import org.mandas.docker.client.auth.RegistryAuthSupplier; @@ -196,6 +183,12 @@ import org.mandas.docker.client.messages.swarm.Task; import org.mandas.docker.client.messages.swarm.UnlockKey; import org.mandas.docker.client.npipe.NpipeConnectionSocketFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.google.common.net.HostAndPort; public class DefaultDockerClient implements DockerClient, Closeable { @@ -225,8 +218,9 @@ private CreateProgressHandler(ProgressHandler delegate) { } private String getImageId() { - Preconditions.checkState(imageId != null, - "Could not acquire image ID or digest following create"); + if (imageId == null) { + throw new IllegalStateException("Could not acquire image ID or digest following create"); + } return imageId; } @@ -264,7 +258,7 @@ private LoadProgressHandler(ProgressHandler delegate) { } private Set<String> getImageNames() { - return ImmutableSet.copyOf(imageNames); + return unmodifiableSet(new HashSet<>(imageNames)); } @Override @@ -298,8 +292,9 @@ private BuildProgressHandler(ProgressHandler delegate) { } private String getImageId() { - Preconditions.checkState(imageId != null, - "Could not acquire image ID or digest following build"); + if (imageId == null) { + throw new IllegalStateException("Could not acquire image ID or digest following build"); + } return imageId; } @@ -431,8 +426,9 @@ public DefaultDockerClient(final URI uri, final DockerCertificatesStore dockerCe * @param builder DefaultDockerClient builder */ protected DefaultDockerClient(final Builder builder) { - final URI originalUri = checkNotNull(builder.uri, "uri"); - checkNotNull(originalUri.getScheme(), "url has null scheme"); + requireNonNull(builder.uri, "uri"); + final URI originalUri = builder.uri; + requireNonNull(originalUri.getScheme(), "url has null scheme"); this.apiVersion = builder.apiVersion(); if ((builder.dockerCertificatesStore != null) && !originalUri.getScheme().equals("https")) { @@ -509,7 +505,8 @@ private ClientConfig updateProxy(ClientConfig config, Builder builder) { } } if (!skipProxy) { - String proxyPort = checkNotNull(System.getProperty("http.proxyPort"), "http.proxyPort"); + String proxyPort = System.getProperty("http.proxyPort"); + requireNonNull(proxyPort, "http.proxyPort"); config.property(ClientProperties.PROXY_URI, (!proxyHost.startsWith("http") ? "http://" : "") + proxyHost + ":" + proxyPort); final String proxyUser = System.getProperty("http.proxyUser"); @@ -536,7 +533,7 @@ private String toRegExp(String hostnameWithWildcards) { @Override public String getHost() { - return fromNullable(uri.getHost()).or("localhost"); + return ofNullable(uri.getHost()).orElse("localhost"); } private HttpClientConnectionManager getConnectionManager(Builder builder) { @@ -633,14 +630,14 @@ public List<Container> listContainers(final ListContainersParam... params) private WebTarget addParameters(WebTarget resource, final Param... params) throws DockerException { - final Map<String, List<String>> filters = newHashMap(); + final Map<String, List<String>> filters = new HashMap<>(); for (final Param param : params) { if (param instanceof FilterParam) { List<String> filterValueList; if (filters.containsKey(param.name())) { filterValueList = filters.get(param.name()); } else { - filterValueList = Lists.newArrayList(); + filterValueList = new ArrayList<>(); } filterValueList.add(param.value()); filters.put(param.name(), filterValueList); @@ -660,7 +657,7 @@ private WebTarget addParameters(WebTarget resource, final Param... params) private Map<String, String> getQueryParamMap(final WebTarget resource) { final String queryParams = resource.getUri().getQuery(); - final Map<String, String> paramsMap = Maps.newHashMap(); + final Map<String, String> paramsMap = new HashMap<>(); if (queryParams != null) { for (final String queryParam : queryParams.split("&")) { final String[] kv = queryParam.split("="); @@ -728,8 +725,9 @@ public ContainerCreation createContainer(final ContainerConfig config, final Str .path("containers").path("create"); if (name != null) { - checkArgument(CONTAINER_NAME_PATTERN.matcher(name).matches(), - "Invalid container name: \"%s\"", name); + if (!CONTAINER_NAME_PATTERN.matcher(name).matches()) { + throw new IllegalArgumentException(String.format("Invalid container name: \"%s\"", name)); + } resource = resource.queryParam("name", name); } @@ -753,7 +751,7 @@ public ContainerCreation createContainer(final ContainerConfig config, final Str @Override public void startContainer(final String containerId) throws DockerException, InterruptedException { - checkNotNull(containerId, "containerId"); + requireNonNull(containerId, "containerId"); log.info("Starting container with Id: {}", containerId); @@ -791,14 +789,14 @@ private void containerAction(final String containerId, final String action, @Override public void pauseContainer(final String containerId) throws DockerException, InterruptedException { - checkNotNull(containerId, "containerId"); + requireNonNull(containerId, "containerId"); containerAction(containerId, "pause"); } @Override public void unpauseContainer(final String containerId) throws DockerException, InterruptedException { - checkNotNull(containerId, "containerId"); + requireNonNull(containerId, "containerId"); containerAction(containerId, "unpause"); } @@ -810,8 +808,8 @@ public void restartContainer(String containerId) throws DockerException, Interru @Override public void restartContainer(String containerId, int secondsToWaitBeforeRestart) throws DockerException, InterruptedException { - checkNotNull(containerId, "containerId"); - checkNotNull(secondsToWaitBeforeRestart, "secondsToWait"); + requireNonNull(containerId, "containerId"); + requireNonNull(secondsToWaitBeforeRestart, "secondsToWait"); MultivaluedMap<String, String> queryParameters = new MultivaluedHashMap<>(); queryParameters.add("t", String.valueOf(secondsToWaitBeforeRestart)); @@ -821,14 +819,14 @@ public void restartContainer(String containerId, int secondsToWaitBeforeRestart) @Override public void killContainer(final String containerId) throws DockerException, InterruptedException { - checkNotNull(containerId, "containerId"); + requireNonNull(containerId, "containerId"); containerAction(containerId, "kill"); } @Override public void killContainer(final String containerId, final Signal signal) throws DockerException, InterruptedException { - checkNotNull(containerId, "containerId"); + requireNonNull(containerId, "containerId"); MultivaluedMap<String, String> queryParameters = new MultivaluedHashMap<>(); queryParameters.add("signal", signal.getName()); @@ -839,7 +837,7 @@ public void killContainer(final String containerId, final Signal signal) @Override public Distribution getDistribution(String imageName) throws DockerException, InterruptedException { - checkNotNull(imageName, "containerName"); + requireNonNull(imageName, "containerName"); final WebTarget resource = resource().path("distribution").path(imageName).path("json"); return request(GET, DISTRIBUTION, resource, resource.request(APPLICATION_JSON_TYPE)); } @@ -969,7 +967,7 @@ public TopResults topContainer(final String containerId, final String psArgs) throws DockerException, InterruptedException { try { WebTarget resource = resource().path("containers").path(containerId).path("top"); - if (!Strings.isNullOrEmpty(psArgs)) { + if (psArgs != null && !"".equals(psArgs.trim())) { resource = resource.queryParam("ps_args", psArgs); } return request(GET, TopResults.class, resource, resource.request(APPLICATION_JSON_TYPE)); @@ -1063,22 +1061,22 @@ public ContainerCreation commitContainer(final String containerId, final String author) throws DockerException, InterruptedException { - checkNotNull(containerId, "containerId"); - checkNotNull(repo, "repo"); - checkNotNull(config, "containerConfig"); + requireNonNull(containerId, "containerId"); + requireNonNull(repo, "repo"); + requireNonNull(config, "containerConfig"); WebTarget resource = resource() .path("commit") .queryParam("container", containerId) .queryParam("repo", repo); - if (!isNullOrEmpty(author)) { + if (author != null && !"".equals(author.trim())) { resource = resource.queryParam("author", author); } - if (!isNullOrEmpty(comment)) { + if (comment != null && !"".equals(comment.trim())) { resource = resource.queryParam("comment", comment); } - if (!isNullOrEmpty(tag)) { + if (tag != null && !"".equals(tag.trim())) { resource = resource.queryParam("tag", tag); } @@ -1108,8 +1106,9 @@ public void renameContainer(final String containerId, final String name) throw new IllegalArgumentException("Cannot rename container to null"); } - checkArgument(CONTAINER_NAME_PATTERN.matcher(name).matches(), - "Invalid container name: \"%s\"", name); + if (!CONTAINER_NAME_PATTERN.matcher(name).matches()) { + throw new IllegalArgumentException(String.format("Invalid container name: \"%s\"", name)); + } resource = resource.queryParam("name", name); log.info("Renaming container with id {}. New name {}.", containerId, name); @@ -1221,7 +1220,7 @@ public InputStream save(final String... images) resource = resource().path("images").path("get"); if (images.length > 1) { for (final String image : images) { - if (!isNullOrEmpty(image)) { + if (image != null && !"".equals(image.trim())) { resource = resource.queryParam("names", urlEncode(image)); } } @@ -1410,7 +1409,7 @@ public String build(final Path directory, final String name, final ProgressHandl public String build(final Path directory, final String name, final String dockerfile, final ProgressHandler handler, final BuildParam... params) throws DockerException, InterruptedException, IOException { - checkNotNull(handler, "handler"); + requireNonNull(handler, "handler"); WebTarget resource = noTimeoutResource().path("build"); @@ -1536,7 +1535,7 @@ public EventStream events(EventsParam... params) public LogStream attachContainer(final String containerId, final AttachParameter... params) throws DockerException, InterruptedException { - checkNotNull(containerId, "containerId"); + requireNonNull(containerId, "containerId"); WebTarget resource = noTimeoutResource().path("containers").path(containerId).path("attach"); for (final AttachParameter param : params) { @@ -2371,7 +2370,7 @@ public void resizeTty(final String containerId, final Integer height, final Inte private void checkTtyParams(final Integer height, final Integer width) throws BadParamException { if ((height == null && width == null) || (height != null && height == 0) || (width != null && width == 0)) { - final Map<String, String> paramMap = Maps.newHashMap(); + final Map<String, String> paramMap = new HashMap<>(); paramMap.put("h", height == null ? null : height.toString()); paramMap.put("w", width == null ? null : width.toString()); throw new BadParamException(paramMap, "Either width or height must be non-null and > 0"); @@ -2619,7 +2618,7 @@ public void deleteSecret(final String secretId) throws DockerException, Interrup private WebTarget resource() { final WebTarget target = client.target(uri); - if (!isNullOrEmpty(apiVersion)) { + if (apiVersion != null && !"".equals(apiVersion.trim())) { return target.path(apiVersion); } return target; @@ -2627,7 +2626,7 @@ private WebTarget resource() { private WebTarget noTimeoutResource() { final WebTarget target = noTimeoutClient.target(uri); - if (!isNullOrEmpty(apiVersion)) { + if (apiVersion != null && !"".equals(apiVersion.trim())) { return target.path(apiVersion); } return target; @@ -2737,7 +2736,7 @@ private void requestAndTail(final String method, final ProgressHandler handler, Response response = request(method, Response.class, resource, request); if (response.getStatusInfo().getFamily() != Response.Status.Family.SUCCESSFUL) { throw new DockerRequestException(method, resource.getUri(), response.getStatus(), - message(response), null); + response.readEntity(String.class), null); } tailResponse(method, response, handler, resource); } @@ -2777,7 +2776,7 @@ private RuntimeException propagate(final String method, final WebTarget resource if (response != null) { throw new DockerRequestException(method, resource.getUri(), response.getStatus(), - message(response), cause); + response.readEntity(String.class), cause); } else if ((cause instanceof SocketTimeoutException) || (cause instanceof ConnectTimeoutException)) { throw new DockerTimeoutException(method, resource.getUri(), ex); @@ -2789,21 +2788,6 @@ private RuntimeException propagate(final String method, final WebTarget resource } } - private String message(final Response response) { - final Readable reader; - try { - reader = new InputStreamReader(response.readEntity(InputStream.class), UTF_8); - } catch (IllegalStateException e) { - return null; - } - - try { - return CharStreams.toString(reader); - } catch (IOException ignore) { - return null; - } - } - private String authHeader(final RegistryAuth registryAuth) throws DockerException { // the docker daemon requires that the X-Registry-Auth header is specified // with a non-empty string even if your registry doesn't use authentication @@ -2874,12 +2858,12 @@ public static Builder builder() { */ public static Builder fromEnv() throws DockerCertificateException { final String endpoint = DockerHost.endpointFromEnv(); - final Path dockerCertPath = Paths.get(Iterables.find( - Arrays.asList(DockerHost.certPathFromEnv(), - DockerHost.configPathFromEnv(), - DockerHost.defaultCertPath()), - Predicates.notNull())); - + final Path dockerCertPath = Paths.get(asList(certPathFromEnv(), configPathFromEnv(), defaultCertPath()) + .stream() + .filter(cert -> cert != null) + .findFirst() + .orElseThrow(() -> new NoSuchElementException("Cannot find docker certificated path"))); + final Builder builder = new Builder(); final Optional<DockerCertificatesStore> certs = DockerCertificates.builder() @@ -2896,7 +2880,7 @@ public static Builder fromEnv() throws DockerCertificateException { final String scheme = certs.isPresent() ? "https" : "http"; final int port = hostAndPort.getPortOrDefault(DockerHost.defaultPort()); - final String address = isNullOrEmpty(hostText) ? DockerHost.defaultAddress() : hostText; + final String address = hostText == null || "".equals(hostText.trim()) ? DockerHost.defaultAddress() : hostText; builder.uri(scheme + "://" + address + ":" + port); } diff --git a/src/main/java/org/mandas/docker/client/DefaultLogStream.java b/src/main/java/org/mandas/docker/client/DefaultLogStream.java index 933990806..5a91faa88 100644 --- a/src/main/java/org/mandas/docker/client/DefaultLogStream.java +++ b/src/main/java/org/mandas/docker/client/DefaultLogStream.java @@ -20,18 +20,16 @@ package org.mandas.docker.client; -import static com.google.common.base.Charsets.UTF_8; -import static com.google.common.base.Throwables.throwIfUnchecked; - -import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.Throwables; -import com.google.common.collect.AbstractIterator; -import com.google.common.io.Closer; +import static java.nio.charset.StandardCharsets.UTF_8; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; + +import com.google.common.collect.AbstractIterator; +import com.google.common.io.Closer; class DefaultLogStream extends AbstractIterator<LogMessage> implements LogStream { @@ -41,7 +39,6 @@ private DefaultLogStream(final InputStream stream) { this(new LogReader(stream)); } - @VisibleForTesting DefaultLogStream(final LogReader reader) { this.reader = reader; } @@ -56,7 +53,6 @@ protected LogMessage computeNext() { try { message = reader.nextMessage(); } catch (IOException e) { - throwIfUnchecked(e); throw new RuntimeException(e); } if (message == null) { @@ -70,13 +66,12 @@ public void close() { try { reader.close(); } catch (IOException e) { - throwIfUnchecked(e); throw new RuntimeException(e); } } @Override -public String readFully() { + public String readFully() { final StringBuilder stringBuilder = new StringBuilder(); while (hasNext()) { stringBuilder.append(UTF_8.decode(next().content())); diff --git a/src/main/java/org/mandas/docker/client/DockerCertificates.java b/src/main/java/org/mandas/docker/client/DockerCertificates.java index fc2aa9e55..49a12bf14 100644 --- a/src/main/java/org/mandas/docker/client/DockerCertificates.java +++ b/src/main/java/org/mandas/docker/client/DockerCertificates.java @@ -20,10 +20,8 @@ package org.mandas.docker.client; -import com.google.common.base.Joiner; -import com.google.common.base.Optional; -import com.google.common.collect.ImmutableSet; -import org.mandas.docker.client.exceptions.DockerCertificateException; +import static java.util.Collections.unmodifiableSet; +import static java.util.stream.Collectors.joining; import java.io.BufferedReader; import java.io.IOException; @@ -45,7 +43,10 @@ import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; import java.util.List; +import java.util.Optional; import java.util.Set; import javax.net.ssl.HostnameVerifier; @@ -56,6 +57,7 @@ import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.openssl.PEMKeyPair; import org.bouncycastle.openssl.PEMParser; +import org.mandas.docker.client.exceptions.DockerCertificateException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -70,7 +72,7 @@ public class DockerCertificates implements DockerCertificatesStore { public static final String DEFAULT_CLIENT_KEY_NAME = "key.pem"; private static final char[] KEY_STORE_PASSWORD = "docker!!11!!one!".toCharArray(); - private static final Set<String> PRIVATE_KEY_ALGS = ImmutableSet.of("RSA", "EC"); + private static final Set<String> PRIVATE_KEY_ALGS = unmodifiableSet(new HashSet<>(Arrays.asList("RSA", "EC"))); private static final Logger log = LoggerFactory.getLogger(DockerCertificates.class); private final SSLContext sslContext; @@ -170,7 +172,7 @@ private static PrivateKey tryGeneratePrivateKey(final PKCS8EncodedKeySpec spec, } final String error = String.format("Could not generate private key from spec. Tried using %s", - Joiner.on(", ").join(algorithms)); + algorithms.stream().collect(joining(", "))); throw new InvalidKeySpecException(error); } @@ -250,14 +252,14 @@ public Builder sslFactory(final SslContextFactory sslContextFactory) { public Optional<DockerCertificatesStore> build() throws DockerCertificateException { if (this.caCertPath == null || this.clientKeyPath == null || this.clientCertPath == null) { log.debug("caCertPath, clientKeyPath or clientCertPath not specified, not using SSL"); - return Optional.absent(); + return Optional.empty(); } else if (Files.exists(this.caCertPath) && Files.exists(this.clientKeyPath) && Files.exists(this.clientCertPath)) { return Optional.of((DockerCertificatesStore) new DockerCertificates(this)); } else { log.debug("{}, {} or {} does not exist, not using SSL", this.caCertPath, this.clientKeyPath, this.clientCertPath); - return Optional.absent(); + return Optional.empty(); } } } diff --git a/src/main/java/org/mandas/docker/client/DockerClient.java b/src/main/java/org/mandas/docker/client/DockerClient.java index edd92e0e9..cc23588d2 100644 --- a/src/main/java/org/mandas/docker/client/DockerClient.java +++ b/src/main/java/org/mandas/docker/client/DockerClient.java @@ -21,7 +21,6 @@ package org.mandas.docker.client; -import static com.google.common.base.Strings.isNullOrEmpty; import static org.mandas.docker.client.messages.Network.Type.BUILTIN; import static org.mandas.docker.client.messages.Network.Type.CUSTOM; @@ -38,7 +37,6 @@ import org.mandas.docker.client.exceptions.NotFoundException; import org.mandas.docker.client.exceptions.PermissionException; import org.mandas.docker.client.exceptions.ServiceNotFoundException; -import org.mandas.docker.client.exceptions.UnsupportedApiVersionException; import org.mandas.docker.client.messages.Container; import org.mandas.docker.client.messages.ContainerChange; import org.mandas.docker.client.messages.ContainerConfig; @@ -1806,7 +1804,7 @@ public static ListNetworksParam customNetworks() { * @since Docker 1.12, API version 1.24 */ public static ListNetworksParam withLabel(String label, String value) { - return isNullOrEmpty(value) ? filter("label", label) : filter("label", label + "=" + value); + return value == null || "".equals(value.trim()) ? filter("label", label) : filter("label", label + "=" + value); } /** @@ -2374,7 +2372,7 @@ public static ListContainersParam withStatusExited() { * @return ListContainersParam */ public static ListContainersParam withLabel(final String label, final String value) { - return isNullOrEmpty(value) ? filter("label", label) : filter("label", label + "=" + value); + return value == null || "".equals(value.trim()) ? filter("label", label) : filter("label", label + "=" + value); } /** @@ -2482,7 +2480,7 @@ public static ListImagesParam danglingImages(final boolean dangling) { * @return ListImagesParam */ public static ListImagesParam withLabel(final String label, final String value) { - return isNullOrEmpty(value) ? filter("label", label) : filter("label", label + "=" + value); + return value == null || "".equals(value.trim()) ? filter("label", label) : filter("label", label + "=" + value); } /** @@ -2639,7 +2637,7 @@ public static EventsParam type(final Event.Type type) { * @since API 1.21 */ public static EventsParam label(final String label, final String value) { - return isNullOrEmpty(value) ? filter("label", label) : filter("label", label + "=" + value); + return value == null || "".equals(value.trim()) ? filter("label", label) : filter("label", label + "=" + value); } /** diff --git a/src/main/java/org/mandas/docker/client/DockerConfigReader.java b/src/main/java/org/mandas/docker/client/DockerConfigReader.java index de84fd2e2..1286dc34c 100644 --- a/src/main/java/org/mandas/docker/client/DockerConfigReader.java +++ b/src/main/java/org/mandas/docker/client/DockerConfigReader.java @@ -20,7 +20,7 @@ package org.mandas.docker.client; -import static com.google.common.base.Preconditions.checkNotNull; +import static java.util.Objects.requireNonNull; import java.io.IOException; import java.net.URI; @@ -32,6 +32,7 @@ import java.util.Collection; import java.util.HashSet; import java.util.Map; +import java.util.Objects; import java.util.Set; import org.mandas.docker.client.messages.DockerCredentialHelperAuth; @@ -41,7 +42,6 @@ import org.slf4j.LoggerFactory; import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.common.annotations.VisibleForTesting; public class DockerConfigReader { private static final Logger LOG = LoggerFactory.getLogger(DockerConfigReader.class); @@ -70,7 +70,6 @@ public RegistryAuth anyRegistryAuth() throws IOException { * @param configPath Path to the docker config file. * @return Some registry auth value. */ - @VisibleForTesting RegistryAuth anyRegistryAuth(final Path configPath) throws IOException { final Collection<RegistryAuth> registryAuths = authForAllRegistries(configPath).configs().values(); @@ -87,7 +86,7 @@ RegistryAuth anyRegistryAuth(final Path configPath) throws IOException { * @throws IOException If the file cannot be read, or its JSON cannot be parsed */ public RegistryConfigs authForAllRegistries(final Path configPath) throws IOException { - checkNotNull(configPath); + requireNonNull(configPath); final DockerConfig config = MAPPER.readValue(configPath.toFile(), DockerConfig.class); if (config == null) { @@ -177,8 +176,8 @@ public RegistryConfigs authForAllRegistries(final Path configPath) throws IOExce */ public RegistryAuth authForRegistry(final Path configPath, final String registry) throws IOException { - checkNotNull(configPath); - checkNotNull(registry); + requireNonNull(configPath); + requireNonNull(registry); final DockerConfig config = MAPPER.readValue(configPath.toFile(), DockerConfig.class); if (config == null) { @@ -265,8 +264,8 @@ private RegistryAuth authWithCredentialHelper(final String credsStore, } private String getCredentialStore(final DockerConfig config, final String registry) { - checkNotNull(config, "Docker config cannot be null"); - checkNotNull(registry, "registry cannot be null"); + requireNonNull(config, "Docker config cannot be null"); + requireNonNull(registry, "registry cannot be null"); // Check for the registry in the credHelpers map first. // If it isn't there, default to credsStore. diff --git a/src/main/java/org/mandas/docker/client/DockerCredentialHelper.java b/src/main/java/org/mandas/docker/client/DockerCredentialHelper.java index 7caf396e5..89850106c 100644 --- a/src/main/java/org/mandas/docker/client/DockerCredentialHelper.java +++ b/src/main/java/org/mandas/docker/client/DockerCredentialHelper.java @@ -20,11 +20,11 @@ package org.mandas.docker.client; -import com.google.common.annotations.VisibleForTesting; -import org.mandas.docker.client.messages.DockerCredentialHelperAuth; import java.io.IOException; import java.util.Map; +import org.mandas.docker.client.messages.DockerCredentialHelperAuth; + /** * This class interacts with a docker credential helper. * See https://github.com/docker/docker-credential-helpers. @@ -53,7 +53,6 @@ public class DockerCredentialHelper { /** * An interface to be mocked during testing. */ - @VisibleForTesting interface CredentialHelperDelegate { int store(String credsStore, DockerCredentialHelperAuth auth) @@ -69,12 +68,10 @@ int store(String credsStore, DockerCredentialHelperAuth auth) private static CredentialHelperDelegate credentialHelperDelegate = new SystemCredentialHelperDelegate(); - @VisibleForTesting static void setCredentialHelperDelegate(final CredentialHelperDelegate delegate) { credentialHelperDelegate = delegate; } - @VisibleForTesting static void restoreSystemCredentialHelperDelegate() { credentialHelperDelegate = new SystemCredentialHelperDelegate(); } diff --git a/src/main/java/org/mandas/docker/client/DockerHost.java b/src/main/java/org/mandas/docker/client/DockerHost.java index d02c33135..14e49d0b3 100644 --- a/src/main/java/org/mandas/docker/client/DockerHost.java +++ b/src/main/java/org/mandas/docker/client/DockerHost.java @@ -20,17 +20,12 @@ package org.mandas.docker.client; -import static com.google.common.base.MoreObjects.firstNonNull; -import static com.google.common.base.Strings.isNullOrEmpty; - -import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.MoreObjects; -import com.google.common.net.HostAndPort; - import java.net.URI; import java.nio.file.Paths; import java.util.Locale; +import com.google.common.net.HostAndPort; + /** * Represents a dockerd endpoint. A codified DOCKER_HOST. */ @@ -39,7 +34,6 @@ public class DockerHost { /** * An interface to be mocked during testing. */ - @VisibleForTesting interface SystemDelegate { String getProperty(String key); @@ -83,10 +77,10 @@ private DockerHost(final String endpoint, final String certPath) { final String stripped = endpoint.replaceAll(".*://", ""); final HostAndPort hostAndPort = HostAndPort.fromString(stripped); final String hostText = hostAndPort.getHost(); - final String scheme = isNullOrEmpty(certPath) ? "http" : "https"; + final String scheme = certPath == null || "".equals(certPath.trim()) ? "http" : "https"; this.port = hostAndPort.getPortOrDefault(defaultPort()); - this.address = isNullOrEmpty(hostText) ? DEFAULT_ADDRESS : hostText; + this.address = hostText == null || "".equals(hostText.trim()) ? DEFAULT_ADDRESS : hostText; this.host = address + ":" + port; this.uri = URI.create(scheme + "://" + address + ":" + port); this.bindUri = URI.create("tcp://" + address + ":" + port); @@ -151,12 +145,10 @@ public String dockerCertPath() { return certPath; } - @VisibleForTesting static void setSystemDelegate(final SystemDelegate delegate) { systemDelegate = delegate; } - @VisibleForTesting static void restoreSystemDelegate() { systemDelegate = defaultSystemDelegate; } @@ -197,7 +189,12 @@ static String defaultDockerEndpoint() { } static String endpointFromEnv() { - return firstNonNull(systemDelegate.getenv("DOCKER_HOST"), defaultDockerEndpoint()); + String endPointFromEnv = systemDelegate.getenv("DOCKER_HOST"); + if (endPointFromEnv != null) { + return endPointFromEnv; + } + + return defaultDockerEndpoint(); } public static String defaultUnixEndpoint() { @@ -243,14 +240,14 @@ static String configPathFromEnv() { @Override public String toString() { - return MoreObjects.toStringHelper(this) - .add("host", host) - .add("uri", uri) - .add("bindUri", bindUri) - .add("address", address) - .add("port", port) - .add("certPath", certPath) - .toString(); + return "DockerHost{" + + "host=" + host + + ",uri=" + uri + + ",bindUri=" + bindUri + + ",address=" + address + + ",port=" + port + + ",certPath=" + certPath == null? "null": certPath + + "}"; } @Override diff --git a/src/main/java/org/mandas/docker/client/EventStream.java b/src/main/java/org/mandas/docker/client/EventStream.java index c1471a4cd..0b43e5bba 100644 --- a/src/main/java/org/mandas/docker/client/EventStream.java +++ b/src/main/java/org/mandas/docker/client/EventStream.java @@ -21,12 +21,9 @@ package org.mandas.docker.client; import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.common.base.Throwables; import com.google.common.collect.AbstractIterator; import org.mandas.docker.client.messages.Event; -import static com.google.common.base.Throwables.throwIfUnchecked; - import java.io.Closeable; import java.io.IOException; @@ -46,7 +43,6 @@ protected Event computeNext() { try { event = reader.nextMessage(); } catch (IOException e) { - throwIfUnchecked(e); throw new RuntimeException(e); } if (event == null) { @@ -60,7 +56,6 @@ public void close() { try { reader.close(); } catch (IOException e) { - throwIfUnchecked(e); throw new RuntimeException(e); } } diff --git a/src/main/java/org/mandas/docker/client/ImageRef.java b/src/main/java/org/mandas/docker/client/ImageRef.java index c6d827393..110dec4ea 100644 --- a/src/main/java/org/mandas/docker/client/ImageRef.java +++ b/src/main/java/org/mandas/docker/client/ImageRef.java @@ -20,7 +20,6 @@ package org.mandas.docker.client; -import com.google.common.annotations.VisibleForTesting; import com.google.common.base.MoreObjects; public class ImageRef { @@ -87,15 +86,14 @@ public String getRegistryUrl() { @Override public String toString() { - return MoreObjects.toStringHelper(this) - .add("registry", registry) - .add("image", image) - .add("tag", tag) - .toString(); + return "ImageRef{" + + "registry=" + registry != null? registry: null + + ",image=" + image != null? image: null + + ",tag=" + tag != null? tag: null + + "}"; } /** Return registry server address given first part of image. */ - @VisibleForTesting static String parseRegistryUrl(final String url) { if (url.equals("docker.io") || url.equals("index.docker.io")) { return DEFAULT_REGISTRY_URL; diff --git a/src/main/java/org/mandas/docker/client/LogMessage.java b/src/main/java/org/mandas/docker/client/LogMessage.java index 713cd60e6..d82e72324 100644 --- a/src/main/java/org/mandas/docker/client/LogMessage.java +++ b/src/main/java/org/mandas/docker/client/LogMessage.java @@ -20,7 +20,7 @@ package org.mandas.docker.client; -import static com.google.common.base.Preconditions.checkNotNull; +import static java.util.Objects.requireNonNull; import java.nio.ByteBuffer; @@ -34,8 +34,10 @@ public LogMessage(final int streamId, final ByteBuffer content) { } public LogMessage(final Stream stream, final ByteBuffer content) { - this.stream = checkNotNull(stream, "stream"); - this.content = checkNotNull(content, "content"); + requireNonNull(stream, "stream"); + requireNonNull(content, "content"); + this.stream = stream; + this.content = content; } public Stream stream() { diff --git a/src/main/java/org/mandas/docker/client/LogReader.java b/src/main/java/org/mandas/docker/client/LogReader.java index e4ff6392e..5f2294827 100644 --- a/src/main/java/org/mandas/docker/client/LogReader.java +++ b/src/main/java/org/mandas/docker/client/LogReader.java @@ -20,17 +20,14 @@ package org.mandas.docker.client; -import static com.google.common.io.ByteStreams.copy; -import static com.google.common.io.ByteStreams.nullOutputStream; - -import com.google.common.io.ByteStreams; -import org.mandas.docker.client.LogMessage.Stream; - import java.io.Closeable; +import java.io.EOFException; import java.io.IOException; import java.io.InputStream; import java.nio.ByteBuffer; +import org.mandas.docker.client.LogMessage.Stream; + public class LogReader implements Closeable { private final InputStream stream; @@ -46,7 +43,7 @@ public LogMessage nextMessage() throws IOException { // Read header final byte[] headerBytes = new byte[HEADER_SIZE]; - final int n = ByteStreams.read(stream, headerBytes, 0, HEADER_SIZE); + final int n = readAllBytes(headerBytes); if (n == 0) { return null; } @@ -66,15 +63,31 @@ public LogMessage nextMessage() throws IOException { streamId = Stream.STDOUT.id(); frame = new byte[stream.available()]; } - ByteStreams.readFully(stream, frame); + + int total = readAllBytes(frame); + + if (total < frame.length) { + throw new EOFException("EOF before reading " + frame.length + " bytes. " + total + " read instead."); + } + return new LogMessage(streamId, ByteBuffer.wrap(frame)); } + private int readAllBytes(byte[] buf) throws IOException { + int total = 0; + while (total < buf.length) { + int result = stream.read(buf, total, buf.length - total); + if (result == -1) { + break; + } + total += result; + } + + return total; + } + @Override public void close() throws IOException { - // Jersey will close the stream and release the connection after we read all the data. - // We cannot call the stream's close method because it an instance of UncloseableInputStream, - // where close is a no-op. - copy(stream, nullOutputStream()); + stream.close(); } } diff --git a/src/main/java/org/mandas/docker/client/ObjectMapperProvider.java b/src/main/java/org/mandas/docker/client/ObjectMapperProvider.java index 841a7a89a..c831c26b7 100644 --- a/src/main/java/org/mandas/docker/client/ObjectMapperProvider.java +++ b/src/main/java/org/mandas/docker/client/ObjectMapperProvider.java @@ -20,8 +20,10 @@ package org.mandas.docker.client; +import static java.util.Collections.emptyMap; +import static java.util.stream.Collectors.toMap; + import java.io.IOException; -import java.util.Collections; import java.util.Map; import java.util.Set; @@ -42,8 +44,6 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.module.SimpleModule; -import com.google.common.base.Function; -import com.google.common.collect.Maps; @Produces(MediaType.APPLICATION_JSON) @SuppressWarnings({"rawtypes", "unchecked"}) @@ -51,13 +51,6 @@ public class ObjectMapperProvider implements ContextResolver<ObjectMapper> { private static final Logger log = LoggerFactory.getLogger(ObjectMapperProvider.class); - private static final Function<? super Object, ?> EMPTY_MAP = new Function<Object, Object>() { - @Override - public Object apply(final Object input) { - return Collections.emptyMap(); - } - }; - private static final SimpleModule MODULE = new SimpleModule(); private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); @@ -88,7 +81,7 @@ public static class SetSerializer extends JsonSerializer<Set> { @Override public void serialize(final Set value, final JsonGenerator jgen, final SerializerProvider provider) throws IOException { - final Map map = (value == null) ? null : Maps.asMap(value, EMPTY_MAP); + final Map map = (value == null) ? null : (Map) value.stream().collect(toMap(s -> s, s -> emptyMap())); OBJECT_MAPPER.writeValue(jgen, map); } } diff --git a/src/main/java/org/mandas/docker/client/ProgressStream.java b/src/main/java/org/mandas/docker/client/ProgressStream.java index 0c89cb318..40b42dcab 100644 --- a/src/main/java/org/mandas/docker/client/ProgressStream.java +++ b/src/main/java/org/mandas/docker/client/ProgressStream.java @@ -20,22 +20,21 @@ package org.mandas.docker.client; -import static com.google.common.io.ByteStreams.copy; -import static com.google.common.io.ByteStreams.nullOutputStream; import static org.mandas.docker.client.ObjectMapperProvider.objectMapper; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.MappingIterator; -import org.mandas.docker.client.exceptions.DockerException; -import org.mandas.docker.client.exceptions.DockerTimeoutException; -import org.mandas.docker.client.messages.ProgressMessage; - import java.io.Closeable; import java.io.IOException; import java.io.InputStream; import java.net.SocketTimeoutException; import java.net.URI; +import org.mandas.docker.client.exceptions.DockerException; +import org.mandas.docker.client.exceptions.DockerTimeoutException; +import org.mandas.docker.client.messages.ProgressMessage; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.MappingIterator; + class ProgressStream implements Closeable { @@ -80,9 +79,6 @@ public void tail(ProgressHandler handler, final String method, final URI uri) @Override public void close() throws IOException { - // Jersey will close the stream and release the connection after we read all the data. - // We cannot call the stream's close method because it an instance of UncloseableInputStream, - // where close is a no-op. - copy(stream, nullOutputStream()); + stream.close(); } } diff --git a/src/main/java/org/mandas/docker/client/SystemCredentialHelperDelegate.java b/src/main/java/org/mandas/docker/client/SystemCredentialHelperDelegate.java index 28197eaa7..824261b5f 100644 --- a/src/main/java/org/mandas/docker/client/SystemCredentialHelperDelegate.java +++ b/src/main/java/org/mandas/docker/client/SystemCredentialHelperDelegate.java @@ -30,14 +30,13 @@ import java.util.Map; import java.util.stream.Collectors; +import org.mandas.docker.client.DockerCredentialHelper.CredentialHelperDelegate; +import org.mandas.docker.client.messages.DockerCredentialHelperAuth; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.common.annotations.VisibleForTesting; -import org.mandas.docker.client.DockerCredentialHelper.CredentialHelperDelegate; -import org.mandas.docker.client.messages.DockerCredentialHelperAuth; /** * The default credential helper delegate. @@ -120,7 +119,6 @@ public Map<String, String> list(final String credsStore) throws IOException { } } - @VisibleForTesting static DockerCredentialHelperAuth readServerAuthDetails(final BufferedReader input) throws IOException { final String serverAuthDetails = input.lines().collect(Collectors.joining()); diff --git a/src/main/java/org/mandas/docker/client/auth/MultiRegistryAuthSupplier.java b/src/main/java/org/mandas/docker/client/auth/MultiRegistryAuthSupplier.java index 4913ef665..a3ccf4974 100644 --- a/src/main/java/org/mandas/docker/client/auth/MultiRegistryAuthSupplier.java +++ b/src/main/java/org/mandas/docker/client/auth/MultiRegistryAuthSupplier.java @@ -20,14 +20,17 @@ package org.mandas.docker.client.auth; -import com.google.common.collect.Lists; -import org.mandas.docker.client.exceptions.DockerException; -import org.mandas.docker.client.messages.RegistryAuth; -import org.mandas.docker.client.messages.RegistryConfigs; +import static java.util.Collections.reverse; + +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import org.mandas.docker.client.exceptions.DockerException; +import org.mandas.docker.client.messages.RegistryAuth; +import org.mandas.docker.client.messages.RegistryConfigs; + /** * A RegistryAuthSupplier that combines authentication info from multiple RegistryAuthSupplier * instances. @@ -73,7 +76,9 @@ public RegistryConfigs authForBuild() throws DockerException { final Map<String, RegistryAuth> allConfigs = new HashMap<>(); // iterate through suppliers in reverse so that the earlier suppliers in the list // have precedence - for (RegistryAuthSupplier supplier : Lists.reverse(suppliers)) { + List<RegistryAuthSupplier> reversedSuppliers = new ArrayList<>(suppliers); + reverse(reversedSuppliers); + for (RegistryAuthSupplier supplier : reversedSuppliers) { final RegistryConfigs configs = supplier.authForBuild(); if (configs != null && configs.configs() != null) { allConfigs.putAll(configs.configs()); diff --git a/src/main/java/org/mandas/docker/client/auth/gcr/ContainerRegistryAuthSupplier.java b/src/main/java/org/mandas/docker/client/auth/gcr/ContainerRegistryAuthSupplier.java index ffacf6886..b41e75db5 100644 --- a/src/main/java/org/mandas/docker/client/auth/gcr/ContainerRegistryAuthSupplier.java +++ b/src/main/java/org/mandas/docker/client/auth/gcr/ContainerRegistryAuthSupplier.java @@ -20,29 +20,33 @@ package org.mandas.docker.client.auth.gcr; -import com.google.auth.oauth2.AccessToken; -import com.google.auth.oauth2.GoogleCredentials; -import com.google.auth.oauth2.ServiceAccountCredentials; -import com.google.auth.oauth2.UserCredentials; -import com.google.common.annotations.VisibleForTesting; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; -import org.mandas.docker.client.auth.RegistryAuthSupplier; -import org.mandas.docker.client.exceptions.DockerException; -import org.mandas.docker.client.messages.RegistryAuth; -import org.mandas.docker.client.messages.RegistryConfigs; +import static java.util.Arrays.asList; +import static java.util.Collections.unmodifiableSet; + import java.io.IOException; import java.io.InputStream; import java.time.Clock; import java.util.Collection; +import java.util.Collections; import java.util.Date; import java.util.HashMap; +import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.concurrent.TimeUnit; + +import org.mandas.docker.client.auth.RegistryAuthSupplier; +import org.mandas.docker.client.exceptions.DockerException; +import org.mandas.docker.client.messages.RegistryAuth; +import org.mandas.docker.client.messages.RegistryConfigs; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.google.auth.oauth2.AccessToken; +import com.google.auth.oauth2.GoogleCredentials; +import com.google.auth.oauth2.ServiceAccountCredentials; +import com.google.auth.oauth2.UserCredentials; + /** * A RegistryAuthSupplier for getting access tokens from a Google Cloud Platform service or user * account. This implementation uses the google-auth-library-oauth2-http library to get an access @@ -66,7 +70,7 @@ public class ContainerRegistryAuthSupplier implements RegistryAuthSupplier { // the list returned by `gcloud docker -a` // this may change in the future, and we can't know all values - but should cover most use cases - private static final Set<String> GCR_REGISTRIES = ImmutableSet.of( + private static final Set<String> GCR_REGISTRIES = unmodifiableSet(new HashSet<>(asList( "gcr.io", "us.gcr.io", "eu.gcr.io", @@ -80,7 +84,7 @@ public class ContainerRegistryAuthSupplier implements RegistryAuthSupplier { "eu-mirror.gcr.io", "asia-mirror.gcr.io", "mirror.gcr.io" - ); + ))); /** * Constructs a ContainerRegistryAuthSupplier for the account with the given credentials. @@ -127,7 +131,7 @@ public static class Builder { private final GoogleCredentials credentials; private Collection<String> scopes = - ImmutableList.of("https://www.googleapis.com/auth/devstorage.read_write"); + Collections.singletonList("https://www.googleapis.com/auth/devstorage.read_write"); private long minimumExpiryMillis = TimeUnit.MINUTES.toMillis(1); @@ -182,7 +186,6 @@ public ContainerRegistryAuthSupplier build() { * Refreshes a GoogleCredentials instance. This only exists for testing - we cannot mock calls to * {@link GoogleCredentials#refresh()} as the method is final. */ - @VisibleForTesting interface CredentialRefresher { void refresh(GoogleCredentials credentials) throws IOException; @@ -201,7 +204,6 @@ public void refresh(final GoogleCredentials credentials) throws IOException { private final long minimumExpiryMillis; private final CredentialRefresher credentialRefresher; - @VisibleForTesting ContainerRegistryAuthSupplier( final GoogleCredentials credentials, final Clock clock, diff --git a/src/main/java/org/mandas/docker/client/messages/HostConfig.java b/src/main/java/org/mandas/docker/client/messages/HostConfig.java index 9c1b5b9f9..0567f78ea 100644 --- a/src/main/java/org/mandas/docker/client/messages/HostConfig.java +++ b/src/main/java/org/mandas/docker/client/messages/HostConfig.java @@ -20,9 +20,9 @@ package org.mandas.docker.client.messages; -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Strings.isNullOrEmpty; +import static java.lang.String.format; import static java.util.Arrays.stream; +import static java.util.stream.Collectors.joining; import static java.util.stream.Collectors.toList; import java.util.ArrayList; @@ -41,7 +41,6 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.google.common.base.Joiner; @JsonDeserialize(builder = ImmutableHostConfig.Builder.class) @Immutable @@ -314,8 +313,9 @@ public static Builder builder() { default void check() { if (extraHosts() != null) { for (final String extraHost : extraHosts()) { - checkArgument(extraHost.contains(":"), - "extra host arg '%s' must contain a ':'", extraHost); + if (!extraHost.contains(".")) { + throw new IllegalArgumentException(format("extra host arg '%s' must contain a ':'", extraHost)); + } } } } @@ -522,9 +522,9 @@ static Builder builder() { @Derived @JsonIgnore default String representation() { - if (isNullOrEmpty(to())) { + if (to() == null || "".equals(to().trim())) { return ""; - } else if (isNullOrEmpty(from())) { + } else if (from() == null || "".equals(from().trim())) { return to(); } @@ -548,7 +548,7 @@ default String representation() { } } - final String optionsValue = Joiner.on(',').join(options); + final String optionsValue = options.stream().collect(joining(",")); return (optionsValue.isEmpty()) ? bind : bind + ":" + optionsValue; } diff --git a/src/main/java/org/mandas/docker/client/messages/RegistryConfigs.java b/src/main/java/org/mandas/docker/client/messages/RegistryConfigs.java index d7062ff03..5b1eeed9f 100644 --- a/src/main/java/org/mandas/docker/client/messages/RegistryConfigs.java +++ b/src/main/java/org/mandas/docker/client/messages/RegistryConfigs.java @@ -20,12 +20,14 @@ package org.mandas.docker.client.messages; +import static java.util.stream.Collectors.toMap; + import java.util.Map; +import java.util.Map.Entry; import org.immutables.value.Value.Immutable; import com.fasterxml.jackson.annotation.JsonCreator; -import com.google.common.collect.Maps; /** * A formatted string passed in X-Registry-Config request header. @@ -66,22 +68,18 @@ public static RegistryConfigs create(final Map<String, RegistryAuth> configs) { // need to add serverAddress to each RegistryAuth instance; it is not available when // Jackson is deserializing the RegistryAuth field - final Map<String, RegistryAuth> transformedMap = Maps.transformEntries(configs, - new Maps.EntryTransformer<String, RegistryAuth, RegistryAuth>() { - @Override - public RegistryAuth transformEntry(final String key, final RegistryAuth value) { - if (value == null) { - return null; - } - if (value.serverAddress() == null) { - return value.toBuilder() - .serverAddress(key) - .build(); - } - return value; - } - }); - + final Map<String, RegistryAuth> transformedMap = configs.entrySet().stream() + .collect(toMap(Entry::getKey, entry -> { + RegistryAuth value = entry.getValue(); + if (value == null) { + return null; + } + if (value.serverAddress() == null) { + return value.toBuilder().serverAddress(entry.getKey()).build(); + } + return value; + })); + return builder().configs(transformedMap).build(); } diff --git a/src/test/java/org/mandas/docker/client/DefaultDockerClientTest.java b/src/test/java/org/mandas/docker/client/DefaultDockerClientTest.java index da2241fe3..87fde3c4f 100644 --- a/src/test/java/org/mandas/docker/client/DefaultDockerClientTest.java +++ b/src/test/java/org/mandas/docker/client/DefaultDockerClientTest.java @@ -27,8 +27,11 @@ import static com.google.common.collect.Lists.newArrayList; import static java.lang.String.format; import static java.lang.System.getenv; +import static java.util.Arrays.asList; import static java.util.Collections.singletonList; import static java.util.Collections.singletonMap; +import static java.util.Collections.unmodifiableList; +import static java.util.stream.Collectors.toList; import static org.apache.commons.lang.StringUtils.containsIgnoreCase; import static org.awaitility.Awaitility.await; import static org.hamcrest.Matchers.allOf; @@ -130,6 +133,7 @@ import java.util.Collections; import java.util.Date; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Random; @@ -273,12 +277,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.util.StdDateFormat; import com.google.common.base.Throwables; -import com.google.common.collect.Collections2; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; import com.google.common.collect.Lists; -import com.google.common.collect.Sets; import com.google.common.io.Resources; import com.google.common.util.concurrent.SettableFuture; @@ -681,8 +680,9 @@ public void testCreate() throws Exception { sut.create(image, imagePayload); } - final Collection<Image> images = Collections2.filter(sut.listImages(), - img -> img.repoTags() != null && img.repoTags().contains(image + ":latest")); + final Collection<Image> images = sut.listImages().stream() + .filter(img -> img.repoTags() != null && img.repoTags().contains(image + ":latest")) + .collect(toList()); assertThat(images.size(), greaterThan(0)); @@ -783,7 +783,7 @@ public void testRemoveImage() throws Exception { final String imageLatest = "dxia/cirros:latest"; final String imageVersion = "dxia/cirros:0.3.0"; - final Set<RemovedImage> removedImages = Sets.newHashSet(); + final Set<RemovedImage> removedImages = new HashSet<>(); removedImages.addAll(sut.removeImage(imageLatest)); removedImages.addAll(sut.removeImage(imageVersion)); @@ -1139,7 +1139,7 @@ public void testExportContainer() throws Exception { final ContainerCreation creation = sut.createContainer(config, name); final String id = creation.id(); - final ImmutableSet.Builder<String> files = ImmutableSet.builder(); + final Set<String> files = new HashSet<>(); try (TarArchiveInputStream tarStream = new TarArchiveInputStream(sut.exportContainer(id))) { TarArchiveEntry entry; while ((entry = tarStream.getNextTarEntry()) != null) { @@ -1148,7 +1148,7 @@ public void testExportContainer() throws Exception { } // Check that some common files exist - assertThat(files.build(), both(hasItem("bin/")).and(hasItem("bin/sh"))); + assertThat(files, both(hasItem("bin/")).and(hasItem("bin/sh"))); } @Test @@ -1164,7 +1164,7 @@ public void testArchiveContainer() throws Exception { final ContainerCreation creation = sut.createContainer(config, name); final String id = creation.id(); - final ImmutableSet.Builder<String> files = ImmutableSet.builder(); + final Set<String> files = new HashSet<>(); try (final TarArchiveInputStream tarStream = new TarArchiveInputStream(sut.archiveContainer(id, "/bin"))) { TarArchiveEntry entry; @@ -1174,7 +1174,7 @@ public void testArchiveContainer() throws Exception { } // Check that some common files exist - assertThat(files.build(), both(hasItem("bin/")).and(hasItem("bin/wc"))); + assertThat(files, both(hasItem("bin/")).and(hasItem("bin/wc"))); } @Test @@ -1437,7 +1437,7 @@ public void integrationTest() throws Exception { } // Copy the same files from container - final ImmutableSet.Builder<String> filesDownloaded = ImmutableSet.builder(); + final Set<String> filesDownloaded = new HashSet<>(); try (TarArchiveInputStream tarStream = new TarArchiveInputStream( sut.archiveContainer(id, "/tmp"))) { TarArchiveEntry entry; @@ -1453,7 +1453,7 @@ public void integrationTest() throws Exception { for (final File file : files) { if (!file.isDirectory()) { boolean found = false; - for (final String fileDownloaded : filesDownloaded.build()) { + for (final String fileDownloaded : filesDownloaded) { if (fileDownloaded.contains(file.getName())) { found = true; } @@ -1824,7 +1824,7 @@ public void testContainerWithBlkioOptions() throws Exception { hostConfigBuilder.blkioWeight(300); - final List<HostConfig.BlkioDeviceRate> deviceRates = ImmutableList.of( + final List<HostConfig.BlkioDeviceRate> deviceRates = Collections.singletonList( HostConfig.BlkioDeviceRate.builder().path("/dev/loop0").rate(1024).build() ); hostConfigBuilder.blkioDeviceReadBps(deviceRates); @@ -2269,7 +2269,7 @@ public void testEventFiltersWithSpaces() throws Exception { .image(BUSYBOX_LATEST) .cmd("sleep", "5") // Generate some healthy_status events - .healthcheck(Healthcheck.create(ImmutableList.of("CMD-SHELL", "true"), + .healthcheck(Healthcheck.create(unmodifiableList(asList("CMD-SHELL", "true")), 1000000000L, 1000000000L, 3, 1000000000L)) .build(); @@ -2367,7 +2367,7 @@ public void testListImages() throws Exception { // Can list by name final List<Image> imagesByName = sut.listImages(byName(BUSYBOX)); assertThat(imagesByName.size(), greaterThan(0)); - final Set<String> repoTags = Sets.newHashSet(); + final Set<String> repoTags = new HashSet<>(); for (final Image imageByName : imagesByName) { if (imageByName.repoTags() != null) { repoTags.addAll(imageByName.repoTags()); @@ -3358,7 +3358,7 @@ public void testExecInspect() throws Exception { assertThat(processConfig.tty(), is(true)); assertThat(processConfig.entrypoint(), is("sh")); assertThat(processConfig.arguments(), - Matchers.<List<String>>is(ImmutableList.of("-c", "exit 2"))); + Matchers.<List<String>>is(unmodifiableList(asList("-c", "exit 2")))); assertNotNull(started.containerId(), "containerId"); } @@ -3409,7 +3409,7 @@ public void testListContainers() throws Exception { final ContainerConfig containerConfig = ContainerConfig.builder() .image(BUSYBOX_LATEST) .cmd("sh", "-c", "while :; do sleep 1; done") - .labels(ImmutableMap.of(label, labelValue)) + .labels(singletonMap(label, labelValue)) .build(); final String containerName = randomName(); final ContainerCreation containerCreation = sut.createContainer(containerConfig, containerName); @@ -3476,9 +3476,9 @@ public void testListContainers() throws Exception { public void testContainerLabels() throws Exception { sut.pull(BUSYBOX_LATEST); - final Map<String, String> labels = ImmutableMap.of( - "name", "starship", "foo", "bar" - ); + Map<String, String> labels = new HashMap<>(); + labels.put("name", "starship"); + labels.put("foo", "bar"); // Create container final ContainerConfig config = ContainerConfig.builder() @@ -3496,9 +3496,9 @@ public void testContainerLabels() throws Exception { final ContainerInfo containerInfo = sut.inspectContainer(id); assertThat(containerInfo.config().labels(), is(labels)); - final Map<String, String> labels2 = ImmutableMap.of( - "name", "starship", "foo", "baz" - ); + final Map<String, String> labels2 = new HashMap<>(); + labels2.put("name", "starship"); + labels2.put("foo", "baz"); // Create second container with different labels final ContainerConfig config2 = ContainerConfig.builder() @@ -3637,8 +3637,9 @@ public void testNetworks() throws Exception { .driver("default") .config(singletonList(ipamConfig)) .build(); - final Map<String, String> labels = ImmutableMap.of( - "name", "starship", "foo", "bar"); + final Map<String, String> labels = new HashMap<>(); + labels.put("name", "starship"); + labels.put("foo", "bar"); final NetworkConfig networkConfig = NetworkConfig.builder().name(networkName).driver("bridge").checkDuplicate(true).ipam(ipam) .internal(false).enableIPv6(false).labels(labels) @@ -3677,9 +3678,9 @@ public void testNetworks() throws Exception { @Test public void testFilterNetworks() throws Exception { final NetworkConfig network1Config = NetworkConfig.builder().checkDuplicate(true) - .name(randomName()).labels(ImmutableMap.of("is-test", "true")).build(); + .name(randomName()).labels(singletonMap("is-test", "true")).build(); final NetworkConfig network2Config = NetworkConfig.builder().checkDuplicate(true) - .name(randomName()).labels(ImmutableMap.of("is-test", "")).build(); + .name(randomName()).labels(singletonMap("is-test", "")).build(); final Network network1 = createNetwork(network1Config); final Network network2 = createNetwork(network2Config); final Network hostNetwork = getHostNetwork(); @@ -3865,7 +3866,7 @@ public void testNetworksConnectContainerWithEndpointConfig() throws Exception { final String dummyAlias = "value-does-not-matter"; final EndpointConfig endpointConfig = EndpointConfig.builder() .ipamConfig(EndpointIpamConfig.builder().ipv4Address(ip).build()) - .aliases(ImmutableList.of(dummyAlias)) + .aliases(Collections.singletonList(dummyAlias)) .build(); final NetworkConnection networkConnection = NetworkConnection.builder() @@ -4085,7 +4086,7 @@ public void testCreateVolume() throws Exception { sut.removeVolume(blankVolume); // Create volume with attributes - final ImmutableMap<String, String> labels = ImmutableMap.of("foo", "bar"); + final Map<String, String> labels = Collections.singletonMap("foo", "bar"); final String volName = randomName(); final Volume toCreate; toCreate = Volume.builder() @@ -4351,7 +4352,7 @@ public void testTmpfs() throws Exception { // Pull image sut.pull(BUSYBOX_LATEST); - final ImmutableMap<String, String> tmpfs = ImmutableMap.of("/tmp", "rw,noexec,nosuid,size=50m"); + final Map<String, String> tmpfs = Collections.singletonMap("/tmp", "rw,noexec,nosuid,size=50m"); final ContainerConfig config = ContainerConfig.builder() .image(BUSYBOX_LATEST) @@ -4394,7 +4395,7 @@ public void testStorageOpt() throws Exception { // Pull image sut.pull(BUSYBOX_LATEST); - final ImmutableMap<String, String> storageOpt = ImmutableMap.of("size", "20G"); + final Map<String, String> storageOpt = Collections.singletonMap("size", "20G"); final ContainerConfig config = ContainerConfig.builder() .image(BUSYBOX_LATEST) @@ -4503,7 +4504,7 @@ public void testUpdateSwarm() throws Exception { final Swarm swarm = sut.inspectSwarm(); final ThreadLocalRandom random = ThreadLocalRandom.current(); - final Map<String, String> newLabels = ImmutableMap.of("foo", "bar"); + final Map<String, String> newLabels = Collections.singletonMap("foo", "bar"); final OrchestrationConfig newOrchestration = OrchestrationConfig.builder() .taskHistoryRetentionLimit(random.nextInt(1, 10)) .build(); @@ -4632,7 +4633,9 @@ public void testSecretOperations() throws Exception { final String secretData = Base64.getEncoder().encodeToString("testdata".getBytes(StandardCharsets.UTF_8)); - final Map<String, String> labels = ImmutableMap.of("foo", "bar", "1", "a"); + final Map<String, String> labels = new HashMap<>(); + labels.put("foo", "bar"); + labels.put("1", "a"); String secretName = randomName(); final SecretSpec secretSpec = SecretSpec.builder() @@ -4808,7 +4811,9 @@ public void testCreateServiceWithSecretHostnameHostsAndHealthcheck() throws Exce final String secretData = Base64.getEncoder().encodeToString("testdata".getBytes(StandardCharsets.UTF_8)); - final Map<String, String> labels = ImmutableMap.of("foo", "bar", "1", "a"); + final Map<String, String> labels = new HashMap<>(); + labels.put("foo", "bar"); + labels.put("1", "a"); String secretName = randomName(); final SecretSpec secretSpec = SecretSpec.builder() diff --git a/src/test/java/org/mandas/docker/client/DefaultDockerClientUnitTest.java b/src/test/java/org/mandas/docker/client/DefaultDockerClientUnitTest.java index 752850bc0..2f74f8e94 100644 --- a/src/test/java/org/mandas/docker/client/DefaultDockerClientUnitTest.java +++ b/src/test/java/org/mandas/docker/client/DefaultDockerClientUnitTest.java @@ -20,12 +20,14 @@ package org.mandas.docker.client; -import static org.mandas.docker.FixtureUtil.fixture; import static com.spotify.hamcrest.jackson.JsonMatchers.jsonArray; import static com.spotify.hamcrest.jackson.JsonMatchers.jsonObject; import static com.spotify.hamcrest.jackson.JsonMatchers.jsonText; import static com.spotify.hamcrest.pojo.IsPojo.pojo; +import static java.util.Arrays.asList; import static java.util.Collections.singletonList; +import static java.util.Collections.singletonMap; +import static java.util.Collections.unmodifiableList; import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.containsInAnyOrder; @@ -40,17 +42,32 @@ import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; import static org.junit.Assert.assertThat; +import static org.mandas.docker.FixtureUtil.fixture; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.ObjectNode; -import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Lists; -import com.google.common.io.Resources; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.sql.Date; +import java.time.Instant; +import java.util.Arrays; +import java.util.Base64; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.TimeUnit; + +import org.glassfish.jersey.client.RequestEntityProcessing; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; import org.mandas.docker.client.DockerClient.Signal; import org.mandas.docker.client.auth.RegistryAuthSupplier; import org.mandas.docker.client.exceptions.ConflictException; @@ -87,31 +104,19 @@ import org.mandas.docker.client.messages.swarm.Task; import org.mandas.docker.client.messages.swarm.TaskSpec; import org.mandas.docker.client.messages.swarm.Version; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.sql.Date; -import java.time.Instant; -import java.util.Arrays; -import java.util.Base64; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.concurrent.TimeUnit; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; +import com.google.common.base.Preconditions; +import com.google.common.io.Resources; + import okhttp3.HttpUrl; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import okhttp3.mockwebserver.RecordedRequest; import okio.Buffer; -import org.glassfish.jersey.client.RequestEntityProcessing; -import org.junit.After; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - /** * Tests DefaultDockerClient against a {@link okhttp3.mockwebserver.MockWebServer} instance, so * we can assert what the HTTP requests look like that DefaultDockerClient sends and test how @@ -240,7 +245,7 @@ private RecordedRequest takeRequestImmediately() throws InterruptedException { public void testCustomHeaders() throws Exception { builder.header("int", 1); builder.header("string", "2"); - builder.header("list", Lists.newArrayList("a", "b", "c")); + builder.header("list", Arrays.asList("a", "b", "c")); server.enqueue(new MockResponse()); @@ -309,8 +314,8 @@ public void testCapAddAndDrop() throws Exception { final DefaultDockerClient dockerClient = new DefaultDockerClient(builder); final HostConfig hostConfig = HostConfig.builder() - .capAdd(ImmutableList.of("foo", "bar")) - .capAdd(ImmutableList.of("baz", "qux")) + .capAdd(unmodifiableList(asList("foo", "bar"))) + .capAdd(unmodifiableList(asList("baz", "qux"))) .build(); final ContainerConfig containerConfig = ContainerConfig.builder() @@ -349,21 +354,21 @@ private static Set<String> childrenTextNodes(ArrayNode arrayNode) { @Test public void testBuildPassesMultipleRegistryConfigs() throws Exception { - final RegistryConfigs registryConfigs = RegistryConfigs.create(ImmutableMap.of( - "server1", RegistryAuth.builder() + Map<String, RegistryAuth> registryAuths = new HashMap<>(); + registryAuths.put("server1", RegistryAuth.builder() .serverAddress("server1") .username("u1") .password("p1") .email("e1") - .build(), - - "server2", RegistryAuth.builder() + .build()); + registryAuths.put("server2", RegistryAuth.builder() .serverAddress("server2") .username("u2") .password("p2") .email("e2") - .build() - )); + .build()); + + final RegistryConfigs registryConfigs = RegistryConfigs.create(registryAuths); final RegistryAuthSupplier authSupplier = mock(RegistryAuthSupplier.class); when(authSupplier.authForBuild()).thenReturn(registryConfigs); @@ -710,7 +715,7 @@ public void testCreateServiceWithPlacementPreference() throws IOException, DockerException, InterruptedException { final DefaultDockerClient dockerClient = new DefaultDockerClient(builder); - final ImmutableList<Preference> prefs = ImmutableList.of( + final List<Preference> prefs = Collections.singletonList( Preference.create( Spread.create( "test" @@ -775,7 +780,7 @@ public void testCreateServiceWithConfig() throws Exception { final TaskSpec taskSpec = TaskSpec.builder() .containerSpec(ContainerSpec.builder() .image("this_image_is_found_in_the_registry") - .configs(ImmutableList.of(configBind)) + .configs(Collections.singletonList(configBind)) .build()) .build(); @@ -1163,16 +1168,16 @@ public void testInspectVolume() throws Exception { assertThat(volume.name(), is("tardis")); assertThat(volume.driver(), is("custom")); assertThat(volume.mountpoint(), is("/var/lib/docker/volumes/tardis")); - assertThat(volume.status(), is(ImmutableMap.of("hello", "world"))); - assertThat(volume.labels(), is(ImmutableMap.of( - "com.example.some-label", "some-value", - "com.example.some-other-label", "some-other-value" - ))); + assertThat(volume.status(), is(singletonMap("hello", "world"))); + Map<String, String> expectedLabels = new HashMap<>(); + expectedLabels.put("com.example.some-label", "some-value"); + expectedLabels.put("com.example.some-other-label", "some-other-value"); + assertThat(volume.labels(), is(expectedLabels)); assertThat(volume.scope(), is("local")); - assertThat(volume.options(), is(ImmutableMap.of( - "foo", "bar", - "baz", "qux" - ))); + Map<String, String> expectedOptions = new HashMap<>(); + expectedOptions.put("foo", "bar"); + expectedOptions.put("baz", "qux"); + assertThat(volume.options(), is(expectedOptions)); } @Test @@ -1241,15 +1246,15 @@ public void testGetDistribution() throws Exception { assertThat(distribution.descriptor().mediaType(), is( "application/vnd.docker.distribution.manifest.v2+json" )); - assertThat(distribution.platforms().get(0).osFeatures(), is(ImmutableList.of( + assertThat(distribution.platforms().get(0).osFeatures(), is(unmodifiableList(asList( "feature1", "feature2" - ))); - assertThat(distribution.platforms().get(0).features(), is(ImmutableList.of( + )))); + assertThat(distribution.platforms().get(0).features(), is(unmodifiableList(asList( "feature1", "feature2" - ))); - assertThat(distribution.descriptor().urls(), is(ImmutableList.of( + )))); + assertThat(distribution.descriptor().urls(), is(unmodifiableList(asList( "url1", "url2" - ))); + )))); } @Test diff --git a/src/test/java/org/mandas/docker/client/DockerCertificatesTest.java b/src/test/java/org/mandas/docker/client/DockerCertificatesTest.java index 240baab32..278848540 100644 --- a/src/test/java/org/mandas/docker/client/DockerCertificatesTest.java +++ b/src/test/java/org/mandas/docker/client/DockerCertificatesTest.java @@ -28,7 +28,6 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; -import com.google.common.base.Optional; import com.google.common.io.Resources; import org.mandas.docker.client.DockerCertificates.SslContextFactory; import org.mandas.docker.client.exceptions.DockerCertificateException; @@ -36,6 +35,8 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.security.KeyStore; +import java.util.Optional; + import org.junit.Test; import org.mockito.ArgumentCaptor; diff --git a/src/test/java/org/mandas/docker/client/ImageRefTest.java b/src/test/java/org/mandas/docker/client/ImageRefTest.java index 2a462d57a..d556b053c 100644 --- a/src/test/java/org/mandas/docker/client/ImageRefTest.java +++ b/src/test/java/org/mandas/docker/client/ImageRefTest.java @@ -26,7 +26,6 @@ import static org.hamcrest.Matchers.nullValue; import static org.junit.Assert.assertThat; -import java.net.URL; import org.hamcrest.FeatureMatcher; import org.hamcrest.Matcher; import org.junit.Test; diff --git a/src/test/java/org/mandas/docker/client/auth/ConfigFileRegistryAuthSupplierTest.java b/src/test/java/org/mandas/docker/client/auth/ConfigFileRegistryAuthSupplierTest.java index 7de93d466..60af9cf18 100644 --- a/src/test/java/org/mandas/docker/client/auth/ConfigFileRegistryAuthSupplierTest.java +++ b/src/test/java/org/mandas/docker/client/auth/ConfigFileRegistryAuthSupplierTest.java @@ -20,6 +20,7 @@ package org.mandas.docker.client.auth; +import static java.util.Collections.singletonMap; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.nullValue; @@ -27,23 +28,23 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; -import static org.mockito.Matchers.any; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import com.google.common.collect.ImmutableMap; -import org.mandas.docker.client.DockerConfigReader; -import org.mandas.docker.client.messages.RegistryAuth; -import org.mandas.docker.client.messages.RegistryConfigs; import java.io.File; import java.nio.file.Files; import java.nio.file.Path; + import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; +import org.mandas.docker.client.DockerConfigReader; +import org.mandas.docker.client.messages.RegistryAuth; +import org.mandas.docker.client.messages.RegistryConfigs; public class ConfigFileRegistryAuthSupplierTest { @@ -120,7 +121,7 @@ public void testAuthForBuild_ConfigFileEmptyFile() throws Exception { @Test public void testAuthForBuild_Success() throws Exception { - final RegistryConfigs configs = RegistryConfigs.create(ImmutableMap.of( + final RegistryConfigs configs = RegistryConfigs.create(singletonMap( "server1", RegistryAuth.builder() .serverAddress("server1") diff --git a/src/test/java/org/mandas/docker/client/auth/MultiRegistryAuthSupplierTest.java b/src/test/java/org/mandas/docker/client/auth/MultiRegistryAuthSupplierTest.java index 0aa2f01a9..ddf383e8a 100644 --- a/src/test/java/org/mandas/docker/client/auth/MultiRegistryAuthSupplierTest.java +++ b/src/test/java/org/mandas/docker/client/auth/MultiRegistryAuthSupplierTest.java @@ -20,6 +20,8 @@ package org.mandas.docker.client.auth; +import static java.util.Arrays.asList; +import static java.util.Collections.unmodifiableList; import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.hasEntry; import static org.hamcrest.Matchers.is; @@ -29,11 +31,12 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; +import java.util.HashMap; +import java.util.Map; + +import org.junit.Test; import org.mandas.docker.client.messages.RegistryAuth; import org.mandas.docker.client.messages.RegistryConfigs; -import org.junit.Test; public class MultiRegistryAuthSupplierTest { @@ -41,7 +44,7 @@ public class MultiRegistryAuthSupplierTest { private final RegistryAuthSupplier supplier2 = mock(RegistryAuthSupplier.class); private final RegistryAuthSupplier multiSupplier = - new MultiRegistryAuthSupplier(ImmutableList.of(supplier1, supplier2)); + new MultiRegistryAuthSupplier(unmodifiableList(asList(supplier1, supplier2))); @Test public void testAuthFor() throws Exception { @@ -106,15 +109,15 @@ public void testAuthForBuild() throws Exception { .serverAddress("c") .build(); - when(supplier1.authForBuild()).thenReturn(RegistryConfigs.create(ImmutableMap.of( - "a", auth1, - "b", auth2 - ))); + Map<String, RegistryAuth> expectedSup1Auths = new HashMap<>(); + expectedSup1Auths.put("a", auth1); + expectedSup1Auths.put("b", auth2); + when(supplier1.authForBuild()).thenReturn(RegistryConfigs.create(expectedSup1Auths)); - when(supplier2.authForBuild()).thenReturn(RegistryConfigs.create(ImmutableMap.of( - "b", auth3, - "c", auth4 - ))); + Map<String, RegistryAuth> expectedSup2Auths = new HashMap<>(); + expectedSup2Auths.put("b", auth3); + expectedSup2Auths.put("c", auth4); + when(supplier2.authForBuild()).thenReturn(RegistryConfigs.create(expectedSup2Auths)); // ensure that supplier1 had priority for server b assertThat(multiSupplier.authForBuild().configs(), allOf( @@ -132,18 +135,17 @@ public void testAuthForBuild_ReturnsNull() throws Exception { when(supplier1.authForBuild()).thenReturn(null); - final RegistryConfigs registryConfigs = RegistryConfigs.create(ImmutableMap.of( - "a", - RegistryAuth.builder() + Map<String, RegistryAuth> expectedAuths = new HashMap<>(); + expectedAuths.put("a", RegistryAuth.builder() .username("1") .serverAddress("a") - .build(), - "b", - RegistryAuth.builder() + .build()); + expectedAuths.put("b", RegistryAuth.builder() .username("2") .serverAddress("b") - .build() - )); + .build()); + + final RegistryConfigs registryConfigs = RegistryConfigs.create(expectedAuths); when(supplier2.authForBuild()).thenReturn(registryConfigs); assertThat(multiSupplier.authForBuild(), is(registryConfigs)); diff --git a/src/test/java/org/mandas/docker/client/messages/EventTest.java b/src/test/java/org/mandas/docker/client/messages/EventTest.java index 3af4e363f..0e7f50deb 100644 --- a/src/test/java/org/mandas/docker/client/messages/EventTest.java +++ b/src/test/java/org/mandas/docker/client/messages/EventTest.java @@ -23,21 +23,25 @@ import static org.hamcrest.Matchers.equalTo; import static org.junit.Assert.assertThat; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.common.collect.ImmutableMap; -import org.mandas.docker.client.ObjectMapperProvider; - import java.util.Date; +import java.util.HashMap; +import java.util.Map; import org.junit.Test; +import org.mandas.docker.client.ObjectMapperProvider; + +import com.fasterxml.jackson.databind.ObjectMapper; public class EventTest { @Test public void serializationRoundTripTest() throws Exception { // Test serializing and deserializing the same Event instance works and preserves data + Map<String, String> attributes = new HashMap<>(); + attributes.put("image", "nginx"); + attributes.put("name", "docker-nginx"); final Event event = Event.builder().type(Event.Type.CONTAINER).action("create") - .actor(Event.Actor.create("bar", ImmutableMap.of("image", "nginx", "name", "docker-nginx"))) + .actor(Event.Actor.create("bar", attributes)) .time(new Date(1487356000)).timeNano(100L).build(); final ObjectMapper mapper = ObjectMapperProvider.objectMapper(); diff --git a/src/test/java/org/mandas/docker/client/messages/IpamTest.java b/src/test/java/org/mandas/docker/client/messages/IpamTest.java index d019a2861..a13029811 100644 --- a/src/test/java/org/mandas/docker/client/messages/IpamTest.java +++ b/src/test/java/org/mandas/docker/client/messages/IpamTest.java @@ -20,18 +20,18 @@ package org.mandas.docker.client.messages; -import static org.mandas.docker.FixtureUtil.fixture; +import static java.util.Collections.singletonMap; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.nullValue; +import static org.mandas.docker.FixtureUtil.fixture; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.common.collect.ImmutableMap; +import org.junit.Test; import org.mandas.docker.client.ObjectMapperProvider; -import org.junit.Test; +import com.fasterxml.jackson.databind.ObjectMapper; public class IpamTest { @@ -43,7 +43,7 @@ public void testDeserialize() throws Exception { objectMapper.readValue(fixture("fixtures/1.29/ipam.json"), Ipam.class); assertThat(ipam.driver(), equalTo("default")); assertThat(ipam.config(), contains(IpamConfig.builder().subnet("172.17.0.0/16").build())); - assertThat(ipam.options(), equalTo(ImmutableMap.of("foo", "bar"))); + assertThat(ipam.options(), equalTo(singletonMap("foo", "bar"))); } @Test diff --git a/src/test/java/org/mandas/docker/client/messages/swarm/DriverTest.java b/src/test/java/org/mandas/docker/client/messages/swarm/DriverTest.java index 236eb4d07..d8e91fa5a 100644 --- a/src/test/java/org/mandas/docker/client/messages/swarm/DriverTest.java +++ b/src/test/java/org/mandas/docker/client/messages/swarm/DriverTest.java @@ -20,17 +20,20 @@ package org.mandas.docker.client.messages.swarm; -import static org.mandas.docker.FixtureUtil.fixture; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.nullValue; import static org.junit.Assert.assertThat; +import static org.mandas.docker.FixtureUtil.fixture; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.common.collect.ImmutableMap; -import org.mandas.docker.client.ObjectMapperProvider; import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + import org.junit.Test; +import org.mandas.docker.client.ObjectMapperProvider; + +import com.fasterxml.jackson.databind.ObjectMapper; public class DriverTest { @@ -40,8 +43,11 @@ public class DriverTest { public void test1_32() throws Exception { final Driver driver = objectMapper.readValue(fixture( "fixtures/1.32/driver.json"), Driver.class); + Map<String, String> expected = new HashMap<>(); + expected.put("1", "A"); + expected.put("2", "B"); assertThat(driver.name(), equalTo("my-driver")); - assertThat(driver.options(), equalTo(ImmutableMap.of("1", "A", "2", "B"))); + assertThat(driver.options(), equalTo(expected)); } @Test diff --git a/src/test/java/org/mandas/docker/it/PushPullIT.java b/src/test/java/org/mandas/docker/it/PushPullIT.java index 2351a4486..4ed6d1050 100644 --- a/src/test/java/org/mandas/docker/it/PushPullIT.java +++ b/src/test/java/org/mandas/docker/it/PushPullIT.java @@ -21,12 +21,27 @@ package org.mandas.docker.it; import static com.google.common.base.Strings.isNullOrEmpty; +import static java.util.Arrays.asList; import static java.util.Collections.singletonMap; +import static java.util.Collections.unmodifiableList; import static java.util.concurrent.TimeUnit.SECONDS; import static org.hamcrest.CoreMatchers.isA; -import com.google.common.collect.ImmutableList; -import com.google.common.io.Resources; +import java.nio.file.Paths; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.concurrent.Callable; + +import javax.ws.rs.NotAuthorizedException; + +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.rules.TestName; import org.mandas.docker.Polling; import org.mandas.docker.client.DefaultDockerClient; import org.mandas.docker.client.DockerClient; @@ -46,21 +61,7 @@ import org.mandas.docker.client.messages.RegistryAuth; import org.mandas.docker.client.messages.RegistryConfigs; -import java.nio.file.Paths; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.concurrent.Callable; - -import javax.ws.rs.NotAuthorizedException; - -import org.junit.After; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.junit.rules.TestName; +import com.google.common.io.Resources; /** * These integration tests check we can push images to and pull from a private registry running as a @@ -308,10 +309,10 @@ private static String startAuthedRegistry(final DockerClient client) throws Exce final Map<String, List<PortBinding>> ports = singletonMap( "5000/tcp", Collections.singletonList(PortBinding.of("0.0.0.0", 5000))); final HostConfig hostConfig = HostConfig.builder().portBindings(ports) - .binds(ImmutableList.of( + .binds(unmodifiableList(asList( Resources.getResource("dockerRegistry/auth").getPath() + ":/auth", Resources.getResource("dockerRegistry/certs").getPath() + ":/certs" - )) + ))) /* * Mounting volumes requires special permissions on Docker >= 1.10. * Until a proper Seccomp profile is in place, run container privileged. @@ -322,14 +323,14 @@ private static String startAuthedRegistry(final DockerClient client) throws Exce final ContainerConfig containerConfig = ContainerConfig.builder() .image(REGISTRY_IMAGE) .hostConfig(hostConfig) - .env(ImmutableList.of( + .env(unmodifiableList(asList( "REGISTRY_AUTH=htpasswd", "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm", "REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd", "REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt", "REGISTRY_HTTP_TLS_KEY=/certs/domain.key", "REGISTRY_HTTP_SECRET=super-secret" - )) + ))) .build(); return startAndAwaitContainer(client, containerConfig, REGISTRY_NAME);