Skip to content

Commit

Permalink
Fixed #194 - Implementing system/df API call
Browse files Browse the repository at this point in the history
  • Loading branch information
Boris Kuzmic committed Dec 3, 2018
1 parent 778ff9b commit 78c9778
Show file tree
Hide file tree
Showing 9 changed files with 296 additions and 3 deletions.
34 changes: 34 additions & 0 deletions src/main/java/com/amihaiemil/docker/DiskSpaceInfo.java
@@ -0,0 +1,34 @@
package com.amihaiemil.docker;

/**
* Info about Docker disk space usage in bytes.
* @author Boris Kuzmic (boris.kuzmic@gmail.com)
* @since 0.0.6
*/
public interface DiskSpaceInfo {

/**
* Images disk usage.
* @return Disk usage for images in bytes
*/
Long images();

/**
* Containers disk usage.
* @return Disk usage for containers in bytes
*/
Long containers();

/**
* Volumes disk usage.
* @return Disk usage for volumes in bytes
*/
Long volumes();

/**
* Total disk usage.
* @return Total disk usage in bytes
*/
Long totalSpace();

}
6 changes: 6 additions & 0 deletions src/main/java/com/amihaiemil/docker/Docker.java
Expand Up @@ -82,6 +82,12 @@ public interface Docker {
*/
Swarm swarm();

/**
* Entry point for the DockerSystem API.
* @return DockerSystem.
*/
DockerSystem system();

/**
* The underlying, immutable, Apache HttpClient.<br><br>
*
Expand Down
23 changes: 23 additions & 0 deletions src/main/java/com/amihaiemil/docker/DockerSystem.java
@@ -0,0 +1,23 @@
package com.amihaiemil.docker;

import java.io.IOException;

/**
* Docker System API entry point.
* @author Boris Kuzmic (boris.kuzmic@gmail.com)
* @see <a href="https://docs.docker.com/engine/reference/commandline/system/">Docker DockerSystem API</a>
* @since 0.0.6
*/
public interface DockerSystem {

/**
* Show docker disk usage.
* @return The created {@link DiskSpaceInfo}.
* @throws IOException If an I/O error occurs.
* @throws UnexpectedResponseException If the API responds with an
* unexpected status.
*/
DiskSpaceInfo diskUsage()
throws IOException, UnexpectedResponseException;

}
9 changes: 9 additions & 0 deletions src/main/java/com/amihaiemil/docker/RtDocker.java
Expand Up @@ -120,6 +120,15 @@ public final Swarm swarm() {
);
}

@Override
public DockerSystem system() {
return new RtDockerSystem(
this.client,
URI.create(this.baseUri.toString().concat("/system")),
this
);
}

@Override
public HttpClient httpClient() {
return this.client;
Expand Down
66 changes: 66 additions & 0 deletions src/main/java/com/amihaiemil/docker/RtDockerSystem.java
@@ -0,0 +1,66 @@
package com.amihaiemil.docker;

import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;

import java.io.IOException;
import java.net.URI;

/**
* System API.
*
* @author Boris Kuzmic (boris.kuzmic@gmail.com)
* @since 0.0.6
*/
public final class RtDockerSystem implements DockerSystem {

/**
* Apache HttpClient which sends the requests.
*/
private final HttpClient client;

/**
* Base URI.
*/
private final URI baseUri;

/**
* Docker engine.
*/
private Docker docker;

/**
* Ctor.
*
* @param client Given HTTP Client.
* @param baseUri Base URI, ending with /system.
* @param dkr The Docker engine.
*/
RtDockerSystem(final HttpClient client, final URI baseUri,
final Docker dkr) {
this.client = client;
this.baseUri = baseUri;
this.docker = dkr;
}

@Override
public DiskSpaceInfo diskUsage() throws IOException,
UnexpectedResponseException {
final HttpGet init = new HttpGet(this.baseUri.toString() + "/df");
try {
return new SystemDiskSpaceInfo(this.client.execute(
init,
new ReadJsonObject(
new MatchStatus(
init.getURI(),
HttpStatus.SC_OK
)
)
));
} finally {
init.releaseConnection();
}
}

}
60 changes: 60 additions & 0 deletions src/main/java/com/amihaiemil/docker/SystemDiskSpaceInfo.java
@@ -0,0 +1,60 @@
package com.amihaiemil.docker;

import javax.json.JsonArray;
import javax.json.JsonObject;

/**
* Docker disk space usage information.
* @author Boris Kuzmic (boris.kuzmic@gmail.com)
* @since 0.0.6
*/
public final class SystemDiskSpaceInfo implements DiskSpaceInfo {

/**
* Response Json object from system/df call.
*/
private final JsonObject json;

/**
* Ctor.
* @param jsonObject Response Json from system/df call
*/
SystemDiskSpaceInfo(final JsonObject jsonObject) {
this.json = jsonObject;
}

@Override
public Long images() {
return this.json.getJsonNumber("LayersSize").longValue();
}

@Override
public Long containers() {
Long totalContainersSpace = 0L;
JsonArray containers = this.json.getJsonArray("Containers");
for (int i=0; i<containers.size(); i++) {
JsonObject container = containers.getJsonObject(i);
totalContainersSpace +=
container.getJsonNumber("SizeRootFs").longValue();
}
return totalContainersSpace;
}

@Override
public Long volumes() {
Long totalVolumesSpace = 0L;
JsonArray volumes = this.json.getJsonArray("Volumes");
for (int i=0; i<volumes.size(); i++) {
JsonObject volume = volumes.getJsonObject(i);
totalVolumesSpace +=
volume.getJsonObject("UsageData")
.getJsonNumber("Size").longValue();
}
return totalVolumesSpace;
}

@Override
public Long totalSpace() {
return this.images() + this.containers() + this.volumes();
}
}
33 changes: 33 additions & 0 deletions src/test/java/com/amihaiemil/docker/RtDockerSystemITCase.java
@@ -0,0 +1,33 @@
package com.amihaiemil.docker;

import org.hamcrest.MatcherAssert;
import org.hamcrest.Matchers;
import org.junit.Test;

import java.io.File;

/**
* Integration tests for RtDockerSystem.
*
* @author Boris Kuzmic (boris.kuzmic@gmail.com)
* @since 0.0.6
*/
public final class RtDockerSystemITCase {

/**
* Show Docker disk space info.
* @throws Exception If something goes wrong.
*/
@Test
public void showDiskSpaceInfo() throws Exception {
final Docker docker = new LocalDocker(
new File("/var/run/docker.sock")
);

DiskSpaceInfo info = docker.system().diskUsage();

MatcherAssert.assertThat(info.totalSpace(),
Matchers.greaterThanOrEqualTo(0L));
}

}
61 changes: 61 additions & 0 deletions src/test/java/com/amihaiemil/docker/RtDockerSystemTestCase.java
@@ -0,0 +1,61 @@
package com.amihaiemil.docker;

import com.amihaiemil.docker.mock.AssertRequest;
import com.amihaiemil.docker.mock.Response;
import org.apache.http.HttpStatus;
import org.hamcrest.MatcherAssert;
import org.hamcrest.Matchers;
import org.junit.Test;
import org.mockito.Mockito;

import javax.json.Json;
import java.net.URI;

/**
* Unit tests for RtDockerSystem.
*
* @author Boris Kuzmic (boris.kuzmic@gmail.com)
* @since 0.0.6
* @checkstyle MethodName (500 lines)
*/
public final class RtDockerSystemTestCase {

/**
* Must return the same disk space usage for images, containers and
* volumes as in json array returned by the service.
*
* @throws Exception If an error occurs.
*/
@Test
public void returnsDiskSpaceUsage() throws Exception {
long totalSpace = new RtDockerSystem(
new AssertRequest(
new Response(
HttpStatus.SC_OK,
Json.createObjectBuilder()
.add("LayersSize", 250)
.add("Containers",
Json.createArrayBuilder()
.add(Json.createObjectBuilder()
.add("SizeRootFs", 50))
).add("Volumes",
Json.createArrayBuilder()
.add(
Json.createObjectBuilder()
.add("UsageData",
Json.createObjectBuilder()
.add("Size", 200)))
).build().toString()
)
),
URI.create("http://localhost/system"),
Mockito.mock(Docker.class)
).diskUsage().totalSpace();
MatcherAssert.assertThat(
totalSpace,
Matchers.is(500L)
);
}


}
7 changes: 4 additions & 3 deletions src/test/java/com/amihaiemil/docker/RtImagesTestCase.java
Expand Up @@ -28,15 +28,16 @@
import com.amihaiemil.docker.mock.AssertRequest;
import com.amihaiemil.docker.mock.Condition;
import com.amihaiemil.docker.mock.Response;
import java.net.URI;
import java.util.concurrent.atomic.AtomicInteger;
import javax.json.Json;
import org.apache.http.HttpStatus;
import org.hamcrest.MatcherAssert;
import org.hamcrest.Matchers;
import org.junit.Test;
import org.mockito.Mockito;

import javax.json.Json;
import java.net.URI;
import java.util.concurrent.atomic.AtomicInteger;

/**
* Unit tests for {@link RtImages}.
* @author George Aristy (george.aristy@gmail.com)
Expand Down

0 comments on commit 78c9778

Please sign in to comment.