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-odata2.git
The following commit(s) were added to refs/heads/master by this push:
new f7679dc [OLINGO-1494]OData V2: Serialize error details
f7679dc is described below
commit f7679dc94491d4aa2a5146df94038565f721ef59
Author: ramya vasanth <[email protected]>
AuthorDate: Thu Nov 19 14:49:54 2020 +0530
[OLINGO-1494]OData V2: Serialize error details
---
.../odata2/api/processor/ODataErrorContext.java | 67 ++++++++++++++++++++--
.../olingo/odata2/core/ep/AtomEntityProvider.java | 23 +++++++-
.../core/ep/ContentTypeBasedEntityProvider.java | 2 +
.../olingo/odata2/core/ep/JsonEntityProvider.java | 23 +++++++-
.../olingo/odata2/core/ep/ProviderFacadeImpl.java | 3 +-
.../ep/producer/JsonErrorDocumentProducer.java | 43 +++++++++++---
.../core/ep/producer/XmlErrorDocumentProducer.java | 58 ++++++++++++++++---
.../olingo/odata2/core/ep/util/FormatJson.java | 3 +
.../olingo/odata2/core/ep/util/FormatXml.java | 4 ++
.../core/ep/producer/JsonErrorProducerTest.java | 39 +++++++++++++
.../core/ep/producer/XmlErrorProducerTest.java | 60 ++++++++++++++++++-
11 files changed, 298 insertions(+), 27 deletions(-)
diff --git
a/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/processor/ODataErrorContext.java
b/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/processor/ODataErrorContext.java
index 70527be..881c352 100644
---
a/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/processor/ODataErrorContext.java
+++
b/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/processor/ODataErrorContext.java
@@ -19,6 +19,8 @@
package org.apache.olingo.odata2.api.processor;
import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
@@ -36,16 +38,24 @@ import org.apache.olingo.odata2.api.uri.PathInfo;
*/
public class ODataErrorContext {
+ // General purpose attributes
private String contentType;
private HttpStatusCodes httpStatus;
- private String errorCode;
- private String message;
- private Locale locale;
private Exception exception;
private Map<String, List<String>> requestHeaders;
+ private PathInfo pathInfo;
private URI requestUri;
+
+ // Standard OData Error Response
+ private String errorCode;
+ private Locale locale;
+ private String message;
private String innerError;
- private PathInfo pathInfo;
+
+ // Extended OData Error Response
+ private String severity;
+ private String target;
+ private Collection<ODataErrorContext> errorDetails = new
ArrayList<ODataErrorContext>();
/**
* create a new context object
@@ -119,6 +129,22 @@ public class ODataErrorContext {
}
/**
+ * Return OData severity that is returned in error response.
+ * @return an application defined severity
+ */
+ public String getSeverity() {
+ return severity;
+}
+
+ /**
+ * Set OData severity that should be returned in error response.
+ * @param severity an application defined severity
+ */
+ public void setSeverity(String severity) {
+ this.severity = severity;
+ }
+
+/**
* Return a translated error message.
* @return translated message
*/
@@ -209,6 +235,39 @@ public class ODataErrorContext {
}
/**
+ * Get a collection of detailed errors for a OData inner error to be
returned in error response.
+ * @return a inner error message
+ */
+ public Collection<ODataErrorContext> getErrorDetails() {
+ return errorDetails;
+ }
+
+ /**
+ * Get a target of detailed error for a OData inner error to be returned in
error response.
+ * @return a target
+ */
+ public String getTarget() {
+ return target;
+ }
+
+ /**
+ * Set a target for a OData detailed error to be returned in error response.
+ * @param target a target
+ */
+ public void setTarget(String target) {
+ this.target = target;
+ }
+
+/**
+ * Set a collection of detailed errors for a OData inner error to be
returned in error response.
+ * If set, will overwrite the <code>innerError</code> element.
+ * @param errorDetails a inner error message
+ */
+ public void setErrorDetails(Collection<ODataErrorContext> errorDetails) {
+ this.errorDetails = errorDetails;
+ }
+
+ /**
* Get {@link PathInfo} object.
* May be <code>NULL</code> if no path info was created/set till error
occurred (but may be over written by
* application).
diff --git
a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/AtomEntityProvider.java
b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/AtomEntityProvider.java
index 201ffc7..4576ce5 100644
---
a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/AtomEntityProvider.java
+++
b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/AtomEntityProvider.java
@@ -103,6 +103,25 @@ public class AtomEntityProvider implements
ContentTypeBasedEntityProvider {
@Override
public ODataResponse writeErrorDocument(final HttpStatusCodes status, final
String errorCode, final String message,
final Locale locale, final String innerError) {
+ ODataErrorContext context = new ODataErrorContext();
+ context.setHttpStatus(status);
+ context.setErrorCode(errorCode);
+ context.setMessage(message);
+ context.setLocale(locale);
+ context.setInnerError(innerError);
+
+ return writeErrorDocument(context);
+ }
+
+ /**
+ * <p>Serializes an error message according to the OData standard.</p>
+ * <p>In case an error occurs, it is logged.
+ * An exception is not thrown because this method is used in exception
handling.</p>
+ * @param context the {@link ODataErrorContext} associated with this error
+ * @return an {@link ODataResponse} containing the serialized error message
+ */
+ @Override
+ public ODataResponse writeErrorDocument(ODataErrorContext context) {
CircleStreamBuffer csb = new CircleStreamBuffer();
try {
@@ -110,14 +129,14 @@ public class AtomEntityProvider implements
ContentTypeBasedEntityProvider {
XMLStreamWriter writer =
XmlHelper.getXMLOutputFactory().createXMLStreamWriter(outStream,
DEFAULT_CHARSET);
XmlErrorDocumentProducer producer = new XmlErrorDocumentProducer();
- producer.writeErrorDocument(writer, errorCode, message, locale,
innerError);
+ producer.writeErrorDocument(writer, context);
writer.flush();
csb.closeWrite();
ODataResponseBuilder response =
ODataResponse.entity(csb.getInputStream())
.header(ODataHttpHeaders.DATASERVICEVERSION, ODataServiceVersion.V10)
- .status(status);
+ .status(context.getHttpStatus());
return response.build();
} catch (Exception e) {
csb.close();
diff --git
a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/ContentTypeBasedEntityProvider.java
b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/ContentTypeBasedEntityProvider.java
index 249931d..2cd2479 100644
---
a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/ContentTypeBasedEntityProvider.java
+++
b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/ContentTypeBasedEntityProvider.java
@@ -81,6 +81,8 @@ public interface ContentTypeBasedEntityProvider {
ODataResponse writeErrorDocument(HttpStatusCodes status, String errorCode,
String message, Locale locale,
String innerError);
+ ODataResponse writeErrorDocument(ODataErrorContext context);
+
ServiceDocument readServiceDocument(InputStream serviceDocument) throws
EntityProviderException;
ODataDeltaFeed readDeltaFeed(EdmEntitySet entitySet, InputStream content,
EntityProviderReadProperties properties)
diff --git
a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/JsonEntityProvider.java
b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/JsonEntityProvider.java
index fa94320..1d87012 100644
---
a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/JsonEntityProvider.java
+++
b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/JsonEntityProvider.java
@@ -85,15 +85,34 @@ public class JsonEntityProvider implements
ContentTypeBasedEntityProvider {
@Override
public ODataResponse writeErrorDocument(final HttpStatusCodes status, final
String errorCode, final String message,
final Locale locale, final String innerError) {
+ ODataErrorContext context = new ODataErrorContext();
+ context.setHttpStatus(status);
+ context.setErrorCode(errorCode);
+ context.setMessage(message);
+ context.setLocale(locale);
+ context.setInnerError(innerError);
+
+ return writeErrorDocument(context);
+ }
+
+ /**
+ * <p>Serializes an error message according to the OData standard.</p>
+ * <p>In case an error occurs, it is logged.
+ * An exception is not thrown because this method is used in exception
handling.</p>
+ * @param context the {@link ODataErrorContext} associated with this error
+ * @return an {@link ODataResponse} containing the serialized error message
+ */
+ @Override
+ public ODataResponse writeErrorDocument(ODataErrorContext context) {
CircleStreamBuffer buffer = new CircleStreamBuffer();
try {
BufferedWriter writer = new BufferedWriter(new
OutputStreamWriter(buffer.getOutputStream(), DEFAULT_CHARSET));
- new JsonErrorDocumentProducer().writeErrorDocument(writer, errorCode,
message, locale, innerError);
+ new JsonErrorDocumentProducer().writeErrorDocument(writer, context);
writer.flush();
buffer.closeWrite();
- return ODataResponse.status(status)
+ return ODataResponse.status(context.getHttpStatus())
.entity(buffer.getInputStream())
.header(ODataHttpHeaders.DATASERVICEVERSION, ODataServiceVersion.V10)
.build();
diff --git
a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/ProviderFacadeImpl.java
b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/ProviderFacadeImpl.java
index 9acf487..01a564d 100644
---
a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/ProviderFacadeImpl.java
+++
b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/ProviderFacadeImpl.java
@@ -87,8 +87,7 @@ public class ProviderFacadeImpl implements
EntityProviderInterface {
@Override
public ODataResponse writeErrorDocument(final ODataErrorContext context) {
try {
- return
create(context.getContentType()).writeErrorDocument(context.getHttpStatus(),
context.getErrorCode(),
- context.getMessage(), context.getLocale(), context.getInnerError());
+ return create(context.getContentType()).writeErrorDocument(context);
} catch (EntityProviderException e) {
throw new ODataRuntimeException(e);
}
diff --git
a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/JsonErrorDocumentProducer.java
b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/JsonErrorDocumentProducer.java
index 54b5760..c838886 100644
---
a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/JsonErrorDocumentProducer.java
+++
b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/JsonErrorDocumentProducer.java
@@ -22,6 +22,7 @@ import java.io.IOException;
import java.io.Writer;
import java.util.Locale;
+import org.apache.olingo.odata2.api.processor.ODataErrorContext;
import org.apache.olingo.odata2.core.ep.util.FormatJson;
import org.apache.olingo.odata2.core.ep.util.JsonStreamWriter;
@@ -32,13 +33,25 @@ public class JsonErrorDocumentProducer {
public void writeErrorDocument(final Writer writer, final String errorCode,
final String message,
final Locale locale, final String innerError) throws IOException {
- JsonStreamWriter jsonStreamWriter = new JsonStreamWriter(writer);
+ ODataErrorContext context = new ODataErrorContext();
+ context.setErrorCode(errorCode);
+ context.setMessage(message);
+ context.setLocale(locale);
+ context.setInnerError(innerError);
+
+ writeErrorDocument(writer, context);
+ }
+ public void writeErrorDocument(final Writer writer, ODataErrorContext
context) throws IOException {
+ Locale locale = context.getLocale();
+ String innerError = context.getInnerError();
+
+ JsonStreamWriter jsonStreamWriter = new JsonStreamWriter(writer);
jsonStreamWriter
.beginObject()
.name(FormatJson.ERROR)
.beginObject()
- .namedStringValue(FormatJson.CODE, errorCode)
+ .namedStringValue(FormatJson.CODE, context.getErrorCode())
.separator()
.name(FormatJson.MESSAGE)
.beginObject()
@@ -48,12 +61,28 @@ public class JsonErrorDocumentProducer {
locale.getLanguage()
+ (locale.getCountry() == null ||
locale.getCountry().isEmpty() ? "" : ("-" + locale.getCountry())))
.separator()
- .namedStringValue(FormatJson.VALUE, message)
+ .namedStringValue(FormatJson.VALUE, context.getMessage())
.endObject();
- if (innerError != null) {
- jsonStreamWriter.separator()
- .namedStringValue(FormatJson.INNER_ERROR, innerError);
- }
+ if (!context.getErrorDetails().isEmpty()) {
+ int cntr = 0;
+
jsonStreamWriter.separator().name(FormatJson.INNER_ERROR).beginObject().name(FormatJson.ERROR_DETAILS)
+ .beginArray();
+ for (ODataErrorContext detail : context.getErrorDetails()) {
+ if (cntr > 0) {
+ jsonStreamWriter.separator();
+ }
+ cntr++;
+ jsonStreamWriter.beginObject()
+ .namedStringValue(FormatJson.CODE,
detail.getErrorCode()).separator()
+ .namedStringValue(FormatJson.MESSAGE,
detail.getMessage()).separator()
+ .namedStringValue(FormatJson.TARGET,
detail.getTarget()).separator()
+ .namedStringValue(FormatJson.SEVERITY, detail.getSeverity())
+ .endObject();
+ }
+ jsonStreamWriter.endArray().endObject();
+ } else if (innerError != null) {
+
jsonStreamWriter.separator().namedStringValue(FormatJson.INNER_ERROR,
innerError);
+ }
jsonStreamWriter.endObject()
.endObject();
}
diff --git
a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/XmlErrorDocumentProducer.java
b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/XmlErrorDocumentProducer.java
index 05ee992..e5ff2fd 100644
---
a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/XmlErrorDocumentProducer.java
+++
b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/XmlErrorDocumentProducer.java
@@ -18,26 +18,40 @@
******************************************************************************/
package org.apache.olingo.odata2.core.ep.producer;
+import java.util.Collection;
import java.util.Locale;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
import org.apache.olingo.odata2.api.edm.Edm;
+import org.apache.olingo.odata2.api.processor.ODataErrorContext;
import org.apache.olingo.odata2.core.ep.util.FormatXml;
public class XmlErrorDocumentProducer {
public void writeErrorDocument(final XMLStreamWriter writer, final String
errorCode, final String message,
final Locale locale, final String innerError) throws XMLStreamException {
+ ODataErrorContext context = new ODataErrorContext();
+ context.setErrorCode(errorCode);
+ context.setMessage(message);
+ context.setLocale(locale);
+ context.setInnerError(innerError);
+
+ writeErrorDocument(writer, context);
+ }
+
+ public void writeErrorDocument(final XMLStreamWriter writer,
ODataErrorContext context) throws XMLStreamException {
+ Locale locale = context.getLocale();
+ String errorCode = context.getErrorCode();
+ String message = context.getMessage();
+ String innerError = context.getInnerError();
+ Collection<ODataErrorContext> errorDetails = context.getErrorDetails();
+
writer.writeStartDocument();
writer.writeStartElement(FormatXml.M_ERROR);
writer.writeDefaultNamespace(Edm.NAMESPACE_M_2007_08);
- writer.writeStartElement(FormatXml.M_CODE);
- if (errorCode != null) {
- writer.writeCharacters(errorCode);
- }
- writer.writeEndElement();
+ writeSimpleElement(writer, FormatXml.M_CODE, errorCode);
writer.writeStartElement(FormatXml.M_MESSAGE);
if (locale != null) {
writer.writeAttribute(Edm.PREFIX_XML, Edm.NAMESPACE_XML_1998,
FormatXml.XML_LANG, getLocale(locale));
@@ -49,15 +63,33 @@ public class XmlErrorDocumentProducer {
}
writer.writeEndElement();
- if (innerError != null) {
- writer.writeStartElement(FormatXml.M_INNER_ERROR);
- writer.writeCharacters(innerError);
- writer.writeEndElement();
+ if (!errorDetails.isEmpty()) {
+ writeErrorDetails(writer, errorDetails);
+ } else if (innerError != null) {
+ writeSimpleElement(writer, FormatXml.M_INNER_ERROR, innerError);
}
writer.writeEndDocument();
}
+ private void writeErrorDetails(final XMLStreamWriter writer,
Collection<ODataErrorContext> errorDetails)
+ throws XMLStreamException {
+ writer.writeStartElement(FormatXml.M_INNER_ERROR);
+ writer.writeStartElement(FormatXml.M_ERROR_DETAILS);
+ for (ODataErrorContext detail : errorDetails) {
+ writer.writeStartElement(FormatXml.M_ERROR_DETAIL);
+
+ writeSimpleElement(writer, FormatXml.M_CODE,
detail.getErrorCode());
+ writeSimpleElement(writer, FormatXml.M_MESSAGE,
detail.getMessage());
+ writeSimpleElement(writer, FormatXml.M_TARGET, detail.getTarget());
+ writeSimpleElement(writer, FormatXml.M_SEVERITY,
detail.getSeverity());
+
+ writer.writeEndElement();
+ }
+ writer.writeEndElement();
+ writer.writeEndElement();
+ }
+
/**
* Gets language and country as defined in RFC 4646 based on {@link Locale}.
*/
@@ -69,4 +101,12 @@ public class XmlErrorDocumentProducer {
}
}
+ private void writeSimpleElement(final XMLStreamWriter writer, String
elementName, String value)
+ throws XMLStreamException {
+ writer.writeStartElement(elementName);
+ if (null != value) {
+ writer.writeCharacters(value);
+ }
+ writer.writeEndElement();
+ }
}
diff --git
a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/util/FormatJson.java
b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/util/FormatJson.java
index f1010c0..7b36ef8 100644
---
a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/util/FormatJson.java
+++
b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/util/FormatJson.java
@@ -46,9 +46,12 @@ public class FormatJson {
public static final String ERROR = "error";
public static final String CODE = "code";
public static final String MESSAGE = "message";
+ public static final String TARGET = "target";
+ public static final String SEVERITY = "severity";
public static final String LANG = "lang";
public static final String VALUE = "value";
public static final String INNER_ERROR = "innererror";
+ public static final String ERROR_DETAILS = "errordetails";
public static final String DELTA = "__delta";
public static final String ODATA_CONTEXT = "@odata.context";
public static final String DELTA_CONTEXT_PREFIX = "$metadata#";
diff --git
a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/util/FormatXml.java
b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/util/FormatXml.java
index 8ad0181..058093d 100644
---
a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/util/FormatXml.java
+++
b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/util/FormatXml.java
@@ -40,9 +40,13 @@ public class FormatXml {
public static final String M_INLINE = "inline";
public static final String M_ERROR = "error";
+ public static final String M_SEVERITY = "severity";
+ public static final String M_TARGET = "target";
public static final String M_CODE = "code";
public static final String M_MESSAGE = "message";
public static final String M_INNER_ERROR = "innererror";
+ public static final String M_ERROR_DETAILS = "errordetails";
+ public static final String M_ERROR_DETAIL = "errordetail";
public static final String D_ELEMENT = "element";
public static final String D_LINKS = "links";
diff --git
a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/producer/JsonErrorProducerTest.java
b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/producer/JsonErrorProducerTest.java
index 29f1e95..8feea0b 100644
---
a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/producer/JsonErrorProducerTest.java
+++
b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/producer/JsonErrorProducerTest.java
@@ -22,6 +22,7 @@ import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNull;
import java.io.InputStream;
+import java.util.Arrays;
import java.util.Locale;
import org.apache.olingo.odata2.api.ODataServiceVersion;
@@ -55,6 +56,44 @@ public class JsonErrorProducerTest {
testSerializeJSON(null, null, null);
}
+ @Test
+ public void jsonSerializationWithDetails() throws Exception {
+ String errorCode = "500";
+ String message = "Main message";
+ Locale locale = Locale.GERMAN;
+ String innerError = "Inner Error";
+
+ ODataErrorContext detailed1 = new ODataErrorContext();
+ detailed1.setErrorCode("500");
+ detailed1.setMessage("Detailed message");
+ detailed1.setSeverity("error");
+ detailed1.setTarget("element1");
+
+ ODataErrorContext detailed2 = new ODataErrorContext();
+ detailed2.setErrorCode("404");
+ detailed2.setMessage("Detailed message 2");
+ detailed2.setSeverity("warn");
+ detailed2.setTarget("element2");
+
+ ODataErrorContext ctx = new ODataErrorContext();
+ ctx.setContentType(HttpContentType.APPLICATION_JSON);
+ ctx.setErrorCode(errorCode);
+ ctx.setHttpStatus(HttpStatusCodes.INTERNAL_SERVER_ERROR);
+ ctx.setLocale(locale);
+ ctx.setMessage(message);
+ ctx.setInnerError(innerError);
+ ctx.setErrorDetails(Arrays.asList(detailed1, detailed2));
+
+ ODataResponse response = new ProviderFacadeImpl().writeErrorDocument(ctx);
+ final String jsonErrorMessage =
StringHelper.inputStreamToString((InputStream) response.getEntity());
+ assertEquals(jsonErrorMessage,
+
"{\"error\":{\"code\":\"500\",\"message\":{\"lang\":\"de\",\"value\":\"Main
message\"},"
+ + "\"innererror\":"
+ + "{\"errordetails\":["
+ + "{\"code\":\"500\",\"message\":\"Detailed
message\",\"target\":\"element1\",\"severity\":\"error\"},"
+ + "{\"code\":\"404\",\"message\":\"Detailed message
2\",\"target\":\"element2\",\"severity\":\"warn\"}]}}}");
+ }
+
// helper method
private void testSerializeJSON(final String errorCode, final String message,
final Locale locale) throws Exception {
ODataErrorContext ctx = new ODataErrorContext();
diff --git
a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/producer/XmlErrorProducerTest.java
b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/producer/XmlErrorProducerTest.java
index 85538ce..9aa88f5 100644
---
a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/producer/XmlErrorProducerTest.java
+++
b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/producer/XmlErrorProducerTest.java
@@ -27,6 +27,7 @@ import static org.junit.Assert.assertNull;
import java.io.IOException;
import java.io.InputStream;
+import java.util.Collections;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
@@ -149,6 +150,38 @@ public class XmlErrorProducerTest extends
AbstractXmlProducerTestHelper {
}
@Test
+ public void withErrorDetails() throws Exception {
+ String errorCode = "500";
+ String message = "Main message";
+ String detailedMessage = "Detailed message";
+ String severity = "error";
+ String target = "element1";
+ Locale locale = Locale.GERMAN;
+ String innerError = "Inner Error";
+
+ ODataErrorContext detailed = new ODataErrorContext();
+ detailed.setErrorCode(errorCode);
+ detailed.setMessage(detailedMessage);
+ detailed.setSeverity(severity);
+ detailed.setTarget(target);
+
+ ODataErrorContext ctx = new ODataErrorContext();
+ ctx.setContentType(contentType);
+ ctx.setErrorCode(errorCode);
+ ctx.setHttpStatus(expectedStatus);
+ ctx.setLocale(locale);
+ ctx.setMessage(message);
+ ctx.setInnerError(innerError);
+ ctx.setErrorDetails(Collections.singletonList(detailed));
+
+ ODataResponse response = new ProviderFacadeImpl().writeErrorDocument(ctx);
+ String errorXml = verifyResponse(response);
+ System.out.println(errorXml);
+ verifyXml(errorCode, message, locale, innerError, errorXml);
+ verifyDetailsXml(errorCode, detailedMessage, severity, target, errorXml);
+ }
+
+ @Test
public void normal() throws Exception {
serializeError(null, "Message", null, Locale.GERMAN);
serializeError(null, "Message", null, Locale.ENGLISH);
@@ -222,8 +255,14 @@ public class XmlErrorProducerTest extends
AbstractXmlProducerTestHelper {
private void
serializeError(final String errorCode, final String message, final
String innerError, final Locale locale)
throws Exception {
+ ODataErrorContext context = new ODataErrorContext();
+ context.setHttpStatus(expectedStatus);
+ context.setErrorCode(errorCode);
+ context.setMessage(message);
+ context.setLocale(locale);
+ context.setInnerError(innerError);
ODataResponse response =
- new AtomEntityProvider().writeErrorDocument(expectedStatus, errorCode,
message, locale, innerError);
+ new AtomEntityProvider().writeErrorDocument(context);
String errorXml = verifyResponse(response);
verifyXml(errorCode, message, locale, innerError, errorXml);
}
@@ -267,4 +306,23 @@ public class XmlErrorProducerTest extends
AbstractXmlProducerTestHelper {
assertXpathExists("/a:error/a:innererror", errorXml);
}
}
+
+ private void verifyDetailsXml(final String errorCode, final String message,
+ String severity, String target, final String errorXml) throws
Exception {
+ assertXpathExists("/a:error/a:innererror/a:errordetails/a:errordetail",
errorXml);
+
+ if (errorCode != null) {
+ assertXpathEvaluatesTo(errorCode,
"/a:error/a:innererror/a:errordetails/a:errordetail/a:code", errorXml);
+ }
+ if (message != null) {
+ assertXpathEvaluatesTo(message,
"/a:error/a:innererror/a:errordetails/a:errordetail/a:message", errorXml);
+ }
+ if (severity != null) {
+ assertXpathEvaluatesTo(severity,
"/a:error/a:innererror/a:errordetails/a:errordetail/a:severity", errorXml);
+ }
+ if (target != null) {
+ assertXpathEvaluatesTo(target,
"/a:error/a:innererror/a:errordetails/a:errordetail/a:target", errorXml);
+ }
+ }
+
}