[OLINGO-1442]Support update requests on Stream properties
diff --git a/fit/src/test/java/org/apache/olingo/fit/tecsvc/http/BasicStreamITCase.java b/fit/src/test/java/org/apache/olingo/fit/tecsvc/http/BasicStreamITCase.java
index 697c970..dd1819a 100644
--- a/fit/src/test/java/org/apache/olingo/fit/tecsvc/http/BasicStreamITCase.java
+++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/http/BasicStreamITCase.java
@@ -21,6 +21,10 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.io.BufferedOutputStream;
+import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
@@ -310,6 +314,33 @@
+ "{\"@id\":\"ESWithStream(7)\"}]}"));
}
+ @Test
+ public void putRequestOnStreamProperty() throws Exception {
+ URL url = new URL(SERVICE_URI + "ESWithStream(7)/PropertyStream");
+
+ HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+ connection.setRequestMethod(HttpMethod.PUT.name());
+ connection.setRequestProperty(HttpHeader.CONTENT_TYPE, "image/jpeg");
+ connection.setRequestProperty(HttpHeader.IF_MATCH, "*");
+ connection.setRequestProperty(HttpHeader.ACCEPT, "application/json");
+ InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream("sample.png");
+ byte[] bytes = IOUtils.toByteArray(in);
+ connection.setDoOutput(true);
+ BufferedOutputStream out = new BufferedOutputStream(connection.getOutputStream());
+ try {
+ out.write(bytes, 0, bytes.length);
+ out.flush();
+ } finally {
+ out.close();
+ }
+ connection.connect();
+
+ assertEquals(HttpStatusCode.OK.getStatusCode(), connection.getResponseCode());
+ assertEquals(ContentType.parse("image/jpeg"),
+ ContentType.create(connection.getHeaderField(HttpHeader.CONTENT_TYPE)));
+ assertEquals(bytes.length, IOUtils.toByteArray(connection.getInputStream()).length);
+ }
+
@Override
protected ODataClient getClient() {
return null;
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataDispatcher.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataDispatcher.java
index 9d0bc67..985bee6 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataDispatcher.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataDispatcher.java
@@ -83,6 +83,7 @@
private final ODataHandlerImpl handler;
private static final String RETURN_MINIMAL = "return=minimal";
private static final String RETURN_REPRESENTATION = "return=representation";
+ private static final String EDMSTREAM = "Edm.Stream";
public ODataDispatcher(final UriInfo uriInfo, final ODataHandlerImpl handler) {
this.uriInfo = uriInfo;
@@ -458,8 +459,17 @@
}
} else if (method == HttpMethod.PUT || method == HttpMethod.PATCH) {
validatePreconditions(request, false);
- final ContentType requestFormat = getSupportedContentType(request.getHeader(HttpHeader.CONTENT_TYPE),
- representationType, true);
+ ContentType requestFormat = null;
+ List<UriResource> uriResources = uriInfo.getUriResourceParts();
+ UriResource uriResource = uriResources.get(uriResources.size() - 1);
+ if (uriResource instanceof UriResourcePrimitiveProperty &&
+ ((UriResourcePrimitiveProperty)uriResource).getType()
+ .getFullQualifiedName().getFullQualifiedNameAsString().equalsIgnoreCase(EDMSTREAM)) {
+ requestFormat = ContentType.parse(request.getHeader(HttpHeader.CONTENT_TYPE));
+ } else {
+ requestFormat = getSupportedContentType(request.getHeader(HttpHeader.CONTENT_TYPE),
+ representationType, true);
+ }
final ContentType responseFormat = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(),
request, handler.getCustomContentTypeSupport(), representationType);
if (isCollection) {
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalPrimitiveComplexProcessor.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalPrimitiveComplexProcessor.java
index d3983a3..2565555 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalPrimitiveComplexProcessor.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalPrimitiveComplexProcessor.java
@@ -86,7 +86,7 @@
PrimitiveCollectionProcessor, CountPrimitiveCollectionProcessor,
ComplexProcessor, ComplexCollectionProcessor, CountComplexCollectionProcessor {
- private static final Object EDMSTREAM = "Edm.Stream";
+ private static final String EDMSTREAM = "Edm.Stream";
public TechnicalPrimitiveComplexProcessor(final DataProvider dataProvider,
final ServiceMetadata serviceMetadata) {
@@ -334,9 +334,12 @@
Property property = getPropertyData(entity, path);
- if (representationType == RepresentationType.VALUE) {
+ if (representationType == RepresentationType.VALUE ||
+ edmProperty.getType().getFullQualifiedName()
+ .getFullQualifiedNameAsString().equalsIgnoreCase(EDMSTREAM)) {
final FixedFormatDeserializer deserializer = odata.createFixedFormatDeserializer();
- final Object value = edmProperty.getType() == odata.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Binary) ?
+ final Object value = edmProperty.getType() == odata.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Binary)
+ || edmProperty.getType() == odata.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Stream) ?
deserializer.binary(request.getBody()) :
deserializer.primitiveValue(request.getBody(), edmProperty);
dataProvider.updatePropertyValue(property, value);
@@ -354,7 +357,9 @@
final Return returnPreference = odata.createPreferences(request.getHeaders(HttpHeader.PREFER)).getReturn();
if (returnPreference == null || returnPreference == Return.REPRESENTATION) {
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
- if (representationType == RepresentationType.VALUE) {
+ if (representationType == RepresentationType.VALUE ||
+ edmProperty.getType().getFullQualifiedName()
+ .getFullQualifiedNameAsString().equalsIgnoreCase(EDMSTREAM)) {
response.setContent(
serializePrimitiveValue(property, edmProperty, (EdmPrimitiveType) edmProperty.getType(), null));
} else {
@@ -362,7 +367,12 @@
edmProperty.getType(), null, representationType, responseFormat, null, null);
response.setContent(result.getContent());
}
- response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
+ if (edmProperty.getType().getFullQualifiedName()
+ .getFullQualifiedNameAsString().equalsIgnoreCase(EDMSTREAM)) {
+ response.setHeader(HttpHeader.CONTENT_TYPE, requestFormat.toContentTypeString());
+ } else {
+ response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
+ }
} else {
response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
}
@@ -519,7 +529,8 @@
private InputStream serializePrimitiveValue(final Property property, final EdmProperty edmProperty,
final EdmPrimitiveType type, final EdmReturnType returnType) throws SerializerException {
final FixedFormatSerializer serializer = odata.createFixedFormatSerializer();
- return type == odata.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Binary) ?
+ return type == odata.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Binary) ||
+ type == odata.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Stream) ?
serializer.binary((byte[]) property.getValue()) :
serializer.primitiveValue(type, property.getValue(),
PrimitiveValueSerializerOptions.with()