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 <james.bog...@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>