Skip to content

Commit

Permalink
RtImages.iterator() + tests
Browse files Browse the repository at this point in the history
  • Loading branch information
amihaiemil committed May 24, 2018
1 parent 0eb4a99 commit 69d31d3
Show file tree
Hide file tree
Showing 11 changed files with 207 additions and 57 deletions.
2 changes: 1 addition & 1 deletion src/main/java/com/amihaiemil/docker/Image.java
Expand Up @@ -35,7 +35,7 @@
* @see <a href="https://docs.docker.com/engine/api/v1.35/#tag/Image">Docker Images API</a>
* @since 0.0.1
*/
public interface Image {
public interface Image extends JsonObject {

/**
* Return low-level information about this image.
Expand Down
8 changes: 0 additions & 8 deletions src/main/java/com/amihaiemil/docker/Images.java
Expand Up @@ -38,14 +38,6 @@
* Images interface. See the docs referenced above for more details.
*/
public interface Images extends Iterable<Image> {
/**
* All images on the docker server.
* @return The images.
* @throws IOException If an I/O error occurs.
* @throws UnexpectedResponseException If the API responds with an
* unexpected status.
*/
Iterable<Image> iterate() throws IOException, UnexpectedResponseException;

/**
* Creates an image by pulling it from a registry.
Expand Down
1 change: 0 additions & 1 deletion src/main/java/com/amihaiemil/docker/JsonResource.java
Expand Up @@ -89,7 +89,6 @@ public String getString(final String name) {

@Override
public String getString(final String name, final String defaultValue) {
// new ResourcesIterator<Container>().
return this.resource.getString(name, defaultValue);
}

Expand Down
5 changes: 1 addition & 4 deletions src/main/java/com/amihaiemil/docker/MatchStatus.java
Expand Up @@ -25,10 +25,8 @@
*/
package com.amihaiemil.docker;

import java.io.IOException;
import java.net.URI;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler;

/**
Expand Down Expand Up @@ -61,8 +59,7 @@ final class MatchStatus implements ResponseHandler<HttpResponse> {
}

@Override
public HttpResponse handleResponse(final HttpResponse response)
throws ClientProtocolException, IOException {
public HttpResponse handleResponse(final HttpResponse response) {
final int actual = response.getStatusLine().getStatusCode();
if(actual != this.expected) {
throw new UnexpectedResponseException(
Expand Down
65 changes: 65 additions & 0 deletions src/main/java/com/amihaiemil/docker/ReadJsonArray.java
@@ -0,0 +1,65 @@
/**
* Copyright (c) 2018, 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.HttpResponse;
import org.apache.http.client.ResponseHandler;
import javax.json.Json;
import javax.json.JsonArray;
import java.io.IOException;

/**
* Handler that reads a JsonArray from the response.
* @author Mihai Andronache (amihaiemil@gmail.com)
* @version $Id$
* @since 0.0.
* @todo #84:30min Write some unit tests for this class, it is
* currently only tested by RtImagesITCase#iteratesImages.
*/
final class ReadJsonArray implements ResponseHandler<JsonArray> {

/**
* Handlers to be executed before actually reading the array.
*/
private final ResponseHandler<HttpResponse> other;

/**
* Ctor.
* @param other Handlers to be executed before actually reading the array.
*/
ReadJsonArray(final ResponseHandler<HttpResponse> other) {
this.other = other;
}

@Override
public JsonArray handleResponse(final HttpResponse httpResponse)
throws IOException {
final HttpResponse resp = this.other.handleResponse(httpResponse);
return Json.createReader(
resp.getEntity().getContent()
).readArray();
}
}
53 changes: 50 additions & 3 deletions src/main/java/com/amihaiemil/docker/ResourcesIterator.java
Expand Up @@ -25,23 +25,70 @@
*/
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.JsonArray;
import javax.json.JsonObject;
import java.io.IOException;
import java.util.Iterator;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
* Iterator over Docker resources (Containers, Images etc).
* @author Mihai Andronache (amihaiemil@gmail.com)
* @version $Id$
* @since 0.0.1
* @param <T> The Json resoure (Image, Container etc) returned by the API.
*/
public class ResourcesIterator<T extends JsonObject> implements Iterator<T> {
final class ResourcesIterator<T extends JsonObject> implements Iterator<T> {

/**
* Iterated resources.
*/
private final Iterator<T> resources;

/**
* Ctor.
* @param client Used HTTP Client.
* @param request HTTP Request.
* @param mapper Function which should map the received JsonObject
* to the specified resource.
*/
ResourcesIterator(
final HttpClient client, final HttpGet request,
final Function<JsonObject, T> mapper
) {
try {
final JsonArray array = client.execute(
request,
new ReadJsonArray(
new MatchStatus(request.getURI(), HttpStatus.SC_OK)
)
);
this.resources = array.stream()
.map(json -> (JsonObject) json)
.map(
json -> mapper.apply(json)
).collect(Collectors.toList())
.iterator();
} catch (final IOException ex) {
throw new IllegalStateException(
"IOException when calling " + request.getURI().toString(), ex
);
} finally {
request.releaseConnection();
}
}

@Override
public boolean hasNext() {
return false;
return this.resources.hasNext();
}

@Override
public T next() {
return null;
return this.resources.next();
}
}
6 changes: 4 additions & 2 deletions src/main/java/com/amihaiemil/docker/RtImage.java
Expand Up @@ -39,7 +39,7 @@
* @version $Id$
* @since 0.0.1
*/
final class RtImage implements Image {
final class RtImage extends JsonResource implements Image {
/**
* Apache HttpClient which sends the requests.
*/
Expand All @@ -52,10 +52,12 @@ final class RtImage implements Image {

/**
* Ctor.
* @param rep JsonObject representation of this Image.
* @param client The http client.
* @param uri The URI for this image.
*/
RtImage(final HttpClient client, final URI uri) {
RtImage(final JsonObject rep, final HttpClient client, final URI uri) {
super(rep);
this.client = client;
this.baseUri = uri;
}
Expand Down
46 changes: 11 additions & 35 deletions src/main/java/com/amihaiemil/docker/RtImages.java
Expand Up @@ -29,10 +29,6 @@
import java.net.URI;
import java.net.URL;
import java.util.Iterator;
import java.util.stream.Collectors;
import javax.json.Json;
import javax.json.JsonObject;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
Expand Down Expand Up @@ -65,31 +61,6 @@ final class RtImages implements Images {
this.baseUri = uri;
}

@Override
public Iterable<Image> iterate() throws IOException {
final HttpGet get = new HttpGet(
this.baseUri.toString().concat("/json")
);
try {
final HttpResponse response = this.client.execute(
get,
new MatchStatus(get.getURI(), HttpStatus.SC_OK)
);
return Json.createReader(response.getEntity().getContent())
.readArray()
.stream()
.map(json -> (JsonObject) json)
.map(json -> new RtImage(
this.client,
URI.create(
this.baseUri.toString() + "/" + json.getString("Id")
)
)).collect(Collectors.toList());
} finally {
get.releaseConnection();
}
}

// @checkstyle ParameterNumber (4 lines)
@Override
public Images create(
Expand Down Expand Up @@ -129,14 +100,19 @@ public void prune() throws IOException, UnexpectedResponseException {
}
}


// @todo #84:30min Should return an Iterator<? extends JsonResource>
// which would take a Request, a HttpClient and a Mapper in its ctor,
// to know how to map each JsonObject to its resource type
// (Image, Containter etc)
@Override
public Iterator<Image> iterator() {
throw new UnsupportedOperationException("Not supported yet.");
return new ResourcesIterator<Image>(
this.client,
new HttpGet(this.baseUri.toString().concat("/json")),
json-> new RtImage(
json,
this.client,
URI.create(
this.baseUri.toString() + "/" + json.getString("Id")
)
)
);
}

}
11 changes: 11 additions & 0 deletions src/test/java/com/amihaiemil/docker/RtImageTestCase.java
Expand Up @@ -52,6 +52,7 @@ public final class RtImageTestCase {
@Test
public void inspectsItself() throws Exception {
final Image image = new RtImage(
Json.createObjectBuilder().build(),
new AssertRequest(
new Response(
HttpStatus.SC_OK,
Expand Down Expand Up @@ -97,6 +98,7 @@ public void inspectsItself() throws Exception {
public void returnsHistory() {
MatcherAssert.assertThat(
new RtImage(
Json.createObjectBuilder().build(),
new AssertRequest(
new Response(
HttpStatus.SC_OK,
Expand All @@ -119,6 +121,7 @@ public void returnsHistory() {
@Test
public void deleteSendsCorrectRequest() throws Exception {
new RtImage(
Json.createObjectBuilder().build(),
new AssertRequest(
new Response(HttpStatus.SC_OK),
new Condition(
Expand All @@ -144,6 +147,7 @@ public void deleteSendsCorrectRequest() throws Exception {
@Test(expected = UnexpectedResponseException.class)
public void deleteErrorOn404() throws Exception {
new RtImage(
Json.createObjectBuilder().build(),
new AssertRequest(
new Response(HttpStatus.SC_NOT_FOUND)
),
Expand All @@ -159,6 +163,7 @@ public void deleteErrorOn404() throws Exception {
@Test(expected = UnexpectedResponseException.class)
public void deleteErrorOn409() throws Exception {
new RtImage(
Json.createObjectBuilder().build(),
new AssertRequest(
new Response(HttpStatus.SC_CONFLICT)
),
Expand All @@ -174,6 +179,7 @@ public void deleteErrorOn409() throws Exception {
@Test(expected = UnexpectedResponseException.class)
public void deleteErrorOn500() throws Exception {
new RtImage(
Json.createObjectBuilder().build(),
new AssertRequest(
new Response(HttpStatus.SC_INTERNAL_SERVER_ERROR)
),
Expand All @@ -190,6 +196,7 @@ public void deleteErrorOn500() throws Exception {
@Test
public void tagsOk() throws Exception {
new RtImage(
Json.createObjectBuilder().build(),
new AssertRequest(
new Response(HttpStatus.SC_CREATED),
new Condition(
Expand All @@ -215,6 +222,7 @@ public void tagsOk() throws Exception {
@Test(expected = UnexpectedResponseException.class)
public void tagErrorIfResponseIs400() throws Exception {
new RtImage(
Json.createObjectBuilder().build(),
new AssertRequest(
new Response(HttpStatus.SC_BAD_REQUEST)
),
Expand All @@ -230,6 +238,7 @@ public void tagErrorIfResponseIs400() throws Exception {
@Test(expected = UnexpectedResponseException.class)
public void tagErrorIfResponseIs404() throws Exception {
new RtImage(
Json.createObjectBuilder().build(),
new AssertRequest(
new Response(HttpStatus.SC_NOT_FOUND)
),
Expand All @@ -245,6 +254,7 @@ public void tagErrorIfResponseIs404() throws Exception {
@Test(expected = UnexpectedResponseException.class)
public void tagErrorIfResponseIs409() throws Exception {
new RtImage(
Json.createObjectBuilder().build(),
new AssertRequest(
new Response(HttpStatus.SC_CONFLICT)
),
Expand All @@ -260,6 +270,7 @@ public void tagErrorIfResponseIs409() throws Exception {
@Test(expected = UnexpectedResponseException.class)
public void tagErrorIfResponseIs500() throws Exception {
new RtImage(
Json.createObjectBuilder().build(),
new AssertRequest(
new Response(HttpStatus.SC_INTERNAL_SERVER_ERROR)
),
Expand Down

0 comments on commit 69d31d3

Please sign in to comment.