You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by mi...@apache.org on 2015/06/10 22:16:33 UTC
[19/26] olingo-odata4 git commit: [OLINGO-663] metadata ETag
[OLINGO-663] metadata ETag
Change-Id: I93bcf78b9be2a34e46c4f2f4d8ec739faf197951
Signed-off-by: Christian Amend <ch...@sap.com>
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/a604fa78
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/a604fa78
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/a604fa78
Branch: refs/heads/OLINGO-642_OSGi-Sample
Commit: a604fa78f2a85dbd612da7f5c0546e3424ae2698
Parents: 4cd8752
Author: Klaus Straubinger <kl...@sap.com>
Authored: Fri Jun 5 15:44:05 2015 +0200
Committer: Christian Amend <ch...@sap.com>
Committed: Mon Jun 8 10:01:27 2015 +0200
----------------------------------------------------------------------
.../fit/tecsvc/client/BatchClientITCase.java | 10 +-
.../fit/tecsvc/client/ConditionalITCase.java | 35 +++
.../tecsvc/client/PrimitiveComplexITCase.java | 18 +-
.../fit/tecsvc/http/BasicBatchITCase.java | 2 +-
.../retrieve/EdmMetadataRequestImpl.java | 31 ++-
.../retrieve/XMLMetadataRequestImpl.java | 21 +-
.../olingo/server/api/ServiceMetadata.java | 6 +-
.../server/api/processor/DefaultProcessor.java | 2 +-
.../server/api/serializer/ODataSerializer.java | 88 +++---
.../server/core/responses/PropertyResponse.java | 6 +-
.../core/responses/ServiceDocumentResponse.java | 2 +-
.../serializer/json/ODataJsonSerializer.java | 61 +++--
.../json/ServiceDocumentJsonSerializer.java | 33 ++-
.../serializer/xml/ODataXmlSerializerImpl.java | 12 +-
.../olingo/server/core/etag/ETagHelperTest.java | 79 ++++++
.../olingo/server/core/etag/ETagParserTest.java | 2 +-
.../server/tecsvc/MetadataETagSupport.java | 40 +++
.../olingo/server/tecsvc/TechnicalServlet.java | 17 +-
.../processor/TechnicalActionProcessor.java | 6 +-
.../TechnicalPrimitiveComplexProcessor.java | 7 +-
.../json/ODataJsonSerializerTest.java | 270 ++++++++++---------
.../serializer/json/ServiceDocumentTest.java | 108 ++------
.../server/sample/processor/CarsProcessor.java | 2 +-
23 files changed, 526 insertions(+), 332 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a604fa78/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BatchClientITCase.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BatchClientITCase.java b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BatchClientITCase.java
index 63c9a7f..932f9b1 100644
--- a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BatchClientITCase.java
+++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BatchClientITCase.java
@@ -170,7 +170,7 @@ public class BatchClientITCase extends AbstractTestITCase {
assertEquals(1, oDataResonse.getHeader("OData-Version").size());
assertEquals("4.0", oDataResonse.getHeader("OData-Version").toArray()[0]);
assertEquals(1, oDataResonse.getHeader("Content-Length").size());
- assertEquals("538", oDataResonse.getHeader("Content-Length").toArray()[0]);
+ assertEquals("582", oDataResonse.getHeader("Content-Length").toArray()[0]);
assertEquals("application/json;odata.metadata=minimal", oDataResonse.getContentType());
}
@@ -202,7 +202,7 @@ public class BatchClientITCase extends AbstractTestITCase {
assertEquals(1, oDataResonse.getHeader("OData-Version").size());
assertEquals("4.0", oDataResonse.getHeader("OData-Version").toArray()[0]);
assertEquals(1, oDataResonse.getHeader("Content-Length").size());
- assertEquals("538", oDataResonse.getHeader("Content-Length").toArray()[0]);
+ assertEquals("582", oDataResonse.getHeader("Content-Length").toArray()[0]);
assertEquals("application/json;odata.metadata=minimal", oDataResonse.getContentType());
}
@@ -234,7 +234,7 @@ public class BatchClientITCase extends AbstractTestITCase {
assertEquals(1, oDataResonse.getHeader("OData-Version").size());
assertEquals("4.0", oDataResonse.getHeader("OData-Version").toArray()[0]);
assertEquals(1, oDataResonse.getHeader("Content-Length").size());
- assertEquals("538", oDataResonse.getHeader("Content-Length").toArray()[0]);
+ assertEquals("582", oDataResonse.getHeader("Content-Length").toArray()[0]);
assertEquals("application/json;odata.metadata=minimal", oDataResonse.getContentType());
// Check second get request
@@ -334,7 +334,7 @@ public class BatchClientITCase extends AbstractTestITCase {
assertEquals(1, oDataResonse.getHeader("OData-Version").size());
assertEquals("4.0", oDataResonse.getHeader("OData-Version").toArray()[0]);
assertEquals(1, oDataResonse.getHeader("Content-Length").size());
- assertEquals("538", oDataResonse.getHeader("Content-Length").toArray()[0]);
+ assertEquals("582", oDataResonse.getHeader("Content-Length").toArray()[0]);
assertEquals("application/json;odata.metadata=minimal", oDataResonse.getContentType());
// Check second get request
@@ -357,7 +357,7 @@ public class BatchClientITCase extends AbstractTestITCase {
assertEquals(1, oDataResonse.getHeader("OData-Version").size());
assertEquals("4.0", oDataResonse.getHeader("OData-Version").toArray()[0]);
assertEquals(1, oDataResonse.getHeader("Content-Length").size());
- assertEquals("446", oDataResonse.getHeader("Content-Length").toArray()[0]);
+ assertEquals("490", oDataResonse.getHeader("Content-Length").toArray()[0]);
assertEquals("application/json;odata.metadata=minimal", oDataResonse.getContentType());
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a604fa78/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/ConditionalITCase.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/ConditionalITCase.java b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/ConditionalITCase.java
index 796c2c4..c5d2926 100644
--- a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/ConditionalITCase.java
+++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/ConditionalITCase.java
@@ -35,16 +35,20 @@ import org.apache.olingo.client.api.communication.request.cud.ODataDeleteRequest
import org.apache.olingo.client.api.communication.request.cud.ODataEntityUpdateRequest;
import org.apache.olingo.client.api.communication.request.cud.ODataPropertyUpdateRequest;
import org.apache.olingo.client.api.communication.request.cud.UpdateType;
+import org.apache.olingo.client.api.communication.request.retrieve.EdmMetadataRequest;
import org.apache.olingo.client.api.communication.request.retrieve.ODataEntityRequest;
import org.apache.olingo.client.api.communication.request.retrieve.ODataPropertyRequest;
+import org.apache.olingo.client.api.communication.request.retrieve.ODataServiceDocumentRequest;
import org.apache.olingo.client.api.communication.request.retrieve.ODataValueRequest;
import org.apache.olingo.client.api.communication.request.streamed.ODataMediaEntityUpdateRequest;
import org.apache.olingo.client.api.communication.response.ODataDeleteResponse;
import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
import org.apache.olingo.client.api.domain.ClientEntity;
import org.apache.olingo.client.api.domain.ClientProperty;
+import org.apache.olingo.client.api.domain.ClientServiceDocument;
import org.apache.olingo.client.api.http.HttpClientException;
import org.apache.olingo.client.core.ODataClientFactory;
+import org.apache.olingo.commons.api.edm.Edm;
import org.apache.olingo.commons.api.format.ODataFormat;
import org.apache.olingo.commons.api.http.HttpHeader;
import org.apache.olingo.commons.api.http.HttpStatusCode;
@@ -65,6 +69,37 @@ public final class ConditionalITCase extends AbstractBaseTestITCase {
.appendEntitySetSegment("ESMedia").appendKeySegment(1).appendValueSegment().build();
@Test
+ public void readServiceDocument() throws Exception {
+ ODataServiceDocumentRequest request = client.getRetrieveRequestFactory()
+ .getServiceDocumentRequest(TecSvcConst.BASE_URI);
+ ODataRetrieveResponse<ClientServiceDocument> response = request.execute();
+ assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode());
+
+ request = client.getRetrieveRequestFactory().getServiceDocumentRequest(TecSvcConst.BASE_URI);
+ request.setIfNoneMatch(response.getETag());
+ assertEquals(HttpStatusCode.NOT_MODIFIED.getStatusCode(), request.execute().getStatusCode());
+
+ request = client.getRetrieveRequestFactory().getServiceDocumentRequest(TecSvcConst.BASE_URI);
+ request.setIfMatch("W/\"0\"");
+ executeAndExpectError(request, HttpStatusCode.PRECONDITION_FAILED);
+ }
+
+ @Test
+ public void readMetadataDocument() throws Exception {
+ EdmMetadataRequest request = client.getRetrieveRequestFactory().getMetadataRequest(TecSvcConst.BASE_URI);
+ ODataRetrieveResponse<Edm> response = request.execute();
+ assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode());
+
+ request = client.getRetrieveRequestFactory().getMetadataRequest(TecSvcConst.BASE_URI);
+ request.setIfNoneMatch(response.getETag());
+ assertEquals(HttpStatusCode.NOT_MODIFIED.getStatusCode(), request.execute().getStatusCode());
+
+ request = client.getRetrieveRequestFactory().getMetadataRequest(TecSvcConst.BASE_URI);
+ request.setIfMatch("W/\"0\"");
+ executeAndExpectError(request, HttpStatusCode.PRECONDITION_FAILED);
+ }
+
+ @Test
public void readWithWrongIfMatch() throws Exception {
ODataEntityRequest<ClientEntity> request = client.getRetrieveRequestFactory().getEntityRequest(uriEntity);
request.setIfMatch("W/\"1\"");
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a604fa78/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/PrimitiveComplexITCase.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/PrimitiveComplexITCase.java b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/PrimitiveComplexITCase.java
index d71e6a0..04f9768 100644
--- a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/PrimitiveComplexITCase.java
+++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/PrimitiveComplexITCase.java
@@ -6,9 +6,9 @@
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -87,10 +87,9 @@ public class PrimitiveComplexITCase extends AbstractBaseTestITCase {
.appendPropertySegment("PropertyString")
.build());
ODataRetrieveResponse<ClientProperty> response = request.execute();
- String expectedResult =
- "{\"@odata.context\":\"$metadata#ESTwoPrim(32766)/PropertyString\"," +
- "\"value\":\"Test String1\"}";
- assertEquals(expectedResult, IOUtils.toString(response.getRawResponse(), "UTF-8"));
+ String actualResult = IOUtils.toString(response.getRawResponse(), "UTF-8");
+ assertTrue(actualResult.startsWith("{\"@odata.context\":\"$metadata#ESTwoPrim(32766)/PropertyString\","));
+ assertTrue(actualResult.endsWith("\"value\":\"Test String1\"}"));
}
@Test
@@ -167,10 +166,9 @@ public class PrimitiveComplexITCase extends AbstractBaseTestITCase {
.appendPropertySegment("PropertyComp")
.build());
ODataRetrieveResponse<ClientProperty> response = request.execute();
- String expectedResult =
- "{\"@odata.context\":\"$metadata#ESMixPrimCollComp(7)/PropertyComp\"," +
- "\"PropertyInt16\":222,\"PropertyString\":\"TEST B\"}";
- assertEquals(expectedResult, IOUtils.toString(response.getRawResponse(), "UTF-8"));
+ String actualResult = IOUtils.toString(response.getRawResponse(), "UTF-8");
+ assertTrue(actualResult.startsWith("{\"@odata.context\":\"$metadata#ESMixPrimCollComp(7)/PropertyComp\","));
+ assertTrue(actualResult.endsWith("\"PropertyInt16\":222,\"PropertyString\":\"TEST B\"}"));
}
@Test
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a604fa78/fit/src/test/java/org/apache/olingo/fit/tecsvc/http/BasicBatchITCase.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/tecsvc/http/BasicBatchITCase.java b/fit/src/test/java/org/apache/olingo/fit/tecsvc/http/BasicBatchITCase.java
index 11b7a3e..3964d3b 100644
--- a/fit/src/test/java/org/apache/olingo/fit/tecsvc/http/BasicBatchITCase.java
+++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/http/BasicBatchITCase.java
@@ -60,7 +60,7 @@ public class BasicBatchITCase extends AbstractBaseTestITCase {
assertEquals("HTTP/1.1 200 OK", reader.readLine());
assertEquals("OData-Version: 4.0", reader.readLine());
assertEquals("Content-Type: application/json;odata.metadata=minimal", reader.readLine());
- assertEquals("Content-Length: 538", reader.readLine());
+ assertEquals("Content-Length: 582", reader.readLine());
blankLine(reader);
reader.close();
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a604fa78/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/EdmMetadataRequestImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/EdmMetadataRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/EdmMetadataRequestImpl.java
index 8366304..ee5e2e7 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/EdmMetadataRequestImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/EdmMetadataRequestImpl.java
@@ -19,10 +19,13 @@
package org.apache.olingo.client.core.communication.request.retrieve;
import java.net.URI;
+import java.util.Collection;
import org.apache.http.client.HttpClient;
import org.apache.olingo.client.api.ODataClient;
+import org.apache.olingo.client.api.communication.header.HeaderName;
import org.apache.olingo.client.api.communication.request.retrieve.EdmMetadataRequest;
+import org.apache.olingo.client.api.communication.request.retrieve.XMLMetadataRequest;
import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
import org.apache.olingo.client.api.edm.xml.XMLMetadata;
import org.apache.olingo.commons.api.edm.Edm;
@@ -43,8 +46,17 @@ class EdmMetadataRequestImpl extends AbstractMetadataRequestImpl<Edm> implements
private EdmMetadataResponseImpl getPrivateResponse() {
if (privateResponse == null) {
- final ODataRetrieveResponse<XMLMetadata> xmlMetadataResponse =
- odataClient.getRetrieveRequestFactory().getXMLMetadataRequest(serviceRoot).execute();
+ XMLMetadataRequest request = odataClient.getRetrieveRequestFactory().getXMLMetadataRequest(serviceRoot);
+ if (getPrefer() != null) {
+ request.setPrefer(getPrefer());
+ }
+ if (getIfMatch() != null) {
+ request.setIfMatch(getIfMatch());
+ }
+ if (getIfNoneMatch() != null) {
+ request.setIfNoneMatch(getIfNoneMatch());
+ }
+ final ODataRetrieveResponse<XMLMetadata> xmlMetadataResponse = request.execute();
privateResponse = new EdmMetadataResponseImpl(odataClient, httpClient, xmlMetadataResponse);
}
@@ -90,6 +102,21 @@ class EdmMetadataRequestImpl extends AbstractMetadataRequestImpl<Edm> implements
return xmlMetadataResponse.getStatusMessage();
}
+ @Override
+ public Collection<String> getHeaderNames() {
+ return xmlMetadataResponse.getHeaderNames();
+ }
+
+ @Override
+ public Collection<String> getHeader(final String name) {
+ return xmlMetadataResponse.getHeader(name);
+ }
+
+ @Override
+ public Collection<String> getHeader(final HeaderName name) {
+ return xmlMetadataResponse.getHeader(name);
+ }
+
public XMLMetadata getXMLMetadata() {
if (metadata == null) {
try {
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a604fa78/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/XMLMetadataRequestImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/XMLMetadataRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/XMLMetadataRequestImpl.java
index ff49b7b..2e432c8 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/XMLMetadataRequestImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/XMLMetadataRequestImpl.java
@@ -35,6 +35,7 @@ import org.apache.olingo.commons.api.edm.provider.CsdlAnnotation;
import org.apache.olingo.commons.api.edm.provider.CsdlAnnotations;
import org.apache.olingo.commons.api.edm.provider.CsdlSchema;
import org.apache.olingo.commons.api.format.ODataFormat;
+import org.apache.olingo.commons.api.http.HttpStatusCode;
public class XMLMetadataRequestImpl
extends AbstractMetadataRequestImpl<XMLMetadata>
@@ -46,9 +47,21 @@ public class XMLMetadataRequestImpl
@Override
public ODataRetrieveResponse<XMLMetadata> execute() {
- final SingleXMLMetadatRequestImpl rootReq = new SingleXMLMetadatRequestImpl(odataClient, uri, null);
+ SingleXMLMetadatRequestImpl rootReq = new SingleXMLMetadatRequestImpl(odataClient, uri, null);
+ if (getPrefer() != null) {
+ rootReq.setPrefer(getPrefer());
+ }
+ if (getIfMatch() != null) {
+ rootReq.setIfMatch(getIfMatch());
+ }
+ if (getIfNoneMatch() != null) {
+ rootReq.setIfNoneMatch(getIfNoneMatch());
+ }
final ODataRetrieveResponse<XMLMetadata> rootRes = rootReq.execute();
+ if (rootRes.getStatusCode() != HttpStatusCode.OK.getStatusCode()) {
+ return rootRes;
+ }
final XMLMetadataResponseImpl response =
new XMLMetadataResponseImpl(odataClient, httpClient, rootReq.getHttpResponse(), rootRes.getBody());
@@ -176,12 +189,8 @@ public class XMLMetadataRequestImpl
final HttpResponse res, final XMLMetadata metadata) {
super(odataClient, httpClient, null);
+ initFromHttpResponse(res);
this.metadata = metadata;
-
- statusCode = res.getStatusLine().getStatusCode();
- statusMessage = res.getStatusLine().getReasonPhrase();
-
- hasBeenInitialized = true;
}
@Override
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a604fa78/lib/server-api/src/main/java/org/apache/olingo/server/api/ServiceMetadata.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/ServiceMetadata.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/ServiceMetadata.java
index 3cecd8b..a12f1ac 100644
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/ServiceMetadata.java
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/ServiceMetadata.java
@@ -46,7 +46,9 @@ public interface ServiceMetadata {
* @return list of defined emdx references of this service
*/
List<EdmxReference> getReferences();
-
+
+ /**
+ * @return metadata ETag support
+ */
ServiceMetadataETagSupport getServiceMetadataETagSupport();
-
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a604fa78/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/DefaultProcessor.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/DefaultProcessor.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/DefaultProcessor.java
index f73ed27..c209764 100644
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/DefaultProcessor.java
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/DefaultProcessor.java
@@ -73,7 +73,7 @@ public class DefaultProcessor implements MetadataProcessor, ServiceDocumentProce
response.setStatusCode(HttpStatusCode.NOT_MODIFIED.getStatusCode());
} else {
ODataSerializer serializer = odata.createSerializer(ODataFormat.fromContentType(requestedContentType));
- response.setContent(serializer.serviceDocument(serviceMetadata.getEdm(), null).getContent());
+ response.setContent(serializer.serviceDocument(serviceMetadata, null).getContent());
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
response.setHeader(HttpHeader.CONTENT_TYPE, requestedContentType.toContentTypeString());
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a604fa78/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/ODataSerializer.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/ODataSerializer.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/ODataSerializer.java
index 470d090..3727064 100644
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/ODataSerializer.java
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/ODataSerializer.java
@@ -22,7 +22,6 @@ import org.apache.olingo.commons.api.data.ContextURL;
import org.apache.olingo.commons.api.data.Entity;
import org.apache.olingo.commons.api.data.EntityCollection;
import org.apache.olingo.commons.api.data.Property;
-import org.apache.olingo.commons.api.edm.Edm;
import org.apache.olingo.commons.api.edm.EdmComplexType;
import org.apache.olingo.commons.api.edm.EdmEntitySet;
import org.apache.olingo.commons.api.edm.EdmEntityType;
@@ -38,10 +37,10 @@ public interface ODataSerializer {
/**
* Writes the service document into an InputStream.
- * @param edm the Entity Data Model
- * @param serviceRoot the service-root URI of this OData service
+ * @param serviceMetadata the metadata information for the service
+ * @param serviceRoot the service-root URI of this OData service
*/
- SerializerResult serviceDocument(Edm edm, String serviceRoot) throws SerializerException;
+ SerializerResult serviceDocument(ServiceMetadata serviceMetadata, String serviceRoot) throws SerializerException;
/**
* Writes the metadata document into an InputStream.
@@ -52,91 +51,86 @@ public interface ODataSerializer {
/**
* Writes an ODataError into an InputStream.
* @param error the main error
- * @return inputStream containing the OData-formatted error
*/
SerializerResult error(ODataServerError error) throws SerializerException;
/**
* Writes entity-collection data into an InputStream.
- * @param metadata Metadata for the service
+ * @param metadata metadata for the service
* @param entityType the {@link EdmEntityType}
- * @param entitySet the data of the entity set
- * @param options options for the serializer
+ * @param entitySet the data of the entity set
+ * @param options options for the serializer
*/
SerializerResult entityCollection(ServiceMetadata metadata, EdmEntityType entityType,
EntityCollection entitySet, EntityCollectionSerializerOptions options) throws SerializerException;
/**
* Writes entity data into an InputStream.
- * @param metadata Metadata for the service
+ * @param metadata metadata for the service
* @param entityType the {@link EdmEntityType}
- * @param entity the data of the entity
- * @param options options for the serializer
+ * @param entity the data of the entity
+ * @param options options for the serializer
*/
SerializerResult entity(ServiceMetadata metadata, EdmEntityType entityType, Entity entity,
EntitySerializerOptions options) throws SerializerException;
/**
* Writes primitive-type instance data into an InputStream.
- * @param type primitive type
+ * @param metadata metadata for the service
+ * @param type primitive type
* @param property property value
- * @param options options for the serializer
+ * @param options options for the serializer
*/
- SerializerResult primitive(EdmPrimitiveType type, Property property, PrimitiveSerializerOptions options)
- throws SerializerException;
+ SerializerResult primitive(ServiceMetadata metadata, EdmPrimitiveType type, Property property,
+ PrimitiveSerializerOptions options) throws SerializerException;
/**
* Writes complex-type instance data into an InputStream.
- * @param metadata Metadata for the service
- * @param type complex type
+ * @param metadata metadata for the service
+ * @param type complex type
* @param property property value
- * @param options options for the serializer
+ * @param options options for the serializer
*/
SerializerResult complex(ServiceMetadata metadata, EdmComplexType type, Property property,
ComplexSerializerOptions options) throws SerializerException;
/**
* Writes data of a collection of primitive-type instances into an InputStream.
- * @param type primitive type
+ * @param metadata metadata for the service
+ * @param type primitive type
* @param property property value
- * @param options options for the serializer
+ * @param options options for the serializer
*/
- SerializerResult primitiveCollection(EdmPrimitiveType type, Property property, PrimitiveSerializerOptions options)
- throws SerializerException;
+ SerializerResult primitiveCollection(ServiceMetadata metadata, EdmPrimitiveType type, Property property,
+ PrimitiveSerializerOptions options) throws SerializerException;
/**
* Writes data of a collection of complex-type instances into an InputStream.
- * @param metadata Metadata for the service
- * @param type complex type
+ * @param metadata metadata for the service
+ * @param type complex type
* @param property property value
- * @param options options for the serializer
+ * @param options options for the serializer
*/
SerializerResult complexCollection(ServiceMetadata metadata, EdmComplexType type, Property property,
ComplexSerializerOptions options) throws SerializerException;
-
+
/**
- * Writes a single entity reference into an InputStream
- *
- * @param metadata Metadata for the service
- * @param edmEntitySet {@link EdmEntitySet}
- * @param entity data of the entity
- * @param contextUrl {@link ContextURL}
- * @return Serialized entity reference
- * @throws SerializerException
+ * Writes a single entity reference into an InputStream.
+ * @param metadata metadata for the service
+ * @param edmEntitySet {@link EdmEntitySet}
+ * @param entity data of the entity
+ * @param contextURL {@link ContextURL}
*/
- SerializerResult reference(ServiceMetadata metadata, EdmEntitySet edmEntitySet, Entity entity,
- final ContextURL contextUrl) throws SerializerException;
-
+ SerializerResult reference(ServiceMetadata metadata, EdmEntitySet edmEntitySet, Entity entity,
+ ContextURL contextURL) throws SerializerException;
+
/**
- * Writes entity collection references into an InputStream
- *
- * @param metadata Metadata for the service
- * @param edmEntitySet {@link EdmEntitySet}
- * @param entityCollection data of the entity collection
- * @param contextURL
- * @return Serialized entity reference
- * @throws SerializerException
+ * Writes entity-collection references into an InputStream.
+ * @param metadata metadata for the service
+ * @param edmEntitySet {@link EdmEntitySet}
+ * @param entityCollection data of the entity collection
+ * @param contextURL {@link ContextURL}
*/
- SerializerResult referenceCollection(ServiceMetadata metadata, EdmEntitySet edmEntitySet,
- EntityCollection entityCollection, final ContextURL contextURL) throws SerializerException;
+ SerializerResult referenceCollection(ServiceMetadata metadata, EdmEntitySet edmEntitySet,
+ EntityCollection entityCollection, ContextURL contextURL) throws SerializerException;
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a604fa78/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/PropertyResponse.java
----------------------------------------------------------------------
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 1353ece..0cf4ff2 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
@@ -120,9 +120,11 @@ public class PropertyResponse extends ServiceResponse {
private void writePrimitiveProperty(EdmPrimitiveType type, Property property)
throws SerializerException {
if(this.collection) {
- this.response.setContent(this.serializer.primitiveCollection(type, property, this.primitiveOptions).getContent());
+ this.response.setContent(
+ this.serializer.primitiveCollection(metadata, type, property, this.primitiveOptions).getContent());
} else {
- this.response.setContent(this.serializer.primitive(type, property, this.primitiveOptions).getContent());
+ this.response.setContent(
+ this.serializer.primitive(metadata, type, property, this.primitiveOptions).getContent());
}
writeOK(this.responseContentType.toContentTypeString());
close();
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a604fa78/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/ServiceDocumentResponse.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/ServiceDocumentResponse.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/ServiceDocumentResponse.java
index 43bafbc..407510d 100644
--- a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/ServiceDocumentResponse.java
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/ServiceDocumentResponse.java
@@ -51,7 +51,7 @@ public class ServiceDocumentResponse extends ServiceResponse {
public void writeServiceDocument(String serviceRoot)
throws ODataLibraryException {
assert (!isClosed());
- this.response.setContent(this.serializer.serviceDocument(this.metadata.getEdm(), serviceRoot).getContent());
+ this.response.setContent(this.serializer.serviceDocument(metadata, serviceRoot).getContent());
writeOK(this.responseContentType.toContentTypeString());
close();
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a604fa78/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java
index 08f557a..168adfa 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java
@@ -31,7 +31,6 @@ import org.apache.olingo.commons.api.data.EntityCollection;
import org.apache.olingo.commons.api.data.Link;
import org.apache.olingo.commons.api.data.Linked;
import org.apache.olingo.commons.api.data.Property;
-import org.apache.olingo.commons.api.edm.Edm;
import org.apache.olingo.commons.api.edm.EdmComplexType;
import org.apache.olingo.commons.api.edm.EdmEntitySet;
import org.apache.olingo.commons.api.edm.EdmEntityType;
@@ -80,7 +79,8 @@ public class ODataJsonSerializer implements ODataSerializer {
}
@Override
- public SerializerResult serviceDocument(final Edm edm, final String serviceRoot) throws SerializerException {
+ public SerializerResult serviceDocument(final ServiceMetadata metadata, final String serviceRoot)
+ throws SerializerException {
CircleStreamBuffer buffer;
JsonGenerator gen = null;
@@ -89,7 +89,7 @@ public class ODataJsonSerializer implements ODataSerializer {
gen = new JsonFactory().createGenerator(buffer.getOutputStream())
.setPrettyPrinter(new DefaultPrettyPrinter());
- new ServiceDocumentJsonSerializer(edm, serviceRoot).writeServiceDocument(gen);
+ new ServiceDocumentJsonSerializer(metadata, serviceRoot, format).writeServiceDocument(gen);
gen.close();
@@ -146,6 +146,8 @@ public class ODataJsonSerializer implements ODataSerializer {
ContextURLBuilder.create(contextURL).toASCIIString());
}
+ writeMetadataETag(metadata, json);
+
if (options != null && options.getCount() != null && options.getCount().getValue()
&& entitySet.getCount() != null) {
writeCount(entitySet, json);
@@ -196,6 +198,16 @@ public class ODataJsonSerializer implements ODataSerializer {
return contextURL;
}
+ private void writeMetadataETag(final ServiceMetadata metadata, JsonGenerator json) throws IOException {
+ if (format != ODataFormat.JSON_NO_METADATA
+ && metadata != null
+ && metadata.getServiceMetadataETagSupport() != null
+ && metadata.getServiceMetadataETagSupport().getMetadataETag() != null) {
+ json.writeStringField(Constants.JSON_METADATA_ETAG,
+ metadata.getServiceMetadataETagSupport().getMetadataETag());
+ }
+ }
+
protected void writeEntitySet(final ServiceMetadata metadata, final EdmEntityType entityType,
final EntityCollection entitySet, final ExpandOption expand, final SelectOption select,
final boolean onlyReference, final JsonGenerator json) throws IOException,
@@ -219,8 +231,9 @@ public class ODataJsonSerializer implements ODataSerializer {
throws IOException, SerializerException {
json.writeStartObject();
if (format != ODataFormat.JSON_NO_METADATA) {
- if (contextURL != null) {
+ if (contextURL != null) { // top-level entity
json.writeStringField(Constants.JSON_CONTEXT, ContextURLBuilder.create(contextURL).toASCIIString());
+ writeMetadataETag(metadata, json);
}
if (entity.getETag() != null) {
json.writeStringField(Constants.JSON_ETAG, entity.getETag());
@@ -529,8 +542,8 @@ public class ODataJsonSerializer implements ODataSerializer {
}
@Override
- public SerializerResult primitive(final EdmPrimitiveType type, final Property property,
- final PrimitiveSerializerOptions options) throws SerializerException {
+ public SerializerResult primitive(final ServiceMetadata metadata, final EdmPrimitiveType type,
+ final Property property, final PrimitiveSerializerOptions options) throws SerializerException {
final ContextURL contextURL = checkContextURL(options == null ? null : options.getContextURL());
CircleStreamBuffer buffer = new CircleStreamBuffer();
try {
@@ -539,6 +552,7 @@ public class ODataJsonSerializer implements ODataSerializer {
if (contextURL != null) {
json.writeStringField(Constants.JSON_CONTEXT, ContextURLBuilder.create(contextURL).toASCIIString());
}
+ writeMetadataETag(metadata, json);
if (property.isNull()) {
throw new SerializerException("Property value can not be null.", SerializerException.MessageKeys.NULL_INPUT);
} else {
@@ -572,6 +586,7 @@ public class ODataJsonSerializer implements ODataSerializer {
if (contextURL != null) {
json.writeStringField(Constants.JSON_CONTEXT, ContextURLBuilder.create(contextURL).toASCIIString());
}
+ writeMetadataETag(metadata, json);
EdmComplexType resolvedType = resolveComplexType(metadata, type, property.getType());
if (!resolvedType.equals(type)) {
json.writeStringField(Constants.JSON_TYPE, "#" + property.getType());
@@ -593,8 +608,8 @@ public class ODataJsonSerializer implements ODataSerializer {
}
@Override
- public SerializerResult primitiveCollection(final EdmPrimitiveType type, final Property property,
- final PrimitiveSerializerOptions options) throws SerializerException {
+ public SerializerResult primitiveCollection(final ServiceMetadata metadata, final EdmPrimitiveType type,
+ final Property property, final PrimitiveSerializerOptions options) throws SerializerException {
final ContextURL contextURL = checkContextURL(options == null ? null : options.getContextURL());
CircleStreamBuffer buffer = new CircleStreamBuffer();
try {
@@ -603,6 +618,7 @@ public class ODataJsonSerializer implements ODataSerializer {
if (contextURL != null) {
json.writeStringField(Constants.JSON_CONTEXT, ContextURLBuilder.create(contextURL).toASCIIString());
}
+ writeMetadataETag(metadata, json);
json.writeFieldName(Constants.VALUE);
writePrimitiveCollection(type, property,
options.isNullable(), options.getMaxLength(), options.getPrecision(), options.getScale(),
@@ -632,6 +648,7 @@ public class ODataJsonSerializer implements ODataSerializer {
if (contextURL != null) {
json.writeStringField(Constants.JSON_CONTEXT, ContextURLBuilder.create(contextURL).toASCIIString());
}
+ writeMetadataETag(metadata, json);
json.writeFieldName(Constants.VALUE);
writeComplexCollection(type, property, null, json);
json.writeEndObject();
@@ -656,8 +673,8 @@ public class ODataJsonSerializer implements ODataSerializer {
try {
final JsonGenerator json = new JsonFactory().createGenerator(buffer.getOutputStream());
- writeReference(edmEntitySet, entity, contextURL, uriHelper, json);
-
+ writeReference(metadata, edmEntitySet, entity, contextURL, uriHelper, json);
+
json.close();
} catch (IOException e) {
throw new SerializerException("An I/O exception occurred.", e, SerializerException.MessageKeys.IO_EXCEPTION);
@@ -682,8 +699,9 @@ public class ODataJsonSerializer implements ODataSerializer {
}
json.writeStringField(Constants.JSON_CONTEXT, ContextURLBuilder.create(contextURL).toASCIIString());
- writeReferenceCollection(metadata, edmEntitySet, entityCollection, uriHelper,json);
-
+ writeMetadataETag(metadata, json);
+ writeReferenceCollection(edmEntitySet, entityCollection, uriHelper,json);
+
if(entityCollection.getNext() != null) {
writeNextLink(entityCollection, json);
}
@@ -697,27 +715,26 @@ public class ODataJsonSerializer implements ODataSerializer {
return SerializerResultImpl.with().content(buffer.getInputStream()).build();
}
- protected void writeReferenceCollection(final ServiceMetadata metadata, final EdmEntitySet edmEntitySet,
- final EntityCollection entityCollection, final UriHelper uriHelper, final JsonGenerator json)
- throws IOException, SerializerException {
-
+ protected void writeReferenceCollection(final EdmEntitySet edmEntitySet, final EntityCollection entityCollection,
+ final UriHelper uriHelper, final JsonGenerator json) throws IOException, SerializerException {
json.writeArrayFieldStart(Constants.VALUE);
for(final Entity entity : entityCollection.getEntities()) {
- writeReference(edmEntitySet, entity, null, uriHelper, json);
+ writeReference(null, edmEntitySet, entity, null, uriHelper, json);
}
json.writeEndArray();
}
- protected void writeReference(final EdmEntitySet edmEntitySet, final Entity entity, final ContextURL contextURL,
- final UriHelper uriHelper, final JsonGenerator json) throws IOException, SerializerException {
-
+ protected void writeReference(final ServiceMetadata metadata, final EdmEntitySet edmEntitySet, final Entity entity,
+ final ContextURL contextURL, final UriHelper uriHelper, final JsonGenerator json)
+ throws IOException, SerializerException {
json.writeStartObject();
- if(contextURL != null) {
+ if (contextURL != null) {
json.writeStringField(Constants.JSON_CONTEXT, ContextURLBuilder.create(contextURL).toASCIIString());
+ writeMetadataETag(metadata, json);
}
-
+
json.writeStringField(Constants.JSON_ID, uriHelper.buildCanonicalURL(edmEntitySet, entity));
json.writeEndObject();
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a604fa78/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ServiceDocumentJsonSerializer.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ServiceDocumentJsonSerializer.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ServiceDocumentJsonSerializer.java
index e2f7261..65b4673 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ServiceDocumentJsonSerializer.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ServiceDocumentJsonSerializer.java
@@ -26,6 +26,8 @@ import org.apache.olingo.commons.api.edm.EdmEntityContainer;
import org.apache.olingo.commons.api.edm.EdmEntitySet;
import org.apache.olingo.commons.api.edm.EdmFunctionImport;
import org.apache.olingo.commons.api.edm.EdmSingleton;
+import org.apache.olingo.commons.api.format.ODataFormat;
+import org.apache.olingo.server.api.ServiceMetadata;
import com.fasterxml.jackson.core.JsonGenerator;
@@ -36,32 +38,37 @@ public class ServiceDocumentJsonSerializer {
public static final String SINGLETON = "Singleton";
public static final String SERVICE_DOCUMENT = "ServiceDocument";
- private final Edm edm;
+ private final ServiceMetadata metadata;
private final String serviceRoot;
+ private final ODataFormat format;
- public ServiceDocumentJsonSerializer(final Edm edm, final String serviceRoot) {
- this.edm = edm;
+ public ServiceDocumentJsonSerializer(final ServiceMetadata metadata, final String serviceRoot,
+ final ODataFormat format) {
+ this.metadata = metadata;
this.serviceRoot = serviceRoot;
+ this.format = format;
}
public void writeServiceDocument(final JsonGenerator gen) throws IOException {
gen.writeStartObject();
- Object metadataUri;
+ final String metadataUri =
+ (serviceRoot == null ? "" :
+ serviceRoot.endsWith("/") ? serviceRoot : (serviceRoot + "/"))
+ + Constants.METADATA;
+ gen.writeObjectField(Constants.JSON_CONTEXT, metadataUri);
- if (serviceRoot == null) {
- metadataUri = Constants.METADATA;
- } else {
- if (serviceRoot.endsWith("/")) {
- metadataUri = serviceRoot + Constants.METADATA;
- } else {
- metadataUri = serviceRoot + "/" + Constants.METADATA;
- }
+ if (format != ODataFormat.JSON_NO_METADATA
+ && metadata != null
+ && metadata.getServiceMetadataETagSupport() != null
+ && metadata.getServiceMetadataETagSupport().getMetadataETag() != null) {
+ gen.writeStringField(Constants.JSON_METADATA_ETAG,
+ metadata.getServiceMetadataETagSupport().getMetadataETag());
}
- gen.writeObjectField(Constants.JSON_CONTEXT, metadataUri);
gen.writeArrayFieldStart(Constants.VALUE);
+ final Edm edm = metadata.getEdm();
writeEntitySets(gen, edm);
writeFunctionImports(gen, edm);
writeSingletons(gen, edm);
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a604fa78/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializerImpl.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializerImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializerImpl.java
index 795a330..e6b04a6 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializerImpl.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializerImpl.java
@@ -26,7 +26,6 @@ import org.apache.olingo.commons.api.data.ContextURL;
import org.apache.olingo.commons.api.data.Entity;
import org.apache.olingo.commons.api.data.EntityCollection;
import org.apache.olingo.commons.api.data.Property;
-import org.apache.olingo.commons.api.edm.Edm;
import org.apache.olingo.commons.api.edm.EdmComplexType;
import org.apache.olingo.commons.api.edm.EdmEntitySet;
import org.apache.olingo.commons.api.edm.EdmEntityType;
@@ -53,7 +52,8 @@ public class ODataXmlSerializerImpl implements ODataSerializer {
private static final Logger log = LoggerFactory.getLogger(ODataXmlSerializerImpl.class);
@Override
- public SerializerResultImpl serviceDocument(final Edm edm, final String serviceRoot) throws SerializerException {
+ public SerializerResultImpl serviceDocument(final ServiceMetadata metadata, final String serviceRoot)
+ throws SerializerException {
throw new SerializerException("Service Document not implemented for XML format",
SerializerException.MessageKeys.NOT_IMPLEMENTED);
}
@@ -110,8 +110,8 @@ public class ODataXmlSerializerImpl implements ODataSerializer {
}
@Override
- public SerializerResult primitive(final EdmPrimitiveType type, final Property property,
- final PrimitiveSerializerOptions options) throws SerializerException {
+ public SerializerResult primitive(final ServiceMetadata metadata, final EdmPrimitiveType type,
+ final Property property, final PrimitiveSerializerOptions options) throws SerializerException {
throw new SerializerException("Serialization not implemented for XML format.",
SerializerException.MessageKeys.NOT_IMPLEMENTED);
}
@@ -124,8 +124,8 @@ public class ODataXmlSerializerImpl implements ODataSerializer {
}
@Override
- public SerializerResult primitiveCollection(final EdmPrimitiveType type, final Property property,
- final PrimitiveSerializerOptions options) throws SerializerException {
+ public SerializerResult primitiveCollection(final ServiceMetadata metadata, final EdmPrimitiveType type,
+ final Property property, final PrimitiveSerializerOptions options) throws SerializerException {
throw new SerializerException("Serialization not implemented for XML format.",
SerializerException.MessageKeys.NOT_IMPLEMENTED);
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a604fa78/lib/server-core/src/test/java/org/apache/olingo/server/core/etag/ETagHelperTest.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/test/java/org/apache/olingo/server/core/etag/ETagHelperTest.java b/lib/server-core/src/test/java/org/apache/olingo/server/core/etag/ETagHelperTest.java
new file mode 100644
index 0000000..e992a5c
--- /dev/null
+++ b/lib/server-core/src/test/java/org/apache/olingo/server/core/etag/ETagHelperTest.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.olingo.server.core.etag;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Collections;
+
+import org.apache.olingo.server.api.OData;
+import org.apache.olingo.server.api.etag.ETagHelper;
+import org.apache.olingo.server.api.etag.PreconditionException;
+import org.junit.Test;
+
+public class ETagHelperTest {
+
+ private static final ETagHelper eTagHelper = OData.newInstance().createETagHelper();
+
+ @Test
+ public void readPrecondition() throws Exception {
+ assertFalse(eTagHelper.checkReadPreconditions(null, null, null));
+ assertFalse(eTagHelper.checkReadPreconditions("\"ETag\"", null, null));
+ assertFalse(eTagHelper.checkReadPreconditions(null, Collections.singleton("\"ETag\""), null));
+ assertFalse(eTagHelper.checkReadPreconditions(null, null, Collections.singleton("\"ETag\"")));
+ assertFalse(eTagHelper.checkReadPreconditions("\"ETag\"", Collections.singleton("\"ETag\""), null));
+ assertFalse(eTagHelper.checkReadPreconditions("\"ETag\"", Collections.singleton("*"), null));
+ assertTrue(eTagHelper.checkReadPreconditions("\"ETag\"", null, Collections.singleton("\"ETag\"")));
+ assertTrue(eTagHelper.checkReadPreconditions("\"ETag\"", null, Collections.singleton("*")));
+ assertFalse(eTagHelper.checkReadPreconditions("\"ETag\"", null, Collections.singleton("\"ETag2\"")));
+ }
+
+ @Test(expected = PreconditionException.class)
+ public void readPreconditionFail() throws Exception {
+ eTagHelper.checkReadPreconditions("\"ETag\"", Collections.singleton("\"ETag2\""), null);
+ }
+
+ @Test
+ public void changePrecondition() throws Exception {
+ eTagHelper.checkChangePreconditions(null, null, null);
+ eTagHelper.checkChangePreconditions("\"ETag\"", null, null);
+ eTagHelper.checkChangePreconditions(null, Collections.singleton("\"ETag\""), null);
+ eTagHelper.checkChangePreconditions(null, Collections.singleton("*"), null);
+ eTagHelper.checkChangePreconditions(null, null, Collections.singleton("*"));
+ eTagHelper.checkChangePreconditions("\"ETag\"", Collections.singleton("\"ETag\""), null);
+ eTagHelper.checkChangePreconditions("\"ETag\"", Collections.singleton("*"), null);
+ eTagHelper.checkChangePreconditions("\"ETag\"", null, Collections.singleton("\"ETag2\""));
+ }
+
+ @Test(expected = PreconditionException.class)
+ public void changePreconditionFailIfMatch() throws Exception {
+ eTagHelper.checkChangePreconditions("\"ETag\"", Collections.singleton("\"ETag2\""), null);
+ }
+
+ @Test(expected = PreconditionException.class)
+ public void changePreconditionFailIfNoneMatch() throws Exception {
+ eTagHelper.checkChangePreconditions("\"ETag\"", null, Collections.singleton("\"ETag\""));
+ }
+
+ @Test(expected = PreconditionException.class)
+ public void changePreconditionFailIfNoneMatchAll() throws Exception {
+ eTagHelper.checkChangePreconditions("\"ETag\"", null, Collections.singleton("*"));
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a604fa78/lib/server-core/src/test/java/org/apache/olingo/server/core/etag/ETagParserTest.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/test/java/org/apache/olingo/server/core/etag/ETagParserTest.java b/lib/server-core/src/test/java/org/apache/olingo/server/core/etag/ETagParserTest.java
index 059d53d..3e68af6 100644
--- a/lib/server-core/src/test/java/org/apache/olingo/server/core/etag/ETagParserTest.java
+++ b/lib/server-core/src/test/java/org/apache/olingo/server/core/etag/ETagParserTest.java
@@ -126,4 +126,4 @@ public class ETagParserTest {
assertFalse(eTagHelper.createETagInformation(Arrays.asList("\"ETag1\",\"ETag2\"", "\"ETag3\",\"ETag4\""))
.isMatchedBy("\"ETag5\""));
}
-}
\ No newline at end of file
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a604fa78/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/MetadataETagSupport.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/MetadataETagSupport.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/MetadataETagSupport.java
new file mode 100644
index 0000000..e235bcf
--- /dev/null
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/MetadataETagSupport.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.olingo.server.tecsvc;
+
+import org.apache.olingo.server.api.etag.ServiceMetadataETagSupport;
+
+public class MetadataETagSupport implements ServiceMetadataETagSupport {
+
+ private final String metadataETag;
+
+ public MetadataETagSupport(final String metadataETag) {
+ this.metadataETag = metadataETag;
+ }
+
+ @Override
+ public String getMetadataETag() {
+ return metadataETag;
+ }
+
+ @Override
+ public String getServiceDocumentETag() {
+ return metadataETag;
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a604fa78/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/TechnicalServlet.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/TechnicalServlet.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/TechnicalServlet.java
index a96f585..349af30 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/TechnicalServlet.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/TechnicalServlet.java
@@ -20,7 +20,7 @@ package org.apache.olingo.server.tecsvc;
import java.io.IOException;
import java.net.URI;
-import java.util.Arrays;
+import java.util.Collections;
import java.util.List;
import javax.servlet.ServletException;
@@ -47,6 +47,16 @@ public class TechnicalServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private static final Logger LOG = LoggerFactory.getLogger(TechnicalServlet.class);
+ /**
+ * <p>ETag for the service document and the metadata document</p>
+ * <p>We use the same field for service-document and metadata-document ETags.
+ * It must change whenever the corresponding document changes.
+ * We don't know when someone changed the EDM in a way that changes one of these
+ * documents, but we do know that the EDM is defined completely in code and that
+ * therefore any change must be deployed, resulting in re-loading of this class,
+ * giving this field a new and hopefully unique value.</p>
+ */
+ private static final String metadataETag = "W/\"" + System.nanoTime() + "\"";
@Override
protected void service(final HttpServletRequest request, final HttpServletResponse response)
@@ -55,8 +65,9 @@ public class TechnicalServlet extends HttpServlet {
OData odata = OData.newInstance();
EdmxReference reference = new EdmxReference(URI.create("../v4.0/cs02/vocabularies/Org.OData.Core.V1.xml"));
reference.addInclude(new EdmxReferenceInclude("Org.OData.Core.V1", "Core"));
- final List<EdmxReference> references = Arrays.asList(reference);
- final ServiceMetadata serviceMetadata = odata.createServiceMetadata(new EdmTechProvider(references), references);
+ final List<EdmxReference> references = Collections.singletonList(reference);
+ final ServiceMetadata serviceMetadata = odata.createServiceMetadata(
+ new EdmTechProvider(references), references, new MetadataETagSupport(metadataETag));
HttpSession session = request.getSession(true);
DataProvider dataProvider = (DataProvider) session.getAttribute(DataProvider.class.getName());
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a604fa78/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalActionProcessor.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalActionProcessor.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalActionProcessor.java
index f3f85fd..da8c5cc 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalActionProcessor.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalActionProcessor.java
@@ -176,7 +176,7 @@ public class TechnicalActionProcessor extends TechnicalProcessor
SerializerResult result =
odata.createSerializer(ODataFormat.fromContentType(responseFormat))
- .primitiveCollection(type, property, options);
+ .primitiveCollection(serviceMetadata, type, property, options);
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
response.setContent(result.getContent());
@@ -208,8 +208,8 @@ public class TechnicalActionProcessor extends TechnicalProcessor
ContextURL contextURL = ContextURL.with().type(type).build();
PrimitiveSerializerOptions options = PrimitiveSerializerOptions.with().contextURL(contextURL).build();
- SerializerResult result = odata.createSerializer(ODataFormat.fromContentType(responseFormat)).primitive(type,
- property, options);
+ SerializerResult result = odata.createSerializer(ODataFormat.fromContentType(responseFormat))
+ .primitive(serviceMetadata, type, property, options);
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
response.setContent(result.getContent());
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a604fa78/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalPrimitiveComplexProcessor.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalPrimitiveComplexProcessor.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalPrimitiveComplexProcessor.java
index 58b38c4..4ff7634 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalPrimitiveComplexProcessor.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalPrimitiveComplexProcessor.java
@@ -278,6 +278,9 @@ public class TechnicalPrimitiveComplexProcessor extends TechnicalProcessor
property.setValue(property.getValueType(), edmProperty.isCollection() ? Collections.emptyList() : null);
dataProvider.updateETag(entity);
response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
+ if (entity.getETag() != null) {
+ response.setHeader(HttpHeader.ETAG, entity.getETag());
+ }
} else {
throw new ODataApplicationException("Not nullable.", HttpStatusCode.BAD_REQUEST.getStatusCode(), Locale.ROOT);
}
@@ -333,7 +336,7 @@ public class TechnicalPrimitiveComplexProcessor extends TechnicalProcessor
SerializerResult result = null;
switch (representationType) {
case PRIMITIVE:
- result = serializer.primitive((EdmPrimitiveType) type, property,
+ result = serializer.primitive(serviceMetadata, (EdmPrimitiveType) type, property,
PrimitiveSerializerOptions.with().contextURL(contextURL)
.nullable(edmProperty == null ? returnType.isNullable() : edmProperty.isNullable())
.maxLength(edmProperty == null ? returnType.getMaxLength() : edmProperty.getMaxLength())
@@ -349,7 +352,7 @@ public class TechnicalPrimitiveComplexProcessor extends TechnicalProcessor
.build());
break;
case COLLECTION_PRIMITIVE:
- result = serializer.primitiveCollection((EdmPrimitiveType) type, property,
+ result = serializer.primitiveCollection(serviceMetadata, (EdmPrimitiveType) type, property,
PrimitiveSerializerOptions.with().contextURL(contextURL)
.nullable(edmProperty == null ? returnType.isNullable() : edmProperty.isNullable())
.maxLength(edmProperty == null ? returnType.getMaxLength() : edmProperty.getMaxLength())