diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ServiceHandler.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ServiceHandler.java index 8f8fc1dbd..77e1cfe3d 100644 --- a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ServiceHandler.java +++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ServiceHandler.java @@ -134,14 +134,18 @@ public interface ServiceHandler extends Processor { * DeleteProperty 11.4.9.2 * @param request * @param property - Updated property. + * @param rawValue - $value based call, where property value provided is in byte[] format. + * user must convert the value to correct datatype format before update. + * The semantics of conversion are not defined. * @param merge - if the property is complex, true here means merge, false is replace * @param entityETag - entity tag to match before update operation, "*" allows all. * @param response * @throws ODataLibraryException * @throws ODataApplicationException */ - void updateProperty(DataRequest request, Property property, boolean merge, String entityETag, - PropertyResponse response) throws ODataLibraryException, ODataApplicationException; + void updateProperty(DataRequest request, Property property, boolean rawValue, + boolean merge, String entityETag, PropertyResponse response) + throws ODataLibraryException, ODataApplicationException; /** * Update Stream property, if StreamContent is null, it should treated as delete request diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/legacy/ProcessorServiceHandler.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/legacy/ProcessorServiceHandler.java index d4d0662ff..de5843c23 100644 --- a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/legacy/ProcessorServiceHandler.java +++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/legacy/ProcessorServiceHandler.java @@ -228,7 +228,7 @@ public class ProcessorServiceHandler implements ServiceHandler { } @Override - public void updateProperty(DataRequest request, Property property, boolean merge, + public void updateProperty(DataRequest request, Property property, boolean rawValue, boolean merge, String entityETag, PropertyResponse response) throws ODataLibraryException, ODataApplicationException { if (property.isPrimitive()) { diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/DataRequest.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/DataRequest.java index fecc8b80e..de26be071 100644 --- a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/DataRequest.java +++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/DataRequest.java @@ -574,14 +574,14 @@ public class DataRequest extends ServiceRequest { handler.read(DataRequest.this, buildResponse(response, edmProperty)); } } else if (isPATCH()) { - handler.updateProperty(DataRequest.this, getPropertyValueFromClient(edmProperty), true, + handler.updateProperty(DataRequest.this, getPropertyValueFromClient(edmProperty), false, true, getETag(), buildResponse(response, edmProperty)); } else if (isPUT()) { if (isPropertyStream()) { handler.upsertStreamProperty(DataRequest.this, getETag(), request.getBody(), new NoContentResponse(getServiceMetaData(), response)); } else { - handler.updateProperty(DataRequest.this, getPropertyValueFromClient(edmProperty), false, + handler.updateProperty(DataRequest.this, getPropertyValueFromClient(edmProperty), false, false, getETag(), buildResponse(response, edmProperty)); } } else if (isDELETE()) { @@ -591,7 +591,7 @@ public class DataRequest extends ServiceRequest { } else { Property property = new Property(edmProperty.getType().getFullQualifiedName() .getFullQualifiedNameAsString(), edmProperty.getName()); - handler.updateProperty(DataRequest.this, property, false, getETag(), + handler.updateProperty(DataRequest.this, property, false, false, getETag(), buildResponse(response, edmProperty)); } } @@ -679,7 +679,7 @@ public class DataRequest extends ServiceRequest { edmProperty.getName()); PropertyResponse propertyResponse = PropertyResponse.getInstance(DataRequest.this, response, edmProperty.getType(), getContextURL(odata), edmProperty.isCollection()); - handler.updateProperty(DataRequest.this, property, false, getETag(), propertyResponse); + handler.updateProperty(DataRequest.this, property, true, false, getETag(), propertyResponse); } else if (isPUT()) { PropertyResponse propertyResponse = PropertyResponse.getInstance(DataRequest.this, response, edmProperty.getType(), getContextURL(odata), edmProperty.isCollection()); @@ -687,7 +687,7 @@ public class DataRequest extends ServiceRequest { edmProperty.getType().getFullQualifiedName().getFullQualifiedNameAsString(), edmProperty.getName()); property.setValue(ValueType.PRIMITIVE, getRawValueFromClient()); - handler.updateProperty(DataRequest.this, property, false, + handler.updateProperty(DataRequest.this, property, true, false, getETag(), propertyResponse); } } diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/PropertyResponse.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/PropertyResponse.java index 290abb5fc..7bb2c2458 100644 --- a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/PropertyResponse.java +++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/PropertyResponse.java @@ -53,11 +53,15 @@ public class PropertyResponse extends ServiceResponse { SerializerException { ContentType type = request.getResponseContentType(); + + // this is special case to allow $value based PUT/DELETE, which do not really + // need a serializer but request comes in with text/plain content type and there + // is no serializer for that. ODataSerializer serializer = null; - if (type.equals(ContentType.TEXT_PLAIN)) { - serializer = request.getSerializer(ContentType.APPLICATION_JSON); - } else { + try { serializer = request.getSerializer(); + } catch (SerializerException e) { + serializer = request.getSerializer(ContentType.APPLICATION_JSON); } if (edmType.getKind() == EdmTypeKind.PRIMITIVE) { diff --git a/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinHandler.java b/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinHandler.java index c2ca7a696..b83c0e4d8 100644 --- a/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinHandler.java +++ b/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinHandler.java @@ -30,6 +30,7 @@ import org.apache.olingo.commons.api.data.Entity; import org.apache.olingo.commons.api.data.EntityCollection; import org.apache.olingo.commons.api.data.Link; import org.apache.olingo.commons.api.data.Property; +import org.apache.olingo.commons.api.data.ValueType; import org.apache.olingo.commons.api.edm.EdmAction; import org.apache.olingo.commons.api.edm.EdmEntitySet; import org.apache.olingo.commons.api.edm.EdmEntityType; @@ -318,10 +319,16 @@ public class TripPinHandler implements ServiceHandler { } @Override - public void updateProperty(DataRequest request, final Property property, boolean merge, + public void updateProperty(DataRequest request, final Property property, boolean rawValue, boolean merge, String entityETag, PropertyResponse response) throws ODataLibraryException, ODataApplicationException { + if (rawValue && property.getValue() != null) { + // this is more generic, stricter conversion rules must taken in a real service + byte[] value = (byte[])property.getValue(); + property.setValue(ValueType.PRIMITIVE, new String(value)); + } + EdmEntitySet edmEntitySet = request.getEntitySet(); Entity entity = this.dataModel.getEntity(edmEntitySet.getName(), request.getKeyPredicates()); if (entity == null) { diff --git a/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinServiceTest.java b/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinServiceTest.java index 048643940..eb2384b6e 100644 --- a/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinServiceTest.java +++ b/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinServiceTest.java @@ -209,10 +209,13 @@ public class TripPinServiceTest { // Note that in-real services must convert raw value (byte[]) to // the data type it needs to save in in updateProperty method String editUrl = baseURL + "/Airlines('AF')/Name/$value"; - HttpPut request = new HttpPut(editUrl); - request.setEntity(new StringEntity("Safari")); - HttpResponse response = httpSend(request, 204); + HttpPut put = new HttpPut(editUrl); + put.setEntity(new StringEntity("Safari")); + HttpResponse response = httpSend(put, 204); EntityUtils.consumeQuietly(response.getEntity()); + + response = httpGET(baseURL + "/Airlines('AF')/Name/$value", 200); + assertEquals("Safari", IOUtils.toString(response.getEntity().getContent())); } @Test @Ignore