From b78343bd09e6b73bd6777c4ae90971dd109a6fcb Mon Sep 17 00:00:00 2001 From: Ramesh Reddy Date: Mon, 27 Apr 2015 11:16:34 -0500 Subject: [PATCH] OLINGO-573: validating to make sure key predicates are supplied for update, delete entity requests --- .../server/core/requests/DataRequest.java | 5 +++ .../server/example/TripPinDataModel.java | 42 +++++++++++++++++++ .../olingo/server/example/TripPinHandler.java | 20 ++++++++- .../server/example/TripPinServiceTest.java | 27 ++++++++++++ 4 files changed, 92 insertions(+), 2 deletions(-) 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 b3be91c15..98daf7a00 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 @@ -273,6 +273,11 @@ public class DataRequest extends ServiceRequest { return false; } + // in update, delete entity cases, predicate must be there + if ((isPATCH() || isPUT() || isDELETE()) + && (getKeyPredicates() == null || getKeyPredicates().isEmpty())) { + return false; + } return true; } diff --git a/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinDataModel.java b/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinDataModel.java index 78bd012a5..290f38d5c 100644 --- a/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinDataModel.java +++ b/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinDataModel.java @@ -630,6 +630,48 @@ public class TripPinDataModel { return copy; } + public boolean updateEntity(EdmEntitySet edmEntitySet, String eTag, String key, Object keyValue, + boolean merge, Entity changes, String baseURL) throws ODataApplicationException { + boolean updated = false; + + if (merge) { + EntityCollection set = getEntitySet(edmEntitySet.getName()); + Iterator it = set.getEntities().iterator(); + while (it.hasNext()) { + Entity entity = it.next(); + if (entity.getProperty(key).getValue().equals(keyValue) && eTag.equals("*") + || eTag.equals(entity.getETag())) { + + for (Property p :changes.getProperties()) { + for (Property p1: entity.getProperties()) { + if (p.getName().equals(p1.getName())) { + p1.setValue(p1.getValueType(), p.getValue()); + updated = true; + break; + } + } + } + break; + } + } + } else { + // this is delete, then insert + EntityCollection set = getEntitySet(edmEntitySet.getName()); + Iterator it = set.getEntities().iterator(); + while (it.hasNext()) { + Entity entity = it.next(); + if (entity.getProperty(key).getValue().equals(keyValue) && eTag.equals("*") + || eTag.equals(entity.getETag())) { + Property p = entity.getProperty(key); + changes.addProperty(p); + createEntity(edmEntitySet, changes, baseURL); + updated = true; + } + } + } + return updated; + } + public boolean deleteEntity(String entitySetName, String eTag, String key, Object keyValue) { EntityCollection set = getEntitySet(entitySetName); Iterator it = set.getEntities().iterator(); 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 c180a0692..df2b645b5 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 @@ -273,9 +273,25 @@ public class TripPinHandler implements ServiceHandler { } @Override - public void updateEntity(DataRequest request, Entity entity, boolean merge, String entityETag, + public void updateEntity(DataRequest request, Entity entity, boolean merge, String eTag, EntityResponse response) throws ODataTranslatedException, ODataApplicationException { - response.writeServerError(true); + EdmEntitySet edmEntitySet = request.getEntitySet(); + + Entity currentEntity = this.dataModel.getEntity(edmEntitySet.getName(), request.getKeyPredicates()); + if (currentEntity == null) { + response.writeNotFound(true); + return; + } + String key = edmEntitySet.getEntityType().getKeyPredicateNames().get(0); + String baseURL = request.getODataRequest().getRawBaseUri(); + boolean updated = this.dataModel.updateEntity(edmEntitySet, eTag, key, currentEntity + .getProperty(key).getValue(), merge, entity, baseURL); + + if (updated) { + response.writeUpdatedEntity(); + } else { + response.writeNotModified(); + } } @Override 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 c64bfb575..9476f0987 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 @@ -34,6 +34,7 @@ import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpDelete; import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPatch; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpPut; import org.apache.http.entity.ByteArrayEntity; @@ -418,6 +419,32 @@ public class TripPinServiceTest { EntityUtils.consumeQuietly(response.getEntity()); } + @Test + public void testUpdateEntity() throws Exception { + String payload = "{" + + " \"Emails\":[" + + " \"Krista@example.com\"," + + " \"Krista@gmail.com\"" + + " ]" + + "}"; + HttpPatch updateRequest = new HttpPatch(baseURL+"/People('kristakemp')"); + updateRequest.setEntity(new StringEntity(payload, ContentType.APPLICATION_JSON)); + httpSend(updateRequest, 204); + + HttpResponse response = httpGET(baseURL + "/People('kristakemp')", 200); + JsonNode node = getJSONNode(response); + assertEquals("$metadata#People/$entity", node.get("@odata.context").asText()); + assertEquals("Krista@example.com", node.get("Emails").get(0).asText()); + assertEquals("Krista@gmail.com", node.get("Emails").get(1).asText()); + } + + @Test + public void testDeleteEntity() throws Exception{ + // fail because no key predicates supplied + HttpDelete deleteRequest = new HttpDelete(baseURL+"/People"); + HttpResponse response = httpSend(deleteRequest, 405); + EntityUtils.consumeQuietly(response.getEntity()); + } @Test public void testCreateEntityWithLinkToRelatedEntities() throws Exception {