Merge pull request #3094 from aspnet/release/2.2

Merge release/2.2
This commit is contained in:
Mikael Mengistu 2018-10-08 15:57:17 -07:00 committed by GitHub
commit f861de3cd0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 152 additions and 214 deletions

View File

@ -3,30 +3,24 @@
package com.microsoft.aspnet.signalr; package com.microsoft.aspnet.signalr;
import java.util.ArrayList; import java.util.*;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
class CallbackMap { class CallbackMap {
private ConcurrentHashMap<String, List<InvocationHandler>> handlers = new ConcurrentHashMap<>(); private Map<String, List<InvocationHandler>> handlers = new ConcurrentHashMap<>();
public InvocationHandler put(String target, ActionBase action, ArrayList<Class<?>> classes) { public InvocationHandler put(String target, ActionBase action, Class<?>... classes) {
InvocationHandler handler = new InvocationHandler(action, Collections.unmodifiableList(classes)); InvocationHandler handler = new InvocationHandler(action, classes);
handlers.compute(target, (key, value) -> {
handlers.computeIfPresent(target, (methodName, handlerList) -> { if (value == null) {
handlerList.add(handler); value = new ArrayList<>();
return handlerList; }
value.add(handler);
return value;
}); });
handlers.computeIfAbsent(target, (ac) -> new ArrayList<>(Arrays.asList(handler)));
return handler; return handler;
} }
public Boolean containsKey(String key) {
return handlers.containsKey(key);
}
public List<InvocationHandler> get(String key) { public List<InvocationHandler> get(String key) {
return handlers.get(key); return handlers.get(key);
} }

View File

@ -3,8 +3,8 @@
package com.microsoft.aspnet.signalr; package com.microsoft.aspnet.signalr;
class CloseMessage extends HubMessage { final class CloseMessage extends HubMessage {
private String error; private final String error;
@Override @Override
public HubMessageType getMessageType() { public HubMessageType getMessageType() {
@ -12,6 +12,7 @@ class CloseMessage extends HubMessage {
} }
public CloseMessage() { public CloseMessage() {
this(null);
} }
public CloseMessage(String error) { public CloseMessage(String error) {

View File

@ -3,15 +3,14 @@
package com.microsoft.aspnet.signalr; package com.microsoft.aspnet.signalr;
class CompletionMessage extends HubMessage { final class CompletionMessage extends HubMessage {
private int type = HubMessageType.COMPLETION.value; private final int type = HubMessageType.COMPLETION.value;
private String invocationId; private final String invocationId;
private Object result; private final Object result;
private String error; private final String error;
public CompletionMessage(String invocationId, Object result, String error) { public CompletionMessage(String invocationId, Object result, String error) {
if (error != null && result != null) if (error != null && result != null) {
{
throw new IllegalArgumentException("Expected either 'error' or 'result' to be provided, but not both"); throw new IllegalArgumentException("Expected either 'error' or 'result' to be provided, but not both");
} }
this.invocationId = invocationId; this.invocationId = invocationId;

View File

@ -82,19 +82,22 @@ class DefaultHttpClient extends HttpClient {
@Override @Override
public CompletableFuture<HttpResponse> send(HttpRequest httpRequest) { public CompletableFuture<HttpResponse> send(HttpRequest httpRequest) {
Request.Builder requestBuilder = new Request.Builder().url(httpRequest.getUrl()); Request.Builder requestBuilder = new Request.Builder().url(httpRequest.getUrl());
if (httpRequest.getMethod() == "GET") {
requestBuilder.get(); switch (httpRequest.getMethod()) {
} else if (httpRequest.getMethod() == "POST") { case "GET":
RequestBody body = RequestBody.create(null, new byte[] {}); requestBuilder.get();
requestBuilder.post(body); break;
} else if (httpRequest.getMethod() == "DELETE") { case "POST":
requestBuilder.delete(); RequestBody body = RequestBody.create(null, new byte[]{});
requestBuilder.post(body);
break;
case "DELETE":
requestBuilder.delete();
break;
} }
if (httpRequest.getHeaders() != null) { if (httpRequest.getHeaders() != null) {
httpRequest.getHeaders().forEach((key, value) -> { httpRequest.getHeaders().forEach(requestBuilder::addHeader);
requestBuilder.addHeader(key, value);
});
} }
Request request = requestBuilder.build(); Request request = requestBuilder.build();

View File

@ -6,7 +6,7 @@ package com.microsoft.aspnet.signalr;
import com.google.gson.Gson; import com.google.gson.Gson;
class HandshakeProtocol { class HandshakeProtocol {
private static Gson gson = new Gson(); private static final Gson gson = new Gson();
private static final String RECORD_SEPARATOR = "\u001e"; private static final String RECORD_SEPARATOR = "\u001e";
public static String createHandshakeRequestMessage(HandshakeRequestMessage message) { public static String createHandshakeRequestMessage(HandshakeRequestMessage message) {

View File

@ -3,9 +3,9 @@
package com.microsoft.aspnet.signalr; package com.microsoft.aspnet.signalr;
class HandshakeRequestMessage { final class HandshakeRequestMessage {
String protocol; private final String protocol;
int version; private final int version;
public HandshakeRequestMessage(String protocol, int version) { public HandshakeRequestMessage(String protocol, int version) {
this.protocol = protocol; this.protocol = protocol;

View File

@ -3,8 +3,8 @@
package com.microsoft.aspnet.signalr; package com.microsoft.aspnet.signalr;
class HandshakeResponseMessage { final class HandshakeResponseMessage {
public String error; private final String error;
public HandshakeResponseMessage() { public HandshakeResponseMessage() {
this(null); this(null);
@ -13,4 +13,8 @@ class HandshakeResponseMessage {
public HandshakeResponseMessage(String error) { public HandshakeResponseMessage(String error) {
this.error = error; this.error = error;
} }
public String getHandshakeError() {
return error;
}
} }

View File

@ -10,7 +10,7 @@ import java.util.concurrent.CompletableFuture;
class HttpRequest { class HttpRequest {
private String method; private String method;
private String url; private String url;
private Map<String, String> headers = new HashMap<>(); private final Map<String, String> headers = new HashMap<>();
public void setMethod(String method) { public void setMethod(String method) {
this.method = method; this.method = method;
@ -20,14 +20,12 @@ class HttpRequest {
this.url = url; this.url = url;
} }
public void setHeader(String key, String value) { public void addHeader(String key, String value) {
this.headers.put(key, value); this.headers.put(key, value);
} }
public void setHeaders(Map<String, String> headers) { public void addHeaders(Map<String, String> headers) {
headers.forEach((key, value) -> { this.headers.putAll(headers);
this.headers.put(key, value);
});
} }
public String getMethod() { public String getMethod() {
@ -44,17 +42,16 @@ class HttpRequest {
} }
class HttpResponse { class HttpResponse {
private int statusCode; private final int statusCode;
private String statusText; private final String statusText;
private String content = null; private final String content;
public HttpResponse(int statusCode) { public HttpResponse(int statusCode) {
this.statusCode = statusCode; this(statusCode, "");
} }
public HttpResponse(int statusCode, String statusText) { public HttpResponse(int statusCode, String statusText) {
this.statusCode = statusCode; this(statusCode, statusText, "");
this.statusText = statusText;
} }
public HttpResponse(int statusCode, String statusText, String content) { public HttpResponse(int statusCode, String statusText, String content) {

View File

@ -17,28 +17,28 @@ import java.util.function.Consumer;
import java.util.function.Supplier; import java.util.function.Supplier;
public class HubConnection { public class HubConnection {
private static final String RECORD_SEPARATOR = "\u001e";
private static List<Class<?>> emptyArray = new ArrayList<>();
private static int MAX_NEGOTIATE_ATTEMPTS = 100;
private String baseUrl; private String baseUrl;
private Transport transport; private Transport transport;
private OnReceiveCallBack callback; private OnReceiveCallBack callback;
private CallbackMap handlers = new CallbackMap(); private CallbackMap handlers = new CallbackMap();
private HubProtocol protocol; private HubProtocol protocol;
private Boolean handshakeReceived = false; private Boolean handshakeReceived = false;
private static final String RECORD_SEPARATOR = "\u001e";
private HubConnectionState hubConnectionState = HubConnectionState.DISCONNECTED; private HubConnectionState hubConnectionState = HubConnectionState.DISCONNECTED;
private Lock hubConnectionStateLock = new ReentrantLock(); private Lock hubConnectionStateLock = new ReentrantLock();
private Logger logger; private Logger logger;
private List<Consumer<Exception>> onClosedCallbackList; private List<Consumer<Exception>> onClosedCallbackList;
private boolean skipNegotiate = false; private boolean skipNegotiate;
private Supplier<CompletableFuture<String>> accessTokenProvider; private Supplier<CompletableFuture<String>> accessTokenProvider;
private Map<String, String> headers = new HashMap<>(); private Map<String, String> headers = new HashMap<>();
private ConnectionState connectionState = null; private ConnectionState connectionState = null;
private HttpClient httpClient; private HttpClient httpClient;
private String stopError; private String stopError;
private static ArrayList<Class<?>> emptyArray = new ArrayList<>(); HubConnection(String url, HttpConnectionOptions options) {
private static int MAX_NEGOTIATE_ATTEMPTS = 100;
public HubConnection(String url, HttpConnectionOptions options) {
if (url == null || url.isEmpty()) { if (url == null || url.isEmpty()) {
throw new IllegalArgumentException("A valid url is required."); throw new IllegalArgumentException("A valid url is required.");
} }
@ -75,10 +75,10 @@ public class HubConnection {
int handshakeLength = payload.indexOf(RECORD_SEPARATOR) + 1; int handshakeLength = payload.indexOf(RECORD_SEPARATOR) + 1;
String handshakeResponseString = payload.substring(0, handshakeLength - 1); String handshakeResponseString = payload.substring(0, handshakeLength - 1);
HandshakeResponseMessage handshakeResponse = HandshakeProtocol.parseHandshakeResponse(handshakeResponseString); HandshakeResponseMessage handshakeResponse = HandshakeProtocol.parseHandshakeResponse(handshakeResponseString);
if (handshakeResponse.error != null) { if (handshakeResponse.getHandshakeError() != null) {
String errorMessage = "Error in handshake " + handshakeResponse.error; String errorMessage = "Error in handshake " + handshakeResponse.getHandshakeError();
logger.log(LogLevel.Error, errorMessage); logger.log(LogLevel.Error, errorMessage);
throw new HubException(errorMessage); throw new RuntimeException(errorMessage);
} }
handshakeReceived = true; handshakeReceived = true;
@ -135,7 +135,7 @@ public class HubConnection {
private CompletableFuture<NegotiateResponse> handleNegotiate(String url) { private CompletableFuture<NegotiateResponse> handleNegotiate(String url) {
HttpRequest request = new HttpRequest(); HttpRequest request = new HttpRequest();
request.setHeaders(this.headers); request.addHeaders(this.headers);
return httpClient.post(Negotiate.resolveNegotiateUrl(url), request).thenCompose((response) -> { return httpClient.post(Negotiate.resolveNegotiateUrl(url), request).thenCompose((response) -> {
if (response.getStatusCode() != 200) { if (response.getStatusCode() != 200) {
@ -179,10 +179,9 @@ public class HubConnection {
/** /**
* Starts a connection to the server. * Starts a connection to the server.
* * @return A completable future that completes when the connection has been established.
* @throws Exception An error occurred while connecting.
*/ */
public CompletableFuture<Void> start() throws Exception { public CompletableFuture<Void> start() {
if (hubConnectionState != HubConnectionState.DISCONNECTED) { if (hubConnectionState != HubConnectionState.DISCONNECTED) {
return CompletableFuture.completedFuture(null); return CompletableFuture.completedFuture(null);
} }
@ -247,11 +246,7 @@ public class HubConnection {
if (response.getRedirectUrl() == null) { if (response.getRedirectUrl() == null) {
if (!response.getAvailableTransports().contains("WebSockets")) { if (!response.getAvailableTransports().contains("WebSockets")) {
try { throw new RuntimeException("There were no compatible transports on the server.");
throw new HubException("There were no compatible transports on the server.");
} catch (HubException e) {
throw new RuntimeException(e);
}
} }
String finalUrl = url; String finalUrl = url;
@ -272,6 +267,8 @@ public class HubConnection {
/** /**
* Stops a connection to the server. * Stops a connection to the server.
* @param errorMessage An error message if the connected needs to be stopped because of an error.
* @return A completable future that completes when the connection has been stopped.
*/ */
private CompletableFuture<Void> stop(String errorMessage) { private CompletableFuture<Void> stop(String errorMessage) {
hubConnectionStateLock.lock(); hubConnectionStateLock.lock();
@ -295,6 +292,7 @@ public class HubConnection {
/** /**
* Stops a connection to the server. * Stops a connection to the server.
* @return A completable future that completes when the connection has been stopped.
*/ */
public CompletableFuture<Void> stop() { public CompletableFuture<Void> stop() {
return stop(null); return stop(null);
@ -414,9 +412,7 @@ public class HubConnection {
*/ */
public Subscription on(String target, Action callback) { public Subscription on(String target, Action callback) {
ActionBase action = args -> callback.invoke(); ActionBase action = args -> callback.invoke();
InvocationHandler handler = handlers.put(target, action, emptyArray); return registerHandler(target, action);
logger.log(LogLevel.Trace, "Registering handler for client method: %s.", target);
return new Subscription(handlers, handler, target);
} }
/** /**
@ -430,11 +426,8 @@ public class HubConnection {
*/ */
public <T1> Subscription on(String target, Action1<T1> callback, Class<T1> param1) { public <T1> Subscription on(String target, Action1<T1> callback, Class<T1> param1) {
ActionBase action = params -> callback.invoke(param1.cast(params[0])); ActionBase action = params -> callback.invoke(param1.cast(params[0]));
ArrayList<Class<?>> classes = new ArrayList<>(1); return registerHandler(target, action, param1);
classes.add(param1);
InvocationHandler handler = handlers.put(target, action, classes);
logger.log(LogLevel.Trace, "Registering handler for client method: %s.", target);
return new Subscription(handlers, handler, target);
} }
/** /**
@ -452,12 +445,7 @@ public class HubConnection {
ActionBase action = params -> { ActionBase action = params -> {
callback.invoke(param1.cast(params[0]), param2.cast(params[1])); callback.invoke(param1.cast(params[0]), param2.cast(params[1]));
}; };
ArrayList<Class<?>> classes = new ArrayList<>(2); return registerHandler(target, action, param1, param2);
classes.add(param1);
classes.add(param2);
InvocationHandler handler = handlers.put(target, action, classes);
logger.log(LogLevel.Trace, "Registering handler for client method: %s.", target);
return new Subscription(handlers, handler, target);
} }
/** /**
@ -478,13 +466,7 @@ public class HubConnection {
ActionBase action = params -> { ActionBase action = params -> {
callback.invoke(param1.cast(params[0]), param2.cast(params[1]), param3.cast(params[2])); callback.invoke(param1.cast(params[0]), param2.cast(params[1]), param3.cast(params[2]));
}; };
ArrayList<Class<?>> classes = new ArrayList<>(3); return registerHandler(target, action, param1, param2, param3);
classes.add(param1);
classes.add(param2);
classes.add(param3);
InvocationHandler handler = handlers.put(target, action, classes);
logger.log(LogLevel.Trace, "Registering handler for client method: %s.", target);
return new Subscription(handlers, handler, target);
} }
/** /**
@ -507,14 +489,7 @@ public class HubConnection {
ActionBase action = params -> { ActionBase action = params -> {
callback.invoke(param1.cast(params[0]), param2.cast(params[1]), param3.cast(params[2]), param4.cast(params[3])); callback.invoke(param1.cast(params[0]), param2.cast(params[1]), param3.cast(params[2]), param4.cast(params[3]));
}; };
ArrayList<Class<?>> classes = new ArrayList<>(4); return registerHandler(target, action, param1, param2, param3, param4);
classes.add(param1);
classes.add(param2);
classes.add(param3);
classes.add(param4);
InvocationHandler handler = handlers.put(target, action, classes);
logger.log(LogLevel.Trace, "Registering handler for client method: %s.", target);
return new Subscription(handlers, handler, target);
} }
/** /**
@ -540,15 +515,7 @@ public class HubConnection {
callback.invoke(param1.cast(params[0]), param2.cast(params[1]), param3.cast(params[2]), param4.cast(params[3]), callback.invoke(param1.cast(params[0]), param2.cast(params[1]), param3.cast(params[2]), param4.cast(params[3]),
param5.cast(params[4])); param5.cast(params[4]));
}; };
ArrayList<Class<?>> classes = new ArrayList<>(5); return registerHandler(target, action, param1, param2, param3, param4, param5);
classes.add(param1);
classes.add(param2);
classes.add(param3);
classes.add(param4);
classes.add(param5);
InvocationHandler handler = handlers.put(target, action, classes);
logger.log(LogLevel.Trace, "Registering handler for client method: %s.", target);
return new Subscription(handlers, handler, target);
} }
/** /**
@ -576,16 +543,7 @@ public class HubConnection {
callback.invoke(param1.cast(params[0]), param2.cast(params[1]), param3.cast(params[2]), param4.cast(params[3]), callback.invoke(param1.cast(params[0]), param2.cast(params[1]), param3.cast(params[2]), param4.cast(params[3]),
param5.cast(params[4]), param6.cast(params[5])); param5.cast(params[4]), param6.cast(params[5]));
}; };
ArrayList<Class<?>> classes = new ArrayList<>(6); return registerHandler(target, action, param1, param2, param3, param4, param5, param6);
classes.add(param1);
classes.add(param2);
classes.add(param3);
classes.add(param4);
classes.add(param5);
classes.add(param6);
InvocationHandler handler = handlers.put(target, action, classes);
logger.log(LogLevel.Trace, "Registering handler for client method: %s.", target);
return new Subscription(handlers, handler, target);
} }
/** /**
@ -615,17 +573,7 @@ public class HubConnection {
callback.invoke(param1.cast(params[0]), param2.cast(params[1]), param3.cast(params[2]), param4.cast(params[3]), callback.invoke(param1.cast(params[0]), param2.cast(params[1]), param3.cast(params[2]), param4.cast(params[3]),
param5.cast(params[4]), param6.cast(params[5]), param7.cast(params[6])); param5.cast(params[4]), param6.cast(params[5]), param7.cast(params[6]));
}; };
ArrayList<Class<?>> classes = new ArrayList<>(7); return registerHandler(target, action, param1, param2, param3, param4, param5, param6, param7);
classes.add(param1);
classes.add(param2);
classes.add(param3);
classes.add(param4);
classes.add(param5);
classes.add(param6);
classes.add(param7);
InvocationHandler handler = handlers.put(target, action, classes);
logger.log(LogLevel.Trace, "Registering handler for client method: %s.", target);
return new Subscription(handlers, handler, target);
} }
/** /**
@ -657,25 +605,20 @@ public class HubConnection {
callback.invoke(param1.cast(params[0]), param2.cast(params[1]), param3.cast(params[2]), param4.cast(params[3]), callback.invoke(param1.cast(params[0]), param2.cast(params[1]), param3.cast(params[2]), param4.cast(params[3]),
param5.cast(params[4]), param6.cast(params[5]), param7.cast(params[6]), param8.cast(params[7])); param5.cast(params[4]), param6.cast(params[5]), param7.cast(params[6]), param8.cast(params[7]));
}; };
ArrayList<Class<?>> classes = new ArrayList<>(8); return registerHandler(target, action, param1, param2, param3, param4, param5, param6, param7, param8);
classes.add(param1); }
classes.add(param2);
classes.add(param3); private Subscription registerHandler(String target, ActionBase action, Class<?>... types) {
classes.add(param4); InvocationHandler handler = handlers.put(target, action, types);
classes.add(param5); logger.log(LogLevel.Debug, "Registering handler for client method: '%s'.", target);
classes.add(param6);
classes.add(param7);
classes.add(param8);
InvocationHandler handler = handlers.put(target, action, classes);
logger.log(LogLevel.Trace, "Registering handler for client method: %s.", target);
return new Subscription(handlers, handler, target); return new Subscription(handlers, handler, target);
} }
private class ConnectionState implements InvocationBinder { private final class ConnectionState implements InvocationBinder {
private HubConnection connection; private final HubConnection connection;
private AtomicInteger nextId = new AtomicInteger(0); private final AtomicInteger nextId = new AtomicInteger(0);
private HashMap<String, InvocationRequest> pendingInvocations = new HashMap<>(); private final HashMap<String, InvocationRequest> pendingInvocations = new HashMap<>();
private Lock lock = new ReentrantLock(); private final Lock lock = new ReentrantLock();
public ConnectionState(HubConnection connection) { public ConnectionState(HubConnection connection) {
this.connection = connection; this.connection = connection;
@ -755,7 +698,7 @@ public class HubConnection {
return emptyArray; return emptyArray;
} }
if (handlers.size() == 0) { if (handlers.isEmpty()) {
throw new Exception(String.format("There are no callbacks registered for the method '%s'.", methodName)); throw new Exception(String.format("There are no callbacks registered for the method '%s'.", methodName));
} }

View File

@ -9,26 +9,23 @@ public class HubConnectionBuilder {
private Logger logger; private Logger logger;
private HttpConnectionOptions options = null; private HttpConnectionOptions options = null;
public HubConnectionBuilder withUrl(String url) { private HubConnectionBuilder(String url) {
if (url == null || url.isEmpty()) {
throw new IllegalArgumentException("A valid url is required.");
}
this.url = url; this.url = url;
return this;
} }
public HubConnectionBuilder withUrl(String url, Transport transport) { public static HubConnectionBuilder create(String url) {
if (url == null || url.isEmpty()) { if (url == null || url.isEmpty()) {
throw new IllegalArgumentException("A valid url is required."); throw new IllegalArgumentException("A valid url is required.");
} }
this.url = url; return new HubConnectionBuilder(url);
}
public HubConnectionBuilder withTransport(Transport transport) {
this.transport = transport; this.transport = transport;
return this; return this;
} }
public HubConnectionBuilder withUrl(String url, HttpConnectionOptions options) { public HubConnectionBuilder withOptions(HttpConnectionOptions options) {
this.url = url;
this.options = options; this.options = options;
return this; return this;
} }
@ -44,9 +41,6 @@ public class HubConnectionBuilder {
} }
public HubConnection build() { public HubConnection build() {
if (this.url == null) {
throw new RuntimeException("The 'HubConnectionBuilder.withUrl' method must be called before building the connection.");
}
if (options == null) { if (options == null) {
options = new HttpConnectionOptions(); options = new HttpConnectionOptions();
} }

View File

@ -3,15 +3,16 @@
package com.microsoft.aspnet.signalr; package com.microsoft.aspnet.signalr;
import java.util.Arrays;
import java.util.List; import java.util.List;
class InvocationHandler { class InvocationHandler {
private List<Class<?>> classes; private List<Class<?>> classes;
private ActionBase action; private ActionBase action;
InvocationHandler(ActionBase action, List<Class<?>> classes) { InvocationHandler(ActionBase action, Class<?>... classes) {
this.action = action; this.action = action;
this.classes = classes; this.classes = Arrays.asList(classes);
} }
public List<Class<?>> getClasses() { public List<Class<?>> getClasses() {

View File

@ -4,10 +4,10 @@
package com.microsoft.aspnet.signalr; package com.microsoft.aspnet.signalr;
class InvocationMessage extends HubMessage { class InvocationMessage extends HubMessage {
int type = HubMessageType.INVOCATION.value; private final int type = HubMessageType.INVOCATION.value;
protected String invocationId; private final String invocationId;
private String target; private final String target;
private Object[] arguments; private final Object[] arguments;
public InvocationMessage(String invocationId, String target, Object[] args) { public InvocationMessage(String invocationId, String target, Object[] args) {
this.invocationId = invocationId; this.invocationId = invocationId;
@ -23,18 +23,10 @@ class InvocationMessage extends HubMessage {
return target; return target;
} }
public void setTarget(String target) {
this.target = target;
}
public Object[] getArguments() { public Object[] getArguments() {
return arguments; return arguments;
} }
public void setArguments(Object[] arguments) {
this.arguments = arguments;
}
@Override @Override
public HubMessageType getMessageType() { public HubMessageType getMessageType() {
return HubMessageType.INVOCATION; return HubMessageType.INVOCATION;

View File

@ -20,13 +20,13 @@ class HandshakeProtocolTest {
public void VerifyParseEmptyHandshakeResponseMessage() { public void VerifyParseEmptyHandshakeResponseMessage() {
String emptyHandshakeResponse = "{}"; String emptyHandshakeResponse = "{}";
HandshakeResponseMessage hsr = HandshakeProtocol.parseHandshakeResponse(emptyHandshakeResponse); HandshakeResponseMessage hsr = HandshakeProtocol.parseHandshakeResponse(emptyHandshakeResponse);
assertNull(hsr.error); assertNull(hsr.getHandshakeError());
} }
@Test @Test
public void VerifyParseHandshakeResponseMessage() { public void VerifyParseHandshakeResponseMessage() {
String handshakeResponseWithError = "{\"error\": \"Requested protocol \'messagepack\' is not available.\"}"; String handshakeResponseWithError = "{\"error\": \"Requested protocol \'messagepack\' is not available.\"}";
HandshakeResponseMessage hsr = HandshakeProtocol.parseHandshakeResponse(handshakeResponseWithError); HandshakeResponseMessage hsr = HandshakeProtocol.parseHandshakeResponse(handshakeResponseWithError);
assertEquals(hsr.error, "Requested protocol 'messagepack' is not available."); assertEquals(hsr.getHandshakeError(), "Requested protocol 'messagepack' is not available.");
} }
} }

View File

@ -9,24 +9,15 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
public class HubConnectionBuilderTest { public class HubConnectionBuilderTest {
@Test
public void callingBuildWithoutCallingWithUrlThrows() {
HubConnectionBuilder builder = new HubConnectionBuilder();
Throwable exception = assertThrows(RuntimeException.class, () -> builder.build());
assertEquals("The \'HubConnectionBuilder.withUrl\' method must be called before building the connection.", exception.getMessage());
}
@Test @Test
public void passingInNullToWithUrlThrows() { public void passingInNullToWithUrlThrows() {
HubConnectionBuilder builder = new HubConnectionBuilder(); Throwable exception = assertThrows(IllegalArgumentException.class, () -> HubConnectionBuilder.create(null));
Throwable exception = assertThrows(IllegalArgumentException.class, () -> builder.withUrl(null));
assertEquals("A valid url is required.", exception.getMessage()); assertEquals("A valid url is required.", exception.getMessage());
} }
@Test @Test
public void passingInEmptyStringToWihtUrlThrows() { public void passingInEmptyStringToWihtUrlThrows() {
HubConnectionBuilder builder = new HubConnectionBuilder(); Throwable exception = assertThrows(IllegalArgumentException.class, () -> HubConnectionBuilder.create(""));
Throwable exception = assertThrows(IllegalArgumentException.class, () -> builder.withUrl(""));
assertEquals("A valid url is required.", exception.getMessage()); assertEquals("A valid url is required.", exception.getMessage());
} }
} }

View File

@ -63,9 +63,9 @@ class HubConnectionTest {
Transport mockTransport = new MockTransport(); Transport mockTransport = new MockTransport();
HttpConnectionOptions options = new HttpConnectionOptions(); HttpConnectionOptions options = new HttpConnectionOptions();
options.setTransport(mockTransport); options.setTransport(mockTransport);
options.setLoglevel(LogLevel.Information);
options.setSkipNegotiate(true); options.setSkipNegotiate(true);
HubConnection hubConnection = new HubConnectionBuilder().withUrl("http://www.example.com", options).build(); HubConnection hubConnection = TestUtils.createHubConnection("http://example.com", mockTransport);
hubConnection.start(); hubConnection.start();
assertEquals(HubConnectionState.CONNECTED, hubConnection.getConnectionState()); assertEquals(HubConnectionState.CONNECTED, hubConnection.getConnectionState());
@ -89,12 +89,12 @@ class HubConnectionTest {
} }
@Test @Test
public void hubConnectionReceiveHandshakeResponseWithError() throws Exception { public void hubConnectionReceiveHandshakeResponseWithError() {
MockTransport mockTransport = new MockTransport(); MockTransport mockTransport = new MockTransport();
HubConnection hubConnection = TestUtils.createHubConnection("http://example.com", mockTransport); HubConnection hubConnection = TestUtils.createHubConnection("http://example.com", mockTransport);
hubConnection.start(); hubConnection.start();
Throwable exception = assertThrows(HubException.class, () -> mockTransport.receiveMessage("{\"error\":\"Requested protocol 'messagepack' is not available.\"}" + RECORD_SEPARATOR)); Throwable exception = assertThrows(RuntimeException.class, () -> mockTransport.receiveMessage("{\"error\":\"Requested protocol 'messagepack' is not available.\"}" + RECORD_SEPARATOR));
assertEquals("Error in handshake Requested protocol 'messagepack' is not available.", exception.getMessage()); assertEquals("Error in handshake Requested protocol 'messagepack' is not available.", exception.getMessage());
} }
@ -912,9 +912,10 @@ class HubConnectionTest {
HttpConnectionOptions options = new HttpConnectionOptions(); HttpConnectionOptions options = new HttpConnectionOptions();
options.setHttpClient(client); options.setHttpClient(client);
HubConnection hubConnection = new HubConnectionBuilder() HubConnection hubConnection = HubConnectionBuilder
.withUrl("http://example.com", options) .create("http://example.com")
.build(); .withOptions(options)
.build();
try { try {
hubConnection.start().get(1000, TimeUnit.MILLISECONDS); hubConnection.start().get(1000, TimeUnit.MILLISECONDS);
@ -932,8 +933,9 @@ class HubConnectionTest {
HttpConnectionOptions options = new HttpConnectionOptions(); HttpConnectionOptions options = new HttpConnectionOptions();
options.setHttpClient(client); options.setHttpClient(client);
HubConnection hubConnection = new HubConnectionBuilder() HubConnection hubConnection = HubConnectionBuilder
.withUrl("http://example.com", options) .create("http://example.com")
.withOptions(options)
.build(); .build();
ExecutionException exception = assertThrows(ExecutionException.class, () -> hubConnection.start().get(1000, TimeUnit.MILLISECONDS)); ExecutionException exception = assertThrows(ExecutionException.class, () -> hubConnection.start().get(1000, TimeUnit.MILLISECONDS));
@ -951,9 +953,10 @@ class HubConnectionTest {
HttpConnectionOptions options = new HttpConnectionOptions(); HttpConnectionOptions options = new HttpConnectionOptions();
options.setTransport(transport); options.setTransport(transport);
options.setHttpClient(client); options.setHttpClient(client);
HubConnection hubConnection = new HubConnectionBuilder() HubConnection hubConnection = HubConnectionBuilder
.withUrl("http://example.com", options) .create("http://example.com")
.build(); .withOptions(options)
.build();
hubConnection.start().get(1000, TimeUnit.MILLISECONDS); hubConnection.start().get(1000, TimeUnit.MILLISECONDS);
@ -971,9 +974,10 @@ class HubConnectionTest {
HttpConnectionOptions options = new HttpConnectionOptions(); HttpConnectionOptions options = new HttpConnectionOptions();
options.setTransport(transport); options.setTransport(transport);
options.setHttpClient(client); options.setHttpClient(client);
HubConnection hubConnection = new HubConnectionBuilder() HubConnection hubConnection = HubConnectionBuilder
.withUrl("http://example.com", options) .create("http://example.com")
.build(); .withOptions(options)
.build();
ExecutionException exception = assertThrows(ExecutionException.class, () -> hubConnection.start().get(1000, TimeUnit.MILLISECONDS)); ExecutionException exception = assertThrows(ExecutionException.class, () -> hubConnection.start().get(1000, TimeUnit.MILLISECONDS));
assertEquals("Test error.", exception.getCause().getMessage()); assertEquals("Test error.", exception.getCause().getMessage());
@ -991,9 +995,10 @@ class HubConnectionTest {
HttpConnectionOptions options = new HttpConnectionOptions(); HttpConnectionOptions options = new HttpConnectionOptions();
options.setTransport(transport); options.setTransport(transport);
options.setHttpClient(client); options.setHttpClient(client);
HubConnection hubConnection = new HubConnectionBuilder() HubConnection hubConnection = HubConnectionBuilder
.withUrl("http://example.com", options) .create("http://example.com")
.build(); .withOptions(options)
.build();
hubConnection.start().get(1000, TimeUnit.MILLISECONDS); hubConnection.start().get(1000, TimeUnit.MILLISECONDS);
assertEquals(HubConnectionState.CONNECTED, hubConnection.getConnectionState()); assertEquals(HubConnectionState.CONNECTED, hubConnection.getConnectionState());
@ -1018,7 +1023,10 @@ class HubConnectionTest {
options.setTransport(transport); options.setTransport(transport);
options.setHttpClient(client); options.setHttpClient(client);
options.setAccessTokenProvider(() -> CompletableFuture.completedFuture("secretToken")); options.setAccessTokenProvider(() -> CompletableFuture.completedFuture("secretToken"));
HubConnection hubConnection = new HubConnectionBuilder().withUrl("http://example.com", options).build(); HubConnection hubConnection = HubConnectionBuilder
.create("http://example.com")
.withOptions(options)
.build();
hubConnection.start().get(1000, TimeUnit.MILLISECONDS); hubConnection.start().get(1000, TimeUnit.MILLISECONDS);
assertEquals(HubConnectionState.CONNECTED, hubConnection.getConnectionState()); assertEquals(HubConnectionState.CONNECTED, hubConnection.getConnectionState());
@ -1044,7 +1052,10 @@ class HubConnectionTest {
options.setTransport(transport); options.setTransport(transport);
options.setHttpClient(client); options.setHttpClient(client);
options.setAccessTokenProvider(() -> CompletableFuture.completedFuture("secretToken")); options.setAccessTokenProvider(() -> CompletableFuture.completedFuture("secretToken"));
HubConnection hubConnection = new HubConnectionBuilder().withUrl("http://example.com", options).build(); HubConnection hubConnection = HubConnectionBuilder
.create("http://example.com")
.withOptions(options)
.build();
hubConnection.start().get(1000, TimeUnit.MILLISECONDS); hubConnection.start().get(1000, TimeUnit.MILLISECONDS);
assertEquals(HubConnectionState.CONNECTED, hubConnection.getConnectionState()); assertEquals(HubConnectionState.CONNECTED, hubConnection.getConnectionState());
@ -1059,7 +1070,10 @@ class HubConnectionTest {
HttpConnectionOptions options = new HttpConnectionOptions(); HttpConnectionOptions options = new HttpConnectionOptions();
options.setTransport(transport); options.setTransport(transport);
options.setSkipNegotiate(true); options.setSkipNegotiate(true);
HubConnection hubConnection = new HubConnectionBuilder().withUrl("http://example.com", options).build(); HubConnection hubConnection = HubConnectionBuilder
.create("http://example.com")
.withOptions(options)
.build();
hubConnection.start().get(1000, TimeUnit.MILLISECONDS); hubConnection.start().get(1000, TimeUnit.MILLISECONDS);
assertEquals(HubConnectionState.CONNECTED, hubConnection.getConnectionState()); assertEquals(HubConnectionState.CONNECTED, hubConnection.getConnectionState());
@ -1083,7 +1097,10 @@ class HubConnectionTest {
HttpConnectionOptions options = new HttpConnectionOptions(); HttpConnectionOptions options = new HttpConnectionOptions();
options.setTransport(mockTransport); options.setTransport(mockTransport);
options.setHttpClient(client); options.setHttpClient(client);
HubConnection hubConnection = new HubConnectionBuilder().withUrl("http://example.com", options).build(); HubConnection hubConnection = HubConnectionBuilder
.create("http://example.com")
.withOptions(options)
.build();
hubConnection.start().get(1000, TimeUnit.MILLISECONDS); hubConnection.start().get(1000, TimeUnit.MILLISECONDS);
assertEquals(HubConnectionState.CONNECTED, hubConnection.getConnectionState()); assertEquals(HubConnectionState.CONNECTED, hubConnection.getConnectionState());
@ -1106,7 +1123,10 @@ class HubConnectionTest {
HttpConnectionOptions options = new HttpConnectionOptions(); HttpConnectionOptions options = new HttpConnectionOptions();
options.setTransport(transport); options.setTransport(transport);
options.setHttpClient(client); options.setHttpClient(client);
HubConnection hubConnection = new HubConnectionBuilder().withUrl("http://example.com", options).build(); HubConnection hubConnection = HubConnectionBuilder
.create("http://example.com")
.withOptions(options)
.build();
ExecutionException exception = assertThrows(ExecutionException.class, () -> hubConnection.start().get(1000, TimeUnit.MILLISECONDS)); ExecutionException exception = assertThrows(ExecutionException.class, () -> hubConnection.start().get(1000, TimeUnit.MILLISECONDS));
assertEquals("Unexpected status code returned from negotiate: 500 Internal server error.", exception.getCause().getMessage()); assertEquals("Unexpected status code returned from negotiate: 500 Internal server error.", exception.getCause().getMessage());

View File

@ -18,7 +18,7 @@ class TestUtils {
options.setLogger(logger); options.setLogger(logger);
options.setSkipNegotiate(skipNegotiate); options.setSkipNegotiate(skipNegotiate);
options.setHttpClient(client); options.setHttpClient(client);
HubConnectionBuilder builder = new HubConnectionBuilder(); HubConnectionBuilder builder = HubConnectionBuilder.create(url);
return builder.withUrl(url, options).build(); return builder.withOptions(options).build();
} }
} }

View File

@ -18,8 +18,7 @@ public class Chat {
System.out.print("Enter your name:"); System.out.print("Enter your name:");
String enteredName = reader.nextLine(); String enteredName = reader.nextLine();
HubConnection hubConnection = new HubConnectionBuilder() HubConnection hubConnection = HubConnectionBuilder.create(input)
.withUrl(input)
.configureLogging(LogLevel.Information).build(); .configureLogging(LogLevel.Information).build();
hubConnection.on("Send", (name, message) -> { hubConnection.on("Send", (name, message) -> {