[OLINGO-349] ODataError serialization. Move to commons pending
This commit is contained in:
parent
9469058193
commit
9403aeced7
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* 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.api.serializer;
|
||||
|
||||
//TODO: Where to put this class
|
||||
public class ODataError {
|
||||
|
||||
String code;
|
||||
String message;
|
||||
String target;
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
public String getCode() {
|
||||
return 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.
|
||||
* @param code
|
||||
* @return this for method chaining
|
||||
*/
|
||||
public ODataError setCode(String code) {
|
||||
this.code = code;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
|
@ -19,6 +19,7 @@
|
|||
package org.apache.olingo.server.api.serializer;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.olingo.commons.api.data.ContextURL;
|
||||
import org.apache.olingo.commons.api.data.Entity;
|
||||
|
@ -38,4 +39,12 @@ 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
|
||||
* @param details a list of details. MAY be null or empty.
|
||||
* @return inputStream containing the OData formatted error
|
||||
*/
|
||||
InputStream error(ODataError error, List<ODataError> details);
|
||||
}
|
||||
|
|
|
@ -69,6 +69,11 @@
|
|||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-simple</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
package org.apache.olingo.server.core.serializer;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
|
||||
import javax.xml.stream.XMLOutputFactory;
|
||||
import javax.xml.stream.XMLStreamException;
|
||||
|
@ -31,6 +32,7 @@ import org.apache.olingo.commons.api.data.EntitySet;
|
|||
import org.apache.olingo.commons.api.edm.Edm;
|
||||
import org.apache.olingo.commons.api.edm.EdmEntitySet;
|
||||
import org.apache.olingo.commons.api.edm.EdmEntityType;
|
||||
import org.apache.olingo.server.api.serializer.ODataError;
|
||||
import org.apache.olingo.server.api.serializer.ODataSerializer;
|
||||
import org.apache.olingo.server.core.serializer.utils.CircleStreamBuffer;
|
||||
import org.apache.olingo.server.core.serializer.xml.MetadataDocumentXmlSerializer;
|
||||
|
@ -86,4 +88,9 @@ public class ODataXmlSerializerImpl implements ODataSerializer {
|
|||
throw new ODataRuntimeException("Entityset serialization not implemented for XML format");
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream error(ODataError error, List<ODataError> details) {
|
||||
throw new ODataRuntimeException("error serialization not implemented for XML format");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* 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 java.util.List;
|
||||
|
||||
import org.apache.olingo.commons.api.ODataRuntimeException;
|
||||
import org.apache.olingo.server.api.serializer.ODataError;
|
||||
|
||||
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, List<ODataError> details) throws IOException {
|
||||
if (error == null) {
|
||||
throw new ODataRuntimeException("ODataError object MUST NOT be null!");
|
||||
}
|
||||
json.writeStartObject();
|
||||
json.writeFieldName(ERROR);
|
||||
|
||||
json.writeStartObject();
|
||||
writeODataError(json, error);
|
||||
|
||||
if(details != null){
|
||||
json.writeArrayFieldStart(DETAILS);
|
||||
for(ODataError detailedError : details){
|
||||
json.writeStartObject();
|
||||
writeODataError(json, detailedError);
|
||||
json.writeEndObject();
|
||||
}
|
||||
json.writeEndArray();
|
||||
}
|
||||
|
||||
json.writeEndObject();
|
||||
json.writeEndObject();
|
||||
}
|
||||
|
||||
private void writeODataError(JsonGenerator json, ODataError error) throws IOException, JsonGenerationException {
|
||||
if (error.getCode() == null) {
|
||||
json.writeNullField(CODE);
|
||||
} else {
|
||||
json.writeStringField(CODE, error.getCode());
|
||||
}
|
||||
if (error.getMessage() == null) {
|
||||
json.writeNullField(MESSAGE);
|
||||
} else {
|
||||
json.writeStringField(MESSAGE, error.getMessage());
|
||||
}
|
||||
|
||||
if (error.getTarget() != null) {
|
||||
json.writeStringField(TARGET, error.getTarget());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -26,6 +26,7 @@ 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.core.edm.primitivetype.EdmPrimitiveTypeFactory;
|
||||
import org.apache.olingo.server.api.serializer.ODataError;
|
||||
import org.apache.olingo.server.api.serializer.ODataSerializer;
|
||||
import org.apache.olingo.server.core.serializer.utils.CircleStreamBuffer;
|
||||
import org.slf4j.Logger;
|
||||
|
@ -172,7 +173,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 +181,7 @@ public class ODataJsonSerializer implements ODataSerializer {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private void writeCollection(EdmProperty edmProperty, Property property, JsonGenerator json)
|
||||
throws IOException, EdmPrimitiveTypeException {
|
||||
json.writeStartArray();
|
||||
|
@ -243,7 +245,7 @@ public class ODataJsonSerializer implements ODataSerializer {
|
|||
}
|
||||
|
||||
private void writeComplexValue(final EdmProperty edmProperty, final List<Property> 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 +263,18 @@ public class ODataJsonSerializer implements ODataSerializer {
|
|||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream error(ODataError error, List<ODataError> details) {
|
||||
CircleStreamBuffer buffer = new CircleStreamBuffer();
|
||||
try {
|
||||
JsonGenerator json = new JsonFactory().createGenerator(buffer.getOutputStream());
|
||||
ODataErrorSerializer ser = new ODataErrorSerializer();
|
||||
ser.writeErrorDocument(json, error, details);
|
||||
json.close();
|
||||
} catch (final IOException e) {
|
||||
throw new ODataRuntimeException(e);
|
||||
}
|
||||
return buffer.getInputStream();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,134 @@
|
|||
/*
|
||||
* 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.format.ODataFormat;
|
||||
import org.apache.olingo.server.api.OData;
|
||||
import org.apache.olingo.server.api.serializer.ODataError;
|
||||
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, null);
|
||||
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, null);
|
||||
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, null);
|
||||
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, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void emptyDetailsList() throws Exception {
|
||||
ODataError error = new ODataError();
|
||||
error.setMessage("ErrorMessage");
|
||||
InputStream stream = ser.error(error, new ArrayList<ODataError>());
|
||||
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, null);
|
||||
String jsonString = IOUtils.toString(stream);
|
||||
assertEquals("{\"error\":{\"code\":null,\"message\":null}}", jsonString);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void singleDetailNothingSet() throws Exception {
|
||||
List<ODataError> details = new ArrayList<ODataError>();
|
||||
details.add(new ODataError());
|
||||
ODataError error = new ODataError();
|
||||
InputStream stream = ser.error(error, details);
|
||||
String jsonString = IOUtils.toString(stream);
|
||||
assertEquals("{\"error\":{\"code\":null,\"message\":null,\"details\":[{\"code\":null,\"message\":null}]}}",
|
||||
jsonString);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void verifiedWithJacksonParser() throws Exception {
|
||||
List<ODataError> details = new ArrayList<ODataError>();
|
||||
details.add(new ODataError().setCode("detailCode").setMessage("detailMessage").setTarget("detailTarget"));
|
||||
ODataError error = new ODataError().setCode("Code").setMessage("Message").setTarget("Target");
|
||||
InputStream stream = ser.error(error, details);
|
||||
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());
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue