diff --git a/src/main/java/com/amihaiemil/docker/Docker.java b/src/main/java/com/amihaiemil/docker/Docker.java index fbb40fb8..d35e7927 100644 --- a/src/main/java/com/amihaiemil/docker/Docker.java +++ b/src/main/java/com/amihaiemil/docker/Docker.java @@ -103,6 +103,13 @@ Reader events() */ Plugins plugins(); + /** + * Entry point for Version API. + * @return Version. + * @throws IOException If an I/O error occurs. + */ + Version version() throws IOException; + /** * The underlying, immutable, Apache HttpClient.

* diff --git a/src/main/java/com/amihaiemil/docker/RtDocker.java b/src/main/java/com/amihaiemil/docker/RtDocker.java index 53462cd2..09f8494c 100644 --- a/src/main/java/com/amihaiemil/docker/RtDocker.java +++ b/src/main/java/com/amihaiemil/docker/RtDocker.java @@ -158,6 +158,15 @@ public Plugins plugins() { ); } + @Override + public Version version() throws IOException { + final String versionUri = this.baseUri.toString() + "/version"; + return new RtVersion( + this.client, + URI.create(versionUri) + ); + } + @Override public HttpClient httpClient() { return this.client; diff --git a/src/main/java/com/amihaiemil/docker/RtVersion.java b/src/main/java/com/amihaiemil/docker/RtVersion.java new file mode 100644 index 00000000..fc9718df --- /dev/null +++ b/src/main/java/com/amihaiemil/docker/RtVersion.java @@ -0,0 +1,137 @@ +/** + * Copyright (c) 2018-2019, Mihai Emil Andronache + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1)Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2)Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3)Neither the name of docker-java-api nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +package com.amihaiemil.docker; + +import org.apache.http.HttpStatus; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpGet; + +import javax.json.JsonObject; +import java.io.IOException; +import java.net.URI; + +/** + * Runtime {@link Version}. + * @author Michael Lux (michi.lux@gmail.com) + * @since 0.0.11 + */ +final class RtVersion extends JsonResource implements Version { + /** + * Ctor. + * @param client The http client. + * @param uri The URI for this version. + * @throws IOException If an I/O error occurs. + */ + RtVersion(final HttpClient client, final URI uri) throws IOException { + super(fetch(client, uri)); + } + + /** + * Fetch the JsonObject resource. + * @param client The Http client. + * @param uri The request URL. + * @return The fetched JsonObject. + * @throws UnexpectedResponseException If Docker's response code is not 200. + * @throws IOException If an I/O error occurs. + */ + private static JsonObject fetch(final HttpClient client, final URI uri) + throws UnexpectedResponseException, IOException { + final HttpGet version = new HttpGet(uri); + try { + return client.execute( + version, + new ReadJsonObject( + new MatchStatus(version.getURI(), HttpStatus.SC_OK) + ) + ); + } finally { + version.releaseConnection(); + } + } + + /** + * Returns the version of the connected docker engine. + * @return Version of connected docker engine + */ + @Override + public String version() { + return this.getString("Version"); + } + + /** + * Returns the name of the connected docker platform. + * @return Name of the docker platform + */ + @Override + public String platformName() { + return this.getJsonObject("Platform").getString("Name"); + } + + /** + * Returns the API version of the docker engine. + * @return API version + */ + @Override + public String apiVersion() { + return this.getString("ApiVersion"); + } + + /** + * Returns the minimum API version of the docker engine. + * @return Minimum API version + */ + @Override + public String minApiVersion() { + return this.getString("MinAPIVersion"); + } + + /** + * Returns the OS docker is running on. + * @return Name of the OS docker is running on + */ + @Override + public String osName() { + return this.getString("Os"); + } + + /** + * Returns the (CPU) architecture docker is running on. + * @return The (CPU) architecture docker is running on + */ + @Override + public String arch() { + return this.getString("Arch"); + } + + /** + * Reports whether experimental docker features are enabled. + * @return Whether experimental docker features are enabled + */ + @Override + public boolean experimental() { + return this.getBoolean("Experimental"); + } +} diff --git a/src/main/java/com/amihaiemil/docker/Version.java b/src/main/java/com/amihaiemil/docker/Version.java new file mode 100644 index 00000000..09601a13 --- /dev/null +++ b/src/main/java/com/amihaiemil/docker/Version.java @@ -0,0 +1,52 @@ +package com.amihaiemil.docker; + +import javax.json.JsonObject; + +/** + * Version API. + * @author Michael Lux (michi.lux@gmail.com) + * @since 0.0.11 + */ +public interface Version extends JsonObject { + /** + * Returns the version of the connected docker engine. + * @return Version of connected docker engine + */ + String version(); + + /** + * Returns the name of the connected docker platform. + * @return Name of the docker platform + */ + String platformName(); + + /** + * Returns the API version of the docker engine. + * @return API version + */ + String apiVersion(); + + /** + * Returns the minimum API version of the docker engine. + * @return Minimum API version + */ + String minApiVersion(); + + /** + * Returns the OS docker is running on. + * @return Name of the OS docker is running on + */ + String osName(); + + /** + * Returns the (CPU) architecture docker is running on. + * @return The (CPU) architecture docker is running on + */ + String arch(); + + /** + * Reports whether experimental docker features are enabled. + * @return Whether experimental docker features are enabled + */ + boolean experimental(); +} diff --git a/src/test/java/com/amihaiemil/docker/RtVersionTestCase.java b/src/test/java/com/amihaiemil/docker/RtVersionTestCase.java new file mode 100644 index 00000000..a69df7bf --- /dev/null +++ b/src/test/java/com/amihaiemil/docker/RtVersionTestCase.java @@ -0,0 +1,59 @@ +package com.amihaiemil.docker; + +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.HttpStatus; +import org.apache.http.StatusLine; +import org.apache.http.client.HttpClient; +import org.apache.http.client.ResponseHandler; +import org.apache.http.client.methods.HttpGet; +import org.junit.Test; + +import java.io.IOException; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +/** + * Unit tests for {@link RtVersion}. + * @author Michael Lux (michi.lux@gmail.com) + * @since 0.0.11 + */ +public class RtVersionTestCase { + /** + * Must return the same number of images as there are elements in the + * json array returned by the service. + * @throws IOException On I/O error. + */ + @Test + public final void queryDockerVersion() throws IOException { + HttpClient client = mock(HttpClient.class); + when(client.execute(any(HttpGet.class), any(ResponseHandler.class))) + .thenAnswer(invocation -> { + HttpResponse response = mock(HttpResponse.class); + HttpEntity entity = mock(HttpEntity.class); + when(response.getEntity()).thenReturn(entity); + when(entity.getContent()).thenReturn( + getClass().getClassLoader() + .getResourceAsStream("version.json")); + StatusLine statusLine = mock(StatusLine.class); + when(response.getStatusLine()).thenReturn(statusLine); + when(statusLine.getStatusCode()).thenReturn(HttpStatus.SC_OK); + return ((ReadJsonObject) invocation.getArguments()[1]) + .handleResponse(response); + }); + Docker docker = new LocalDocker(client, "v1.35"); + Version version = docker.version(); + assertEquals("19.03.3", version.version()); + assertEquals("Docker Engine - Community", version.platformName()); + assertEquals("1.40", version.apiVersion()); + assertEquals("1.12", version.minApiVersion()); + assertEquals("linux", version.osName()); + assertEquals("amd64", version.arch()); + assertTrue(version.experimental()); + } + +} diff --git a/src/test/resources/version.json b/src/test/resources/version.json new file mode 100644 index 00000000..7c0accc1 --- /dev/null +++ b/src/test/resources/version.json @@ -0,0 +1 @@ +{"Platform":{"Name":"Docker Engine - Community"},"Components":[{"Name":"Engine","Version":"19.03.3","Details":{"ApiVersion":"1.40","Arch":"amd64","BuildTime":"2019-10-08T00:59:17.000000000+00:00","Experimental":"true","GitCommit":"a872fc2f86","GoVersion":"go1.12.10","KernelVersion":"5.3.0-40-generic","MinAPIVersion":"1.12","Os":"linux"}},{"Name":"containerd","Version":"1.2.10","Details":{"GitCommit":"b34a5c8af56e510852c35414db4c1f4fa6172339"}},{"Name":"runc","Version":"1.0.0-rc8+dev","Details":{"GitCommit":"3e425f80a8c931f88e6d94a8c831b9d5aa481657"}},{"Name":"docker-init","Version":"0.18.0","Details":{"GitCommit":"fec3683"}}],"Version":"19.03.3","ApiVersion":"1.40","MinAPIVersion":"1.12","GitCommit":"a872fc2f86","GoVersion":"go1.12.10","Os":"linux","Arch":"amd64","KernelVersion":"5.3.0-40-generic","Experimental":true,"BuildTime":"2019-10-08T00:59:17.000000000+00:00"} \ No newline at end of file