You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@juneau.apache.org by ja...@apache.org on 2020/06/08 16:10:24 UTC

[juneau] branch master updated: RestClient tests

This is an automated email from the ASF dual-hosted git repository.

jamesbognar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/juneau.git


The following commit(s) were added to refs/heads/master by this push:
     new 39bd632  RestClient tests
39bd632 is described below

commit 39bd632c4715491b6f4f0d23c7296ada4a4d728c
Author: JamesBognar <ja...@salesforce.com>
AuthorDate: Mon Jun 8 12:10:06 2020 -0400

    RestClient tests
---
 .../juneau/rest/client2/RestCallInterceptor.java   |  25 ++++-
 .../org/apache/juneau/rest/client2/RestClient.java | 122 ++++++++++++++++++++-
 .../juneau/rest/client2/RestResponseBody.java      |   3 +
 .../juneau/rest/client2/RestResponseHeader.java    |  14 ++-
 4 files changed, 158 insertions(+), 6 deletions(-)

diff --git a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestCallInterceptor.java b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestCallInterceptor.java
index 0241d01..fd26b3a 100644
--- a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestCallInterceptor.java
+++ b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestCallInterceptor.java
@@ -19,7 +19,28 @@ import org.apache.http.*;
  * listening for call lifecycle events.
  *
  * <p>
- * Useful if you want to prevent {@link RestCallException RestCallExceptions} from being thrown on error conditions.
+ * The {@link BasicRestCallInterceptor} is provided as an adapter class for implementing this interface.
+ *
+ * <p>
+ * Note that the {@link RestClient} class itself implements this interface so you can achieve the same results by
+ * overriding the methods on the client class as well.
+ *
+ * <h5 class='figure'>Example:</h5>
+ * <p class='bcode w800'>
+ * 	<jc>// Specialized client that adds a header to every request.</jc>
+ * 	<jk>public class</jk> MyRestClient <jk>extends</jk> RestClient {
+ * 		<ja>@Override</ja>
+ * 		<jk>public void</jk> onInit(RestRequest req) {
+ * 			req.header(<js>"Foo"</js>, <js>"bar"</js>);
+ * 		}
+ * 	}
+ *
+ *	<jc>// Instantiate the client.</jc>
+ *	MyRestClient c = RestClient
+ *		.<jsm>create</jsm>()
+ *		.json()
+ *		.build(MyRestClient.<jk>class</jk>);
+ * </p>
  *
  * <ul class='seealso'>
  * 	<li class='jf'>{@link RestClient#RESTCLIENT_interceptors}
@@ -31,7 +52,7 @@ public interface RestCallInterceptor extends HttpRequestInterceptor, HttpRespons
 
 	/**
 	 * Called immediately after {@link RestRequest} object is created and all headers/query/form-data has been
-	 * set on the request from the client.
+	 * copied from the client to the request object.
 	 *
 	 * @param req The HTTP request object.
 	 * @throws Exception Any exception can be thrown.
diff --git a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestClient.java b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestClient.java
index dd71afc..4f9eca9 100644
--- a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestClient.java
+++ b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestClient.java
@@ -949,7 +949,7 @@ import org.apache.http.client.CookieStore;
  * </ul>
  */
 @ConfigurableContext(nocache=true)
-public class RestClient extends BeanContext implements HttpClient, Closeable {
+public class RestClient extends BeanContext implements HttpClient, Closeable, RestCallHandler, RestCallInterceptor {
 
 	//-------------------------------------------------------------------------------------------------------------------
 	// Configurable properties
@@ -2025,6 +2025,15 @@ public class RestClient extends BeanContext implements HttpClient, Closeable {
 	 * <p>
 	 * Subclasses can override this method to provide specialized handling.
 	 *
+	 * <p>
+	 * The behavior of this method can also be modified by specifying a different {@link RestCallHandler}.
+	 *
+	 * <ul class='seealso'>
+	 * 	<li class='jf'>{@link RestClient#RESTCLIENT_callHandler}
+	 * 	<li class='jm'>{@link RestClientBuilder#callHandler(Class)}
+	 * 	<li class='jm'>{@link RestClientBuilder#callHandler(RestCallHandler)}
+	 * </ul>
+	 *
 	 * @param target The target host for the request.
 	 * 	<br>Implementations may accept <jk>null</jk> if they can still determine a route, for example to a default
 	 * 		target or by inspecting the request.
@@ -2038,7 +2047,8 @@ public class RestClient extends BeanContext implements HttpClient, Closeable {
 	 * @throws IOException In case of a problem or the connection was aborted.
 	 * @throws ClientProtocolException In case of an http protocol error.
 	 */
-	protected HttpResponse execute(HttpHost target, HttpRequestBase request, HttpContext context) throws ClientProtocolException, IOException {
+	@Override /* RestCallHandler */
+	public HttpResponse execute(HttpHost target, HttpRequestBase request, HttpContext context) throws ClientProtocolException, IOException {
 		return callHandler.execute(target, request, context);
 	}
 
@@ -2048,6 +2058,15 @@ public class RestClient extends BeanContext implements HttpClient, Closeable {
 	 * <p>
 	 * Subclasses can override this method to provide specialized handling.
 	 *
+	 * <p>
+	 * The behavior of this method can also be modified by specifying a different {@link RestCallHandler}.
+	 *
+	 * <ul class='seealso'>
+	 * 	<li class='jf'>{@link RestClient#RESTCLIENT_callHandler}
+	 * 	<li class='jm'>{@link RestClientBuilder#callHandler(Class)}
+	 * 	<li class='jm'>{@link RestClientBuilder#callHandler(RestCallHandler)}
+	 * </ul>
+	 *
 	 * @param target The target host for the request.
 	 * 	<br>Implementations may accept <jk>null</jk> if they can still determine a route, for example to a default
 	 * 		target or by inspecting the request.
@@ -2061,7 +2080,8 @@ public class RestClient extends BeanContext implements HttpClient, Closeable {
 	 * @throws IOException In case of a problem or the connection was aborted.
 	 * @throws ClientProtocolException In case of an http protocol error.
 	 */
-	protected HttpResponse execute(HttpHost target, HttpEntityEnclosingRequestBase request, HttpContext context) throws ClientProtocolException, IOException {
+	@Override /* RestCallHandler */
+	public HttpResponse execute(HttpHost target, HttpEntityEnclosingRequestBase request, HttpContext context) throws ClientProtocolException, IOException {
 		return callHandler.execute(target, request, context);
 	}
 
@@ -2776,6 +2796,7 @@ public class RestClient extends BeanContext implements HttpClient, Closeable {
 			for (Object o : formData)
 				req.formData(toFormData(o));
 
+			req.interceptors(this);
 			req.interceptors(interceptors);
 
 			return req;
@@ -3227,6 +3248,101 @@ public class RestClient extends BeanContext implements HttpClient, Closeable {
 		return ()->args.length == 0 ? msg : MessageFormat.format(msg, args);
 	}
 
+
+	//-----------------------------------------------------------------------------------------------------------------
+	// RestCallInterceptor methods
+	//-----------------------------------------------------------------------------------------------------------------
+
+	/**
+	 * Interceptor method called before a request is sent to the server.
+	 *
+	 * <p>
+	 * Subclasses can override this method to intercept the request and perform special modifications.
+	 * The default behavior is a no-op.
+	 *
+	 * <ul class='seealso'>
+	 * 	<li class='jf'>{@link RestClient#RESTCLIENT_interceptors}
+	 * 	<li class='jm'>{@link RestClientBuilder#interceptors(Class...)}
+	 * 	<li class='jm'>{@link RestClientBuilder#interceptors(RestCallInterceptor...)}
+	 * </ul>
+	 */
+	@Override /* HttpRequestInterceptor */
+	public void process(HttpRequest request, HttpContext context) throws HttpException, IOException {
+		// Default is a no-op.
+	}
+
+	/**
+	 * Interceptor method called before the message body is evaluated.
+	 *
+	 * <p>
+	 * Subclasses can override this method to intercept the response and perform special modifications.
+	 * The default behavior is a no-op.
+	 *
+	 * <ul class='seealso'>
+	 * 	<li class='jf'>{@link RestClient#RESTCLIENT_interceptors}
+	 * 	<li class='jm'>{@link RestClientBuilder#interceptors(Class...)}
+	 * 	<li class='jm'>{@link RestClientBuilder#interceptors(RestCallInterceptor...)}
+	 * </ul>
+	 */
+	@Override /* HttpRequestInterceptor */
+	public void process(HttpResponse response, HttpContext context) throws HttpException, IOException {
+		// Default is a no-op.
+	}
+
+	/**
+	 * Interceptor method called immediately after the RestRequest object is created and all headers/query/form-data has been copied from the client.
+	 *
+	 * <p>
+	 * Subclasses can override this method to intercept the request and perform special modifications.
+	 * The default behavior is a no-op.
+	 *
+	 * <ul class='seealso'>
+	 * 	<li class='jf'>{@link RestClient#RESTCLIENT_interceptors}
+	 * 	<li class='jm'>{@link RestClientBuilder#interceptors(Class...)}
+	 * 	<li class='jm'>{@link RestClientBuilder#interceptors(RestCallInterceptor...)}
+	 * </ul>
+	 */
+	@Override /* RestCallInterceptor */
+	public void onInit(RestRequest req) throws Exception {
+		// Default is a no-op.
+	}
+
+	/**
+	 * Interceptor method called immediately after an HTTP response has been received.
+	 *
+	 * <p>
+	 * Subclasses can override this method to intercept the response and perform special modifications.
+	 * The default behavior is a no-op.
+	 *
+	 * <ul class='seealso'>
+	 * 	<li class='jf'>{@link RestClient#RESTCLIENT_interceptors}
+	 * 	<li class='jm'>{@link RestClientBuilder#interceptors(Class...)}
+	 * 	<li class='jm'>{@link RestClientBuilder#interceptors(RestCallInterceptor...)}
+	 * </ul>
+	 */
+	@Override /* RestCallInterceptor */
+	public void onConnect(RestRequest req, RestResponse res) throws Exception {
+		// Default is a no-op.
+	}
+
+	/**
+	 * Interceptor method called immediately after the RestRequest object is created and all headers/query/form-data has been set on the request from the client.
+	 *
+	 * <p>
+	 * Subclasses can override this method to handle any cleanup operations.
+	 * The default behavior is a no-op.
+	 *
+	 * <ul class='seealso'>
+	 * 	<li class='jf'>{@link RestClient#RESTCLIENT_interceptors}
+	 * 	<li class='jm'>{@link RestClientBuilder#interceptors(Class...)}
+	 * 	<li class='jm'>{@link RestClientBuilder#interceptors(RestCallInterceptor...)}
+	 * </ul>
+	 */
+	@Override /* RestCallInterceptor */
+	public void onClose(RestRequest req, RestResponse res) throws Exception {
+		// Default is a no-op.
+	}
+
 	//------------------------------------------------------------------------------------------------
 	// Passthrough methods for HttpClient.
 	//------------------------------------------------------------------------------------------------
diff --git a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestResponseBody.java b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestResponseBody.java
index 5f9d121..e0a8c0f 100644
--- a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestResponseBody.java
+++ b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestResponseBody.java
@@ -1539,6 +1539,9 @@ public class RestResponseBody implements HttpEntity {
 	/**
 	 * Provides the ability to perform fluent-style assertions on this response body.
 	 *
+	 * <p>
+	 * This method is called directly from the {@link RestResponse#assertBody()} method to instantiate a fluent assertions object.
+	 *
 	 * <h5 class='section'>Examples:</h5>
 	 * <p class='bcode w800'>
 	 * 	<jc>// Validates the response body equals the text "OK".</jc>
diff --git a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestResponseHeader.java b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestResponseHeader.java
index 00517b4..b1e6c36 100644
--- a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestResponseHeader.java
+++ b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestResponseHeader.java
@@ -601,6 +601,9 @@ public class RestResponseHeader implements Header {
 	/**
 	 * Provides the ability to perform fluent-style assertions on this response header.
 	 *
+	 * <p>
+	 * This method is called directly from the {@link RestResponse#assertHeader(String)} method to instantiate a fluent assertions object.
+	 *
 	 * <h5 class='section'>Examples:</h5>
 	 * <p class='bcode w800'>
 	 * 	<jc>// Validates the content type header is provided.</jc>
@@ -663,13 +666,16 @@ public class RestResponseHeader implements Header {
 	/**
 	 * Provides the ability to perform fluent-style assertions on an integer response header.
 	 *
+	 * <p>
+	 * This method is called directly from the {@link RestResponse#assertIntHeader(String)} method to instantiate a fluent assertions object.
+	 *
 	 * <h5 class='section'>Examples:</h5>
 	 * <p class='bcode w800'>
 	 * 	<jc>// Validates that the response content age is greather than 1.</jc>
 	 * 	client
 	 * 		.get(<jsf>URL</jsf>)
 	 * 		.run()
-	 * 		.assertIntegerHeader(<js>"Age"</js>).isGreaterThan(1);
+	 * 		.assertIntHeader(<js>"Age"</js>).isGreaterThan(1);
 	 * </p>
 	 *
 	 * @return A new fluent assertion object.
@@ -683,6 +689,9 @@ public class RestResponseHeader implements Header {
 	/**
 	 * Provides the ability to perform fluent-style assertions on a long response header.
 	 *
+	 * <p>
+	 * This method is called directly from the {@link RestResponse#assertLongHeader(String)} method to instantiate a fluent assertions object.
+	 *
 	 * <h5 class='section'>Examples:</h5>
 	 * <p class='bcode w800'>
 	 * 	<jc>// Validates that the response body is not too long.</jc>
@@ -703,6 +712,9 @@ public class RestResponseHeader implements Header {
 	/**
 	 * Provides the ability to perform fluent-style assertions on a date response header.
 	 *
+	 * <p>
+	 * This method is called directly from the {@link RestResponse#assertDateHeader(String)} method to instantiate a fluent assertions object.
+	 *
 	 * <h5 class='section'>Examples:</h5>
 	 * <p class='bcode w800'>
 	 * 	<jc>// Validates that the response content is not expired.</jc>