This is an automated email from the ASF dual-hosted git repository. ramyav pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/olingo-odata4.git
The following commit(s) were added to refs/heads/master by this push: new e365059 [OLINGO-1380] OData V4: Response header information is lost in case of exceptions e365059 is described below commit e3650599007a917890963fbec6a19b437d519e4d Author: ramya vasanth <ramya.vasa...@sap.com> AuthorDate: Fri Aug 2 12:45:02 2019 +0530 [OLINGO-1380] OData V4: Response header information is lost in case of exceptions --- .../olingo/fit/tecsvc/client/BasicITCase.java | 43 +++++++++++++++++ .../communication/ODataClientErrorException.java | 19 ++++++++ .../header/ODataErrorResponseChecker.java | 56 ++++++++++++++-------- .../communication/request/AbstractRequest.java | 10 +++- .../org/apache/olingo/client/core/ErrorTest.java | 20 ++++++++ 5 files changed, 127 insertions(+), 21 deletions(-) diff --git a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BasicITCase.java b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BasicITCase.java index fdde68a..aa1fea5 100644 --- a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BasicITCase.java +++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BasicITCase.java @@ -43,6 +43,7 @@ import java.util.List; import java.util.Map; import org.apache.commons.io.IOUtils; +import org.apache.http.Header; import org.apache.http.client.methods.HttpUriRequest; import org.apache.olingo.client.api.EdmEnabledODataClient; import org.apache.olingo.client.api.ODataClient; @@ -351,6 +352,11 @@ public class BasicITCase extends AbstractParamTecSvcITCase { assertEquals(HttpStatusCode.BAD_REQUEST.getStatusCode(), e.getStatusLine().getStatusCode()); final ODataError error = e.getODataError(); assertThat(error.getMessage(), containsString("key")); + for (Header header : e.getHeaderInfo()) { + if(header.getName().equals("Version")) { + assertEquals(header.getValue(), "4.0"); + } + } } } @@ -1798,4 +1804,41 @@ public class BasicITCase extends AbstractParamTecSvcITCase { assertNotNull(property); assertEquals(3, property.getCollectionValue().size()); } + + @Test + public void readHeaderInfoFromClientException1() throws Exception { + ODataEntityRequest<ClientEntity> request = getClient().getRetrieveRequestFactory() + .getEntityRequest(getClient().newURIBuilder(SERVICE_URI) + .appendEntitySetSegment(ES_MIX_PRIM_COLL_COMP).appendKeySegment("42").build()); + assertNotNull(request); + setCookieHeader(request); + request.setAccept("text/plain"); + try { + request.execute(); + fail("Expected Exception not thrown!"); + } catch (final ODataClientErrorException e) { + assertEquals(HttpStatusCode.BAD_REQUEST.getStatusCode(), e.getStatusLine().getStatusCode()); + final ODataError error = e.getODataError(); + assertThat(error.getMessage(), containsString("key")); + } + } + + @Test + public void readHeaderInfoFromClientException2() throws Exception { + ODataEntityRequest<ClientEntity> request = getClient().getRetrieveRequestFactory() + .getEntityRequest(getClient().newURIBuilder(SERVICE_URI) + .appendEntitySetSegment(ES_MIX_PRIM_COLL_COMP).appendKeySegment("42").build()); + assertNotNull(request); + setCookieHeader(request); + request.setAccept("text/plain"); + request.setContentType("application/json"); + try { + request.execute(); + fail("Expected Exception not thrown!"); + } catch (final ODataClientErrorException e) { + assertEquals(HttpStatusCode.BAD_REQUEST.getStatusCode(), e.getStatusLine().getStatusCode()); + final ODataError error = e.getODataError(); + assertThat(error.getMessage(), containsString("key")); + } + } } diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/ODataClientErrorException.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/ODataClientErrorException.java index fc22ee9..290f59f 100644 --- a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/ODataClientErrorException.java +++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/ODataClientErrorException.java @@ -18,6 +18,7 @@ */ package org.apache.olingo.client.api.communication; +import org.apache.http.Header; import org.apache.http.StatusLine; import org.apache.olingo.commons.api.ex.ODataError; import org.apache.olingo.commons.api.ex.ODataRuntimeException; @@ -34,6 +35,8 @@ public class ODataClientErrorException extends ODataRuntimeException { private final StatusLine statusLine; private final ODataError error; + + private Header[] headerInfo; /** * Constructor. @@ -80,4 +83,20 @@ public class ODataClientErrorException extends ODataRuntimeException { public ODataError getODataError() { return error; } + + /** + * Sets headers + * @param headerInfo + */ + public void setHeaderInfo(Header[] headerInfo) { + this.headerInfo = headerInfo; + } + + /** + * Returns headers + * @return Header[] + */ + public Header[] getHeaderInfo() { + return headerInfo; + } } diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/header/ODataErrorResponseChecker.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/header/ODataErrorResponseChecker.java index bd0bf49..7d2a38b 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/header/ODataErrorResponseChecker.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/header/ODataErrorResponseChecker.java @@ -18,13 +18,16 @@ */ package org.apache.olingo.client.core.communication.header; +import java.io.IOException; import java.io.InputStream; import java.util.Map; +import org.apache.commons.io.IOUtils; import org.apache.http.StatusLine; import org.apache.olingo.client.api.ODataClient; import org.apache.olingo.client.api.communication.ODataClientErrorException; import org.apache.olingo.client.api.communication.ODataServerErrorException; +import org.apache.olingo.client.api.serialization.ODataDeserializerException; import org.apache.olingo.commons.api.ex.ODataError; import org.apache.olingo.commons.api.ex.ODataRuntimeException; import org.apache.olingo.commons.api.format.ContentType; @@ -55,29 +58,42 @@ public final class ODataErrorResponseChecker { } else { final ContentType contentType = accept.contains("xml") ? ContentType.APPLICATION_ATOM_XML : ContentType.JSON; - ODataError error; - try { - error = odataClient.getReader().readError(entity, contentType); - if (error != null) { - Map<String, String> innerError = error.getInnerError(); - if (innerError != null) { - if (innerError.get("internalexception") != null) { - error.setMessage(error.getMessage() + innerError.get("internalexception")); - } else { - error.setMessage(error.getMessage() + innerError.get("message")); + ODataError error = new ODataError(); + if (!accept.contains("text/plain")) { + try { + error = odataClient.getReader().readError(entity, contentType); + if (error != null) { + Map<String, String> innerError = error.getInnerError(); + if (innerError != null) { + if (innerError.get("internalexception") != null) { + error.setMessage(error.getMessage() + innerError.get("internalexception")); + } else { + error.setMessage(error.getMessage() + innerError.get("message")); + } } } + } catch (final RuntimeException e) { + LOG.warn("Error deserializing error response", e); + error = getGenericError( + statusLine.getStatusCode(), + statusLine.getReasonPhrase()); + } catch (final ODataDeserializerException e) { + LOG.warn("Error deserializing error response", e); + error = getGenericError( + statusLine.getStatusCode(), + statusLine.getReasonPhrase()); + } + } else { + error.setCode(String.valueOf(statusLine.getStatusCode())); + error.setTarget(statusLine.getReasonPhrase()); + try { + error.setMessage(IOUtils.toString(entity)); + } catch (IOException e) { + LOG.warn("Error deserializing error response", e); + error = getGenericError( + statusLine.getStatusCode(), + statusLine.getReasonPhrase()); } - } catch (final RuntimeException e) { - LOG.warn("Error deserializing error response", e); - error = getGenericError( - statusLine.getStatusCode(), - statusLine.getReasonPhrase()); - } catch (final ODataDeserializerException e) { - LOG.warn("Error deserializing error response", e); - error = getGenericError( - statusLine.getStatusCode(), - statusLine.getReasonPhrase()); } if (statusLine.getStatusCode() >= 500 && error!= null && diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractRequest.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractRequest.java index b273a71..0163156 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractRequest.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractRequest.java @@ -17,10 +17,12 @@ package org.apache.olingo.client.core.communication.request; import java.io.IOException; +import org.apache.http.Header; import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpUriRequest; import org.apache.olingo.client.api.EdmEnabledODataClient; import org.apache.olingo.client.api.ODataClient; +import org.apache.olingo.client.api.communication.ODataClientErrorException; import org.apache.olingo.client.core.communication.header.ODataErrorResponseChecker; import org.apache.olingo.commons.api.ex.ODataRuntimeException; import org.slf4j.Logger; @@ -32,6 +34,7 @@ public abstract class AbstractRequest { * Logger. */ protected static final Logger LOG = LoggerFactory.getLogger(AbstractRequest.class); + private static final String TEXT_CONTENT_TYPE = "text/plain"; protected void checkRequest(final ODataClient odataClient, final HttpUriRequest request) { // If using and Edm enabled client, checks that the cached service root matches the request URI @@ -50,13 +53,18 @@ public abstract class AbstractRequest { final ODataClient odataClient, final HttpResponse response, final String accept) { if (response.getStatusLine().getStatusCode() >= 400) { + Header contentTypeHeader = response.getEntity() != null ? response.getEntity().getContentType() : null; try { final ODataRuntimeException exception = ODataErrorResponseChecker.checkResponse( odataClient, response.getStatusLine(), response.getEntity() == null ? null : response.getEntity().getContent(), - accept); + (contentTypeHeader != null && + contentTypeHeader.getValue().contains(TEXT_CONTENT_TYPE)) ? TEXT_CONTENT_TYPE : accept); if (exception != null) { + if (exception instanceof ODataClientErrorException) { + ((ODataClientErrorException)exception).setHeaderInfo(response.getAllHeaders()); + } throw exception; } } catch (IOException e) { diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/ErrorTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/ErrorTest.java index ebea132..05e91a0 100644 --- a/lib/client-core/src/test/java/org/apache/olingo/client/core/ErrorTest.java +++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/ErrorTest.java @@ -25,6 +25,7 @@ import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import java.io.ByteArrayInputStream; import java.io.InputStream; import java.util.Map; @@ -126,4 +127,23 @@ public class ErrorTest extends AbstractTest { checkResponse(odataClient, statusLine, null, "Json"); assertTrue(exp.getMessage().startsWith("Internal Server Error")); } + + @Test + public void testExpTextMsg403() throws Exception { + ODataClient odataClient = ODataClientFactory.getClient(); + InputStream entity = new ByteArrayInputStream("CSRF Validation Exception".getBytes()); + StatusLine statusLine = mock(StatusLine.class); + when(statusLine.getStatusCode()).thenReturn(403); + when(statusLine.toString()).thenReturn("Validation Exception"); + when(statusLine.getReasonPhrase()).thenReturn("Forbidden"); + + ODataClientErrorException exp = (ODataClientErrorException) ODataErrorResponseChecker. + checkResponse(odataClient, statusLine, entity, "text/plain"); + assertEquals(exp.getStatusLine().getStatusCode(), 403); + ODataError error = exp.getODataError(); + assertTrue(error.getMessage().equals("CSRF Validation Exception")); + assertEquals(error.getCode(), "403"); + assertEquals(error.getTarget(), "Forbidden"); + assertNull(exp.getHeaderInfo()); + } }