[Java] Add accessTokenProvider (#3046)

This commit is contained in:
BrennanConroy 2018-10-03 14:14:14 -07:00 committed by GitHub
parent 6f45d308ce
commit 2e41a7063b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 217 additions and 103 deletions

View File

@ -3,32 +3,30 @@
package com.microsoft.aspnet.signalr;
import java.util.concurrent.CompletableFuture;
import java.util.function.Supplier;
public class HttpConnectionOptions {
private String url;
private Transport transport;
private LogLevel loglevel;
private Logger logger;
private boolean skipNegotiate;
private Supplier<CompletableFuture<String>> accessTokenProvider;
private HttpClient client;
public HttpConnectionOptions() {}
public HttpConnectionOptions(String url, Transport transport, LogLevel logLevel, boolean skipNegotiate) {
this.url = url;
public HttpConnectionOptions(Transport transport, LogLevel logLevel, boolean skipNegotiate) {
this.transport = transport;
this.skipNegotiate = skipNegotiate;
this.loglevel = logLevel;
}
public HttpConnectionOptions(String url, Transport transport, Logger logger, boolean skipNegotiate) {
this.url = url;
public HttpConnectionOptions(Transport transport, Logger logger, boolean skipNegotiate) {
this.transport = transport;
this.skipNegotiate = skipNegotiate;
this.logger = logger;
}
public void setUrl(String url) {
this.url = url;
}
public void setTransport(Transport transport) {
this.transport = transport;
@ -42,10 +40,6 @@ public class HttpConnectionOptions {
this.skipNegotiate = skipNegotiate;
}
public String getUrl() {
return url;
}
public Transport getTransport() {
return transport;
}
@ -65,4 +59,21 @@ public class HttpConnectionOptions {
public void setLogger(Logger logger) {
this.logger = logger;
}
public void setAccessTokenProvider(Supplier<CompletableFuture<String>> accessTokenProvider) {
this.accessTokenProvider = accessTokenProvider;
}
public Supplier<CompletableFuture<String>> getAccessTokenProvider() {
return accessTokenProvider;
}
// For testing purposes only
void setHttpClient(HttpClient client) {
this.client = client;
}
HttpClient getHttpClient() {
return client;
}
}

View File

@ -14,6 +14,7 @@ import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Consumer;
import java.util.function.Supplier;
public class HubConnection {
private String baseUrl;
@ -28,7 +29,7 @@ public class HubConnection {
private Logger logger;
private List<Consumer<Exception>> onClosedCallbackList;
private boolean skipNegotiate = false;
private String accessToken;
private Supplier<CompletableFuture<String>> accessTokenProvider;
private Map<String, String> headers = new HashMap<>();
private ConnectionState connectionState = null;
private HttpClient httpClient;
@ -36,7 +37,7 @@ public class HubConnection {
private static ArrayList<Class<?>> emptyArray = new ArrayList<>();
private static int MAX_NEGOTIATE_ATTEMPTS = 100;
public HubConnection(String url, Transport transport, Logger logger, boolean skipNegotiate, HttpClient client) {
public HubConnection(String url, HttpConnectionOptions options) {
if (url == null || url.isEmpty()) {
throw new IllegalArgumentException("A valid url is required.");
}
@ -44,26 +45,31 @@ public class HubConnection {
this.baseUrl = url;
this.protocol = new JsonHubProtocol();
if (logger != null) {
this.logger = logger;
if (options.getAccessTokenProvider() != null) {
this.accessTokenProvider = options.getAccessTokenProvider();
} else {
this.accessTokenProvider = () -> CompletableFuture.completedFuture(null);
}
if (options.getLogger() != null) {
this.logger = options.getLogger();
} else {
this.logger = new NullLogger();
}
if (client != null) {
this.httpClient = client;
if (options.getHttpClient() != null) {
this.httpClient = options.getHttpClient();
} else {
this.httpClient = new DefaultHttpClient(this.logger);
}
if (transport != null) {
this.transport = transport;
if (options.getTransport() != null) {
this.transport = options.getTransport();
}
this.skipNegotiate = skipNegotiate;
this.skipNegotiate = options.getSkipNegotiate();
this.callback = (payload) -> {
if (!handshakeReceived) {
int handshakeLength = payload.indexOf(RECORD_SEPARATOR) + 1;
String handshakeResponseString = payload.substring(0, handshakeLength - 1);
@ -126,7 +132,7 @@ public class HubConnection {
};
}
private CompletableFuture<NegotiateResponse> handleNegotiate(String url) throws IOException, InterruptedException, ExecutionException {
private CompletableFuture<NegotiateResponse> handleNegotiate(String url) {
HttpRequest request = new HttpRequest();
request.setHeaders(this.headers);
@ -143,7 +149,15 @@ public class HubConnection {
}
if (negotiateResponse.getAccessToken() != null) {
this.headers.put("Authorization", "Bearer " + negotiateResponse.getAccessToken());
this.accessTokenProvider = () -> CompletableFuture.completedFuture(negotiateResponse.getAccessToken());
String token = "";
try {
// We know the future is already completed in this case
// It's fine to call get() on it.
token = this.accessTokenProvider.get().get();
} catch (InterruptedException | ExecutionException e) {
}
this.headers.put("Authorization", "Bearer " + token);
}
return CompletableFuture.completedFuture(negotiateResponse);
@ -169,11 +183,18 @@ public class HubConnection {
return CompletableFuture.completedFuture(null);
}
CompletableFuture<Void> tokenFuture = accessTokenProvider.get()
.thenAccept((token) -> {
if (token != null) {
this.headers.put("Authorization", "Bearer " + token);
}
});
CompletableFuture<String> negotiate = null;
if (!skipNegotiate) {
negotiate = startNegotiate(baseUrl, 0);
negotiate = tokenFuture.thenCompose((v) -> startNegotiate(baseUrl, 0));
} else {
negotiate = CompletableFuture.completedFuture(baseUrl);
negotiate = tokenFuture.thenCompose((v) -> CompletableFuture.completedFuture(baseUrl));
}
return negotiate.thenCompose((url) -> {
@ -207,7 +228,7 @@ public class HubConnection {
});
}
private CompletableFuture<String> startNegotiate(String url, int negotiateAttempts) throws IOException, InterruptedException, ExecutionException {
private CompletableFuture<String> startNegotiate(String url, int negotiateAttempts) {
if (hubConnectionState != HubConnectionState.DISCONNECTED) {
return CompletableFuture.completedFuture(null);
}
@ -238,11 +259,7 @@ public class HubConnection {
return CompletableFuture.completedFuture(finalUrl);
}
try {
return startNegotiate(response.getRedirectUrl(), negotiateAttempts + 1);
} catch (IOException | InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
}
return startNegotiate(response.getRedirectUrl(), negotiateAttempts + 1);
});
}

View File

@ -7,8 +7,7 @@ public class HubConnectionBuilder {
private String url;
private Transport transport;
private Logger logger;
private boolean skipNegotiate;
private HttpClient client;
private HttpConnectionOptions options = null;
public HubConnectionBuilder withUrl(String url) {
if (url == null || url.isEmpty()) {
@ -30,13 +29,7 @@ public class HubConnectionBuilder {
public HubConnectionBuilder withUrl(String url, HttpConnectionOptions options) {
this.url = url;
this.transport = options.getTransport();
if (options.getLogger() != null) {
this.logger = options.getLogger();
} else if (options.getLoglevel() != null) {
this.logger = new ConsoleLogger(options.getLoglevel());
}
this.skipNegotiate = options.getSkipNegotiate();
this.options = options;
return this;
}
@ -50,16 +43,23 @@ public class HubConnectionBuilder {
return this;
}
// For testing purposes only
HubConnectionBuilder configureHttpClient(HttpClient client) {
this.client = client;
return this;
}
public HubConnection build() {
if (this.url == null) {
throw new RuntimeException("The 'HubConnectionBuilder.withUrl' method must be called before building the connection.");
}
return new HubConnection(url, transport, logger, skipNegotiate, client);
if (options == null) {
options = new HttpConnectionOptions();
}
if (options.getTransport() == null && this.transport != null) {
options.setTransport(this.transport);
}
if (options.getLogger() == null && options.getLoglevel() != null) {
options.setLogger(new ConsoleLogger(options.getLoglevel()));
}
if (options.getLogger() == null && this.logger != null) {
options.setLogger(this.logger);
}
return new HubConnection(url, options);
}
}

View File

@ -13,8 +13,7 @@ class HttpConnectionOptionsTest {
@Test
public void CheckHttpConnectionOptionsFields() {
Transport mockTransport = new MockTransport();
HttpConnectionOptions options = new HttpConnectionOptions("http://example.com", mockTransport, LogLevel.Information, true);
assertEquals("http://example.com",options.getUrl());
HttpConnectionOptions options = new HttpConnectionOptions(mockTransport, LogLevel.Information, true);
assertEquals(LogLevel.Information, options.getLoglevel());
assertTrue(options.getSkipNegotiate());
assertNotNull(options.getTransport());

View File

@ -21,8 +21,7 @@ class HubConnectionTest {
@Test
public void checkHubConnectionState() throws Exception {
Transport mockTransport = new MockTransport();
HubConnection hubConnection = new HubConnection("http://example.com", mockTransport, new NullLogger(), true, new TestHttpClient());
HubConnection hubConnection = TestUtils.createHubConnection("http://example.com");
hubConnection.start();
assertEquals(HubConnectionState.CONNECTED, hubConnection.getConnectionState());
@ -48,7 +47,7 @@ class HubConnectionTest {
@Test
public void hubConnectionClosesAfterCloseMessage() throws Exception {
MockTransport mockTransport = new MockTransport();
HubConnection hubConnection = new HubConnection("http://example.com", mockTransport, new NullLogger(), true, new TestHttpClient());
HubConnection hubConnection = TestUtils.createHubConnection("http://example.com", mockTransport);
hubConnection.start();
mockTransport.receiveMessage("{}" + RECORD_SEPARATOR);
@ -63,7 +62,7 @@ class HubConnectionTest {
@Test
public void hubConnectionReceiveHandshakeResponseWithError() throws Exception {
MockTransport mockTransport = new MockTransport();
HubConnection hubConnection = new HubConnection("http://example.com", mockTransport, new NullLogger(), true, new TestHttpClient());
HubConnection hubConnection = TestUtils.createHubConnection("http://example.com", mockTransport);
hubConnection.start();
Throwable exception = assertThrows(HubException.class, () -> mockTransport.receiveMessage("{\"error\":\"Requested protocol 'messagepack' is not available.\"}" + RECORD_SEPARATOR));
@ -74,7 +73,7 @@ class HubConnectionTest {
public void registeringMultipleHandlersAndBothGetTriggered() throws Exception {
AtomicReference<Double> value = new AtomicReference<>(0.0);
MockTransport mockTransport = new MockTransport();
HubConnection hubConnection = new HubConnection("http://example.com", mockTransport, new NullLogger(), true, new TestHttpClient());
HubConnection hubConnection = TestUtils.createHubConnection("http://example.com", mockTransport);
Action action = () -> value.getAndUpdate((val) -> val + 1);
hubConnection.on("inc", action);
@ -100,7 +99,7 @@ class HubConnectionTest {
public void removeHandlerByName() throws Exception {
AtomicReference<Double> value = new AtomicReference<>(0.0);
MockTransport mockTransport = new MockTransport();
HubConnection hubConnection = new HubConnection("http://example.com", mockTransport, new NullLogger(), true, new TestHttpClient());
HubConnection hubConnection = TestUtils.createHubConnection("http://example.com", mockTransport);
Action action = () -> value.getAndUpdate((val) -> val + 1);
hubConnection.on("inc", action);
@ -127,7 +126,7 @@ class HubConnectionTest {
public void addAndRemoveHandlerImmediately() throws Exception {
AtomicReference<Double> value = new AtomicReference<>(0.0);
MockTransport mockTransport = new MockTransport();
HubConnection hubConnection = new HubConnection("http://example.com", mockTransport, new NullLogger(), true, new TestHttpClient());
HubConnection hubConnection = TestUtils.createHubConnection("http://example.com", mockTransport);
Action action = () -> value.getAndUpdate((val) -> val + 1);
hubConnection.on("inc", action);
@ -152,7 +151,7 @@ class HubConnectionTest {
public void removingMultipleHandlersWithOneCallToRemove() throws Exception {
AtomicReference<Double> value = new AtomicReference<>(0.0);
MockTransport mockTransport = new MockTransport();
HubConnection hubConnection = new HubConnection("http://example.com", mockTransport, new NullLogger(), true, new TestHttpClient());
HubConnection hubConnection = TestUtils.createHubConnection("http://example.com", mockTransport);
Action action = () -> value.getAndUpdate((val) -> val + 1);
Action secondAction = () -> value.getAndUpdate((val) -> val + 2);
@ -184,7 +183,7 @@ class HubConnectionTest {
public void removeHandlerWithUnsubscribe() throws Exception {
AtomicReference<Double> value = new AtomicReference<>(0.0);
MockTransport mockTransport = new MockTransport();
HubConnection hubConnection = new HubConnection("http://example.com", mockTransport, new NullLogger(), true, new TestHttpClient());
HubConnection hubConnection = TestUtils.createHubConnection("http://example.com", mockTransport);
Action action = () -> value.getAndUpdate((val) -> val + 1);
Subscription subscription = hubConnection.on("inc", action);
@ -217,7 +216,7 @@ class HubConnectionTest {
public void unsubscribeTwice() throws Exception {
AtomicReference<Double> value = new AtomicReference<>(0.0);
MockTransport mockTransport = new MockTransport();
HubConnection hubConnection = new HubConnection("http://example.com", mockTransport, new NullLogger(),true, new TestHttpClient());
HubConnection hubConnection = TestUtils.createHubConnection("http://example.com", mockTransport);
Action action = () -> value.getAndUpdate((val) -> val + 1);
Subscription subscription = hubConnection.on("inc", action);
@ -251,7 +250,7 @@ class HubConnectionTest {
public void removeSingleHandlerWithUnsubscribe() throws Exception {
AtomicReference<Double> value = new AtomicReference<>(0.0);
MockTransport mockTransport = new MockTransport();
HubConnection hubConnection = new HubConnection("http://example.com", mockTransport, new NullLogger(), true, new TestHttpClient());
HubConnection hubConnection = TestUtils.createHubConnection("http://example.com", mockTransport);
Action action = () -> value.getAndUpdate((val) -> val + 1);
Action secondAction = () -> value.getAndUpdate((val) -> val + 2);
@ -281,7 +280,7 @@ class HubConnectionTest {
public void addAndRemoveHandlerImmediatelyWithSubscribe() throws Exception {
AtomicReference<Double> value = new AtomicReference<>(0.0);
MockTransport mockTransport = new MockTransport();
HubConnection hubConnection = new HubConnection("http://example.com", mockTransport, new NullLogger(), true, new TestHttpClient());
HubConnection hubConnection = TestUtils.createHubConnection("http://example.com", mockTransport);
Action action = () -> value.getAndUpdate((val) -> val + 1);
Subscription sub = hubConnection.on("inc", action);
@ -306,7 +305,7 @@ class HubConnectionTest {
public void registeringMultipleHandlersThatTakeParamsAndBothGetTriggered() throws Exception {
AtomicReference<Double> value = new AtomicReference<>(0.0);
MockTransport mockTransport = new MockTransport();
HubConnection hubConnection = new HubConnection("http://example.com", mockTransport, new NullLogger(), true, new TestHttpClient());
HubConnection hubConnection = TestUtils.createHubConnection("http://example.com", mockTransport);
Action1<Double> action = (number) -> value.getAndUpdate((val) -> val + number);
@ -325,7 +324,7 @@ class HubConnectionTest {
@Test
public void invokeWaitsForCompletionMessage() throws Exception {
MockTransport mockTransport = new MockTransport();
HubConnection hubConnection = new HubConnection("http://example.com", mockTransport, new NullLogger(), true, new TestHttpClient());
HubConnection hubConnection = TestUtils.createHubConnection("http://example.com", mockTransport);
hubConnection.start();
mockTransport.receiveMessage("{}" + RECORD_SEPARATOR);
@ -342,7 +341,7 @@ class HubConnectionTest {
@Test
public void multipleInvokesWaitForOwnCompletionMessage() throws Exception {
MockTransport mockTransport = new MockTransport();
HubConnection hubConnection = new HubConnection("http://example.com", mockTransport, new NullLogger(), true, new TestHttpClient());
HubConnection hubConnection = TestUtils.createHubConnection("http://example.com", mockTransport);
hubConnection.start();
mockTransport.receiveMessage("{}" + RECORD_SEPARATOR);
@ -365,7 +364,7 @@ class HubConnectionTest {
@Test
public void invokeWorksForPrimitiveTypes() throws Exception {
MockTransport mockTransport = new MockTransport();
HubConnection hubConnection = new HubConnection("http://example.com", mockTransport, new NullLogger(), true, new TestHttpClient());
HubConnection hubConnection = TestUtils.createHubConnection("http://example.com", mockTransport);
hubConnection.start();
mockTransport.receiveMessage("{}" + RECORD_SEPARATOR);
@ -383,7 +382,7 @@ class HubConnectionTest {
@Test
public void completionMessageCanHaveError() throws Exception {
MockTransport mockTransport = new MockTransport();
HubConnection hubConnection = new HubConnection("http://example.com", mockTransport, new NullLogger(), true, new TestHttpClient());
HubConnection hubConnection = TestUtils.createHubConnection("http://example.com", mockTransport);
hubConnection.start();
mockTransport.receiveMessage("{}" + RECORD_SEPARATOR);
@ -407,7 +406,7 @@ class HubConnectionTest {
@Test
public void stopCancelsActiveInvokes() throws Exception {
MockTransport mockTransport = new MockTransport();
HubConnection hubConnection = new HubConnection("http://example.com", mockTransport, new NullLogger(), true, new TestHttpClient());
HubConnection hubConnection = TestUtils.createHubConnection("http://example.com", mockTransport);
hubConnection.start();
mockTransport.receiveMessage("{}" + RECORD_SEPARATOR);
@ -432,7 +431,7 @@ class HubConnectionTest {
public void sendWithNoParamsTriggersOnHandler() throws Exception {
AtomicReference<Integer> value = new AtomicReference<>(0);
MockTransport mockTransport = new MockTransport();
HubConnection hubConnection = new HubConnection("http://example.com", mockTransport, new NullLogger(), true, new TestHttpClient());
HubConnection hubConnection = TestUtils.createHubConnection("http://example.com", mockTransport);
hubConnection.on("inc", () ->{
assertEquals(Integer.valueOf(0), value.get());
@ -451,7 +450,7 @@ class HubConnectionTest {
public void sendWithParamTriggersOnHandler() throws Exception {
AtomicReference<String> value = new AtomicReference<>();
MockTransport mockTransport = new MockTransport();
HubConnection hubConnection = new HubConnection("http://example.com", mockTransport, new NullLogger(), true, new TestHttpClient());
HubConnection hubConnection = TestUtils.createHubConnection("http://example.com", mockTransport);
hubConnection.on("inc", (param) ->{
assertNull(value.get());
@ -473,7 +472,7 @@ class HubConnectionTest {
AtomicReference<Double> value2 = new AtomicReference<>();
MockTransport mockTransport = new MockTransport();
HubConnection hubConnection = new HubConnection("http://example.com", mockTransport, new NullLogger(), true, new TestHttpClient());
HubConnection hubConnection = TestUtils.createHubConnection("http://example.com", mockTransport);
hubConnection.on("inc", (param1, param2) ->{
assertNull(value1.get());
@ -500,7 +499,7 @@ class HubConnectionTest {
AtomicReference<String> value3 = new AtomicReference<>();
MockTransport mockTransport = new MockTransport();
HubConnection hubConnection = new HubConnection("http://example.com", mockTransport, new NullLogger(), true, new TestHttpClient());
HubConnection hubConnection = TestUtils.createHubConnection("http://example.com", mockTransport);
hubConnection.on("inc", (param1, param2, param3) ->{
assertNull(value1.get());
@ -531,7 +530,7 @@ class HubConnectionTest {
AtomicReference<String> value4 = new AtomicReference<>();
MockTransport mockTransport = new MockTransport();
HubConnection hubConnection = new HubConnection("http://example.com", mockTransport, new NullLogger(), true, new TestHttpClient());
HubConnection hubConnection = TestUtils.createHubConnection("http://example.com", mockTransport);
hubConnection.on("inc", (param1, param2, param3, param4) ->{
assertNull(value1.get());
@ -565,7 +564,7 @@ class HubConnectionTest {
AtomicReference<Double> value5 = new AtomicReference<>();
MockTransport mockTransport = new MockTransport();
HubConnection hubConnection = new HubConnection("http://example.com", mockTransport, new NullLogger(), true, new TestHttpClient());
HubConnection hubConnection = TestUtils.createHubConnection("http://example.com", mockTransport);
hubConnection.on("inc", (param1, param2, param3, param4, param5) ->{
assertNull(value1.get());
@ -603,7 +602,7 @@ class HubConnectionTest {
AtomicReference<String> value6 = new AtomicReference<>();
MockTransport mockTransport = new MockTransport();
HubConnection hubConnection = new HubConnection("http://example.com", mockTransport, new NullLogger(), true, new TestHttpClient());
HubConnection hubConnection = TestUtils.createHubConnection("http://example.com", mockTransport);
hubConnection.on("inc", (param1, param2, param3, param4, param5, param6) -> {
assertNull(value1.get());
@ -645,7 +644,7 @@ class HubConnectionTest {
AtomicReference<String> value7 = new AtomicReference<>();
MockTransport mockTransport = new MockTransport();
HubConnection hubConnection = new HubConnection("http://example.com", mockTransport, new NullLogger(), true, new TestHttpClient());
HubConnection hubConnection = TestUtils.createHubConnection("http://example.com", mockTransport);
hubConnection.on("inc", (param1, param2, param3, param4, param5, param6, param7) -> {
assertNull(value1.get());
@ -691,7 +690,7 @@ class HubConnectionTest {
AtomicReference<String> value8 = new AtomicReference<>();
MockTransport mockTransport = new MockTransport();
HubConnection hubConnection = new HubConnection("http://example.com", mockTransport, new NullLogger(), true, new TestHttpClient());
HubConnection hubConnection = TestUtils.createHubConnection("http://example.com", mockTransport);
hubConnection.on("inc", (param1, param2, param3, param4, param5, param6, param7, param8) -> {
assertNull(value1.get());
@ -738,7 +737,7 @@ class HubConnectionTest {
AtomicReference<Custom> value1 = new AtomicReference<>();
MockTransport mockTransport = new MockTransport();
HubConnection hubConnection = new HubConnection("http://example.com", mockTransport, new NullLogger(), true, new TestHttpClient());
HubConnection hubConnection = TestUtils.createHubConnection("http://example.com", mockTransport);
hubConnection.on("inc", (param1) -> {
assertNull(value1.get());
@ -763,7 +762,7 @@ class HubConnectionTest {
public void receiveHandshakeResponseAndMessage() throws Exception {
AtomicReference<Double> value = new AtomicReference<Double>(0.0);
MockTransport mockTransport = new MockTransport();
HubConnection hubConnection = new HubConnection("http://example.com", mockTransport, new NullLogger(), true, new TestHttpClient());
HubConnection hubConnection = TestUtils.createHubConnection("http://example.com", mockTransport);
hubConnection.on("inc", () ->{
assertEquals(Double.valueOf(0), value.get());
@ -784,8 +783,7 @@ class HubConnectionTest {
@Test
public void onClosedCallbackRunsWhenStopIsCalled() throws Exception {
AtomicReference<String> value1 = new AtomicReference<>();
Transport mockTransport = new MockTransport();
HubConnection hubConnection = new HubConnection("http://example.com", mockTransport, new NullLogger(), true, new TestHttpClient());
HubConnection hubConnection = TestUtils.createHubConnection("http://example.com");
hubConnection.start();
hubConnection.onClosed((ex) -> {
assertNull(value1.get());
@ -801,8 +799,7 @@ class HubConnectionTest {
public void multipleOnClosedCallbacksRunWhenStopIsCalled() throws Exception {
AtomicReference<String> value1 = new AtomicReference<>();
AtomicReference<String> value2 = new AtomicReference<>();
Transport mockTransport = new MockTransport();
HubConnection hubConnection = new HubConnection("http://example.com", mockTransport, new NullLogger(), true, new TestHttpClient());
HubConnection hubConnection = TestUtils.createHubConnection("http://example.com");
hubConnection.start();
hubConnection.onClosed((ex) -> {
@ -827,7 +824,7 @@ class HubConnectionTest {
@Test
public void hubConnectionClosesAndRunsOnClosedCallbackAfterCloseMessageWithError() throws Exception {
MockTransport mockTransport = new MockTransport();
HubConnection hubConnection = new HubConnection("http://example.com", mockTransport, new NullLogger(), true, new TestHttpClient());
HubConnection hubConnection = TestUtils.createHubConnection("http://example.com", mockTransport);
hubConnection.onClosed((ex) -> {
assertEquals(ex.getMessage(), "There was an error");
});
@ -843,8 +840,7 @@ class HubConnectionTest {
@Test
public void callingStartOnStartedHubConnectionNoOps() throws Exception {
Transport mockTransport = new MockTransport();
HubConnection hubConnection = new HubConnection("http://example.com", mockTransport, new NullLogger(), true, new TestHttpClient());
HubConnection hubConnection = TestUtils.createHubConnection("http://example.com");
hubConnection.start();
assertEquals(HubConnectionState.CONNECTED, hubConnection.getConnectionState());
@ -857,8 +853,7 @@ class HubConnectionTest {
@Test
public void cannotSendBeforeStart() throws Exception {
Transport mockTransport = new MockTransport();
HubConnection hubConnection = new HubConnection("http://example.com", mockTransport, new NullLogger(), true, new TestHttpClient());
HubConnection hubConnection = TestUtils.createHubConnection("http://example.com");
assertEquals(HubConnectionState.DISCONNECTED, hubConnection.getConnectionState());
Throwable exception = assertThrows(HubException.class, () -> hubConnection.send("inc"));
@ -868,7 +863,7 @@ class HubConnectionTest {
@Test
public void errorWhenReceivingInvokeWithIncorrectArgumentLength() throws Exception {
MockTransport mockTransport = new MockTransport();
HubConnection hubConnection = new HubConnection("http://example.com", mockTransport, new NullLogger(), true, new TestHttpClient());
HubConnection hubConnection = TestUtils.createHubConnection("http://example.com", mockTransport);
hubConnection.on("Send", (s) -> {
assertTrue(false);
}, String.class);
@ -886,9 +881,10 @@ class HubConnectionTest {
TestHttpClient client = new TestHttpClient()
.on("POST", (req) -> CompletableFuture.completedFuture(new HttpResponse(404, "", "")));
HttpConnectionOptions options = new HttpConnectionOptions();
options.setHttpClient(client);
HubConnection hubConnection = new HubConnectionBuilder()
.withUrl("http://example.com")
.configureHttpClient(client)
.withUrl("http://example.com", options)
.build();
try {
@ -905,8 +901,11 @@ class HubConnectionTest {
TestHttpClient client = new TestHttpClient().on("POST", "http://example.com/negotiate",
(req) -> CompletableFuture.completedFuture(new HttpResponse(200, "", "{\"url\":\"http://example.com\"}")));
HubConnection hubConnection = new HubConnectionBuilder().withUrl("http://example.com")
.configureHttpClient(client).build();
HttpConnectionOptions options = new HttpConnectionOptions();
options.setHttpClient(client);
HubConnection hubConnection = new HubConnectionBuilder()
.withUrl("http://example.com", options)
.build();
ExecutionException exception = assertThrows(ExecutionException.class, () -> hubConnection.start().get(1000, TimeUnit.MILLISECONDS));
assertEquals("Negotiate redirection limit exceeded.", exception.getCause().getMessage());
@ -922,8 +921,10 @@ class HubConnectionTest {
MockTransport transport = new MockTransport();
HttpConnectionOptions options = new HttpConnectionOptions();
options.setTransport(transport);
HubConnection hubConnection = new HubConnectionBuilder().withUrl("http://example.com", options)
.configureHttpClient(client).build();
options.setHttpClient(client);
HubConnection hubConnection = new HubConnectionBuilder()
.withUrl("http://example.com", options)
.build();
hubConnection.start().get(1000, TimeUnit.MILLISECONDS);
@ -940,8 +941,10 @@ class HubConnectionTest {
MockTransport transport = new MockTransport();
HttpConnectionOptions options = new HttpConnectionOptions();
options.setTransport(transport);
HubConnection hubConnection = new HubConnectionBuilder().withUrl("http://example.com", options)
.configureHttpClient(client).build();
options.setHttpClient(client);
HubConnection hubConnection = new HubConnectionBuilder()
.withUrl("http://example.com", options)
.build();
ExecutionException exception = assertThrows(ExecutionException.class, () -> hubConnection.start().get(1000, TimeUnit.MILLISECONDS));
assertEquals("Test error.", exception.getCause().getMessage());
@ -958,18 +961,75 @@ class HubConnectionTest {
MockTransport transport = new MockTransport();
HttpConnectionOptions options = new HttpConnectionOptions();
options.setTransport(transport);
HubConnection hubConnection = new HubConnectionBuilder().withUrl("http://example.com", options)
.configureHttpClient(client).build();
options.setHttpClient(client);
HubConnection hubConnection = new HubConnectionBuilder()
.withUrl("http://example.com", options)
.build();
hubConnection.start().get(1000, TimeUnit.MILLISECONDS);
assertEquals(HubConnectionState.CONNECTED, hubConnection.getConnectionState());
hubConnection.stop();
}
@Test
public void accessTokenProviderIsUsedForNegotiate()
throws InterruptedException, ExecutionException, TimeoutException, Exception {
AtomicReference<String> token = new AtomicReference<>();
TestHttpClient client = new TestHttpClient()
.on("POST", "http://example.com/negotiate",
(req) -> {
token.set(req.getHeaders().get("Authorization"));
return CompletableFuture
.completedFuture(new HttpResponse(200, "", "{\"connectionId\":\"bVOiRPG8-6YiJ6d7ZcTOVQ\",\""
+ "availableTransports\":[{\"transport\":\"WebSockets\",\"transferFormats\":[\"Text\",\"Binary\"]}]}"));
});
MockTransport transport = new MockTransport();
HttpConnectionOptions options = new HttpConnectionOptions();
options.setTransport(transport);
options.setHttpClient(client);
options.setAccessTokenProvider(() -> CompletableFuture.completedFuture("secretToken"));
HubConnection hubConnection = new HubConnectionBuilder().withUrl("http://example.com", options).build();
hubConnection.start().get(1000, TimeUnit.MILLISECONDS);
assertEquals(HubConnectionState.CONNECTED, hubConnection.getConnectionState());
hubConnection.stop();
assertEquals("Bearer secretToken", token.get());
}
@Test
public void accessTokenProviderIsOverriddenFromRedirectNegotiate()
throws InterruptedException, ExecutionException, TimeoutException, Exception {
AtomicReference<String> token = new AtomicReference<>();
TestHttpClient client = new TestHttpClient()
.on("POST", "http://example.com/negotiate", (req) -> CompletableFuture.completedFuture(new HttpResponse(200, "", "{\"url\":\"http://testexample.com/\",\"accessToken\":\"newToken\"}")))
.on("POST", "http://testexample.com/negotiate", (req) -> {
token.set(req.getHeaders().get("Authorization"));
return CompletableFuture
.completedFuture(new HttpResponse(200, "", "{\"connectionId\":\"bVOiRPG8-6YiJ6d7ZcTOVQ\",\""
+ "availableTransports\":[{\"transport\":\"WebSockets\",\"transferFormats\":[\"Text\",\"Binary\"]}]}"));
});
MockTransport transport = new MockTransport();
HttpConnectionOptions options = new HttpConnectionOptions();
options.setTransport(transport);
options.setHttpClient(client);
options.setAccessTokenProvider(() -> CompletableFuture.completedFuture("secretToken"));
HubConnection hubConnection = new HubConnectionBuilder().withUrl("http://example.com", options).build();
hubConnection.start().get(1000, TimeUnit.MILLISECONDS);
assertEquals(HubConnectionState.CONNECTED, hubConnection.getConnectionState());
hubConnection.stop();
assertEquals("Bearer newToken", token.get());
}
@Test
public void hubConnectionCanBeStartedAfterBeingStopped() throws Exception {
MockTransport mockTransport = new MockTransport();
HubConnection hubConnection = new HubConnection("http://example.com", mockTransport, new NullLogger(), true, new TestHttpClient());
MockTransport transport = new MockTransport();
HttpConnectionOptions options = new HttpConnectionOptions();
options.setTransport(transport);
options.setSkipNegotiate(true);
HubConnection hubConnection = new HubConnectionBuilder().withUrl("http://example.com", options).build();
hubConnection.start().get(1000, TimeUnit.MILLISECONDS);
assertEquals(HubConnectionState.CONNECTED, hubConnection.getConnectionState());
@ -990,7 +1050,10 @@ class HubConnectionTest {
.on("POST", "http://testexample.com/negotiate", (req) -> CompletableFuture
.completedFuture(new HttpResponse(200, "", "{\"connectionId\":\"bVOiRPG8-6YiJ6d7ZcTOVQ\",\""
+ "availableTransports\":[{\"transport\":\"WebSockets\",\"transferFormats\":[\"Text\",\"Binary\"]}]}")));
HubConnection hubConnection = new HubConnection("http://example.com", mockTransport, new NullLogger(), false, client);
HttpConnectionOptions options = new HttpConnectionOptions();
options.setTransport(mockTransport);
options.setHttpClient(client);
HubConnection hubConnection = new HubConnectionBuilder().withUrl("http://example.com", options).build();
hubConnection.start().get(1000, TimeUnit.MILLISECONDS);
assertEquals(HubConnectionState.CONNECTED, hubConnection.getConnectionState());

View File

@ -0,0 +1,24 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
package com.microsoft.aspnet.signalr;
class TestUtils {
static HubConnection createHubConnection(String url) {
return createHubConnection(url, new MockTransport(), new NullLogger(), true, new TestHttpClient());
}
static HubConnection createHubConnection(String url, Transport transport) {
return createHubConnection(url, transport, new NullLogger(), true, new TestHttpClient());
}
static HubConnection createHubConnection(String url, Transport transport, Logger logger, boolean skipNegotiate, HttpClient client) {
HttpConnectionOptions options = new HttpConnectionOptions();
options.setTransport(transport);
options.setLogger(logger);
options.setSkipNegotiate(skipNegotiate);
options.setHttpClient(client);
HubConnectionBuilder builder = new HubConnectionBuilder();
return builder.withUrl(url, options).build();
}
}