Skip to content

Commit 73afac6

Browse files
authored
Merge pull request #361 from microsoftgraph/feature/cancellable
- adds support for cancelling request
2 parents 0adcd40 + 505c699 commit 73afac6

File tree

4 files changed

+64
-3
lines changed

4 files changed

+64
-3
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
### Added
1111

12+
- Added support for cancelling requests #361
13+
1214
### Changed
1315

1416
- Bumps Azure Core from 1.20.0 to 1.22.0 #359, #360, #341, #342

src/main/java/com/microsoft/graph/http/CoreHttpCallbackFutureWrapper.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
package com.microsoft.graph.http;
22

33
import java.io.IOException;
4-
4+
import java.util.Objects;
5+
import java.util.concurrent.CancellationException;
56
import java.util.concurrent.CompletableFuture;
67

8+
import javax.annotation.Nonnull;
9+
710
import okhttp3.Call;
811
import okhttp3.Callback;
912
import okhttp3.Response;
@@ -13,6 +16,14 @@
1316
*/
1417
class CoreHttpCallbackFutureWrapper implements Callback {
1518
final CompletableFuture<Response> future = new CompletableFuture<>();
19+
public CoreHttpCallbackFutureWrapper(@Nonnull final Call call) {
20+
Objects.requireNonNull(call);
21+
future.whenComplete((r, ex) -> {
22+
if (ex != null && (ex instanceof InterruptedException || ex instanceof CancellationException)) {
23+
call.cancel();
24+
}
25+
});
26+
}
1627
@Override
1728
public void onFailure(Call arg0, IOException arg1) {
1829
future.completeExceptionally(arg1);

src/main/java/com/microsoft/graph/http/CoreHttpProvider.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
import javax.annotation.Nonnull;
5252
import javax.annotation.Nullable;
5353

54+
import okhttp3.Call;
5455
import okhttp3.MediaType;
5556
import okhttp3.OkHttpClient;
5657
import okhttp3.Request;
@@ -375,8 +376,9 @@ private <Result, Body, DeserializeType> java.util.concurrent.CompletableFuture<R
375376
@Nullable final IStatefulResponseHandler<Result, DeserializeType> handler)
376377
throws ClientException {
377378
final Request coreHttpRequest = getHttpRequest(request, resultClass, serializable);
378-
final CoreHttpCallbackFutureWrapper wrapper = new CoreHttpCallbackFutureWrapper();
379-
corehttpClient.newCall(coreHttpRequest).enqueue(wrapper);
379+
final Call call = corehttpClient.newCall(coreHttpRequest);
380+
final CoreHttpCallbackFutureWrapper wrapper = new CoreHttpCallbackFutureWrapper(call);
381+
call.enqueue(wrapper);
380382
return wrapper.future.thenApply(r -> processResponse(r, request, resultClass, serializable, handler));
381383
}
382384
/**
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package com.microsoft.graph.http;
2+
3+
import static org.junit.jupiter.api.Assertions.assertEquals;
4+
import static org.junit.jupiter.api.Assertions.assertThrows;
5+
import static org.junit.jupiter.api.Assertions.assertTrue;
6+
import static org.mockito.Mockito.doAnswer;
7+
import static org.mockito.Mockito.mock;
8+
9+
import java.io.IOException;
10+
import java.util.concurrent.ExecutionException;
11+
12+
import org.junit.jupiter.api.Test;
13+
14+
import okhttp3.Call;
15+
import okhttp3.Response;
16+
17+
class CoreHttpCallbackFutureWrapperTests {
18+
19+
@Test
20+
void throwsIfCallIsNull() {
21+
assertThrows(NullPointerException.class, () -> new CoreHttpCallbackFutureWrapper(null));
22+
}
23+
boolean isCanceled = false;
24+
25+
@Test
26+
void cancelsCall() {
27+
var call = mock(Call.class);
28+
doAnswer(i -> {
29+
isCanceled = true;
30+
return null;
31+
}).when(call).cancel();
32+
var wrapper = new CoreHttpCallbackFutureWrapper(call);
33+
wrapper.future.cancel(true);
34+
assertTrue(isCanceled);
35+
}
36+
37+
@Test
38+
void returnsResponseWhenCompleted() throws IOException, InterruptedException, ExecutionException {
39+
var call = mock(Call.class);
40+
var response = mock(Response.class);
41+
var wrapper = new CoreHttpCallbackFutureWrapper(call);
42+
wrapper.onResponse(call, response);
43+
assertEquals(response, wrapper.future.get());
44+
}
45+
46+
}

0 commit comments

Comments
 (0)