Skip to content

Commit

Permalink
backport latest client changes from nbusy
Browse files Browse the repository at this point in the history
  • Loading branch information
soygul committed Feb 23, 2016
1 parent 64b3b8e commit bc73c36
Show file tree
Hide file tree
Showing 9 changed files with 115 additions and 80 deletions.
18 changes: 9 additions & 9 deletions src/main/java/neptulon/client/Conn.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package neptulon.client;

import neptulon.client.callbacks.ConnCallback;
import neptulon.client.callbacks.ResCallback;

/**
* Neptulon connection interface: https://github.com/neptulon/neptulon
*/
Expand All @@ -26,14 +29,11 @@ public interface Conn {
void middleware(Middleware mw);

/**
* Connects to the given WebSocket server.
*/
void connect();

/**
* Whether the connection is established.
* Connects to the given Neptulon server.
*
* @param handler Handler for connection/disconnection events.
*/
boolean isConnected();
void connect(ConnCallback handler);

/**
* Returns the remote network address.
Expand All @@ -43,12 +43,12 @@ public interface Conn {
/**
* Sends a JSON-RPC request through the connection with an auto generated request ID.
*/
<T> void sendRequest(String method, T params, ResHandler resHandler);
<T> void sendRequest(String method, T params, ResCallback cb);

/**
* Sends a JSON-RPC request through the connection, with array params and auto generated request ID.
*/
void sendRequestArr(String method, ResHandler handler, Object... params);
void sendRequestArr(String method, ResCallback cb, Object... params);

/**
* Closes the connection.
Expand Down
29 changes: 16 additions & 13 deletions src/main/java/neptulon/client/ConnImpl.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package neptulon.client;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

import java.io.IOException;
import java.util.ArrayList;
Expand All @@ -11,6 +12,8 @@
import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;

import neptulon.client.callbacks.ConnCallback;
import neptulon.client.callbacks.ResCallback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
Expand All @@ -26,14 +29,15 @@
*/
public class ConnImpl implements Conn, WebSocketListener {
private static final Logger logger = Logger.getLogger(ConnImpl.class.getSimpleName());
private final Gson gson = new Gson();
private final Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX").create();
private final OkHttpClient client;
private final Request request;
private final WebSocketCall wsCall;
private final List<Middleware> middleware = new ArrayList<>();
private final Map<String, ResHandler> resHandlers = new HashMap<>();
private final Map<String, ResCallback> resCallbacks = new HashMap<>();
private WebSocket ws;
private boolean connected;
private ConnCallback connCallback;

/**
* Initializes a new connection with given server URL.
Expand Down Expand Up @@ -96,31 +100,27 @@ public void middleware(Middleware mw) {
// handleRequest(method, .....) { if isClientConn... else exception } // same goes for go-client

@Override
public void connect() {
public void connect(ConnCallback handler) {
// enqueue this listener implementation to initiate the WebSocket connection
connCallback = handler;
wsCall.enqueue(this);
}

@Override
public boolean isConnected() {
return ws != null && connected;
}

@Override
public void remoteAddr() {

}

@Override
public <T> void sendRequest(String method, T params, ResHandler handler) {
public <T> void sendRequest(String method, T params, ResCallback cb) {
String id = UUID.randomUUID().toString();
neptulon.client.Request r = new neptulon.client.Request<>(id, method, params);
send(r);
resHandlers.put(id, handler);
resCallbacks.put(id, cb);
}

@Override
public void sendRequestArr(String method, ResHandler handler, Object... params) {
public void sendRequestArr(String method, ResCallback cb, Object... params) {

}

Expand All @@ -143,12 +143,15 @@ public void onOpen(WebSocket webSocket, Response response) {
ws = webSocket;
connected = true;
logger.info("WebSocket connected.");
connCallback.connected();
}

@Override
public void onFailure(IOException e, Response response) {
connected = false;
logger.warning("WebSocket connection closed with error: " + e.getMessage());
String reason = e.getMessage();
logger.warning("WebSocket connection closed with error: " + reason);
connCallback.disconnected(reason);
}

@Override
Expand All @@ -158,7 +161,7 @@ public void onMessage(ResponseBody message) throws IOException {
Message msg = gson.fromJson(msgStr, Message.class);
if (msg.method == null || msg.method.isEmpty()) {
// handle response message
resHandlers.get(msg.id).execute(gson, msg);
resCallbacks.get(msg.id).handleResponse(new ResCtx(msg.id, msg.result, msg.error, gson));
return;
}

Expand Down
1 change: 0 additions & 1 deletion src/main/java/neptulon/client/Middleware.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,3 @@
public interface Middleware {
void handler(ReqCtx ctx);
}

4 changes: 0 additions & 4 deletions src/main/java/neptulon/client/ReqCtx.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,6 @@ public ReqCtx(ConnImpl conn, String id, String method, JsonElement params, List<
this.gson = gson;
}

public Conn getConn() {
return conn;
}

public String getID() {
return id;
}
Expand Down
30 changes: 30 additions & 0 deletions src/main/java/neptulon/client/ResCtx.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package neptulon.client;

import com.google.gson.Gson;
import com.google.gson.JsonElement;

/**
* Response context.
*/
public class ResCtx {
private final String id;
private final JsonElement result; // result parameters
private final Message.ResError error; // response error (if any)
private final Gson gson;

public ResCtx(String id, JsonElement result, Message.ResError error, Gson gson) {
this.id = id;
this.result = result;
this.error = error;
this.gson = gson;
}

public String getID() {
return id;
}


public <T> T getResult(Class<T> classOfT) {
return gson.fromJson(result, classOfT);
}
}
16 changes: 0 additions & 16 deletions src/main/java/neptulon/client/ResHandler.java

This file was deleted.

9 changes: 9 additions & 0 deletions src/main/java/neptulon/client/callbacks/ConnCallback.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package neptulon.client.callbacks;

/**
* Callback for connection event.
*/
public interface ConnCallback {
void connected();
void disconnected(String reason);
}
11 changes: 11 additions & 0 deletions src/main/java/neptulon/client/callbacks/ResCallback.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package neptulon.client.callbacks;

import neptulon.client.ResCtx;

/**
* Callback for responses.
*/
public interface ResCallback {
void handleResponse(ResCtx ctx);
}

77 changes: 40 additions & 37 deletions src/test/java/neptulon/client/NeptulonTest.java
Original file line number Diff line number Diff line change
@@ -1,20 +1,36 @@
package neptulon.client;

import neptulon.client.callbacks.ConnCallback;
import neptulon.client.callbacks.ResCallback;
import neptulon.client.middleware.Echo;
import neptulon.client.middleware.Logger;
import neptulon.client.middleware.Router;

import org.junit.Test;

import java.util.concurrent.CountDownLatch;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.IsEqual.equalTo;
import java.util.concurrent.TimeUnit;

public class NeptulonTest {
private static final String URL = "ws://127.0.0.1:3001";

private boolean isTravis() {
return System.getenv().containsKey("TRAVIS");
}

private class EchoMessage {
final String message;

EchoMessage(String message) {
this.message = message;
}
}

/**
* External client test case in line with the Neptulon external client test case specs and event flow.
*/
@Test
public void connect() throws InterruptedException {
public void testExternalClient() throws InterruptedException {
if (isTravis()) {
return;
}
Expand All @@ -25,51 +41,38 @@ public void connect() throws InterruptedException {
router.request("echo", new Echo());
conn.middleware(router);

conn.connect();
Thread.sleep(100);
assertThat("Connection was not established in time.", conn.isConnected());

final CountDownLatch counter = new CountDownLatch(2); // todo: add one more for ws.onClose

conn.sendRequest("echo", new EchoMessage("Hello from Java client!"), new ResHandler<Object>() {
final CountDownLatch connCounter = new CountDownLatch(1);
conn.connect(new ConnCallback() {
@Override
public Class<Object> getType() {
return Object.class;
public void connected() {
connCounter.countDown();
}

@Override
public void handler(Response<Object> res) {
System.out.println("Received 'echo' response: " + res.result);
counter.countDown();
public void disconnected(String reason) {
}
});
connCounter.await(3, TimeUnit.SECONDS);

conn.sendRequest("close", new EchoMessage("Bye from Java client!"), new ResHandler<Object>() {
final CountDownLatch msgCounter = new CountDownLatch(2);
conn.sendRequest("echo", new EchoMessage("Hello from Java client!"), new ResCallback() {
@Override
public Class<Object> getType() {
return Object.class;
public void handleResponse(ResCtx ctx) {
Object res = ctx.getResult(Object.class);
System.out.println("Received 'echo' response: " + res);
msgCounter.countDown();
}

});
conn.sendRequest("close", new EchoMessage("Bye from Java client!"), new ResCallback() {
@Override
public void handler(Response<Object> res) {
System.out.println("Received 'close' response: " + res.result);
counter.countDown();
public void handleResponse(ResCtx ctx) {
Object res = ctx.getResult(Object.class);
System.out.println("Received 'close' response: " + res);
msgCounter.countDown();
}
});
msgCounter.await(3, TimeUnit.SECONDS);

counter.await();
conn.close();
}

private boolean isTravis() {
return System.getenv().containsKey("TRAVIS");
}

private class EchoMessage {
final String message;

EchoMessage(String message) {
this.message = message;
}
}
}
}

0 comments on commit bc73c36

Please sign in to comment.