Skip to content

Commit 5930597

Browse files
committed
Merge branch '__rultor'
2 parents 4008f13 + 0a63878 commit 5930597

File tree

6 files changed

+525
-120
lines changed

6 files changed

+525
-120
lines changed

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

Lines changed: 3 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,8 @@
2626
package com.amihaiemil.docker;
2727

2828
import java.io.IOException;
29-
import java.util.stream.Stream;
30-
3129
import org.apache.http.client.HttpClient;
3230

33-
import javax.json.JsonObject;
34-
3531
/**
3632
* Docker API entry point.
3733
* @author Mihai Andronache (amihaiemil@gmail.com)
@@ -48,25 +44,10 @@ public interface Docker {
4844
boolean ping() throws IOException;
4945

5046
/**
51-
* Read events from the server in real time. Pay attention:<br><br>
52-
* The Stream is <b>infinite</b>, which means you have to specify a
53-
* <b>limit</b> before calling a terminal operation on it. Otherwise,
54-
* your terminal operation will run until the Server closes the connection.
55-
* Example:
56-
* <pre>
57-
* final Docker docker = ...;
58-
* final List&lt;JsonObject&gt; firstTen = docker.events()
59-
* .limit(10).collect(Collectors.toList());
60-
* //It will wait for and return the first 10 real-time events
61-
* //from the server.
62-
* </pre>
63-
* @return The events as a {@link Stream}.
64-
* @throws IOException If an I/O error occurs.
65-
* @throws UnexpectedResponseException If the API responds with an
66-
* unexpected status.
47+
* Entry point for the Events API.
48+
* @return Events.
6749
*/
68-
Stream<JsonObject> events()
69-
throws IOException, UnexpectedResponseException;
50+
Events events();
7051

7152
/**
7253
* Entry point for the Containers API.
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
/**
2+
* Copyright (c) 2018-2020, Mihai Emil Andronache
3+
* All rights reserved.
4+
* Redistribution and use in source and binary forms, with or without
5+
* modification, are permitted provided that the following conditions are met:
6+
* 1)Redistributions of source code must retain the above copyright notice,
7+
* this list of conditions and the following disclaimer.
8+
* 2)Redistributions in binary form must reproduce the above copyright notice,
9+
* this list of conditions and the following disclaimer in the documentation
10+
* and/or other materials provided with the distribution.
11+
* 3)Neither the name of docker-java-api nor the names of its
12+
* contributors may be used to endorse or promote products derived from
13+
* this software without specific prior written permission.
14+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
18+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24+
* POSSIBILITY OF SUCH DAMAGE.
25+
*/
26+
package com.amihaiemil.docker;
27+
28+
import javax.json.JsonObject;
29+
import java.io.IOException;
30+
import java.time.LocalDateTime;
31+
import java.util.Map;
32+
import java.util.function.Supplier;
33+
import java.util.stream.Stream;
34+
35+
/**
36+
* Events API.
37+
* @author Mihai Andronache (amihaiemil@gmail.com)
38+
* @version $Id$
39+
* @since 0.0.13
40+
*/
41+
public interface Events {
42+
43+
/**
44+
* Show events created since the specified timestamp,
45+
* then stream new events.
46+
* @param timestamp Given timestamp.
47+
* @return Filtered Events.
48+
*/
49+
Events since(final LocalDateTime timestamp);
50+
51+
/**
52+
* Show events created until the specified timestamp,
53+
* then stop streaming.
54+
* @param timestamp Given timestamp.
55+
* @return Filtered Events.
56+
*/
57+
Events until(final LocalDateTime timestamp);
58+
59+
/**
60+
* Filter these Events.
61+
* @param filter Supplier of filters.
62+
* @return Filtered Events.
63+
* @see <a href="https://docs.docker.com/engine/api/v1.40/#operation/SystemEvents">Docker API Docs</a>
64+
*/
65+
Events filter(final Supplier<Map<String, Iterable<String>>> filter);
66+
67+
/**
68+
* Start monitoring these events. Pay attention:<br><br>
69+
* The Stream is <b>infinite</b>, which means you have to specify a
70+
* <b>limit</b> before calling a terminal operation on it. Otherwise,
71+
* your terminal operation will run until the Server closes the connection.
72+
* Example:
73+
* <pre>
74+
* final Docker docker = ...;
75+
* final List&lt;JsonObject&gt; firstTen = docker.events().monitor()
76+
* .limit(10).collect(Collectors.toList());
77+
* //It will wait for and return the first 10 real-time events
78+
* //from the server.
79+
* </pre>
80+
* @throws IOException If there is any I/O problem.
81+
* @throws UnexpectedResponseException If the response is not 200 OK.
82+
* @return Stream of events.
83+
*/
84+
Stream<JsonObject> monitor()
85+
throws IOException, UnexpectedResponseException;
86+
87+
/**
88+
* Docker where these events came from.
89+
* @return Docker.
90+
*/
91+
Docker docker();
92+
}

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

Lines changed: 5 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -25,23 +25,13 @@
2525
*/
2626
package com.amihaiemil.docker;
2727

28-
import java.io.ByteArrayInputStream;
2928
import java.io.IOException;
30-
import java.io.InputStream;
3129
import java.net.URI;
32-
import java.util.stream.Stream;
33-
34-
3530
import org.apache.http.HttpResponse;
3631
import org.apache.http.HttpStatus;
3732
import org.apache.http.client.HttpClient;
38-
import org.apache.http.client.methods.CloseableHttpResponse;
3933
import org.apache.http.client.methods.HttpGet;
4034

41-
import javax.json.Json;
42-
import javax.json.JsonObject;
43-
import javax.json.JsonReader;
44-
4535
/**
4636
* Restful Docker.
4737
* @author Mihai Andronache (amihaiemil@gmail.com)
@@ -78,73 +68,13 @@ public final boolean ping() throws IOException {
7868
return response.getStatusLine().getStatusCode() == HttpStatus.SC_OK;
7969
}
8070

81-
/**
82-
* Unlike other methods, we cannot implement this one using Response
83-
* Handlers, because Apache HTTP Client tries to consume the remaining
84-
* content after all the handlers have been executed, which results in
85-
* a blockage, since the underlying InputStream is potentially infinite.
86-
*
87-
* @checkstyle CommentsIndentation (100 lines)
88-
* @checkstyle Indentation (100 lines)
89-
* @return Stream of Events.
90-
* @throws IOException If any I/O problem occurs.
91-
* @throws UnexpectedResponseException If the response status is not 200.
92-
*/
9371
@Override
94-
public Stream<JsonObject> events()
95-
throws IOException, UnexpectedResponseException {
96-
final HttpGet monitor = new HttpGet(
97-
this.baseUri.toString() + "/events"
72+
public Events events() {
73+
return new RtEvents(
74+
this.client,
75+
URI.create(this.baseUri.toString() + "/events"),
76+
this
9877
);
99-
final HttpResponse response = this.client.execute(monitor);
100-
final int actual = response.getStatusLine().getStatusCode();
101-
if(actual != HttpStatus.SC_OK) {
102-
throw new UnexpectedResponseException(
103-
this.baseUri.toString() + "/events",
104-
actual, HttpStatus.SC_OK,
105-
Json.createObjectBuilder().build()
106-
);
107-
} else {
108-
final InputStream content = response.getEntity().getContent();
109-
final Stream<JsonObject> stream = Stream.generate(
110-
() -> {
111-
JsonObject read = null;
112-
try {
113-
final byte[] tmp = new byte[4096];
114-
while (content.read(tmp) != -1) {
115-
try {
116-
final JsonReader reader = Json.createReader(
117-
new ByteArrayInputStream(tmp)
118-
);
119-
read = reader.readObject();
120-
break;
121-
//@checkstyle IllegalCatch (1 line)
122-
} catch (final Exception exception) {
123-
//Couldn't parse byte[] to Json,
124-
//try to read more bytes.
125-
}
126-
}
127-
} catch (final IOException ex) {
128-
throw new IllegalStateException(
129-
"IOException when reading streamed JsonObjects!"
130-
);
131-
}
132-
return read;
133-
}
134-
).onClose(
135-
() -> {
136-
try {
137-
((CloseableHttpResponse) response).close();
138-
} catch (final IOException ex) {
139-
//There is a bug in Apache HTTPClient, when closing
140-
//an infinite InputStream: IOException is thrown
141-
//because the client still tries to read the remainder
142-
// of the closed Stream. We should ignore this case.
143-
}
144-
}
145-
);
146-
return stream;
147-
}
14878
}
14979

15080
@Override

0 commit comments

Comments
 (0)