Skip to content

Commit 383231d

Browse files
authored
feat: add ping method (#47)
Signed-off-by: weiping-code <54316849+weiping-code@users.noreply.github.com>
1 parent 8240ca0 commit 383231d

File tree

11 files changed

+175
-13
lines changed

11 files changed

+175
-13
lines changed

opengemini-client-api/src/main/java/io/opengemini/client/api/OpenGeminiAsyncClient.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,4 +73,9 @@ public interface OpenGeminiAsyncClient extends AutoCloseable {
7373
* @param points the points to write.
7474
*/
7575
CompletableFuture<Void> writeBatch(String database, List<Point> points);
76+
77+
/**
78+
* Ping the OpenGemini server
79+
*/
80+
CompletableFuture<Pong> ping();
7681
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package io.opengemini.client.api;
2+
3+
import lombok.Getter;
4+
5+
@Getter
6+
public class Pong {
7+
8+
/**
9+
* the version of OpenGemini server.
10+
*/
11+
private final String version;
12+
13+
public Pong(String version) {
14+
this.version = version;
15+
}
16+
17+
}

opengemini-client-asynchttpclient/src/main/java/io/opengemini/client/asynchttpclient/OpenGeminiAsyncHttpClient.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@
66
import io.opengemini.client.api.AuthConfig;
77
import io.opengemini.client.api.AuthType;
88
import io.opengemini.client.api.OpenGeminiException;
9+
import io.opengemini.client.api.Pong;
910
import io.opengemini.client.api.Query;
1011
import io.opengemini.client.api.QueryResult;
1112
import io.opengemini.client.common.BaseAsyncClient;
13+
import io.opengemini.client.common.HeaderConst;
1214
import io.opengemini.client.common.JacksonService;
1315
import org.asynchttpclient.AsyncHttpClient;
1416
import org.asynchttpclient.DefaultAsyncHttpClientConfig;
@@ -89,6 +91,18 @@ protected CompletableFuture<Void> executeWrite(String database, String lineProto
8991
return compose(responseFuture, Void.class);
9092
}
9193

94+
/**
95+
* Execute a ping call with AsyncHttpClient.
96+
*/
97+
@Override
98+
protected CompletableFuture<Pong> executePing() {
99+
String pingUrl = getPingUrl();
100+
return asyncHttpClient.prepareGet(nextUrlPrefix() + pingUrl)
101+
.execute()
102+
.toCompletableFuture()
103+
.thenApply(response -> new Pong(response.getHeader(HeaderConst.VERSION)));
104+
}
105+
92106
private <T> CompletableFuture<T> compose(CompletableFuture<Response> responseFuture, Class<T> type) {
93107
return responseFuture.thenCompose(response -> {
94108
HttpResponseStatus responseStatus = HttpResponseStatus.valueOf(response.getStatusCode());

opengemini-client-asynchttpclient/src/test/java/io/opengemini/client/asynchttpclient/OpenGeminiAsyncHttpClientTest.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import io.opengemini.client.api.Address;
44
import io.opengemini.client.api.OpenGeminiException;
55
import io.opengemini.client.api.Point;
6+
import io.opengemini.client.api.Pong;
67
import io.opengemini.client.api.Query;
78
import io.opengemini.client.api.QueryResult;
89
import io.opengemini.client.api.RetentionPolicy;
@@ -257,6 +258,14 @@ void retention_policy_create_failed_for_wrong_duration_param() throws Exception
257258
dropDbFuture.get();
258259
}
259260

261+
@Test
262+
void ping() throws Exception {
263+
CompletableFuture<Pong> pingFuture = openGeminiAsyncHttpClient.ping();
264+
Pong pong = pingFuture.get();
265+
266+
Assertions.assertNotNull(pong.getVersion());
267+
}
268+
260269
private static Point testPoint(String measurementName, int valueIndex, int fieldCount) {
261270
Point testPoint = new Point();
262271
testPoint.setMeasurement(measurementName);

opengemini-client-common/src/main/java/io/opengemini/client/common/BaseAsyncClient.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import io.opengemini.client.api.BaseConfiguration;
44
import io.opengemini.client.api.OpenGeminiAsyncClient;
55
import io.opengemini.client.api.Point;
6+
import io.opengemini.client.api.Pong;
67
import io.opengemini.client.api.Query;
78
import io.opengemini.client.api.QueryResult;
89
import io.opengemini.client.api.RetentionPolicy;
@@ -111,6 +112,14 @@ public CompletableFuture<Void> writeBatch(String database, List<Point> points) {
111112
return executeWrite(database, sj.toString());
112113
}
113114

115+
/**
116+
* {@inheritDoc}
117+
*/
118+
@Override
119+
public CompletableFuture<Pong> ping() {
120+
return executePing();
121+
}
122+
114123
/**
115124
* The implementation class needs to implement this method to execute a GET query call.
116125
*
@@ -133,4 +142,9 @@ public CompletableFuture<Void> writeBatch(String database, List<Point> points) {
133142
*/
134143
protected abstract CompletableFuture<Void> executeWrite(String database, String lineProtocol);
135144

145+
/**
146+
* The implementation class needs to implement this method to execute a ping call.
147+
*/
148+
protected abstract CompletableFuture<Pong> executePing();
149+
136150
}

opengemini-client-common/src/main/java/io/opengemini/client/common/BaseClient.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ protected String getWriteUrl(String database) {
4444
return UrlConst.WRITE + "?db=" + database;
4545
}
4646

47+
protected String getPingUrl() {
48+
return UrlConst.PING;
49+
}
50+
4751
protected String getQueryUrl(Query query) {
4852
String queryUrl = UrlConst.QUERY + "?q=" + encode(query.getCommand());
4953

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package io.opengemini.client.common;
2+
3+
public class HeaderConst {
4+
5+
/**
6+
* the response header name of OpenGemini version
7+
*/
8+
public static final String VERSION = "X-Geminidb-Version";
9+
10+
}

opengemini-client-jdk/src/main/java/io/opengemini/client/jdk/OpenGeminiJdkClient.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@
44
import io.opengemini.client.api.AuthConfig;
55
import io.opengemini.client.api.AuthType;
66
import io.opengemini.client.api.OpenGeminiException;
7+
import io.opengemini.client.api.Pong;
78
import io.opengemini.client.api.Query;
89
import io.opengemini.client.api.QueryResult;
910
import io.opengemini.client.api.TlsConfig;
1011
import io.opengemini.client.common.BaseAsyncClient;
12+
import io.opengemini.client.common.HeaderConst;
1113
import io.opengemini.client.common.JacksonService;
1214
import io.opengemini.client.common.UrlConst;
1315

@@ -96,6 +98,16 @@ protected CompletableFuture<Void> executeWrite(String database, String lineProto
9698
return httpExecute(writeUrl, Void.class, UrlConst.POST, HttpRequest.BodyPublishers.ofString(lineProtocol));
9799
}
98100

101+
/**
102+
* Execute a ping call with java HttpClient.
103+
*/
104+
@Override
105+
protected CompletableFuture<Pong> executePing() {
106+
String pingUrl = getPingUrl();
107+
return get(pingUrl).thenApply(response -> response.headers().firstValue(HeaderConst.VERSION).orElse(null))
108+
.thenApply(Pong::new);
109+
}
110+
99111
private <T> CompletableFuture<T> httpExecute(String url, Class<T> type) {
100112
return httpExecute(url, type, UrlConst.GET);
101113
}

opengemini-client-jdk/src/test/java/io/opengemini/client/jdk/OpenGeminiJdkClientTest.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import io.opengemini.client.api.AuthType;
66
import io.opengemini.client.api.OpenGeminiException;
77
import io.opengemini.client.api.Point;
8+
import io.opengemini.client.api.Pong;
89
import io.opengemini.client.api.Query;
910
import io.opengemini.client.api.QueryResult;
1011
import io.opengemini.client.api.RetentionPolicy;
@@ -267,4 +268,13 @@ void testRetentionPolicyError() {
267268
CompletableFuture<Void> dropdb = openGeminiJdkClient.dropDatabase(database);
268269
dropdb.get();
269270
}
271+
272+
@Test
273+
void ping() throws Exception {
274+
CompletableFuture<Pong> pingFuture = openGeminiJdkClient.ping();
275+
Pong pong = pingFuture.get();
276+
277+
Assertions.assertNotNull(pong.getVersion());
278+
}
279+
270280
}

opengemini-client-okhttp/src/main/java/io/opengemini/client/okhttp/OpenGeminiOkhttpClient.java

Lines changed: 71 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@
44
import io.opengemini.client.api.AuthConfig;
55
import io.opengemini.client.api.AuthType;
66
import io.opengemini.client.api.OpenGeminiException;
7+
import io.opengemini.client.api.Pong;
78
import io.opengemini.client.api.Query;
89
import io.opengemini.client.api.QueryResult;
910
import io.opengemini.client.api.TlsConfig;
1011
import io.opengemini.client.common.BaseAsyncClient;
12+
import io.opengemini.client.common.HeaderConst;
1113
import io.opengemini.client.common.JacksonService;
1214
import okhttp3.Call;
1315
import okhttp3.Callback;
@@ -126,8 +128,22 @@ protected CompletableFuture<Void> executeWrite(String database, String lineProto
126128
return execute(request, Void.class);
127129
}
128130

131+
/**
132+
* Execute a ping call with OkHttpClient.
133+
*/
134+
@Override
135+
protected CompletableFuture<Pong> executePing() {
136+
String pingUrl = getPingUrl();
137+
Request request = new Request.Builder().url(nextUrlPrefix() + pingUrl).get().build();
138+
return composeExtractHeader(execute(request), HeaderConst.VERSION).thenApply(Pong::new);
139+
}
140+
129141
private <T> CompletableFuture<T> execute(Request request, Class<T> type) {
130-
CompletableFuture<T> future = new CompletableFuture<>();
142+
return composeExtractBody(execute(request), type);
143+
}
144+
145+
private CompletableFuture<Response> execute(Request request) {
146+
CompletableFuture<Response> future = new CompletableFuture<>();
131147
Call call = okHttpClient.newCall(request);
132148
call.enqueue(new Callback() {
133149
@Override
@@ -136,16 +152,21 @@ public void onFailure(@NotNull Call call, @NotNull IOException e) {
136152
}
137153

138154
@Override
139-
public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
140-
int statusCode = response.code();
141-
ResponseBody responseBody = response.body();
155+
public void onResponse(@NotNull Call call, @NotNull Response response) {
156+
future.complete(response);
157+
}
158+
});
159+
return future;
160+
}
142161

143-
String responseBodyString;
144-
if (responseBody != null) {
145-
responseBodyString = responseBody.string();
146-
} else {
147-
responseBodyString = null;
148-
}
162+
private static <T> CompletableFuture<T> composeExtractBody(CompletableFuture<Response> responseFuture,
163+
Class<T> type) {
164+
return responseFuture.thenCompose(response -> {
165+
CompletableFuture<T> future = new CompletableFuture<>();
166+
167+
try {
168+
int statusCode = response.code();
169+
String responseBodyString = getResponseBodyString(response);
149170

150171
if (response.isSuccessful()) {
151172
try {
@@ -155,12 +176,49 @@ public void onResponse(@NotNull Call call, @NotNull Response response) throws IO
155176
future.completeExceptionally(e);
156177
}
157178
} else {
158-
String httpErrorMsg = responseBodyString == null ? "empty body" : responseBodyString;
159-
future.completeExceptionally(new OpenGeminiException("http error: " + httpErrorMsg, statusCode));
179+
completeUnsuccessfulResponse(future, responseBodyString, statusCode);
180+
}
181+
} catch (IOException e) {
182+
future.completeExceptionally(e);
183+
}
184+
return future;
185+
});
186+
}
187+
188+
private static CompletableFuture<String> composeExtractHeader(CompletableFuture<Response> responseFuture,
189+
String headerName) {
190+
return responseFuture.thenCompose(response -> {
191+
CompletableFuture<String> future = new CompletableFuture<>();
192+
193+
try {
194+
int statusCode = response.code();
195+
String responseBodyString = getResponseBodyString(response);
196+
197+
if (response.isSuccessful()) {
198+
future.complete(response.header(headerName));
199+
} else {
200+
completeUnsuccessfulResponse(future, responseBodyString, statusCode);
160201
}
202+
} catch (IOException e) {
203+
future.completeExceptionally(e);
161204
}
205+
return future;
162206
});
163-
return future;
207+
}
208+
209+
private static String getResponseBodyString(Response response) throws IOException {
210+
ResponseBody responseBody = response.body();
211+
if (responseBody != null) {
212+
return responseBody.string();
213+
} else {
214+
return null;
215+
}
216+
}
217+
218+
private static <T> void completeUnsuccessfulResponse(CompletableFuture<T> future, String responseBodyString,
219+
int statusCode) {
220+
String httpErrorMsg = responseBodyString == null ? "empty body" : responseBodyString;
221+
future.completeExceptionally(new OpenGeminiException("http error: " + httpErrorMsg, statusCode));
164222
}
165223

166224
@Override

0 commit comments

Comments
 (0)