OLINGO-911: Correcting request with PUT/DELETE verbs to correctly handle serialization and way notify the service about the raw value

This commit is contained in:
Ramesh Reddy 2016-03-18 09:38:26 -05:00
parent 11e040babc
commit 7d10c60c57
6 changed files with 33 additions and 15 deletions

View File

@ -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

View File

@ -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()) {

View File

@ -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);
}
}

View File

@ -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) {

View File

@ -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) {

View File

@ -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