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 c0457be Better reusability of MockRestClient. c0457be is described below commit c0457be5cda07e04864523a13d224110a0ff0d19 Author: JamesBognar <james.bog...@salesforce.com> AuthorDate: Mon Nov 16 11:51:52 2020 -0500 Better reusability of MockRestClient. --- .../java/org/apache/juneau/PropertyStoreTest.java | 1 + .../remote/Remote_RemoteMethodAnnotation_Test.java | 7 +--- .../main/java/org/apache/juneau/PropertyStore.java | 2 + .../org/apache/juneau/assertions/Assertions.java | 16 ++++++++ .../client/RestClient_Config_Context_Test.java | 6 ++- .../client/RestClient_Config_RestClient_Test.java | 45 ++++++++++++++++---- .../rest/client/RestClient_Marshalls_Test.java | 7 ++-- .../org/apache/juneau/rest/client/RestClient.java | 48 +++++++++++++++++++++- .../juneau/rest/client/RestClientBuilder.java | 10 +++-- .../org/apache/juneau/rest/client/RestRequest.java | 16 ++++++++ .../juneau/rest/client/RestResponseBody.java | 10 +++-- .../rest/mock/MockHttpClientConnectionManager.java | 13 +++++- .../apache/juneau/rest/mock/MockRestClient.java | 7 +++- .../juneau/rest/mock/MockRestClientBuilder.java | 6 +-- 14 files changed, 157 insertions(+), 37 deletions(-) diff --git a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/PropertyStoreTest.java b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/PropertyStoreTest.java index 3611052..f50ca4c 100644 --- a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/PropertyStoreTest.java +++ b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/PropertyStoreTest.java @@ -1564,6 +1564,7 @@ public class PropertyStoreTest { public void testSet() { PropertyStoreBuilder b = PropertyStore.create(); b.set(OMap.of("A.foo", "bar")); + b.clear(); b.set(OMap.of("A.baz", "qux")); b.add(null); assertObject(b.build()).json().is("{A:{baz:'qux'}}"); diff --git a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/http/remote/Remote_RemoteMethodAnnotation_Test.java b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/http/remote/Remote_RemoteMethodAnnotation_Test.java index 0f0ceac..920d4e3 100644 --- a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/http/remote/Remote_RemoteMethodAnnotation_Test.java +++ b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/http/remote/Remote_RemoteMethodAnnotation_Test.java @@ -23,7 +23,6 @@ import org.apache.juneau.http.annotation.Body; import org.apache.juneau.http.annotation.Response; import org.apache.juneau.internal.*; import org.apache.juneau.rest.annotation.*; -import org.apache.juneau.rest.client.*; import org.apache.juneau.rest.config.*; import org.apache.juneau.rest.mock.*; import org.junit.*; @@ -238,7 +237,7 @@ public class Remote_RemoteMethodAnnotation_Test { @Test public void d01_returnTypes_partSerialization() throws Exception { - D1 x = client(D.class).openApi().build().getRemote(D1.class); + D1 x = MockRestClient.create(D.class).openApi().build().getRemote(D1.class); assertEquals("foo",x.postX1("foo")); assertEquals("foo",IOUtils.read(x.postX2("foo").getEntity().getContent())); assertEquals("foo",IOUtils.read(x.postX3("foo"))); @@ -257,10 +256,6 @@ public class Remote_RemoteMethodAnnotation_Test { // Helper methods. //------------------------------------------------------------------------------------------------------------------ - private static RestClientBuilder client(Class<?> c) { - return MockRestClient.create(c).simpleJson(); - } - private static <T> T remote(Class<?> rest, Class<T> t) { return MockRestClient.build(rest).getRemote(t); } diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/PropertyStore.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/PropertyStore.java index f9218d9..6c1f025 100644 --- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/PropertyStore.java +++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/PropertyStore.java @@ -20,6 +20,7 @@ import java.lang.reflect.*; import java.util.*; import org.apache.juneau.PropertyStoreBuilder.*; +import org.apache.juneau.assertions.*; import org.apache.juneau.collections.*; import org.apache.juneau.internal.*; import org.apache.juneau.json.*; @@ -565,6 +566,7 @@ public final class PropertyStore { * @return A new property instance. */ public <T> T getInstanceProperty(String key, Object outer, Class<T> type, Object def, ResourceResolver resolver, Object...args) { + Assertions.assertArgNotNull("type", type); Property p = findProperty(key); if (p != null) return p.asInstance(outer, type, resolver, args); diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/assertions/Assertions.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/assertions/Assertions.java index f18224e..71d751d 100644 --- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/assertions/Assertions.java +++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/assertions/Assertions.java @@ -16,6 +16,7 @@ import java.io.*; import java.time.*; import java.util.*; +import org.apache.juneau.*; import org.apache.juneau.internal.*; /** @@ -288,4 +289,19 @@ public class Assertions { public static StringAssertion assertReader(Reader r) throws IOException { return new StringAssertion(r == null ? null : IOUtils.read(r)); } + + /** + * Throws an {@link IllegalArgumentException} if the specified argument is <jk>null</jk>. + * + * @param <T> The argument data type. + * @param arg The argument name. + * @param o The object to check. + * @return The same argument. + * @throws IllegalArgumentException Constructed exception. + */ + public static <T> T assertArgNotNull(String arg, T o) throws IllegalArgumentException { + if (o == null) + throw new BasicIllegalArgumentException("Argument ''{0}'' cannot be null", arg); + return o; + } } diff --git a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Config_Context_Test.java b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Config_Context_Test.java index 94b32b6..0e77869 100644 --- a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Config_Context_Test.java +++ b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Config_Context_Test.java @@ -194,13 +194,15 @@ public class RestClient_Config_Context_Test { @Test public void a11_set() throws Exception { - client(null).set( + client(null) + .add( AMap.of( JSON_simpleMode,true, WSERIALIZER_quoteChar,"'", MOCKRESTCLIENT_restBean,A.class ) - ).json().build().post("/echoBody",new A11()).run().assertBody().is("{foo:1}") + ) + .json().build().post("/echoBody",new A11()).mediaType("text/json").run().assertBody().is("{foo:1}") ; } diff --git a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Config_RestClient_Test.java b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Config_RestClient_Test.java index 719e56d..6cc813e 100644 --- a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Config_RestClient_Test.java +++ b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Config_RestClient_Test.java @@ -365,15 +365,23 @@ public class RestClient_Config_RestClient_Test { @Test public void a09_marshalls() throws Exception { - RestClient x = MockRestClient.create(A.class).marshalls(Xml.DEFAULT,Json.DEFAULT).build(); + final RestClient x = MockRestClient.create(A.class).marshalls(Xml.DEFAULT,Json.DEFAULT).build(); - x.post("/echoBody",bean).run().assertBody().is("{f:1}"); + assertThrown(()->x.post("/echoBody",bean).run()).contains("Content-Type not specified on request. Cannot match correct serializer. Use contentType(String) or mediaType(String) to specify transport language."); + + assertThrown(()->x.post("/echoBody",bean).contentType("text/json").run().getBody().as(ABean.class)).contains("Content-Type not specified in response header. Cannot find appropriate parser."); ABean b = x.post("/echoBody",bean).accept("text/xml").contentType("text/xml").run().cacheBody().assertBody().is("<object><f>1</f></object>").getBody().as(ABean.class); assertObject(b).sameAs(bean); + b = x.post("/echoBody",bean).mediaType("text/xml").run().cacheBody().assertBody().is("<object><f>1</f></object>").getBody().as(ABean.class); + assertObject(b).sameAs(bean); + b = x.post("/echoBody",bean).accept("text/json").contentType("text/json").run().cacheBody().assertBody().is("{\"f\":1}").getBody().as(ABean.class); assertObject(b).sameAs(bean); + + b = x.post("/echoBody",bean).mediaType("text/json").run().cacheBody().assertBody().is("{\"f\":1}").getBody().as(ABean.class); + assertObject(b).sameAs(bean); } @Test @@ -395,19 +403,40 @@ public class RestClient_Config_RestClient_Test { @Test public void a11_serializers_parsers() throws Exception { @SuppressWarnings("unchecked") - RestClient x = MockRestClient.create(A.class).serializers(XmlSerializer.class,JsonSerializer.class).parsers(XmlParser.class,JsonParser.class).build(); + final RestClient x = MockRestClient.create(A.class).serializers(XmlSerializer.class,JsonSerializer.class).parsers(XmlParser.class,JsonParser.class).build(); + + assertThrown(()->x.post("/echoBody",bean).run()).contains("Content-Type not specified on request. Cannot match correct serializer. Use contentType(String) or mediaType(String) to specify transport language."); + + assertThrown(()->x.post("/echoBody",bean).contentType("text/json").run().getBody().as(ABean.class)).contains("Content-Type not specified in response header. Cannot find appropriate parser."); - x.post("/echoBody",bean).run().assertBody().is("{f:1}"); ABean b = x.post("/echoBody",bean).accept("text/xml").contentType("text/xml").run().cacheBody().assertBody().is("<object><f>1</f></object>").getBody().as(ABean.class); assertObject(b).sameAs(bean); + + b = x.post("/echoBody",bean).mediaType("text/xml").run().cacheBody().assertBody().is("<object><f>1</f></object>").getBody().as(ABean.class); + assertObject(b).sameAs(bean); + b = x.post("/echoBody",bean).accept("text/json").contentType("text/json").run().cacheBody().assertBody().is("{\"f\":1}").getBody().as(ABean.class); assertObject(b).sameAs(bean); - x = MockRestClient.create(A.class).serializers(XmlSerializer.DEFAULT,JsonSerializer.DEFAULT).parsers(XmlParser.DEFAULT,JsonParser.DEFAULT).build(); - x.post("/echoBody",bean).run().assertBody().is("{f:1}"); - b = x.post("/echoBody",bean).accept("text/xml").contentType("text/xml").run().cacheBody().assertBody().is("<object><f>1</f></object>").getBody().as(ABean.class); + b = x.post("/echoBody",bean).mediaType("text/json").run().cacheBody().assertBody().is("{\"f\":1}").getBody().as(ABean.class); assertObject(b).sameAs(bean); - b = x.post("/echoBody",bean).accept("text/json").contentType("text/json").run().cacheBody().assertBody().is("{\"f\":1}").getBody().as(ABean.class); + + final RestClient x2 = MockRestClient.create(A.class).serializers(XmlSerializer.DEFAULT,JsonSerializer.DEFAULT).parsers(XmlParser.DEFAULT,JsonParser.DEFAULT).build(); + + assertThrown(()->x2.post("/echoBody",bean).run()).contains("Content-Type not specified on request. Cannot match correct serializer. Use contentType(String) or mediaType(String) to specify transport language."); + + assertThrown(()->x2.post("/echoBody",bean).contentType("text/json").run().getBody().as(ABean.class)).contains("Content-Type not specified in response header. Cannot find appropriate parser."); + + b = x2.post("/echoBody",bean).accept("text/xml").contentType("text/xml").run().cacheBody().assertBody().is("<object><f>1</f></object>").getBody().as(ABean.class); + assertObject(b).sameAs(bean); + + b = x2.post("/echoBody",bean).mediaType("text/xml").run().cacheBody().assertBody().is("<object><f>1</f></object>").getBody().as(ABean.class); + assertObject(b).sameAs(bean); + + b = x2.post("/echoBody",bean).accept("text/json").contentType("text/json").run().cacheBody().assertBody().is("{\"f\":1}").getBody().as(ABean.class); + assertObject(b).sameAs(bean); + + b = x2.post("/echoBody",bean).mediaType("text/json").run().cacheBody().assertBody().is("{\"f\":1}").getBody().as(ABean.class); assertObject(b).sameAs(bean); } diff --git a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Marshalls_Test.java b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Marshalls_Test.java index 1d72279..6f15000 100644 --- a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Marshalls_Test.java +++ b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Marshalls_Test.java @@ -12,6 +12,7 @@ // *************************************************************************************************************************** package org.apache.juneau.rest.client; +import static org.apache.juneau.assertions.Assertions.*; import static org.junit.Assert.*; import static org.junit.runners.MethodSorters.*; @@ -132,8 +133,7 @@ public class RestClient_Marshalls_Test { x.post("/a01",bean).header("Accept","application/x-www-form-urlencoded").header("Content-Type","application/x-www-form-urlencoded").header("X-Accept","application/x-www-form-urlencoded").header("X-Content-Type","application/x-www-form-urlencoded").run().assertCode().is(200).getBody().as(Bean.class).check(); x.post("/a01",bean).header("Accept","text/openapi").header("Content-Type","text/openapi").header("X-Accept","text/openapi").header("X-Content-Type","text/openapi").run().assertCode().is(200).getBody().as(Bean.class).check(); - // Bean will be serialized using toString(). - x.post("/a01",bean).header("X-Accept","nil").header("X-Content-Type","text/plain").run().assertCode().is(200).getBody().as(Bean.class).check(); + assertThrown(()->x.post("/a01",bean).run()).contains("Content-Type not specified on request. Cannot match correct serializer. Use contentType(String) or mediaType(String) to specify transport language."); } //------------------------------------------------------------------------------------------------------------------ @@ -152,8 +152,7 @@ public class RestClient_Marshalls_Test { x.post("/a01",bean).header("Accept","application/x-www-form-urlencoded").header("Content-Type","application/x-www-form-urlencoded").header("X-Accept","application/x-www-form-urlencoded").header("X-Content-Type","application/x-www-form-urlencoded").run().assertCode().is(200).getBody().as(Bean.class).check(); x.post("/a01",bean).header("Accept","text/openapi").header("Content-Type","text/openapi").header("X-Accept","text/openapi").header("X-Content-Type","text/openapi").run().assertCode().is(200).getBody().as(Bean.class).check(); - // Default. - x.post("/a01",bean).header("X-Accept","nil").header("X-Content-Type","text/plain").run().assertCode().is(200).getBody().as(Bean.class).check(); + assertThrown(()->x.post("/a01",bean).run()).contains("Content-Type not specified on request. Cannot match correct serializer. Use contentType(String) or mediaType(String) to specify transport language."); } //------------------------------------------------------------------------------------------------------------------ diff --git a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java index ba6e170..dcf56d8 100644 --- a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java +++ b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java @@ -1093,6 +1093,31 @@ public class RestClient extends BeanContext implements HttpClient, Closeable, Re public static final String RESTCLIENT_callHandler = PREFIX + "callHandler.o"; /** + * Configuration property: Connection manager + * + * <h5 class='section'>Property:</h5> + * <ul class='spaced-list'> + * <li><b>ID:</b> {@link org.apache.juneau.rest.client.RestClient#RESTCLIENT_connectionManager RESTCLIENT_connectionManager} + * <li><b>Name:</b> <js>"RestClient.connectionManager.o"</js> + * <li><b>System property:</b> <c>RestClient.connectionManager</c> + * <li><b>Data type:</b> + * <ul> + * <li><b>Data type:</b> {@link org.apache.http.conn.HttpClientConnectionManager}</c> + * </ul> + * <li><b>Default:</b> Value returned by {@link org.apache.juneau.rest.client.RestClientBuilder#createConnectionManager()} + * <li><b>Methods:</b> + * <ul> + * <li class='jm'>{@link org.apache.juneau.rest.client.RestClientBuilder#connectionManager(HttpClientConnectionManager)} + * </ul> + * </ul> + * + * <h5 class='section'>Description:</h5> + * <p> + * Allows you to override the connection manager used by the HTTP client. + */ + public static final String RESTCLIENT_connectionManager = PREFIX + "connectionManager.o"; + + /** * Configuration property: Console print stream. * * <h5 class='section'>Property:</h5> @@ -1953,6 +1978,7 @@ public class RestClient extends BeanContext implements HttpClient, Closeable, Re private final HeaderSupplier headers; private final NameValuePairSupplier query, formData; final CloseableHttpClient httpClient; + private final HttpClientConnectionManager connectionManager; private final boolean keepHttpClientOpen, leakDetection; private final UrlEncodingSerializer urlEncodingSerializer; // Used for form posts only. private final HttpPartSerializer partSerializer; @@ -2011,6 +2037,7 @@ public class RestClient extends BeanContext implements HttpClient, Closeable, Re protected RestClient(PropertyStore ps) { super(ps); this.httpClient = getInstanceProperty(RESTCLIENT_httpClient, CloseableHttpClient.class); + this.connectionManager = getInstanceProperty(RESTCLIENT_connectionManager, HttpClientConnectionManager.class); this.keepHttpClientOpen = getBooleanProperty(RESTCLIENT_keepHttpClientOpen); this.errorCodes = getInstanceProperty(RESTCLIENT_errorCodes, Predicate.class, ERROR_CODES_DEFAULT); this.executorServiceShutdownOnClose = getBooleanProperty(RESTCLIENT_executorServiceShutdownOnClose); @@ -3452,6 +3479,15 @@ public class RestClient extends BeanContext implements HttpClient, Closeable, Re } /** + * Returns the connection manager if one was specified in the client builder. + * + * @return The connection manager. May be <jk>null</jk>. + */ + public HttpClientConnectionManager getHttpClientConnectionManager() { + return connectionManager; + } + + /** * Executes HTTP request using the default context. * * <ul class='notes'> @@ -3709,7 +3745,11 @@ public class RestClient extends BeanContext implements HttpClient, Closeable, Re return s; } List<Serializer> l = serializers.getSerializers(); - return l.size() == 1 ? l.get(0) : null; + return (l.size() == 1 ? l.get(0) : null); + } + + boolean hasSerializers() { + return ! serializers.getSerializers().isEmpty(); } /* @@ -3726,7 +3766,11 @@ public class RestClient extends BeanContext implements HttpClient, Closeable, Re return p; } List<Parser> l = parsers.getParsers(); - return l.size() == 1 ? l.get(0) : null; + return (l.size() == 1 ? l.get(0) : null); + } + + boolean hasParsers() { + return ! parsers.getParsers().isEmpty(); } @SuppressWarnings("unchecked") diff --git a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClientBuilder.java b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClientBuilder.java index 5474d94..fb4a1de 100644 --- a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClientBuilder.java +++ b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClientBuilder.java @@ -96,7 +96,6 @@ public class RestClientBuilder extends BeanContextBuilder { private HttpClientBuilder httpClientBuilder; private CloseableHttpClient httpClient; - private HttpClientConnectionManager httpClientConnectionManager; private boolean pooled; /** @@ -799,11 +798,14 @@ public class RestClientBuilder extends BeanContextBuilder { * @return The HTTP client to use. */ protected CloseableHttpClient createHttpClient() { + Object cm = peek(RESTCLIENT_connectionManager); // Don't call createConnectionManager() if RestClient.setConnectionManager() was called. - if (httpClientConnectionManager == null) + if (cm == null) httpClientBuilder.setConnectionManager(createConnectionManager()); + else if (cm instanceof HttpClientConnectionManager) + httpClientBuilder.setConnectionManager((HttpClientConnectionManager)cm); else - httpClientBuilder.setConnectionManager(httpClientConnectionManager); + throw new RuntimeException("Invalid type for RESTCLIENT_connectionManager: " + cm.getClass().getName()); return httpClientBuilder.build(); } @@ -5284,7 +5286,7 @@ public class RestClientBuilder extends BeanContextBuilder { */ @FluentSetter public RestClientBuilder connectionManager(HttpClientConnectionManager connManager) { - this.httpClientConnectionManager = connManager; + set(RESTCLIENT_connectionManager, connManager); httpClientBuilder.setConnectionManager(connManager); return this; } diff --git a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestRequest.java b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestRequest.java index 73b01b2..c6bc151 100644 --- a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestRequest.java +++ b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestRequest.java @@ -2452,6 +2452,17 @@ public class RestRequest extends BeanSession implements HttpUriRequest, Configur } /** + * Shortcut for setting the <c>Accept</c> and <c>Content-Type</c> headers on a request. + * + * @param value The new header values. + * @return This object (for method chaining). + * @throws RestCallException Invalid input. + */ + public RestRequest mediaType(Object value) throws RestCallException { + return header("Accept", value).header("Content-Type", value); + } + + /** * Sets the value for the <c>Content-Encoding</c> request header. * * <p> @@ -2868,6 +2879,11 @@ public class RestRequest extends BeanSession implements HttpUriRequest, Configur else if (serializer != null) entity = SerializedHttpEntity.of(input2, serializer).schema(requestBodySchema).contentType(contentType); else { + if (client.hasSerializers()) { + if (contentType == null) + throw new RestCallException(null, null, "Content-Type not specified on request. Cannot match correct serializer. Use contentType(String) or mediaType(String) to specify transport language."); + throw new RestCallException(null, null, "No matching serializer for media type ''{0}''", contentType); + } if (input2 == null) input2 = ""; entity = new StringEntity(BeanContext.DEFAULT.getClassMetaForObject(input2).toString(input2), getRequestContentType(TEXT_PLAIN)); diff --git a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestResponseBody.java b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestResponseBody.java index 8e97735..8162f55 100644 --- a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestResponseBody.java +++ b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestResponseBody.java @@ -816,10 +816,12 @@ public class RestResponseBody implements HttpEntity { if (type.hasInputStreamMutater()) return type.getInputStreamMutater().mutate(asInputStream()); - throw new ParseException( - "Unsupported media-type in request header ''Content-Type'': ''{0}''", - response.getStringHeader("Content-Type") - ); + ct = response.getStringHeader("Content-Type"); + + if (ct == null && client.hasParsers()) + throw new ParseException("Content-Type not specified in response header. Cannot find appropriate parser."); + + throw new ParseException("Unsupported media-type in request header ''Content-Type'': ''{0}''", ct); } catch (ParseException | IOException e) { response.close(); diff --git a/juneau-rest/juneau-rest-mock/src/main/java/org/apache/juneau/rest/mock/MockHttpClientConnectionManager.java b/juneau-rest/juneau-rest-mock/src/main/java/org/apache/juneau/rest/mock/MockHttpClientConnectionManager.java index c2b8781..0001fbb 100644 --- a/juneau-rest/juneau-rest-mock/src/main/java/org/apache/juneau/rest/mock/MockHttpClientConnectionManager.java +++ b/juneau-rest/juneau-rest-mock/src/main/java/org/apache/juneau/rest/mock/MockHttpClientConnectionManager.java @@ -28,7 +28,7 @@ import org.apache.http.protocol.*; * * This implementation is NOT thread safe. */ -class MockHttpClientConnectionManager implements HttpClientConnectionManager { +final class MockHttpClientConnectionManager implements HttpClientConnectionManager { private ConnectionRequest cr; @@ -75,4 +75,15 @@ class MockHttpClientConnectionManager implements HttpClientConnectionManager { @Override /* HttpClientConnectionManager */ public void shutdown() {} + + @Override /* Object */ + public int hashCode() { + return MockHttpClientConnectionManager.class.hashCode(); + } + + @Override /* Object */ + public boolean equals(Object o) { + // All MockHttpClientConnectionManagers are considered equal. + return o != null && o instanceof MockHttpClientConnectionManager; + } } diff --git a/juneau-rest/juneau-rest-mock/src/main/java/org/apache/juneau/rest/mock/MockRestClient.java b/juneau-rest/juneau-rest-mock/src/main/java/org/apache/juneau/rest/mock/MockRestClient.java index 083687c..71df441 100644 --- a/juneau-rest/juneau-rest-mock/src/main/java/org/apache/juneau/rest/mock/MockRestClient.java +++ b/juneau-rest/juneau-rest-mock/src/main/java/org/apache/juneau/rest/mock/MockRestClient.java @@ -25,6 +25,7 @@ import javax.servlet.http.*; import org.apache.http.*; import org.apache.http.client.methods.*; +import org.apache.http.conn.*; import org.apache.http.entity.*; import org.apache.http.message.*; import org.apache.juneau.*; @@ -223,7 +224,6 @@ public class MockRestClient extends RestClient implements HttpClientConnection { MOCKRESTCLIENT_restBeanCtx = PREFIX + "restBeanCtx.o", MOCKRESTCLIENT_servletPath = PREFIX + "servletPath.s", MOCKRESTCLIENT_contextPath = PREFIX + "contextPath.s", - MOCKRESTCLIENT_mockHttpClientConnectionManager = PREFIX + "mockHttpClientConnectionManager.o", MOCKRESTCLIENT_pathVars = PREFIX + "pathVars.oms"; @@ -257,7 +257,10 @@ public class MockRestClient extends RestClient implements HttpClientConnection { this.contextPath = getStringProperty(MOCKRESTCLIENT_contextPath, ""); this.servletPath = getStringProperty(MOCKRESTCLIENT_servletPath, ""); this.pathVars = getMapProperty(MOCKRESTCLIENT_pathVars, String.class); - getInstanceProperty(MOCKRESTCLIENT_mockHttpClientConnectionManager, MockHttpClientConnectionManager.class).init(this); + + HttpClientConnectionManager ccm = getHttpClientConnectionManager(); + if (ccm instanceof MockHttpClientConnectionManager) + ((MockHttpClientConnectionManager)ccm).init(this); } private static PropertyStore preInit(PropertyStore ps) { diff --git a/juneau-rest/juneau-rest-mock/src/main/java/org/apache/juneau/rest/mock/MockRestClientBuilder.java b/juneau-rest/juneau-rest-mock/src/main/java/org/apache/juneau/rest/mock/MockRestClientBuilder.java index 509d16a..fb7e308 100644 --- a/juneau-rest/juneau-rest-mock/src/main/java/org/apache/juneau/rest/mock/MockRestClientBuilder.java +++ b/juneau-rest/juneau-rest-mock/src/main/java/org/apache/juneau/rest/mock/MockRestClientBuilder.java @@ -72,6 +72,7 @@ public class MockRestClientBuilder extends RestClientBuilder { */ protected MockRestClientBuilder(PropertyStore ps) { super(ps); + connectionManager(new MockHttpClientConnectionManager()); } /** @@ -81,7 +82,7 @@ public class MockRestClientBuilder extends RestClientBuilder { * Provided so that this class can be easily subclassed. */ protected MockRestClientBuilder() { - super(null); + this(null); } /** @@ -214,9 +215,6 @@ public class MockRestClientBuilder extends RestClientBuilder { @Override /* ContextBuilder */ public <T extends Context> T build(Class<T> c) { - MockHttpClientConnectionManager cm = new MockHttpClientConnectionManager(); - set(MOCKRESTCLIENT_mockHttpClientConnectionManager, cm); - connectionManager(cm); return super.build(c); }