[OLINGO-663] Set ETags in technical service Change-Id: I92eccdbff85fb1afcd91e609cb232f723f81580e
Signed-off-by: Christian Amend <[email protected]> Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/bec8cb3b Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/bec8cb3b Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/bec8cb3b Branch: refs/heads/master Commit: bec8cb3b2a0f561fe2d8313e77abec98ffbb299d Parents: 1a9cff2 Author: Klaus Straubinger <[email protected]> Authored: Tue May 19 10:18:10 2015 +0200 Committer: Christian Amend <[email protected]> Committed: Tue May 19 10:39:00 2015 +0200 ---------------------------------------------------------------------- .../olingo/fit/tecsvc/client/MediaITCase.java | 4 ++ .../olingo/server/tecsvc/data/DataCreator.java | 7 +++ .../olingo/server/tecsvc/data/DataProvider.java | 45 +++++++++++--------- .../processor/TechnicalEntityProcessor.java | 18 ++++++++ .../json/ODataJsonSerializerTest.java | 14 +++--- 5 files changed, 60 insertions(+), 28 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/bec8cb3b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/MediaITCase.java ---------------------------------------------------------------------- diff --git a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/MediaITCase.java b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/MediaITCase.java index 92336fd..e48f08c 100644 --- a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/MediaITCase.java +++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/MediaITCase.java @@ -20,6 +20,7 @@ package org.apache.olingo.fit.tecsvc.client; import static org.hamcrest.CoreMatchers.startsWith; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertThat; import static org.junit.Assert.fail; @@ -62,6 +63,7 @@ public final class MediaITCase extends AbstractBaseTestITCase { final ODataRetrieveResponse<InputStream> response = request.execute(); assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode()); assertEquals("image/svg+xml", response.getContentType()); + assertEquals("W/\"1\"", response.getETag()); InputStream media = response.getBody(); assertNotNull(media); @@ -113,6 +115,8 @@ public final class MediaITCase extends AbstractBaseTestITCase { assertEquals(HttpStatusCode.OK.getStatusCode(), mediaResponse.getStatusCode()); assertEquals(ContentType.TEXT_PLAIN.toContentTypeString(), mediaResponse.getContentType()); assertEquals("just a test", IOUtils.toString(mediaResponse.getBody())); + assertNotNull(mediaResponse.getETag()); + assertNotEquals("W/\"4\"", mediaResponse.getETag()); } @Test http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/bec8cb3b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataCreator.java ---------------------------------------------------------------------- diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataCreator.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataCreator.java index 81db468..9bc1eb8 100644 --- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataCreator.java +++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataCreator.java @@ -298,6 +298,7 @@ public class DataCreator { createPrimitive("PropertyGuid", GUID), createPrimitive("PropertyInt16", Short.MAX_VALUE), createPrimitive("PropertyInt32", Integer.MAX_VALUE), createPrimitive("PropertyInt64", Long.MAX_VALUE), createPrimitive("PropertySByte", Byte.MAX_VALUE), createPrimitive("PropertyTimeOfDay", getTime(1, 0, 1)))); + entity.setETag("W/\"" + Short.MAX_VALUE + '\"'); entitySet.getEntities().add(entity); entity = new Entity(); @@ -314,6 +315,7 @@ public class DataCreator { createPrimitive("PropertyInt32", Integer.MAX_VALUE), createPrimitive("PropertyInt64", Long.MAX_VALUE), createPrimitive("PropertySByte", Byte.MAX_VALUE), createPrimitive("PropertyTimeOfDay", getTimestamp(1, 1, 1, 7, 45, 12, 765432100)))); + entity.setETag("W/\"7\""); entitySet.getEntities().add(entity); entity = new Entity(); @@ -329,6 +331,7 @@ public class DataCreator { createPrimitive("PropertyGuid", GUID), createPrimitive("PropertyInt16", -25), createPrimitive("PropertyInt32", Integer.MAX_VALUE), createPrimitive("PropertyInt64", Long.MAX_VALUE), createPrimitive("PropertySByte", Byte.MAX_VALUE), createPrimitive("PropertyTimeOfDay", getTime(13, 27, 45)))); + entity.setETag("W/\"0\""); entitySet.getEntities().add(entity); return entitySet; @@ -463,21 +466,25 @@ public class DataCreator { Entity entity = new Entity().addProperty(createPrimitive("PropertyInt16", 1)) .addProperty(createPrimitive(DataProvider.MEDIA_PROPERTY_NAME, createImage("darkturquoise"))); entity.setMediaContentType("image/svg+xml"); + entity.setMediaETag("W/\"1\""); entitySet.getEntities().add(entity); entity = new Entity().addProperty(createPrimitive("PropertyInt16", 2)) .addProperty(createPrimitive(DataProvider.MEDIA_PROPERTY_NAME, createImage("royalblue"))); entity.setMediaContentType("image/svg+xml"); + entity.setMediaETag("W/\"2\""); entitySet.getEntities().add(entity); entity = new Entity().addProperty(createPrimitive("PropertyInt16", 3)) .addProperty(createPrimitive(DataProvider.MEDIA_PROPERTY_NAME, createImage("crimson"))); entity.setMediaContentType("image/svg+xml"); + entity.setMediaETag("W/\"3\""); entitySet.getEntities().add(entity); entity = new Entity().addProperty(createPrimitive("PropertyInt16", 4)) .addProperty(createPrimitive(DataProvider.MEDIA_PROPERTY_NAME, createImage("black"))); entity.setMediaContentType("image/svg+xml"); + entity.setMediaETag("W/\"4\""); entitySet.getEntities().add(entity); return entitySet; http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/bec8cb3b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataProvider.java ---------------------------------------------------------------------- diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataProvider.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataProvider.java index f682cfb..9bad1ed 100644 --- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataProvider.java +++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataProvider.java @@ -56,7 +56,7 @@ public class DataProvider { protected static final String MEDIA_PROPERTY_NAME = "$value"; - final private Map<String, EntityCollection> data; + private Map<String, EntityCollection> data; private Edm edm; private OData odata; @@ -64,6 +64,14 @@ public class DataProvider { data = new DataCreator().getData(); } + public void setEdm(final Edm edm) { + this.edm = edm; + } + + public void setOData(final OData odata) { + this.odata = odata; + } + public EntityCollection readAll(final EdmEntitySet edmEntitySet) throws DataProviderException { return data.get(edmEntitySet.getName()); } @@ -73,9 +81,8 @@ public class DataProvider { return entitySet == null ? null : read(edmEntitySet.getEntityType(), entitySet, keys); } - public Entity - read(final EdmEntityType edmEntityType, final EntityCollection entitySet, final List<UriParameter> keys) - throws DataProviderException { + public Entity read(final EdmEntityType edmEntityType, final EntityCollection entitySet, + final List<UriParameter> keys) throws DataProviderException { try { for (final Entity entity : entitySet.getEntities()) { boolean found = true; @@ -134,7 +141,7 @@ public class DataProvider { final EntityCollection entitySet = readAll(edmEntitySet); final List<Entity> entities = entitySet.getEntities(); final Map<String, Object> newKey = findFreeComposedKey(entities, edmEntitySet.getEntityType()); - final Entity newEntity = new Entity(); + Entity newEntity = new Entity(); newEntity.setType(edmEntityType.getFullQualifiedName().getFullQualifiedNameAsString()); for (final String keyName : edmEntityType.getKeyPredicateNames()) { newEntity.addProperty(DataCreator.createPrimitive(keyName, newKey.get(keyName))); @@ -226,7 +233,7 @@ public class DataProvider { return newProperty; } - public void update(final String rawBaseUri, final EdmEntitySet edmEntitySet, final Entity entity, + public void update(final String rawBaseUri, final EdmEntitySet edmEntitySet, Entity entity, final Entity changedEntity, final boolean patch, final boolean isInsert) throws DataProviderException { final EdmEntityType entityType = edmEntitySet.getEntityType(); @@ -256,11 +263,15 @@ public class DataProvider { } else { handleDeleteSingleNavigationProperties(edmEntitySet, entity, changedEntity); } + + // Update the ETag if present. + if (entity.getETag() != null) { + entity.setETag("W/\"" + System.nanoTime() + "\""); + } } private void handleDeleteSingleNavigationProperties(final EdmEntitySet edmEntitySet, final Entity entity, - final Entity changedEntity) - throws DataProviderException { + final Entity changedEntity) throws DataProviderException { final EdmEntityType entityType = edmEntitySet.getEntityType(); final List<String> navigationPropertyNames = entityType.getNavigationPropertyNames(); @@ -381,8 +392,8 @@ public class DataProvider { } } - private void - setLink(final EdmNavigationProperty navigationProperty, final Entity srcEntity, final Entity targetEntity) { + private void setLink(final EdmNavigationProperty navigationProperty, final Entity srcEntity, + final Entity targetEntity) { if (navigationProperty.isCollection()) { DataCreator.setLinks(srcEntity, navigationProperty.getName(), targetEntity); } else { @@ -475,6 +486,7 @@ public class DataProvider { entity.getProperties().remove(entity.getProperty(MEDIA_PROPERTY_NAME)); entity.addProperty(DataCreator.createPrimitive(MEDIA_PROPERTY_NAME, media)); entity.setMediaContentType(type); + entity.setMediaETag("W/\"" + System.nanoTime() + "\""); } public EntityCollection readFunctionEntitySet(final EdmFunction function, final List<UriParameter> parameters) @@ -517,20 +529,11 @@ public class DataProvider { return ActionData.entityAction(name, actionParameters); } - public EntityCollection - processActionEntityCollection(final String name, final Map<String, Parameter> actionParameters) - throws DataProviderException { + public EntityCollection processActionEntityCollection(final String name, + final Map<String, Parameter> actionParameters) throws DataProviderException { return ActionData.entityCollectionAction(name, actionParameters); } - public void setEdm(final Edm edm) { - this.edm = edm; - } - - public void setOData(final OData odata) { - this.odata = odata; - } - public static class DataProviderException extends ODataApplicationException { private static final long serialVersionUID = 5098059649321796156L; http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/bec8cb3b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java ---------------------------------------------------------------------- diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java index ac70879..535280b 100644 --- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java +++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java @@ -220,6 +220,9 @@ public class TechnicalEntityProcessor extends TechnicalProcessor .getContent()); response.setStatusCode(HttpStatusCode.OK.getStatusCode()); response.setHeader(HttpHeader.CONTENT_TYPE, requestedContentType.toContentTypeString()); + if (entity.getETag() != null) { + response.setHeader(HttpHeader.ETAG, entity.getETag()); + } } @Override @@ -230,6 +233,9 @@ public class TechnicalEntityProcessor extends TechnicalProcessor response.setContent(odata.createFixedFormatSerializer().binary(dataProvider.readMedia(entity))); response.setStatusCode(HttpStatusCode.OK.getStatusCode()); response.setHeader(HttpHeader.CONTENT_TYPE, entity.getMediaContentType()); + if (entity.getMediaETag() != null) { + response.setHeader(HttpHeader.ETAG, entity.getMediaETag()); + } } @Override @@ -279,6 +285,9 @@ public class TechnicalEntityProcessor extends TechnicalProcessor response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString()); response.setHeader(HttpHeader.LOCATION, request.getRawBaseUri() + '/' + odata.createUriHelper().buildCanonicalURL(edmEntitySet, entity)); + if (entity.getETag() != null) { + response.setHeader(HttpHeader.ETAG, entity.getETag()); + } } @Override @@ -319,6 +328,9 @@ public class TechnicalEntityProcessor extends TechnicalProcessor .getContent()); response.setStatusCode(HttpStatusCode.OK.getStatusCode()); response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString()); + if (entity.getETag() != null) { + response.setHeader(HttpHeader.ETAG, entity.getETag()); + } } @Override @@ -338,6 +350,9 @@ public class TechnicalEntityProcessor extends TechnicalProcessor .getContent()); response.setStatusCode(HttpStatusCode.OK.getStatusCode()); response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString()); + if (entity.getETag() != null) { + response.setHeader(HttpHeader.ETAG, entity.getETag()); + } } @Override @@ -377,6 +392,9 @@ public class TechnicalEntityProcessor extends TechnicalProcessor .getContent()); response.setStatusCode((entityResult.isCreated() ? HttpStatusCode.CREATED : HttpStatusCode.OK).getStatusCode()); response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString()); + if (entityResult.getEntity().getETag() != null) { + response.setHeader(HttpHeader.ETAG, entityResult.getEntity().getETag()); + } } } http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/bec8cb3b/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerTest.java ---------------------------------------------------------------------- diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerTest.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerTest.java index e182d15..2e42963 100644 --- a/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerTest.java +++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerTest.java @@ -232,6 +232,7 @@ public class ODataJsonSerializerTest { final String resultString = IOUtils.toString(result); final String expectedResult = "{" + "\"@odata.context\":\"$metadata#ESCompAllPrim/$entity\"," + + "\"@odata.etag\":\"W/\\\"32767\\\"\"," + "\"PropertyInt16\":32767," + "\"PropertyComp\":{" + "\"PropertyString\":\"First Resource - first\"," @@ -322,15 +323,14 @@ public class ODataJsonSerializerTest { @Test public void entityMedia() throws Exception { final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESMedia"); - Entity entity = data.readAll(edmEntitySet).getEntities().get(0); - entity.setMediaETag("theMediaETag"); + final Entity entity = data.readAll(edmEntitySet).getEntities().get(0); final String resultString = IOUtils.toString(serializer.entity(metadata, edmEntitySet.getEntityType(), entity, EntitySerializerOptions.with() .contextURL(ContextURL.with().entitySet(edmEntitySet).suffix(Suffix.ENTITY).build()) .build()).getContent()); final String expectedResult = "{\"@odata.context\":\"$metadata#ESMedia/$entity\"," - + "\"@odata.mediaEtag\":\"theMediaETag\",\"@odata.mediaContentType\":\"image/svg+xml\"," + + "\"@odata.mediaEtag\":\"W/\\\"1\\\"\",\"@odata.mediaContentType\":\"image/svg+xml\"," + "\"PropertyInt16\":1}"; Assert.assertEquals(expectedResult, resultString); } @@ -344,10 +344,10 @@ public class ODataJsonSerializerTest { EntityCollectionSerializerOptions.with() .contextURL(ContextURL.with().entitySet(edmEntitySet).build()).build()).getContent()); final String expectedResult = "{\"@odata.context\":\"$metadata#ESMedia\",\"value\":[" - + "{\"@odata.mediaContentType\":\"image/svg+xml\",\"PropertyInt16\":1}," - + "{\"@odata.mediaContentType\":\"image/svg+xml\",\"PropertyInt16\":2}," - + "{\"@odata.mediaContentType\":\"image/svg+xml\",\"PropertyInt16\":3}," - + "{\"@odata.mediaContentType\":\"image/svg+xml\",\"PropertyInt16\":4}]}"; + + "{\"@odata.mediaEtag\":\"W/\\\"1\\\"\",\"@odata.mediaContentType\":\"image/svg+xml\",\"PropertyInt16\":1}," + + "{\"@odata.mediaEtag\":\"W/\\\"2\\\"\",\"@odata.mediaContentType\":\"image/svg+xml\",\"PropertyInt16\":2}," + + "{\"@odata.mediaEtag\":\"W/\\\"3\\\"\",\"@odata.mediaContentType\":\"image/svg+xml\",\"PropertyInt16\":3}," + + "{\"@odata.mediaEtag\":\"W/\\\"4\\\"\",\"@odata.mediaContentType\":\"image/svg+xml\",\"PropertyInt16\":4}]}"; Assert.assertEquals(expectedResult, resultString); }
