Skip to content

Commit 78c9778

Browse files
author
Boris Kuzmic
committed
Fixed #194 - Implementing system/df API call
1 parent 778ff9b commit 78c9778

File tree

9 files changed

+296
-3
lines changed

9 files changed

+296
-3
lines changed
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package com.amihaiemil.docker;
2+
3+
/**
4+
* Info about Docker disk space usage in bytes.
5+
* @author Boris Kuzmic (boris.kuzmic@gmail.com)
6+
* @since 0.0.6
7+
*/
8+
public interface DiskSpaceInfo {
9+
10+
/**
11+
* Images disk usage.
12+
* @return Disk usage for images in bytes
13+
*/
14+
Long images();
15+
16+
/**
17+
* Containers disk usage.
18+
* @return Disk usage for containers in bytes
19+
*/
20+
Long containers();
21+
22+
/**
23+
* Volumes disk usage.
24+
* @return Disk usage for volumes in bytes
25+
*/
26+
Long volumes();
27+
28+
/**
29+
* Total disk usage.
30+
* @return Total disk usage in bytes
31+
*/
32+
Long totalSpace();
33+
34+
}

src/main/java/com/amihaiemil/docker/Docker.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,12 @@ public interface Docker {
8282
*/
8383
Swarm swarm();
8484

85+
/**
86+
* Entry point for the DockerSystem API.
87+
* @return DockerSystem.
88+
*/
89+
DockerSystem system();
90+
8591
/**
8692
* The underlying, immutable, Apache HttpClient.<br><br>
8793
*
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package com.amihaiemil.docker;
2+
3+
import java.io.IOException;
4+
5+
/**
6+
* Docker System API entry point.
7+
* @author Boris Kuzmic (boris.kuzmic@gmail.com)
8+
* @see <a href="https://docs.docker.com/engine/reference/commandline/system/">Docker DockerSystem API</a>
9+
* @since 0.0.6
10+
*/
11+
public interface DockerSystem {
12+
13+
/**
14+
* Show docker disk usage.
15+
* @return The created {@link DiskSpaceInfo}.
16+
* @throws IOException If an I/O error occurs.
17+
* @throws UnexpectedResponseException If the API responds with an
18+
* unexpected status.
19+
*/
20+
DiskSpaceInfo diskUsage()
21+
throws IOException, UnexpectedResponseException;
22+
23+
}

src/main/java/com/amihaiemil/docker/RtDocker.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,15 @@ public final Swarm swarm() {
120120
);
121121
}
122122

123+
@Override
124+
public DockerSystem system() {
125+
return new RtDockerSystem(
126+
this.client,
127+
URI.create(this.baseUri.toString().concat("/system")),
128+
this
129+
);
130+
}
131+
123132
@Override
124133
public HttpClient httpClient() {
125134
return this.client;
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package com.amihaiemil.docker;
2+
3+
import org.apache.http.HttpStatus;
4+
import org.apache.http.client.HttpClient;
5+
import org.apache.http.client.methods.HttpGet;
6+
7+
import java.io.IOException;
8+
import java.net.URI;
9+
10+
/**
11+
* System API.
12+
*
13+
* @author Boris Kuzmic (boris.kuzmic@gmail.com)
14+
* @since 0.0.6
15+
*/
16+
public final class RtDockerSystem implements DockerSystem {
17+
18+
/**
19+
* Apache HttpClient which sends the requests.
20+
*/
21+
private final HttpClient client;
22+
23+
/**
24+
* Base URI.
25+
*/
26+
private final URI baseUri;
27+
28+
/**
29+
* Docker engine.
30+
*/
31+
private Docker docker;
32+
33+
/**
34+
* Ctor.
35+
*
36+
* @param client Given HTTP Client.
37+
* @param baseUri Base URI, ending with /system.
38+
* @param dkr The Docker engine.
39+
*/
40+
RtDockerSystem(final HttpClient client, final URI baseUri,
41+
final Docker dkr) {
42+
this.client = client;
43+
this.baseUri = baseUri;
44+
this.docker = dkr;
45+
}
46+
47+
@Override
48+
public DiskSpaceInfo diskUsage() throws IOException,
49+
UnexpectedResponseException {
50+
final HttpGet init = new HttpGet(this.baseUri.toString() + "/df");
51+
try {
52+
return new SystemDiskSpaceInfo(this.client.execute(
53+
init,
54+
new ReadJsonObject(
55+
new MatchStatus(
56+
init.getURI(),
57+
HttpStatus.SC_OK
58+
)
59+
)
60+
));
61+
} finally {
62+
init.releaseConnection();
63+
}
64+
}
65+
66+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package com.amihaiemil.docker;
2+
3+
import javax.json.JsonArray;
4+
import javax.json.JsonObject;
5+
6+
/**
7+
* Docker disk space usage information.
8+
* @author Boris Kuzmic (boris.kuzmic@gmail.com)
9+
* @since 0.0.6
10+
*/
11+
public final class SystemDiskSpaceInfo implements DiskSpaceInfo {
12+
13+
/**
14+
* Response Json object from system/df call.
15+
*/
16+
private final JsonObject json;
17+
18+
/**
19+
* Ctor.
20+
* @param jsonObject Response Json from system/df call
21+
*/
22+
SystemDiskSpaceInfo(final JsonObject jsonObject) {
23+
this.json = jsonObject;
24+
}
25+
26+
@Override
27+
public Long images() {
28+
return this.json.getJsonNumber("LayersSize").longValue();
29+
}
30+
31+
@Override
32+
public Long containers() {
33+
Long totalContainersSpace = 0L;
34+
JsonArray containers = this.json.getJsonArray("Containers");
35+
for (int i=0; i<containers.size(); i++) {
36+
JsonObject container = containers.getJsonObject(i);
37+
totalContainersSpace +=
38+
container.getJsonNumber("SizeRootFs").longValue();
39+
}
40+
return totalContainersSpace;
41+
}
42+
43+
@Override
44+
public Long volumes() {
45+
Long totalVolumesSpace = 0L;
46+
JsonArray volumes = this.json.getJsonArray("Volumes");
47+
for (int i=0; i<volumes.size(); i++) {
48+
JsonObject volume = volumes.getJsonObject(i);
49+
totalVolumesSpace +=
50+
volume.getJsonObject("UsageData")
51+
.getJsonNumber("Size").longValue();
52+
}
53+
return totalVolumesSpace;
54+
}
55+
56+
@Override
57+
public Long totalSpace() {
58+
return this.images() + this.containers() + this.volumes();
59+
}
60+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package com.amihaiemil.docker;
2+
3+
import org.hamcrest.MatcherAssert;
4+
import org.hamcrest.Matchers;
5+
import org.junit.Test;
6+
7+
import java.io.File;
8+
9+
/**
10+
* Integration tests for RtDockerSystem.
11+
*
12+
* @author Boris Kuzmic (boris.kuzmic@gmail.com)
13+
* @since 0.0.6
14+
*/
15+
public final class RtDockerSystemITCase {
16+
17+
/**
18+
* Show Docker disk space info.
19+
* @throws Exception If something goes wrong.
20+
*/
21+
@Test
22+
public void showDiskSpaceInfo() throws Exception {
23+
final Docker docker = new LocalDocker(
24+
new File("/var/run/docker.sock")
25+
);
26+
27+
DiskSpaceInfo info = docker.system().diskUsage();
28+
29+
MatcherAssert.assertThat(info.totalSpace(),
30+
Matchers.greaterThanOrEqualTo(0L));
31+
}
32+
33+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package com.amihaiemil.docker;
2+
3+
import com.amihaiemil.docker.mock.AssertRequest;
4+
import com.amihaiemil.docker.mock.Response;
5+
import org.apache.http.HttpStatus;
6+
import org.hamcrest.MatcherAssert;
7+
import org.hamcrest.Matchers;
8+
import org.junit.Test;
9+
import org.mockito.Mockito;
10+
11+
import javax.json.Json;
12+
import java.net.URI;
13+
14+
/**
15+
* Unit tests for RtDockerSystem.
16+
*
17+
* @author Boris Kuzmic (boris.kuzmic@gmail.com)
18+
* @since 0.0.6
19+
* @checkstyle MethodName (500 lines)
20+
*/
21+
public final class RtDockerSystemTestCase {
22+
23+
/**
24+
* Must return the same disk space usage for images, containers and
25+
* volumes as in json array returned by the service.
26+
*
27+
* @throws Exception If an error occurs.
28+
*/
29+
@Test
30+
public void returnsDiskSpaceUsage() throws Exception {
31+
long totalSpace = new RtDockerSystem(
32+
new AssertRequest(
33+
new Response(
34+
HttpStatus.SC_OK,
35+
Json.createObjectBuilder()
36+
.add("LayersSize", 250)
37+
.add("Containers",
38+
Json.createArrayBuilder()
39+
.add(Json.createObjectBuilder()
40+
.add("SizeRootFs", 50))
41+
).add("Volumes",
42+
Json.createArrayBuilder()
43+
.add(
44+
Json.createObjectBuilder()
45+
.add("UsageData",
46+
Json.createObjectBuilder()
47+
.add("Size", 200)))
48+
).build().toString()
49+
)
50+
),
51+
URI.create("http://localhost/system"),
52+
Mockito.mock(Docker.class)
53+
).diskUsage().totalSpace();
54+
MatcherAssert.assertThat(
55+
totalSpace,
56+
Matchers.is(500L)
57+
);
58+
}
59+
60+
61+
}

src/test/java/com/amihaiemil/docker/RtImagesTestCase.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,16 @@
2828
import com.amihaiemil.docker.mock.AssertRequest;
2929
import com.amihaiemil.docker.mock.Condition;
3030
import com.amihaiemil.docker.mock.Response;
31-
import java.net.URI;
32-
import java.util.concurrent.atomic.AtomicInteger;
33-
import javax.json.Json;
3431
import org.apache.http.HttpStatus;
3532
import org.hamcrest.MatcherAssert;
3633
import org.hamcrest.Matchers;
3734
import org.junit.Test;
3835
import org.mockito.Mockito;
3936

37+
import javax.json.Json;
38+
import java.net.URI;
39+
import java.util.concurrent.atomic.AtomicInteger;
40+
4041
/**
4142
* Unit tests for {@link RtImages}.
4243
* @author George Aristy (george.aristy@gmail.com)

0 commit comments

Comments
 (0)