View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.juneau.http.remote;
18  
19  import static org.apache.juneau.TestUtils.*;
20  import static org.apache.juneau.common.utils.IOUtils.*;
21  import static org.apache.juneau.http.HttpHeaders.*;
22  import static org.apache.juneau.http.HttpResources.*;
23  import static org.apache.juneau.http.HttpResponses.*;
24  import static org.junit.jupiter.api.Assertions.*;
25  
26  import java.io.*;
27  
28  import org.apache.juneau.*;
29  import org.apache.juneau.http.annotation.*;
30  import org.apache.juneau.http.resource.*;
31  import org.apache.juneau.http.response.*;
32  import org.apache.juneau.rest.annotation.*;
33  import org.apache.juneau.rest.beans.*;
34  import org.apache.juneau.rest.config.*;
35  import org.apache.juneau.rest.mock.*;
36  import org.junit.jupiter.api.*;
37  
38  class Remote_CommonInterfaces_Test extends TestBase {
39  
40  	//-----------------------------------------------------------------------------------------------------------------
41  	// Simple tests, split annotations.
42  	//-----------------------------------------------------------------------------------------------------------------
43  
44  	@Remote
45  	public interface A {
46  		String putX1(@Content String b);
47  		String getX2(@Query("foo") String b);
48  		String getX3(@Header("foo") String b);
49  	}
50  
51  	@Rest
52  	public static class A1 implements A, BasicJson5Config {
53  		@Override
54  		@RestOp
55  		public String putX1(String b) {
56  			return b;
57  		}
58  		@Override
59  		@RestOp
60  		public String getX2(String b) {
61  			return b;
62  		}
63  		@Override
64  		@RestOp
65  		public String getX3(String b) {
66  			return b;
67  		}
68  	}
69  
70  	@Test void a01_splitAnnotations() {
71  		var x = MockRestClient.buildJson(A1.class).getRemote(A.class);
72  		assertEquals("foo",x.putX1("foo"));
73  		assertEquals("foo",x.getX2("foo"));
74  		assertEquals("foo",x.getX3("foo"));
75  	}
76  
77  	//-----------------------------------------------------------------------------------------------------------------
78  	// Simple tests, combined annotations.
79  	//-----------------------------------------------------------------------------------------------------------------
80  
81  	@Remote
82  	@Rest
83  	public interface B extends BasicJson5Config {
84  		String putX1(@Content String b);
85  		String getX2(@Query("foo") String b);
86  		String getX3(@Header("foo") String b);
87  	}
88  
89  	public static class B1 implements B {
90  		@Override
91  		public String putX1(String b) {
92  			return b;
93  		}
94  		@Override
95  		public String getX2(String b) {
96  			return b;
97  		}
98  		@Override
99  		public String getX3(String b) {
100 			return b;
101 		}
102 	}
103 
104 	@Test void b01_combinedAnnotations() {
105 		var x = MockRestClient.create(B1.class).json().build().getRemote(B.class);
106 		assertEquals("foo",x.putX1("foo"));
107 		assertEquals("foo",x.getX2("foo"));
108 		assertEquals("foo",x.getX3("foo"));
109 	}
110 
111 	//-----------------------------------------------------------------------------------------------------------------
112 	// Standard responses
113 	//-----------------------------------------------------------------------------------------------------------------
114 
115 	@Remote
116 	@Rest
117 	public interface C extends BasicJson5Config {
118 		Ok ok();
119 		Accepted accepted();
120 		AlreadyReported alreadyReported();
121 		Created created();
122 		Found found();
123 		IMUsed iMUsed();
124 		MovedPermanently movedPermanently();
125 		MultipleChoices multipleChoices();
126 		MultiStatus multiStatus();
127 		NoContent noContent();
128 		NonAuthoritiveInformation nonAuthoritiveInformation();
129 		NotModified notModified();
130 		PartialContent partialContent();
131 		PermanentRedirect permanentRedirect();
132 		ResetContent resetContent();
133 		SeeOther seeOther();
134 		TemporaryRedirect temporaryRedirect();
135 		UseProxy useProxy();
136 	}
137 
138 	public static class C1 implements C {
139 		@Override public Ok ok() { return OK; }
140 		@Override public Accepted accepted() { return ACCEPTED; }
141 		@Override public AlreadyReported alreadyReported() { return ALREADY_REPORTED; }
142 		@Override public Created created() { return CREATED; }
143 		@Override public Found found() { return FOUND; }
144 		@Override public IMUsed iMUsed() { return IM_USED; }
145 		@Override public MovedPermanently movedPermanently() { return MOVED_PERMANENTLY; }
146 		@Override public MultipleChoices multipleChoices() { return MULTIPLE_CHOICES; }
147 		@Override public MultiStatus multiStatus() { return MULTI_STATUS; }
148 		@Override public NoContent noContent() { return NO_CONTENT; }
149 		@Override public NonAuthoritiveInformation nonAuthoritiveInformation() { return NON_AUTHORATIVE_INFORMATION; }
150 		@Override public NotModified notModified() { return NOT_MODIFIED; }
151 		@Override public PartialContent partialContent() { return PARTIAL_CONTENT; }
152 		@Override public PermanentRedirect permanentRedirect() { return PERMANENT_REDIRECT; }
153 		@Override public ResetContent resetContent() { return RESET_CONTENT; }
154 		@Override public SeeOther seeOther() { return SEE_OTHER; }
155 		@Override public TemporaryRedirect temporaryRedirect() { return TEMPORARY_REDIRECT; }
156 		@Override public UseProxy useProxy() { return USE_PROXY; }
157 	}
158 
159 	@Test void c01_standardResponses() {
160 
161 		// HttpClient goes into loop if status code is less than 200 so we can't test those.
162 
163 		var x = MockRestClient.create(C1.class).json().disableRedirectHandling().build().getRemote(C.class);
164 		assertContains("HTTP/1.1 200", x.ok());
165 		assertContains("HTTP/1.1 202", x.accepted());
166 		assertContains("HTTP/1.1 208", x.alreadyReported());
167 		assertContains("HTTP/1.1 201", x.created());
168 		assertContains("HTTP/1.1 302", x.found());
169 		assertContains("HTTP/1.1 226", x.iMUsed());
170 		assertContains("HTTP/1.1 301", x.movedPermanently());
171 		assertContains("HTTP/1.1 300", x.multipleChoices());
172 		assertContains("HTTP/1.1 207", x.multiStatus());
173 		assertContains("HTTP/1.1 204", x.noContent());
174 		assertContains("HTTP/1.1 203", x.nonAuthoritiveInformation());
175 		assertContains("HTTP/1.1 304", x.notModified());
176 		assertContains("HTTP/1.1 206", x.partialContent());
177 		assertContains("HTTP/1.1 308", x.permanentRedirect());
178 		assertContains("HTTP/1.1 205", x.resetContent());
179 		assertContains("HTTP/1.1 303", x.seeOther());
180 		assertContains("HTTP/1.1 307", x.temporaryRedirect());
181 		assertContains("HTTP/1.1 305", x.useProxy());
182 	}
183 
184 	//-----------------------------------------------------------------------------------------------------------------
185 	// ReaderResource and StreamResource responses
186 	//-----------------------------------------------------------------------------------------------------------------
187 
188 	@Remote
189 	@Rest
190 	public interface D extends BasicJson5Config {
191 		BasicResource httpResource() throws IOException ;
192 	}
193 
194 	public static class D1 implements D {
195 		@Override
196 		public BasicResource httpResource() throws IOException {
197 			return byteArrayResource("foo".getBytes()).setContentType("text/foo").setHeader("Foo","foo").addHeaders(eTag("\"bar\""));
198 		}
199 	}
200 
201 	@Test void d01_httpResource() throws Exception {
202 		var x = MockRestClient.build(D1.class).getRemote(D.class);
203 		var sr = x.httpResource();
204 		assertEquals("foo",read(sr.getContent()));
205 		assertEquals("foo",sr.getHeaders().getLast("Foo").orElseThrow(RuntimeException::new).getValue());
206 		assertEquals("\"bar\"",sr.getHeaders().getLast("ETag").orElseThrow(RuntimeException::new).getValue());
207 		assertEquals("text/foo",sr.getContentType().getValue());
208 	}
209 
210 	//-----------------------------------------------------------------------------------------------------------------
211 	// Predefined exceptions
212 	//-----------------------------------------------------------------------------------------------------------------
213 
214 	@Remote
215 	@Rest
216 	public interface E extends BasicJson5Config {
217 		void badRequest() throws BadRequest;
218 		void conflict() throws Conflict;
219 		void expectationFailed() throws ExpectationFailed;
220 		void failedDependency() throws FailedDependency;
221 		void forbidden() throws Forbidden;
222 		void gone() throws Gone;
223 		void httpVersionNotSupported() throws HttpVersionNotSupported;
224 		void insufficientStorage() throws InsufficientStorage;
225 		void internalServerError() throws InternalServerError;
226 		void lengthRequired() throws LengthRequired;
227 		void locked() throws Locked;
228 		void loopDetected() throws LoopDetected;
229 		void methodNotAllowed() throws MethodNotAllowed;
230 		void misdirectedRequest() throws MisdirectedRequest;
231 		void networkAuthenticationRequired() throws NetworkAuthenticationRequired;
232 		void notAcceptable() throws NotAcceptable;
233 		void notExtended() throws NotExtended;
234 		void notFound() throws NotFound;
235 		void notImplemented() throws NotImplemented;
236 		void payloadTooLarge() throws PayloadTooLarge;
237 		void preconditionFailed() throws PreconditionFailed;
238 		void preconditionRequired() throws PreconditionRequired;
239 		void rangeNotSatisfiable() throws RangeNotSatisfiable;
240 		void requestHeaderFieldsTooLarge() throws RequestHeaderFieldsTooLarge;
241 		void serviceUnavailable() throws ServiceUnavailable;
242 		void tooManyRequests() throws TooManyRequests;
243 		void unauthorized() throws Unauthorized;
244 		void unavailableForLegalReasons() throws UnavailableForLegalReasons;
245 		void unprocessableEntity() throws UnprocessableEntity;
246 		void unsupportedMediaType() throws UnsupportedMediaType;
247 		void upgradeRequired() throws UpgradeRequired;
248 		void uriTooLong() throws UriTooLong;
249 		void variantAlsoNegotiates() throws VariantAlsoNegotiates;
250 	}
251 
252 	public static class E1 implements E {
253 		@Override
254 		public void badRequest() throws BadRequest {
255 			throw BAD_REQUEST;
256 		}
257 		@Override
258 		public void conflict() throws Conflict {
259 			throw CONFLICT;
260 		}
261 		@Override
262 		public void expectationFailed() throws ExpectationFailed {
263 			throw EXPECTATION_FAILED;
264 		}
265 		@Override
266 		public void failedDependency() throws FailedDependency {
267 			throw FAILED_DEPENDENCY;
268 		}
269 		@Override
270 		public void forbidden() throws Forbidden {
271 			throw FORBIDDEN;
272 		}
273 		@Override
274 		public void gone() throws Gone {
275 			throw GONE;
276 		}
277 		@Override
278 		public void httpVersionNotSupported() throws HttpVersionNotSupported {
279 			throw HTTP_VERSION_NOT_SUPPORTED;
280 		}
281 		@Override
282 		public void insufficientStorage() throws InsufficientStorage {
283 			throw INSUFFICIENT_STORAGE;
284 		}
285 		@Override
286 		public void internalServerError() throws InternalServerError {
287 			throw INTERNAL_SERVER_ERROR;
288 		}
289 		@Override
290 		public void lengthRequired() throws LengthRequired {
291 			throw LENGTH_REQUIRED;
292 		}
293 		@Override
294 		public void locked() throws Locked {
295 			throw LOCKED;
296 		}
297 		@Override
298 		public void loopDetected() throws LoopDetected {
299 			throw LOOP_DETECTED;
300 		}
301 		@Override
302 		public void methodNotAllowed() throws MethodNotAllowed {
303 			throw METHOD_NOT_ALLOWED;
304 		}
305 		@Override
306 		public void misdirectedRequest() throws MisdirectedRequest {
307 			throw MISDIRECTED_REQUEST;
308 		}
309 		@Override
310 		public void networkAuthenticationRequired() throws NetworkAuthenticationRequired {
311 			throw NETWORK_AUTHENTICATION_REQUIRED;
312 		}
313 		@Override
314 		public void notAcceptable() throws NotAcceptable {
315 			throw NOT_ACCEPTABLE;
316 		}
317 		@Override
318 		public void notExtended() throws NotExtended {
319 			throw NOT_EXTENDED;
320 		}
321 		@Override
322 		public void notFound() throws NotFound {
323 			throw NOT_FOUND;
324 		}
325 		@Override
326 		public void notImplemented() throws NotImplemented {
327 			throw NOT_IMPLEMENTED;
328 		}
329 		@Override
330 		public void payloadTooLarge() throws PayloadTooLarge {
331 			throw PAYLOAD_TOO_LARGE;
332 		}
333 		@Override
334 		public void preconditionFailed() throws PreconditionFailed {
335 			throw PRECONDITION_FAILED;
336 		}
337 		@Override
338 		public void preconditionRequired() throws PreconditionRequired {
339 			throw PRECONDITION_REQUIRED;
340 		}
341 		@Override
342 		public void rangeNotSatisfiable() throws RangeNotSatisfiable {
343 			throw RANGE_NOT_SATISFIABLE;
344 		}
345 		@Override
346 		public void requestHeaderFieldsTooLarge() throws RequestHeaderFieldsTooLarge {
347 			throw REQUEST_HEADER_FIELDS_TOO_LARGE;
348 		}
349 		@Override
350 		public void serviceUnavailable() throws ServiceUnavailable {
351 			throw SERVICE_UNAVAILABLE;
352 		}
353 		@Override
354 		public void tooManyRequests() throws TooManyRequests {
355 			throw TOO_MANY_REQUESTS;
356 		}
357 		@Override
358 		public void unauthorized() throws Unauthorized {
359 			throw UNAUTHORIZED;
360 		}
361 		@Override
362 		public void unavailableForLegalReasons() throws UnavailableForLegalReasons {
363 			throw UNAVAILABLE_FOR_LEGAL_REASONS;
364 		}
365 		@Override
366 		public void unprocessableEntity() throws UnprocessableEntity {
367 			throw UNPROCESSABLE_ENTITIY;
368 		}
369 		@Override
370 		public void unsupportedMediaType() throws UnsupportedMediaType {
371 			throw UNSUPPORTED_MEDIA_TYPE;
372 		}
373 		@Override
374 		public void upgradeRequired() throws UpgradeRequired {
375 			throw UPGRADE_REQUIRED;
376 		}
377 		@Override
378 		public void uriTooLong() throws UriTooLong {
379 			throw URI_TOO_LONG;
380 		}
381 		@Override
382 		public void variantAlsoNegotiates() throws VariantAlsoNegotiates {
383 			throw VARIANT_ALSO_NEGOTIATES;
384 		}
385 	}
386 
387 	@Test void e01_predefinedExceptions() {
388 		var x = MockRestClient.create(E1.class).noTrace().build().getRemote(E.class);
389 		assertThrowsWithMessage(BadRequest.class, BadRequest.REASON_PHRASE, x::badRequest);
390 		assertThrowsWithMessage(Conflict.class, Conflict.REASON_PHRASE, x::conflict);
391 		assertThrowsWithMessage(ExpectationFailed.class, ExpectationFailed.REASON_PHRASE, x::expectationFailed);
392 		assertThrowsWithMessage(FailedDependency.class, FailedDependency.REASON_PHRASE, x::failedDependency);
393 		assertThrowsWithMessage(Forbidden.class, Forbidden.REASON_PHRASE, x::forbidden);
394 		assertThrowsWithMessage(Gone.class, Gone.REASON_PHRASE, x::gone);
395 		assertThrowsWithMessage(HttpVersionNotSupported.class, HttpVersionNotSupported.REASON_PHRASE, x::httpVersionNotSupported);
396 		assertThrowsWithMessage(InsufficientStorage.class, InsufficientStorage.REASON_PHRASE, x::insufficientStorage);
397 		assertThrowsWithMessage(InternalServerError.class, InternalServerError.REASON_PHRASE, x::internalServerError);
398 		assertThrowsWithMessage(LengthRequired.class, LengthRequired.REASON_PHRASE, x::lengthRequired);
399 		assertThrowsWithMessage(Locked.class, Locked.REASON_PHRASE, x::locked);
400 		assertThrowsWithMessage(LoopDetected.class, LoopDetected.REASON_PHRASE, x::loopDetected);
401 		assertThrowsWithMessage(MethodNotAllowed.class, MethodNotAllowed.REASON_PHRASE, x::methodNotAllowed);
402 		assertThrowsWithMessage(MisdirectedRequest.class, MisdirectedRequest.REASON_PHRASE, x::misdirectedRequest);
403 		assertThrowsWithMessage(NetworkAuthenticationRequired.class, NetworkAuthenticationRequired.REASON_PHRASE, x::networkAuthenticationRequired);
404 		assertThrowsWithMessage(NotAcceptable.class, NotAcceptable.REASON_PHRASE, x::notAcceptable);
405 		assertThrowsWithMessage(NotExtended.class, NotExtended.REASON_PHRASE, x::notExtended);
406 		assertThrowsWithMessage(NotFound.class, NotFound.REASON_PHRASE, x::notFound);
407 		assertThrowsWithMessage(NotImplemented.class, NotImplemented.REASON_PHRASE, x::notImplemented);
408 		assertThrowsWithMessage(PayloadTooLarge.class, PayloadTooLarge.REASON_PHRASE, x::payloadTooLarge);
409 		assertThrowsWithMessage(PreconditionFailed.class, PreconditionFailed.REASON_PHRASE, x::preconditionFailed);
410 		assertThrowsWithMessage(PreconditionRequired.class, PreconditionRequired.REASON_PHRASE, x::preconditionRequired);
411 		assertThrowsWithMessage(RangeNotSatisfiable.class, RangeNotSatisfiable.REASON_PHRASE, x::rangeNotSatisfiable);
412 		assertThrowsWithMessage(RequestHeaderFieldsTooLarge.class, RequestHeaderFieldsTooLarge.REASON_PHRASE, x::requestHeaderFieldsTooLarge);
413 		assertThrowsWithMessage(ServiceUnavailable.class, ServiceUnavailable.REASON_PHRASE, x::serviceUnavailable);
414 		assertThrowsWithMessage(TooManyRequests.class, TooManyRequests.REASON_PHRASE, x::tooManyRequests);
415 		assertThrowsWithMessage(Unauthorized.class, Unauthorized.REASON_PHRASE, x::unauthorized);
416 		assertThrowsWithMessage(UnavailableForLegalReasons.class, UnavailableForLegalReasons.REASON_PHRASE, x::unavailableForLegalReasons);
417 		assertThrowsWithMessage(UnprocessableEntity.class, UnprocessableEntity.REASON_PHRASE, x::unprocessableEntity);
418 		assertThrowsWithMessage(UnsupportedMediaType.class, UnsupportedMediaType.REASON_PHRASE, x::unsupportedMediaType);
419 		assertThrowsWithMessage(UpgradeRequired.class, UpgradeRequired.REASON_PHRASE, x::upgradeRequired);
420 		assertThrowsWithMessage(UriTooLong.class, UriTooLong.REASON_PHRASE, x::uriTooLong);
421 		assertThrowsWithMessage(VariantAlsoNegotiates.class, VariantAlsoNegotiates.REASON_PHRASE, x::variantAlsoNegotiates);
422 	}
423 
424 	public static class E2 implements E {
425 		@Override
426 		public void badRequest() throws BadRequest {
427 			throw new BadRequest("foo");
428 		}
429 		@Override
430 		public void conflict() throws Conflict {
431 			throw new Conflict("foo");
432 		}
433 		@Override
434 		public void expectationFailed() throws ExpectationFailed {
435 			throw new ExpectationFailed("foo");
436 		}
437 		@Override
438 		public void failedDependency() throws FailedDependency {
439 			throw new FailedDependency("foo");
440 		}
441 		@Override
442 		public void forbidden() throws Forbidden {
443 			throw new Forbidden("foo");
444 		}
445 		@Override
446 		public void gone() throws Gone {
447 			throw new Gone("foo");
448 		}
449 		@Override
450 		public void httpVersionNotSupported() throws HttpVersionNotSupported {
451 			throw new HttpVersionNotSupported("foo");
452 		}
453 		@Override
454 		public void insufficientStorage() throws InsufficientStorage {
455 			throw new InsufficientStorage("foo");
456 		}
457 		@Override
458 		public void internalServerError() throws InternalServerError {
459 			throw new InternalServerError("foo");
460 		}
461 		@Override
462 		public void lengthRequired() throws LengthRequired {
463 			throw new LengthRequired("foo");
464 		}
465 		@Override
466 		public void locked() throws Locked {
467 			throw new Locked("foo");
468 		}
469 		@Override
470 		public void loopDetected() throws LoopDetected {
471 			throw new LoopDetected("foo");
472 		}
473 		@Override
474 		public void methodNotAllowed() throws MethodNotAllowed {
475 			throw new MethodNotAllowed("foo");
476 		}
477 		@Override
478 		public void misdirectedRequest() throws MisdirectedRequest {
479 			throw new MisdirectedRequest("foo");
480 		}
481 		@Override
482 		public void networkAuthenticationRequired() throws NetworkAuthenticationRequired {
483 			throw new NetworkAuthenticationRequired("foo");
484 		}
485 		@Override
486 		public void notAcceptable() throws NotAcceptable {
487 			throw new NotAcceptable("foo");
488 		}
489 		@Override
490 		public void notExtended() throws NotExtended {
491 			throw new NotExtended("foo");
492 		}
493 		@Override
494 		public void notFound() throws NotFound {
495 			throw new NotFound("foo");
496 		}
497 		@Override
498 		public void notImplemented() throws NotImplemented {
499 			throw new NotImplemented("foo");
500 		}
501 		@Override
502 		public void payloadTooLarge() throws PayloadTooLarge {
503 			throw new PayloadTooLarge("foo");
504 		}
505 		@Override
506 		public void preconditionFailed() throws PreconditionFailed {
507 			throw new PreconditionFailed("foo");
508 		}
509 		@Override
510 		public void preconditionRequired() throws PreconditionRequired {
511 			throw new PreconditionRequired("foo");
512 		}
513 		@Override
514 		public void rangeNotSatisfiable() throws RangeNotSatisfiable {
515 			throw new RangeNotSatisfiable("foo");
516 		}
517 		@Override
518 		public void requestHeaderFieldsTooLarge() throws RequestHeaderFieldsTooLarge {
519 			throw new RequestHeaderFieldsTooLarge("foo");
520 		}
521 		@Override
522 		public void serviceUnavailable() throws ServiceUnavailable {
523 			throw new ServiceUnavailable("foo");
524 		}
525 		@Override
526 		public void tooManyRequests() throws TooManyRequests {
527 			throw new TooManyRequests("foo");
528 		}
529 		@Override
530 		public void unauthorized() throws Unauthorized {
531 			throw new Unauthorized("foo");
532 		}
533 		@Override
534 		public void unavailableForLegalReasons() throws UnavailableForLegalReasons {
535 			throw new UnavailableForLegalReasons("foo");
536 		}
537 		@Override
538 		public void unprocessableEntity() throws UnprocessableEntity {
539 			throw new UnprocessableEntity("foo");
540 		}
541 		@Override
542 		public void unsupportedMediaType() throws UnsupportedMediaType {
543 			throw new UnsupportedMediaType("foo");
544 		}
545 		@Override
546 		public void upgradeRequired() throws UpgradeRequired {
547 			throw new UpgradeRequired("foo");
548 		}
549 		@Override
550 		public void uriTooLong() throws UriTooLong {
551 			throw new UriTooLong("foo");
552 		}
553 		@Override
554 		public void variantAlsoNegotiates() throws VariantAlsoNegotiates {
555 			throw new VariantAlsoNegotiates("foo");
556 		}
557 	}
558 
559 	@Test void e02_predefinedExceptions_customMessages() {
560 		var x = MockRestClient.create(E2.class).noTrace().build().getRemote(E.class);
561 		assertThrowsWithMessage(BadRequest.class, "foo", x::badRequest);
562 		assertThrowsWithMessage(Conflict.class, "foo", x::conflict);
563 		assertThrowsWithMessage(ExpectationFailed.class, "foo", x::expectationFailed);
564 		assertThrowsWithMessage(FailedDependency.class, "foo", x::failedDependency);
565 		assertThrowsWithMessage(Forbidden.class, "foo", x::forbidden);
566 		assertThrowsWithMessage(Gone.class, "foo", x::gone);
567 		assertThrowsWithMessage(HttpVersionNotSupported.class, "foo", x::httpVersionNotSupported);
568 		assertThrowsWithMessage(InsufficientStorage.class, "foo", x::insufficientStorage);
569 		assertThrowsWithMessage(InternalServerError.class, "foo", x::internalServerError);
570 		assertThrowsWithMessage(LengthRequired.class, "foo", x::lengthRequired);
571 		assertThrowsWithMessage(Locked.class, "foo", x::locked);
572 		assertThrowsWithMessage(LoopDetected.class, "foo", x::loopDetected);
573 		assertThrowsWithMessage(MethodNotAllowed.class, "foo", x::methodNotAllowed);
574 		assertThrowsWithMessage(MisdirectedRequest.class, "foo", x::misdirectedRequest);
575 		assertThrowsWithMessage(NetworkAuthenticationRequired.class, "foo", x::networkAuthenticationRequired);
576 		assertThrowsWithMessage(NotAcceptable.class, "foo", x::notAcceptable);
577 		assertThrowsWithMessage(NotExtended.class, "foo", x::notExtended);
578 		assertThrowsWithMessage(NotFound.class, "foo", x::notFound);
579 		assertThrowsWithMessage(NotImplemented.class, "foo", x::notImplemented);
580 		assertThrowsWithMessage(PayloadTooLarge.class, "foo", x::payloadTooLarge);
581 		assertThrowsWithMessage(PreconditionFailed.class, "foo", x::preconditionFailed);
582 		assertThrowsWithMessage(PreconditionRequired.class, "foo", x::preconditionRequired);
583 		assertThrowsWithMessage(RangeNotSatisfiable.class, "foo", x::rangeNotSatisfiable);
584 		assertThrowsWithMessage(RequestHeaderFieldsTooLarge.class, "foo", x::requestHeaderFieldsTooLarge);
585 		assertThrowsWithMessage(ServiceUnavailable.class, "foo", x::serviceUnavailable);
586 		assertThrowsWithMessage(TooManyRequests.class, "foo", x::tooManyRequests);
587 		assertThrowsWithMessage(Unauthorized.class, "foo", x::unauthorized);
588 		assertThrowsWithMessage(UnavailableForLegalReasons.class, "foo", x::unavailableForLegalReasons);
589 		assertThrowsWithMessage(UnprocessableEntity.class, "foo", x::unprocessableEntity);
590 		assertThrowsWithMessage(UnsupportedMediaType.class, "foo", x::unsupportedMediaType);
591 		assertThrowsWithMessage(UpgradeRequired.class, "foo", x::upgradeRequired);
592 		assertThrowsWithMessage(UriTooLong.class, "foo", x::uriTooLong);
593 		assertThrowsWithMessage(VariantAlsoNegotiates.class, "foo", x::variantAlsoNegotiates);
594 	}
595 
596 	//-----------------------------------------------------------------------------------------------------------------
597 	// Throwables returned by method instead of thrown.
598 	//-----------------------------------------------------------------------------------------------------------------
599 
600 	@Remote
601 	@Rest
602 	public interface F extends BasicJson5Config {
603 		BadRequest badRequest();
604 		Conflict conflict();
605 		ExpectationFailed expectationFailed();
606 		FailedDependency failedDependency();
607 		Forbidden forbidden();
608 		Gone gone();
609 		HttpVersionNotSupported httpVersionNotSupported();
610 		InsufficientStorage insufficientStorage();
611 		InternalServerError internalServerError();
612 		LengthRequired lengthRequired();
613 		Locked locked();
614 		LoopDetected loopDetected();
615 		MethodNotAllowed methodNotAllowed();
616 		MisdirectedRequest misdirectedRequest();
617 		NetworkAuthenticationRequired networkAuthenticationRequired();
618 		NotAcceptable notAcceptable();
619 		NotExtended notExtended();
620 		NotFound notFound();
621 		NotImplemented notImplemented();
622 		PayloadTooLarge payloadTooLarge();
623 		PreconditionFailed preconditionFailed();
624 		PreconditionRequired preconditionRequired();
625 		RangeNotSatisfiable rangeNotSatisfiable();
626 		RequestHeaderFieldsTooLarge requestHeaderFieldsTooLarge();
627 		ServiceUnavailable serviceUnavailable();
628 		TooManyRequests tooManyRequests();
629 		Unauthorized unauthorized();
630 		UnavailableForLegalReasons unavailableForLegalReasons();
631 		UnprocessableEntity unprocessableEntity();
632 		UnsupportedMediaType unsupportedMediaType();
633 		UpgradeRequired upgradeRequired();
634 		UriTooLong uriTooLong();
635 		VariantAlsoNegotiates variantAlsoNegotiates();
636 	}
637 
638 	public static class F1 implements F {
639 		@Override
640 		public BadRequest badRequest() {
641 			return new BadRequest("foo");
642 		}
643 		@Override
644 		public Conflict conflict() {
645 			return new Conflict("foo");
646 		}
647 		@Override
648 		public ExpectationFailed expectationFailed() {
649 			return new ExpectationFailed("foo");
650 		}
651 		@Override
652 		public FailedDependency failedDependency() {
653 			return new FailedDependency("foo");
654 		}
655 		@Override
656 		public Forbidden forbidden() {
657 			return new Forbidden("foo");
658 		}
659 		@Override
660 		public Gone gone() {
661 			return new Gone("foo");
662 		}
663 		@Override
664 		public HttpVersionNotSupported httpVersionNotSupported() {
665 			return new HttpVersionNotSupported("foo");
666 		}
667 		@Override
668 		public InsufficientStorage insufficientStorage() {
669 			return new InsufficientStorage("foo");
670 		}
671 		@Override
672 		public InternalServerError internalServerError() {
673 			return new InternalServerError("foo");
674 		}
675 		@Override
676 		public LengthRequired lengthRequired() {
677 			return new LengthRequired("foo");
678 		}
679 		@Override
680 		public Locked locked() {
681 			return new Locked("foo");
682 		}
683 		@Override
684 		public LoopDetected loopDetected() {
685 			return new LoopDetected("foo");
686 		}
687 		@Override
688 		public MethodNotAllowed methodNotAllowed() {
689 			return new MethodNotAllowed("foo");
690 		}
691 		@Override
692 		public MisdirectedRequest misdirectedRequest() {
693 			return new MisdirectedRequest("foo");
694 		}
695 		@Override
696 		public NetworkAuthenticationRequired networkAuthenticationRequired() {
697 			return new NetworkAuthenticationRequired("foo");
698 		}
699 		@Override
700 		public NotAcceptable notAcceptable() {
701 			return new NotAcceptable("foo");
702 		}
703 		@Override
704 		public NotExtended notExtended() {
705 			return new NotExtended("foo");
706 		}
707 		@Override
708 		public NotFound notFound() {
709 			return new NotFound("foo");
710 		}
711 		@Override
712 		public NotImplemented notImplemented() {
713 			return new NotImplemented("foo");
714 		}
715 		@Override
716 		public PayloadTooLarge payloadTooLarge() {
717 			return new PayloadTooLarge("foo");
718 		}
719 		@Override
720 		public PreconditionFailed preconditionFailed() {
721 			return new PreconditionFailed("foo");
722 		}
723 		@Override
724 		public PreconditionRequired preconditionRequired() {
725 			return new PreconditionRequired("foo");
726 		}
727 		@Override
728 		public RangeNotSatisfiable rangeNotSatisfiable() {
729 			return new RangeNotSatisfiable("foo");
730 		}
731 		@Override
732 		public RequestHeaderFieldsTooLarge requestHeaderFieldsTooLarge() {
733 			return new RequestHeaderFieldsTooLarge("foo");
734 		}
735 		@Override
736 		public ServiceUnavailable serviceUnavailable() {
737 			return new ServiceUnavailable("foo");
738 		}
739 		@Override
740 		public TooManyRequests tooManyRequests() {
741 			return new TooManyRequests("foo");
742 		}
743 		@Override
744 		public Unauthorized unauthorized() {
745 			return new Unauthorized("foo");
746 		}
747 		@Override
748 		public UnavailableForLegalReasons unavailableForLegalReasons() {
749 			return new UnavailableForLegalReasons("foo");
750 		}
751 		@Override
752 		public UnprocessableEntity unprocessableEntity() {
753 			return new UnprocessableEntity("foo");
754 		}
755 		@Override
756 		public UnsupportedMediaType unsupportedMediaType() {
757 			return new UnsupportedMediaType("foo");
758 		}
759 		@Override
760 		public UpgradeRequired upgradeRequired() {
761 			return new UpgradeRequired("foo");
762 		}
763 		@Override
764 		public UriTooLong uriTooLong() {
765 			return new UriTooLong("foo");
766 		}
767 		@Override
768 		public VariantAlsoNegotiates variantAlsoNegotiates() {
769 			return new VariantAlsoNegotiates("foo");
770 		}
771 	}
772 
773 	@Test void f01_badRequest_returnedExceptions() {
774 		var x = MockRestClient.create(F1.class).noTrace().json().build().getRemote(F.class);
775 		assertEquals("foo",x.badRequest().getMessage());
776 		assertEquals("foo",x.conflict().getMessage());
777 		assertEquals("foo",x.expectationFailed().getMessage());
778 		assertEquals("foo",x.failedDependency().getMessage());
779 		assertEquals("foo",x.forbidden().getMessage());
780 		assertEquals("foo",x.gone().getMessage());
781 		assertEquals("foo",x.httpVersionNotSupported().getMessage());
782 		assertEquals("foo",x.insufficientStorage().getMessage());
783 		assertEquals("foo",x.internalServerError().getMessage());
784 		assertEquals("foo",x.lengthRequired().getMessage());
785 		assertEquals("foo",x.locked().getMessage());
786 		assertEquals("foo",x.loopDetected().getMessage());
787 		assertEquals("foo",x.methodNotAllowed().getMessage());
788 		assertEquals("foo",x.misdirectedRequest().getMessage());
789 		assertEquals("foo",x.networkAuthenticationRequired().getMessage());
790 		assertEquals("foo",x.notAcceptable().getMessage());
791 		assertEquals("foo",x.notExtended().getMessage());
792 		assertEquals("foo",x.notFound().getMessage());
793 		assertEquals("foo",x.notImplemented().getMessage());
794 		assertEquals("foo",x.payloadTooLarge().getMessage());
795 		assertEquals("foo",x.preconditionFailed().getMessage());
796 		assertEquals("foo",x.preconditionRequired().getMessage());
797 		assertEquals("foo",x.rangeNotSatisfiable().getMessage());
798 		assertEquals("foo",x.requestHeaderFieldsTooLarge().getMessage());
799 		assertEquals("foo",x.serviceUnavailable().getMessage());
800 		assertEquals("foo",x.tooManyRequests().getMessage());
801 		assertEquals("foo",x.unauthorized().getMessage());
802 		assertEquals("foo",x.unavailableForLegalReasons().getMessage());
803 		assertEquals("foo",x.unprocessableEntity().getMessage());
804 		assertEquals("foo",x.unsupportedMediaType().getMessage());
805 		assertEquals("foo",x.upgradeRequired().getMessage());
806 		assertEquals("foo",x.uriTooLong().getMessage());
807 		assertEquals("foo",x.variantAlsoNegotiates().getMessage());
808 	}
809 
810 	//-----------------------------------------------------------------------------------------------------------------
811 	// Reader/InputStream return types.
812 	//-----------------------------------------------------------------------------------------------------------------
813 
814 	@Remote
815 	@Rest
816 	public interface G extends BasicJson5Config {
817 		Reader reader();
818 		InputStream inputStream();
819 	}
820 
821 	public static class G1 implements G {
822 		@Override
823 		public Reader reader() {
824 			return TestUtils.reader("foo");
825 		}
826 		@Override
827 		public InputStream inputStream() {
828 			return TestUtils.inputStream("foo");
829 		}
830 	}
831 
832 	@Test void g01_reader_inputStream() throws Exception {
833 		var x = MockRestClient.build(G1.class).getRemote(G.class);
834 		assertEquals("foo",read(x.reader()));
835 		assertEquals("foo",read(x.inputStream()));
836 	}
837 
838 	//-----------------------------------------------------------------------------------------------------------------
839 	// Helper responses
840 	//-----------------------------------------------------------------------------------------------------------------
841 
842 	@Remote
843 	@Rest
844 	public interface IH extends BasicJson5Config {
845 		SeeOtherRoot seeOtherRoot();
846 	}
847 
848 	public static class H implements IH {
849 		@Override
850 		public SeeOtherRoot seeOtherRoot() {
851 			return SeeOtherRoot.INSTANCE;
852 		}
853 	}
854 
855 	@Test void h01_seeOtherRoot() {
856 		var x = MockRestClient.create(H.class).json().disableRedirectHandling().build().getRemote(IH.class);
857 		assertContains("HTTP/1.1 303 See Other", x.seeOtherRoot());
858 	}
859 }