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 69fa29cb0..8d75a3170 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 @@ -28,7 +28,6 @@ import org.apache.olingo.client.api.http.HttpClientException; import org.apache.olingo.commons.api.domain.ODataError; import org.apache.olingo.commons.api.format.ODataFormat; import org.apache.olingo.commons.api.serialization.ODataDeserializerException; -import org.apache.olingo.commons.core.data.ODataErrorImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -40,7 +39,7 @@ public abstract class AbstractRequest { protected static final Logger LOG = LoggerFactory.getLogger(AbstractRequest.class); private ODataError getGenericError(final int code, final String errorMsg) { - final ODataErrorImpl error = new ODataErrorImpl(); + final ODataError error = new ODataError(); error.setCode(String.valueOf(code)); error.setMessage(errorMsg); return error; diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/domain/ODataError.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/domain/ODataError.java index 856bda72d..a910f0874 100644 --- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/domain/ODataError.java +++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/domain/ODataError.java @@ -24,40 +24,109 @@ import java.util.Map; /** * OData error. */ -public interface ODataError { +public class ODataError { + + private String code; + private String message; + private String target; + private List details; + private Map innerError; /** - * Gets error code. - * - * @return error code. + * The value for the code name/value pair is a language-independent string. Its value is a service-defined error code. + * This code serves as a sub-status for the HTTP error code specified in the response. MAY be null. + * @return the error code as a string */ - String getCode(); + public String getCode() { + return code; + } /** - * Gets error message. - * - * @return error message. + * The value for the code name/value pair is a language-independent string. Its value is a service-defined error code. + * This code serves as a sub-status for the HTTP error code specified in the response. MAY be null. + * @param code + * @return this for method chaining */ - String getMessage(); + public ODataError setCode(String code) { + this.code = code; + return this; + } /** - * Gets error target. - * - * @return error message. + * The value for the message name/value pair MUST be a human-readable, language-dependent representation of the error. + * MUST not be null + * @return the message string */ - String getTarget(); + public String getMessage() { + return message; + } + + /** + * The value for the message name/value pair MUST be a human-readable, language-dependent representation of the error. + * MUST not be null + * @param message + * @return this for method chaining + */ + public ODataError setMessage(String message) { + this.message = message; + return this; + } + + /** + * The value for the target name/value pair is the target of the particular error (for example, the name of the + * property in error). MAY be null. + * @return the target string + */ + public String getTarget() { + return target; + } + + /** + * The value for the target name/value pair is the target of the particular error (for example, the name of the + * property in error). MAY be null. + * @param target + * @return this for method chaining + */ + public ODataError setTarget(String target) { + this.target = target; + return this; + } /** * Gets error details. * * @return ODataErrorDetail list. */ - List getDetails(); + public List getDetails() { + return details; + } + + /** + * Sets error details. + * + * @return this for method chaining. + */ + public ODataError setDetails(List details) { + this.details = details; + return this; + } /** * Gets server defined key-value pairs for debug environment only. * - * @return a pair representing server defined object. + * @return a pair representing server defined object. MAY be null. */ - Map getInnerError(); + public Map getInnerError() { + return innerError; + } + + /** + * Sets server defined key-value pairs for debug environment only. + * + * @return this for method chaining. + */ + public ODataError setInnerError(Map innerError) { + this.innerError = innerError; + return this; + } } diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/domain/ODataErrorDetail.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/domain/ODataErrorDetail.java index 90f9ddb70..573525db9 100644 --- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/domain/ODataErrorDetail.java +++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/domain/ODataErrorDetail.java @@ -23,26 +23,51 @@ package org.apache.olingo.commons.api.domain; * {"code": "301","target": "$search" ,"message": "$search query option not supported"} * ],...}}. */ -public interface ODataErrorDetail { +public class ODataErrorDetail { + + private String code; + private String message; + private String target; /** * Gets error code. * * @return error code. */ - String getCode(); + public String getCode() { + return code; + } + + public ODataErrorDetail setCode(final String code) { + this.code = code; + return this; + } /** * Gets error message. * * @return error message. */ - String getMessage(); + public String getMessage() { + return message; + } + + public ODataErrorDetail setMessage(final String message) { + this.message = message; + return this; + } /** * Gets error target. * * @return error message. */ - String getTarget(); + public String getTarget() { + return target; + } + + public ODataErrorDetail setTarget(final String target) { + this.target = target; + return this; + } } diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/ODataErrorDetailImpl.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/ODataErrorDetailImpl.java deleted file mode 100755 index 3347e0761..000000000 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/ODataErrorDetailImpl.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.olingo.commons.core.data; - -import org.apache.olingo.commons.api.domain.ODataErrorDetail; - -public class ODataErrorDetailImpl implements ODataErrorDetail { - - private String code; - - private String message; - - private String target; - - @Override - public String getCode() { - return code; - } - - public void setCode(final String code) { - this.code = code; - } - - @Override - public String getMessage() { - return message; - } - - public void setMessage(final String message) { - this.message = message; - } - - @Override - public String getTarget() { - return target; - } - - public void setTarget(final String target) { - this.target = target; - } -} diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/ODataErrorImpl.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/ODataErrorImpl.java deleted file mode 100755 index cb5df5dee..000000000 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/ODataErrorImpl.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.olingo.commons.core.data; - -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import org.apache.olingo.commons.api.domain.ODataError; -import org.apache.olingo.commons.api.domain.ODataErrorDetail; - -/** - * Example: - * - * { - * "error": { "code": "501", "message": "Unsupported functionality", "target": "query", "details": [ { "code": "301", - * "target": "$search", "message": "$search query option not supported" } ], "innererror": { "trace": [...], "context": - * {...} } } } - * . - */ -public class ODataErrorImpl implements ODataError { - - private String code; - - private String message; - - private String target; - - private List details; - - private Map innerError = new LinkedHashMap(); - - @Override - public String getCode() { - return code; - } - - public void setCode(final String code) { - this.code = code; - } - - @Override - public String getMessage() { - return message; - } - - public void setMessage(final String message) { - this.message = message; - } - - @Override - public String getTarget() { - return target; - } - - public void setTarget(final String target) { - this.target = target; - } - - @Override - public List getDetails() { - return details; - } - - public void setDetails(final List detail) { - details = detail; - } - - @Override - public Map getInnerError() { - return innerError; - } -} diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/AtomDeserializer.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/AtomDeserializer.java index df7821391..3f38331e0 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/AtomDeserializer.java +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/AtomDeserializer.java @@ -66,7 +66,6 @@ import org.apache.olingo.commons.core.data.EntityImpl; import org.apache.olingo.commons.core.data.EntitySetImpl; import org.apache.olingo.commons.core.data.LinkImpl; import org.apache.olingo.commons.core.data.LinkedComplexValueImpl; -import org.apache.olingo.commons.core.data.ODataErrorImpl; import org.apache.olingo.commons.core.data.PropertyImpl; import org.apache.olingo.commons.core.data.v3.LinkCollectionImpl; import org.apache.olingo.commons.core.data.v4.DeltaImpl; @@ -849,7 +848,7 @@ public class AtomDeserializer extends AbstractAtomDealer implements ODataDeseria } private ODataError error(final XMLEventReader reader, final StartElement start) throws XMLStreamException { - final ODataErrorImpl error = new ODataErrorImpl(); + final ODataError error = new ODataError(); boolean setCode = false; boolean codeSet = false; diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonODataErrorDeserializer.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonODataErrorDeserializer.java index 726031484..e75fe8a1c 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonODataErrorDeserializer.java +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonODataErrorDeserializer.java @@ -20,6 +20,7 @@ package org.apache.olingo.commons.core.serialization; import java.io.IOException; import java.util.ArrayList; +import java.util.HashMap; import java.util.Iterator; import java.util.List; @@ -27,7 +28,6 @@ import org.apache.olingo.commons.api.Constants; import org.apache.olingo.commons.api.domain.ODataError; import org.apache.olingo.commons.api.domain.ODataErrorDetail; import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion; -import org.apache.olingo.commons.core.data.ODataErrorImpl; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.JsonNode; @@ -41,7 +41,7 @@ public class JsonODataErrorDeserializer extends JsonDeserializer { protected ODataError doDeserialize(final JsonParser parser) throws IOException { - final ODataErrorImpl error = new ODataErrorImpl(); + final ODataError error = new ODataError(); final ObjectNode tree = parser.getCodec().readTree(parser); if (tree.has(jsonError)) { @@ -73,12 +73,14 @@ public class JsonODataErrorDeserializer extends JsonDeserializer { error.setDetails(details); } if (errorNode.hasNonNull(Constants.ERROR_INNERERROR)) { + HashMap innerErrorMap = new HashMap(); final JsonNode innerError = errorNode.get(Constants.ERROR_INNERERROR); for (final Iterator itor = innerError.fieldNames(); itor.hasNext();) { final String keyTmp = itor.next(); final String val = innerError.get(keyTmp).toString(); - error.getInnerError().put(keyTmp, val); + innerErrorMap.put(keyTmp, val); } + error.setInnerError(innerErrorMap); } } diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonODataErrorDetailDeserializer.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonODataErrorDetailDeserializer.java index 17821db55..f79f154d2 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonODataErrorDetailDeserializer.java +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonODataErrorDetailDeserializer.java @@ -25,7 +25,6 @@ import org.apache.olingo.commons.api.Constants; import org.apache.olingo.commons.api.data.ResWrap; import org.apache.olingo.commons.api.domain.ODataErrorDetail; import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion; -import org.apache.olingo.commons.core.data.ODataErrorDetailImpl; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.JsonNode; @@ -38,7 +37,7 @@ public class JsonODataErrorDetailDeserializer extends JsonDeserializer { protected ResWrap doDeserialize(final JsonParser parser) throws IOException { - final ODataErrorDetailImpl error = new ODataErrorDetailImpl(); + final ODataErrorDetail error = new ODataErrorDetail(); final JsonNode errorNode = parser.getCodec().readTree(parser); if (errorNode.has(Constants.ERROR_CODE)) { error.setCode(errorNode.get(Constants.ERROR_CODE).textValue()); diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/ODataSerializer.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/ODataSerializer.java index 0eaf44070..d1037c588 100644 --- a/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/ODataSerializer.java +++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/ODataSerializer.java @@ -23,6 +23,7 @@ import java.io.InputStream; import org.apache.olingo.commons.api.data.ContextURL; import org.apache.olingo.commons.api.data.Entity; import org.apache.olingo.commons.api.data.EntitySet; +import org.apache.olingo.commons.api.domain.ODataError; import org.apache.olingo.commons.api.edm.Edm; import org.apache.olingo.commons.api.edm.EdmEntitySet; import org.apache.olingo.commons.api.edm.EdmEntityType; @@ -38,4 +39,11 @@ public interface ODataSerializer { InputStream entity(EdmEntityType edmEntityType, Entity entity, ContextURL contextURL); InputStream entitySet(EdmEntitySet edmEntitySet, EntitySet entitySet, ContextURL contextURL); + + /** + * Writes an ODataError into an InputStream + * @param error the main error + * @return inputStream containing the OData formatted error + */ + InputStream error(ODataError error); } diff --git a/lib/server-core/pom.xml b/lib/server-core/pom.xml index f5e19f770..6bf11a243 100644 --- a/lib/server-core/pom.xml +++ b/lib/server-core/pom.xml @@ -69,12 +69,35 @@ org.slf4j slf4j-simple + + commons-io + commons-io + test + - org.antlr + org.codehaus.mojo + build-helper-maven-plugin + 1.7 + + + generate-sources + + add-source + + + + target/generated-sources/antlr4 + + + + + + + org.antlr antlr4-maven-plugin ${antlr.version} diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/ODataXmlSerializerImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/ODataXmlSerializerImpl.java index e24a88c27..2f2afeb38 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/ODataXmlSerializerImpl.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/ODataXmlSerializerImpl.java @@ -28,6 +28,7 @@ import org.apache.olingo.commons.api.ODataRuntimeException; import org.apache.olingo.commons.api.data.ContextURL; import org.apache.olingo.commons.api.data.Entity; import org.apache.olingo.commons.api.data.EntitySet; +import org.apache.olingo.commons.api.domain.ODataError; import org.apache.olingo.commons.api.edm.Edm; import org.apache.olingo.commons.api.edm.EdmEntitySet; import org.apache.olingo.commons.api.edm.EdmEntityType; @@ -86,4 +87,9 @@ public class ODataXmlSerializerImpl implements ODataSerializer { throw new ODataRuntimeException("Entityset serialization not implemented for XML format"); } + @Override + public InputStream error(ODataError error) { + throw new ODataRuntimeException("error serialization not implemented for XML format"); + } + } diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataErrorSerializer.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataErrorSerializer.java new file mode 100644 index 000000000..6d565ac42 --- /dev/null +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataErrorSerializer.java @@ -0,0 +1,79 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.olingo.server.core.serializer.json; + +import java.io.IOException; + +import org.apache.olingo.commons.api.ODataRuntimeException; +import org.apache.olingo.commons.api.domain.ODataError; +import org.apache.olingo.commons.api.domain.ODataErrorDetail; + +import com.fasterxml.jackson.core.JsonGenerationException; +import com.fasterxml.jackson.core.JsonGenerator; + +public class ODataErrorSerializer { + + private static final String ERROR = "error"; + private static final String CODE = "code"; + private static final String MESSAGE = "message"; + private static final String TARGET = "target"; + private static final String DETAILS = "details"; + + public void writeErrorDocument(JsonGenerator json, ODataError error) throws IOException { + if (error == null) { + throw new ODataRuntimeException("ODataError object MUST NOT be null!"); + } + json.writeStartObject(); + json.writeFieldName(ERROR); + + json.writeStartObject(); + writeODataError(json, error.getCode(), error.getMessage(), error.getTarget()); + + if (error.getDetails() != null) { + json.writeArrayFieldStart(DETAILS); + for (ODataErrorDetail detail : error.getDetails()) { + json.writeStartObject(); + writeODataError(json, detail.getCode(), detail.getMessage(), detail.getTarget()); + json.writeEndObject(); + } + json.writeEndArray(); + } + + json.writeEndObject(); + json.writeEndObject(); + } + + private void writeODataError(JsonGenerator json, String code, String message, String target) throws IOException, + JsonGenerationException { + if (code == null) { + json.writeNullField(CODE); + } else { + json.writeStringField(CODE, code); + } + if (message == null) { + json.writeNullField(MESSAGE); + } else { + json.writeStringField(MESSAGE, message); + } + + if (target != null) { + json.writeStringField(TARGET, target); + } + } +} diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java index 022b14b53..4870a5cef 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java @@ -18,24 +18,37 @@ */ package org.apache.olingo.server.core.serializer.json; -import com.fasterxml.jackson.core.JsonFactory; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.util.DefaultPrettyPrinter; +import java.io.BufferedWriter; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStreamWriter; +import java.util.List; + import org.apache.olingo.commons.api.Constants; import org.apache.olingo.commons.api.ODataRuntimeException; -import org.apache.olingo.commons.api.data.*; -import org.apache.olingo.commons.api.edm.*; +import org.apache.olingo.commons.api.data.ContextURL; +import org.apache.olingo.commons.api.data.Entity; +import org.apache.olingo.commons.api.data.EntitySet; +import org.apache.olingo.commons.api.data.LinkedComplexValue; +import org.apache.olingo.commons.api.data.Property; +import org.apache.olingo.commons.api.domain.ODataError; +import org.apache.olingo.commons.api.edm.Edm; +import org.apache.olingo.commons.api.edm.EdmComplexType; +import org.apache.olingo.commons.api.edm.EdmEntitySet; +import org.apache.olingo.commons.api.edm.EdmEntityType; +import org.apache.olingo.commons.api.edm.EdmPrimitiveType; +import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException; +import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind; +import org.apache.olingo.commons.api.edm.EdmProperty; import org.apache.olingo.commons.core.edm.primitivetype.EdmPrimitiveTypeFactory; import org.apache.olingo.server.api.serializer.ODataSerializer; import org.apache.olingo.server.core.serializer.utils.CircleStreamBuffer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.BufferedWriter; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStreamWriter; -import java.util.List; +import com.fasterxml.jackson.core.JsonFactory; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.util.DefaultPrettyPrinter; public class ODataJsonSerializer implements ODataSerializer { @@ -172,7 +185,7 @@ public class ODataJsonSerializer implements ODataSerializer { writePrimitive(edmProperty, property, json); } else if (property.isLinkedComplex()) { writeComplexValue(edmProperty, property.asLinkedComplex().getValue(), json); - } else if(property.isComplex()) { + } else if (property.isComplex()) { writeComplexValue(edmProperty, property.asComplex(), json); } else { throw new ODataRuntimeException("Property type not yet supported!"); @@ -180,6 +193,7 @@ public class ODataJsonSerializer implements ODataSerializer { } } + private void writeCollection(EdmProperty edmProperty, Property property, JsonGenerator json) throws IOException, EdmPrimitiveTypeException { json.writeStartArray(); @@ -243,7 +257,7 @@ public class ODataJsonSerializer implements ODataSerializer { } private void writeComplexValue(final EdmProperty edmProperty, final List properties, - JsonGenerator json) throws IOException, EdmPrimitiveTypeException { + JsonGenerator json) throws IOException, EdmPrimitiveTypeException { final EdmComplexType type = (EdmComplexType) edmProperty.getType(); json.writeStartObject(); for (final String propertyName : type.getPropertyNames()) { @@ -261,4 +275,18 @@ public class ODataJsonSerializer implements ODataSerializer { } return null; } + + @Override + public InputStream error(ODataError error) { + CircleStreamBuffer buffer = new CircleStreamBuffer(); + try { + JsonGenerator json = new JsonFactory().createGenerator(buffer.getOutputStream()); + ODataErrorSerializer ser = new ODataErrorSerializer(); + ser.writeErrorDocument(json, error); + json.close(); + } catch (final IOException e) { + throw new ODataRuntimeException(e); + } + return buffer.getInputStream(); + } } diff --git a/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/json/ODataErrorSerializerTest.java b/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/json/ODataErrorSerializerTest.java new file mode 100644 index 000000000..3eb2c32bd --- /dev/null +++ b/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/json/ODataErrorSerializerTest.java @@ -0,0 +1,135 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.olingo.server.core.serializer.json; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.io.IOUtils; +import org.apache.olingo.commons.api.ODataRuntimeException; +import org.apache.olingo.commons.api.domain.ODataError; +import org.apache.olingo.commons.api.domain.ODataErrorDetail; +import org.apache.olingo.commons.api.format.ODataFormat; +import org.apache.olingo.server.api.OData; +import org.apache.olingo.server.api.serializer.ODataSerializer; +import org.junit.Before; +import org.junit.Test; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.JsonNodeType; + +public class ODataErrorSerializerTest { + + ODataSerializer ser; + + @Before + public void before() { + ser = OData.newInstance().createSerializer(ODataFormat.JSON); + } + + @Test + public void basicODataErrorNoCode() throws Exception { + ODataError error = new ODataError(); + error.setMessage("ErrorMessage"); + InputStream stream = ser.error(error); + String jsonString = IOUtils.toString(stream); + assertEquals("{\"error\":{\"code\":null,\"message\":\"ErrorMessage\"}}", jsonString); + } + + @Test + public void basicODataErrorWithCode() throws Exception { + ODataError error = new ODataError(); + error.setCode("Code").setMessage("ErrorMessage"); + InputStream stream = ser.error(error); + String jsonString = IOUtils.toString(stream); + assertEquals("{\"error\":{\"code\":\"Code\",\"message\":\"ErrorMessage\"}}", jsonString); + } + + @Test + public void basicODataErrorWithCodeAndTarget() throws Exception { + ODataError error = new ODataError(); + error.setCode("Code").setMessage("ErrorMessage").setTarget("Target"); + InputStream stream = ser.error(error); + String jsonString = IOUtils.toString(stream); + assertEquals("{\"error\":{\"code\":\"Code\",\"message\":\"ErrorMessage\",\"target\":\"Target\"}}", jsonString); + } + + @Test(expected = ODataRuntimeException.class) + public void nullErrorResultsInException() throws Exception { + ser.error(null); + } + + @Test + public void emptyDetailsList() throws Exception { + ODataError error = new ODataError(); + error.setMessage("ErrorMessage").setDetails(new ArrayList()); + InputStream stream = ser.error(error); + String jsonString = IOUtils.toString(stream); + assertEquals("{\"error\":{\"code\":null,\"message\":\"ErrorMessage\",\"details\":[]}}", jsonString); + } + + @Test + public void nothingSetAtODataErrorObject() throws Exception { + ODataError error = new ODataError(); + InputStream stream = ser.error(error); + String jsonString = IOUtils.toString(stream); + assertEquals("{\"error\":{\"code\":null,\"message\":null}}", jsonString); + } + + @Test + public void singleDetailNothingSet() throws Exception { + List details = new ArrayList(); + details.add(new ODataErrorDetail()); + ODataError error = new ODataError().setDetails(details); + InputStream stream = ser.error(error); + String jsonString = IOUtils.toString(stream); + assertEquals("{\"error\":{\"code\":null,\"message\":null,\"details\":[{\"code\":null,\"message\":null}]}}", + jsonString); + } + + @Test + public void verifiedWithJacksonParser() throws Exception { + List details = new ArrayList(); + details.add(new ODataErrorDetail().setCode("detailCode").setMessage("detailMessage").setTarget("detailTarget")); + ODataError error = new ODataError().setCode("Code").setMessage("Message").setTarget("Target").setDetails(details); + InputStream stream = ser.error(error); + JsonNode tree = new ObjectMapper().readTree(stream); + assertNotNull(tree); + tree = tree.get("error"); + assertNotNull(tree); + assertEquals("Code", tree.get("code").textValue()); + assertEquals("Message", tree.get("message").textValue()); + assertEquals("Target", tree.get("target").textValue()); + + tree = tree.get("details"); + assertNotNull(tree); + assertEquals(JsonNodeType.ARRAY, tree.getNodeType()); + + tree = tree.get(0); + assertNotNull(tree); + assertEquals("detailCode", tree.get("code").textValue()); + assertEquals("detailMessage", tree.get("message").textValue()); + assertEquals("detailTarget", tree.get("target").textValue()); + } +} diff --git a/lib/server-tecsvc/src/test/java/org/apache/olingo/server/tecsvc/data/JsonDataProviderTest.java b/lib/server-tecsvc/src/test/java/org/apache/olingo/server/tecsvc/data/JsonDataProviderTest.java index 23536ff17..cc8ddce35 100644 --- a/lib/server-tecsvc/src/test/java/org/apache/olingo/server/tecsvc/data/JsonDataProviderTest.java +++ b/lib/server-tecsvc/src/test/java/org/apache/olingo/server/tecsvc/data/JsonDataProviderTest.java @@ -18,6 +18,9 @@ */ package org.apache.olingo.server.tecsvc.data; +import java.io.InputStream; +import java.util.List; + import org.apache.olingo.commons.api.data.ContextURL; import org.apache.olingo.commons.api.data.Entity; import org.apache.olingo.commons.api.data.EntitySet; @@ -39,9 +42,6 @@ import org.apache.olingo.server.tecsvc.provider.EdmTechProvider; import org.junit.Assert; import org.junit.Test; -import java.io.InputStream; -import java.util.List; - /** */ public class JsonDataProviderTest {