|
8 | 8 | import java.util.List; |
9 | 9 | import java.util.Map; |
10 | 10 | import java.util.concurrent.CompletableFuture; |
| 11 | +import java.util.concurrent.CompletionException; |
11 | 12 | import java.util.concurrent.ExecutionException; |
| 13 | +import java.util.concurrent.atomic.AtomicInteger; |
| 14 | +import java.util.concurrent.atomic.AtomicReference; |
12 | 15 | import java.util.stream.Collectors; |
13 | 16 | import java.util.stream.Stream; |
14 | 17 |
|
@@ -106,6 +109,108 @@ void get_withPathParamAndQueryParam_returningBean() { |
106 | 109 | assertThat(dto.otherParam).isEqualTo("other"); |
107 | 110 | } |
108 | 111 |
|
| 112 | + @Test |
| 113 | + void async_whenComplete_returningBean() throws ExecutionException, InterruptedException { |
| 114 | + |
| 115 | + final AtomicInteger counter = new AtomicInteger(); |
| 116 | + final AtomicReference<HelloDto> ref = new AtomicReference<>(); |
| 117 | + |
| 118 | + final CompletableFuture<HelloDto> future = clientContext.request() |
| 119 | + .path("hello/43/2020-03-05").queryParam("otherParam", "other").queryParam("foo", null) |
| 120 | + .GET() |
| 121 | + .async().bean(HelloDto.class); |
| 122 | + |
| 123 | + future.whenComplete((dto, throwable) -> { |
| 124 | + counter.incrementAndGet(); |
| 125 | + ref.set(dto); |
| 126 | + |
| 127 | + assertThat(throwable).isNull(); |
| 128 | + assertThat(dto.id).isEqualTo(43L); |
| 129 | + assertThat(dto.name).isEqualTo("2020-03-05"); |
| 130 | + assertThat(dto.otherParam).isEqualTo("other"); |
| 131 | + }); |
| 132 | + |
| 133 | + // wait ... |
| 134 | + final HelloDto dto = future.get(); |
| 135 | + assertThat(counter.incrementAndGet()).isEqualTo(2); |
| 136 | + assertThat(dto).isSameAs(ref.get()); |
| 137 | + |
| 138 | + assertThat(dto.id).isEqualTo(43L); |
| 139 | + assertThat(dto.name).isEqualTo("2020-03-05"); |
| 140 | + assertThat(dto.otherParam).isEqualTo("other"); |
| 141 | + } |
| 142 | + |
| 143 | + @Test |
| 144 | + void async_whenComplete_throwingHttpException() { |
| 145 | + |
| 146 | + AtomicReference<HttpException> causeRef = new AtomicReference<>(); |
| 147 | + |
| 148 | + final CompletableFuture<HelloDto> future = clientContext.request() |
| 149 | + .path("hello/saveform3") |
| 150 | + .formParam("name", "Bax") |
| 151 | + .formParam("email", "notValidEmail") |
| 152 | + .formParam("url", "notValidUrl") |
| 153 | + .formParam("startDate", "2030-12-03") |
| 154 | + .POST() |
| 155 | + .async() |
| 156 | + .bean(HelloDto.class) |
| 157 | + .whenComplete((helloDto, throwable) -> { |
| 158 | + // we get a throwable |
| 159 | + assertThat(throwable.getCause()).isInstanceOf(HttpException.class); |
| 160 | + assertThat(helloDto).isNull(); |
| 161 | + |
| 162 | + final HttpException httpException = (HttpException) throwable.getCause(); |
| 163 | + causeRef.set(httpException); |
| 164 | + assertThat(httpException.getStatusCode()).isEqualTo(422); |
| 165 | + |
| 166 | + // convert json error response body to a bean |
| 167 | + final ErrorResponse errorResponse = httpException.bean(ErrorResponse.class); |
| 168 | + |
| 169 | + final Map<String, String> errorMap = errorResponse.getErrors(); |
| 170 | + assertThat(errorMap.get("url")).isEqualTo("must be a valid URL"); |
| 171 | + assertThat(errorMap.get("email")).isEqualTo("must be a well-formed email address"); |
| 172 | + }); |
| 173 | + |
| 174 | + try { |
| 175 | + future.join(); |
| 176 | + } catch (CompletionException e) { |
| 177 | + assertThat(e.getCause()).isSameAs(causeRef.get()); |
| 178 | + } |
| 179 | + } |
| 180 | + |
| 181 | + @Test |
| 182 | + void async_exceptionally_style() { |
| 183 | + |
| 184 | + AtomicReference<HttpException> causeRef = new AtomicReference<>(); |
| 185 | + |
| 186 | + final CompletableFuture<HelloDto> future = clientContext.request() |
| 187 | + .path("hello/saveform3") |
| 188 | + .formParam("name", "Bax") |
| 189 | + .formParam("email", "notValidEmail") |
| 190 | + .formParam("url", "notValidUrl") |
| 191 | + .formParam("startDate", "2030-12-03") |
| 192 | + .POST() |
| 193 | + .async() |
| 194 | + .bean(HelloDto.class); |
| 195 | + |
| 196 | + future.exceptionally(throwable -> { |
| 197 | + final HttpException httpException = (HttpException) throwable.getCause(); |
| 198 | + causeRef.set(httpException); |
| 199 | + assertThat(httpException.getStatusCode()).isEqualTo(422); |
| 200 | + |
| 201 | + return new HelloDto(0, "ErrorResponse", ""); |
| 202 | + |
| 203 | + }).thenAccept(helloDto -> { |
| 204 | + assertThat(helloDto.name).isEqualTo("ErrorResponse"); |
| 205 | + }); |
| 206 | + |
| 207 | + try { |
| 208 | + future.join(); |
| 209 | + } catch (CompletionException e) { |
| 210 | + assertThat(e.getCause()).isSameAs(causeRef.get()); |
| 211 | + } |
| 212 | + } |
| 213 | + |
109 | 214 | @Test |
110 | 215 | void post_bean_returningBean_usingExplicitConverters() { |
111 | 216 |
|
|
0 commit comments