Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/main/java/com/amihaiemil/docker/Docker.java
Original file line number Diff line number Diff line change
Expand Up @@ -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.<br><br>
*
Expand Down
9 changes: 9 additions & 0 deletions src/main/java/com/amihaiemil/docker/RtDocker.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
137 changes: 137 additions & 0 deletions src/main/java/com/amihaiemil/docker/RtVersion.java
Original file line number Diff line number Diff line change
@@ -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 ([email protected])
* @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));
Copy link
Owner

@amihaiemil amihaiemil Feb 19, 2020

Choose a reason for hiding this comment

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

@milux Well, this fetch method goes a little against the architecture. How you did it before, it was ok. But I can change it later without modifying the interfaces, so it's ok.

}

/**
* 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");
}
}
Copy link
Owner

Choose a reason for hiding this comment

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

@milux We also need unit tests. See how other unit tests are written, it's not complicated. Generally, PRs should not decrease code coverage.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done, although the method I wrote the unit test is somewhat different from that of the other tests. (Using locally stored JSON resource file for response mockup, for instance.) Hope you're still fine with this...

Copy link
Owner

Choose a reason for hiding this comment

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

@milux Yes, it's fine. It can be changed later, no prob.

52 changes: 52 additions & 0 deletions src/main/java/com/amihaiemil/docker/Version.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package com.amihaiemil.docker;

import javax.json.JsonObject;

/**
* Version API.
* @author Michael Lux ([email protected])
* @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();
}
Copy link
Owner

Choose a reason for hiding this comment

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

@milux We should also have accesor methods, since the JsonObject has quite a few attributes, as I see.
Also, it would be nice to have the docker() method as well, which returns the parent Docker instance.

If you already spent too much time, please leave a puzzle for continuing implementation.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done, plus I have no clue what those "puzzles" are? Read about it somewhere in your code, but didn't quite get it. Can you provide an example for better understanding?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed the local variables because I think they're pointless anyway. Can undo this if you think differently.

Copy link
Owner

Choose a reason for hiding this comment

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

@milux Can you remove the get and is prefixes from the methods name? I never use them, they are just noise in the code :)

I also don't see the docker() method, can you add it?

59 changes: 59 additions & 0 deletions src/test/java/com/amihaiemil/docker/RtVersionTestCase.java
Original file line number Diff line number Diff line change
@@ -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 ([email protected])
* @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());
}

}
1 change: 1 addition & 0 deletions src/test/resources/version.json
Original file line number Diff line number Diff line change
@@ -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"}