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