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 * DeleteProperty 11.4.9.2
* @param request * @param request
* @param property - Updated property. * @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 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 entityETag - entity tag to match before update operation, "*" allows all.
* @param response * @param response
* @throws ODataLibraryException * @throws ODataLibraryException
* @throws ODataApplicationException * @throws ODataApplicationException
*/ */
void updateProperty(DataRequest request, Property property, boolean merge, String entityETag, void updateProperty(DataRequest request, Property property, boolean rawValue,
PropertyResponse response) throws ODataLibraryException, ODataApplicationException; boolean merge, String entityETag, PropertyResponse response)
throws ODataLibraryException, ODataApplicationException;
/** /**
* Update Stream property, if StreamContent is null, it should treated as delete request * 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 @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, String entityETag, PropertyResponse response) throws ODataLibraryException,
ODataApplicationException { ODataApplicationException {
if (property.isPrimitive()) { if (property.isPrimitive()) {

View File

@ -574,14 +574,14 @@ public class DataRequest extends ServiceRequest {
handler.read(DataRequest.this, buildResponse(response, edmProperty)); handler.read(DataRequest.this, buildResponse(response, edmProperty));
} }
} else if (isPATCH()) { } else if (isPATCH()) {
handler.updateProperty(DataRequest.this, getPropertyValueFromClient(edmProperty), true, handler.updateProperty(DataRequest.this, getPropertyValueFromClient(edmProperty), false, true,
getETag(), buildResponse(response, edmProperty)); getETag(), buildResponse(response, edmProperty));
} else if (isPUT()) { } else if (isPUT()) {
if (isPropertyStream()) { if (isPropertyStream()) {
handler.upsertStreamProperty(DataRequest.this, getETag(), request.getBody(), handler.upsertStreamProperty(DataRequest.this, getETag(), request.getBody(),
new NoContentResponse(getServiceMetaData(), response)); new NoContentResponse(getServiceMetaData(), response));
} else { } else {
handler.updateProperty(DataRequest.this, getPropertyValueFromClient(edmProperty), false, handler.updateProperty(DataRequest.this, getPropertyValueFromClient(edmProperty), false, false,
getETag(), buildResponse(response, edmProperty)); getETag(), buildResponse(response, edmProperty));
} }
} else if (isDELETE()) { } else if (isDELETE()) {
@ -591,7 +591,7 @@ public class DataRequest extends ServiceRequest {
} else { } else {
Property property = new Property(edmProperty.getType().getFullQualifiedName() Property property = new Property(edmProperty.getType().getFullQualifiedName()
.getFullQualifiedNameAsString(), edmProperty.getName()); .getFullQualifiedNameAsString(), edmProperty.getName());
handler.updateProperty(DataRequest.this, property, false, getETag(), handler.updateProperty(DataRequest.this, property, false, false, getETag(),
buildResponse(response, edmProperty)); buildResponse(response, edmProperty));
} }
} }
@ -679,7 +679,7 @@ public class DataRequest extends ServiceRequest {
edmProperty.getName()); edmProperty.getName());
PropertyResponse propertyResponse = PropertyResponse.getInstance(DataRequest.this, response, PropertyResponse propertyResponse = PropertyResponse.getInstance(DataRequest.this, response,
edmProperty.getType(), getContextURL(odata), edmProperty.isCollection()); 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()) { } else if (isPUT()) {
PropertyResponse propertyResponse = PropertyResponse.getInstance(DataRequest.this, response, PropertyResponse propertyResponse = PropertyResponse.getInstance(DataRequest.this, response,
edmProperty.getType(), getContextURL(odata), edmProperty.isCollection()); edmProperty.getType(), getContextURL(odata), edmProperty.isCollection());
@ -687,7 +687,7 @@ public class DataRequest extends ServiceRequest {
edmProperty.getType().getFullQualifiedName().getFullQualifiedNameAsString(), edmProperty.getType().getFullQualifiedName().getFullQualifiedNameAsString(),
edmProperty.getName()); edmProperty.getName());
property.setValue(ValueType.PRIMITIVE, getRawValueFromClient()); property.setValue(ValueType.PRIMITIVE, getRawValueFromClient());
handler.updateProperty(DataRequest.this, property, false, handler.updateProperty(DataRequest.this, property, true, false,
getETag(), propertyResponse); getETag(), propertyResponse);
} }
} }

View File

@ -53,11 +53,15 @@ public class PropertyResponse extends ServiceResponse {
SerializerException { SerializerException {
ContentType type = request.getResponseContentType(); 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; ODataSerializer serializer = null;
if (type.equals(ContentType.TEXT_PLAIN)) { try {
serializer = request.getSerializer(ContentType.APPLICATION_JSON);
} else {
serializer = request.getSerializer(); serializer = request.getSerializer();
} catch (SerializerException e) {
serializer = request.getSerializer(ContentType.APPLICATION_JSON);
} }
if (edmType.getKind() == EdmTypeKind.PRIMITIVE) { 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.EntityCollection;
import org.apache.olingo.commons.api.data.Link; import org.apache.olingo.commons.api.data.Link;
import org.apache.olingo.commons.api.data.Property; 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.EdmAction;
import org.apache.olingo.commons.api.edm.EdmEntitySet; import org.apache.olingo.commons.api.edm.EdmEntitySet;
import org.apache.olingo.commons.api.edm.EdmEntityType; import org.apache.olingo.commons.api.edm.EdmEntityType;
@ -318,10 +319,16 @@ public class TripPinHandler implements ServiceHandler {
} }
@Override @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, String entityETag, PropertyResponse response) throws ODataLibraryException,
ODataApplicationException { 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(); EdmEntitySet edmEntitySet = request.getEntitySet();
Entity entity = this.dataModel.getEntity(edmEntitySet.getName(), request.getKeyPredicates()); Entity entity = this.dataModel.getEntity(edmEntitySet.getName(), request.getKeyPredicates());
if (entity == null) { if (entity == null) {

View File

@ -209,10 +209,13 @@ public class TripPinServiceTest {
// Note that in-real services must convert raw value (byte[]) to // Note that in-real services must convert raw value (byte[]) to
// the data type it needs to save in in updateProperty method // the data type it needs to save in in updateProperty method
String editUrl = baseURL + "/Airlines('AF')/Name/$value"; String editUrl = baseURL + "/Airlines('AF')/Name/$value";
HttpPut request = new HttpPut(editUrl); HttpPut put = new HttpPut(editUrl);
request.setEntity(new StringEntity("Safari")); put.setEntity(new StringEntity("Safari"));
HttpResponse response = httpSend(request, 204); HttpResponse response = httpSend(put, 204);
EntityUtils.consumeQuietly(response.getEntity()); EntityUtils.consumeQuietly(response.getEntity());
response = httpGET(baseURL + "/Airlines('AF')/Name/$value", 200);
assertEquals("Safari", IOUtils.toString(response.getEntity().getContent()));
} }
@Test @Ignore @Test @Ignore