[OLINGO-663] Generic Precondition Required Handling

This commit is contained in:
Christian Amend 2015-06-01 13:52:52 +02:00
parent fd71b7ebdd
commit 53881c2acf
5 changed files with 272 additions and 121 deletions

View File

@ -18,6 +18,8 @@
*/ */
package org.apache.olingo.server.api; package org.apache.olingo.server.api;
import org.apache.olingo.commons.api.edm.EdmBindingTarget;
/** /**
* <p>Processors that would like to support etags for certain entity sets can implement this * <p>Processors that would like to support etags for certain entity sets can implement this
* interface.</p> * interface.</p>
@ -32,19 +34,41 @@ public interface CustomETagSupport {
* If this method returns true and an header is not specified we will return a "Precondition Required" response. * If this method returns true and an header is not specified we will return a "Precondition Required" response.
* Validation has to be performed inside the processor methods after the dispatching. * Validation has to be performed inside the processor methods after the dispatching.
* If this method returns false and an header is specified we will ignore the header. * If this method returns false and an header is specified we will ignore the header.
* @param entitySetName * @param entitySetOrSingleton
* @return true if the entity set specified needs an if-match/if-none-match header * @return true if the entity set specified needs an if-match/if-none-match header
*/ */
boolean hasETag(String entitySetName); boolean hasETag(EdmBindingTarget entitySetOrSingleton);
/** /**
* This method will be called for update requests which target a media entity value. * This method will be called for update requests which target a media entity value.
* If this method returns true and an header is not specified we will return a "Precondition Required" response. * If this method returns true and an header is not specified we will return a "Precondition Required" response.
* Validation has to be performed inside the processor methods after the dispatching. * Validation has to be performed inside the processor methods after the dispatching.
* If this method returns false and an header is specified we will ignore the header. * If this method returns false and an header is specified we will ignore the header.
* @param entitySetName * @param entitySetOrSingleton
* @return true if the entity set specified needs an if-match/if-none-match header * @return true if the entity set specified needs an if-match/if-none-match header
*/ */
boolean hasMediaETag(String entitySetName); boolean hasMediaETag(EdmBindingTarget entitySetOrSingleton);
/**
* Since the Olingo library cannot generate a metadata document etag in a generic way we call this method to retrieve
* an application specific etag for the metadata document. If this interface is registered applications can return an
* etag or null here to provide caching support for clients. If a client sends a GET request to the metadata document
* and this method delivers an etag we will match it to the request. If there has been no modification we will return
* a 304 NOT MODIFIED status code. If this interface is not registered or delivers null we just send back the usual
* metadata response.
* @return the application generated etag for the metadata document
*/
String getMetadataETag();
/**
* Since the Olingo library cannot generate a service document etag in a generic way we call this method to retrieve
* an application specific etag for the service document. If this interface is registered applications can return an
* etag or null here to provide caching support for clients. If a client sends a GET request to the service document
* and this method delivers an etag we will match it to the request. If there has been no modification we will return
* a 304 NOT MODIFIED status code. If this interface is not registered or delivers null we just send back the usual
* service document response.
* @return the application generated etag for the service document
*/
String getServiceDocumentETag();
} }

View File

@ -24,7 +24,8 @@ public class PreconditionRequiredException extends ODataTranslatedException {
private static final long serialVersionUID = -8112658467394158700L; private static final long serialVersionUID = -8112658467394158700L;
public static enum MessageKeys implements MessageKey { public static enum MessageKeys implements MessageKey {
MISSING_HEADER; MISSING_HEADER,
INVALID_URI;
@Override @Override
public String getKey() { public String getKey() {

View File

@ -18,9 +18,7 @@
*/ */
package org.apache.olingo.server.core; package org.apache.olingo.server.core;
import java.util.List; import org.apache.olingo.commons.api.edm.EdmBindingTarget;
import org.apache.olingo.commons.api.edm.EdmEntitySet;
import org.apache.olingo.commons.api.edm.EdmFunctionImport; import org.apache.olingo.commons.api.edm.EdmFunctionImport;
import org.apache.olingo.commons.api.edm.EdmNavigationProperty; import org.apache.olingo.commons.api.edm.EdmNavigationProperty;
import org.apache.olingo.server.api.CustomETagSupport; import org.apache.olingo.server.api.CustomETagSupport;
@ -28,8 +26,8 @@ import org.apache.olingo.server.api.uri.UriInfo;
import org.apache.olingo.server.api.uri.UriResource; import org.apache.olingo.server.api.uri.UriResource;
import org.apache.olingo.server.api.uri.UriResourceEntitySet; import org.apache.olingo.server.api.uri.UriResourceEntitySet;
import org.apache.olingo.server.api.uri.UriResourceFunction; import org.apache.olingo.server.api.uri.UriResourceFunction;
import org.apache.olingo.server.api.uri.UriResourceKind;
import org.apache.olingo.server.api.uri.UriResourceNavigation; import org.apache.olingo.server.api.uri.UriResourceNavigation;
import org.apache.olingo.server.api.uri.UriResourceSingleton;
public class PreconditionsValidator { public class PreconditionsValidator {
@ -48,10 +46,10 @@ public class PreconditionsValidator {
} }
public void validatePreconditions(boolean isMediaValue) throws PreconditionRequiredException { public void validatePreconditions(boolean isMediaValue) throws PreconditionRequiredException {
EdmEntitySet affectedEntitySet = extractInformation(); EdmBindingTarget affectedEntitySetOrSingleton = extractInformation();
if (affectedEntitySet != null) { if (affectedEntitySetOrSingleton != null) {
if ((isMediaValue && customETagSupport.hasMediaETag(affectedEntitySet.getName())) || if ((isMediaValue && customETagSupport.hasMediaETag(affectedEntitySetOrSingleton)) ||
(!isMediaValue && customETagSupport.hasETag(affectedEntitySet.getName()))) { (!isMediaValue && customETagSupport.hasETag(affectedEntitySetOrSingleton))) {
checkETagHeaderPresent(); checkETagHeaderPresent();
} }
} }
@ -64,75 +62,69 @@ public class PreconditionsValidator {
} }
} }
private EdmEntitySet extractInformation() { private EdmBindingTarget extractInformation() throws PreconditionRequiredException {
EdmEntitySet affectedEntitySet = null; EdmBindingTarget lastFoundEntitySetOrSingleton = null;
List<UriResource> uriResourceParts = uriInfo.getUriResourceParts(); int counter = 0;
if (uriResourceParts.size() > 0) { for (UriResource uriResourcePart : uriInfo.getUriResourceParts()) {
UriResource uriResourcePart = uriResourceParts.get(uriResourceParts.size() - 1);
switch (uriResourcePart.getKind()) { switch (uriResourcePart.getKind()) {
case function:
lastFoundEntitySetOrSingleton = getEnitySetFromFunctionImport(uriResourcePart);
break;
case singleton:
lastFoundEntitySetOrSingleton = ((UriResourceSingleton) uriResourcePart).getSingleton();
break;
case entitySet: case entitySet:
affectedEntitySet = ((UriResourceEntitySet) uriResourcePart).getEntitySet(); lastFoundEntitySetOrSingleton = getEntitySet(uriResourcePart);
break; break;
case navigationProperty: case navigationProperty:
affectedEntitySet = getEntitySetFromBeginning(); lastFoundEntitySetOrSingleton = getEntitySetFromNavigation(lastFoundEntitySetOrSingleton, uriResourcePart);
break; break;
case value: case value:
affectedEntitySet = getEntitySetOrNavigationEntitySet(uriResourceParts);
break;
case action: case action:
affectedEntitySet = getEntitySetOrNavigationEntitySet(uriResourceParts); // This should not be possible since the URI Parser validates this but to be sure we throw an exception.
if (counter != uriInfo.getUriResourceParts().size() - 1) {
throw new PreconditionRequiredException("$Value or Action must be the last segment in the URI.",
PreconditionRequiredException.MessageKeys.INVALID_URI);
}
break; break;
default: default:
// TODO: Cannot happen but should we throw an exception? lastFoundEntitySetOrSingleton = null;
break; break;
} }
} else { if (lastFoundEntitySetOrSingleton == null) {
// TODO: Cannot happen but should we throw an exception? // Once we loose track of the entity set there is no way to retrieve it.
}
return affectedEntitySet;
}
private EdmEntitySet getEntitySetOrNavigationEntitySet(List<UriResource> uriResourceParts) {
EdmEntitySet affectedEntitySet = null;
UriResource previousResourcePart = uriResourceParts.get(uriResourceParts.size() - 2);
if (previousResourcePart.getKind() == UriResourceKind.entitySet) {
affectedEntitySet = ((UriResourceEntitySet) previousResourcePart).getEntitySet();
} else if (previousResourcePart.getKind() == UriResourceKind.navigationProperty) {
affectedEntitySet = getEntitySetFromBeginning();
}
return affectedEntitySet;
}
private EdmEntitySet getEntitySetFromBeginning() {
EdmEntitySet lastFoundES = null;
for (UriResource uriResourcePart : uriInfo.getUriResourceParts()) {
if (UriResourceKind.function == uriResourcePart.getKind()) {
EdmFunctionImport functionImport = ((UriResourceFunction) uriResourcePart).getFunctionImport();
if (functionImport != null && functionImport.getReturnedEntitySet() != null) {
lastFoundES = functionImport.getReturnedEntitySet();
} else {
lastFoundES = null;
break;
}
} else if (UriResourceKind.entitySet == uriResourcePart.getKind()) {
lastFoundES = ((UriResourceEntitySet) uriResourcePart).getEntitySet();
} else if (UriResourceKind.navigationProperty == uriResourcePart.getKind()) {
EdmNavigationProperty navProp = ((UriResourceNavigation) uriResourcePart).getProperty();
if (lastFoundES != null) {
lastFoundES = (EdmEntitySet) lastFoundES.getRelatedBindingTarget(navProp.getName());
if (lastFoundES == null) {
break;
}
}
} else if (UriResourceKind.value == uriResourcePart.getKind()
|| UriResourceKind.action == uriResourcePart.getKind()) {
// TODO: Should we validate that we are at the end of the resource path
break;
} else {
lastFoundES = null;
break; break;
} }
counter++;
} }
return lastFoundES; return lastFoundEntitySetOrSingleton;
}
private EdmBindingTarget getEnitySetFromFunctionImport(UriResource uriResourcePart) {
UriResourceFunction uriResourceFunction = (UriResourceFunction) uriResourcePart;
EdmFunctionImport functionImport = uriResourceFunction.getFunctionImport();
if (functionImport != null && functionImport.getReturnedEntitySet() != null
&& !uriResourceFunction.isCollection()) {
return functionImport.getReturnedEntitySet();
}
return null;
}
private EdmBindingTarget getEntitySet(UriResource uriResourcePart) {
UriResourceEntitySet uriResourceEntitySet = (UriResourceEntitySet) uriResourcePart;
if (!uriResourceEntitySet.isCollection()) {
return uriResourceEntitySet.getEntitySet();
}
return null;
}
private EdmBindingTarget getEntitySetFromNavigation(EdmBindingTarget lastFoundEntitySetOrSingleton,
UriResource uriResourcePart) {
UriResourceNavigation uriResourceNavigation = (UriResourceNavigation) uriResourcePart;
if (lastFoundEntitySetOrSingleton != null && !uriResourceNavigation.isCollection()) {
EdmNavigationProperty navProp = uriResourceNavigation.getProperty();
return lastFoundEntitySetOrSingleton.getRelatedBindingTarget(navProp.getName());
}
return null;
} }
} }

View File

@ -18,17 +18,28 @@
*/ */
package org.apache.olingo.server.tecsvc; package org.apache.olingo.server.tecsvc;
import org.apache.olingo.commons.api.edm.EdmBindingTarget;
import org.apache.olingo.server.api.CustomETagSupport; import org.apache.olingo.server.api.CustomETagSupport;
public class ETagSupport implements CustomETagSupport { public class ETagSupport implements CustomETagSupport {
@Override @Override
public boolean hasETag(final String entitySetName) { public boolean hasETag(final EdmBindingTarget entitySetOrSingleton) {
return entitySetName.equals("ESCompAllPrim"); return entitySetOrSingleton.getName().equals("ESCompAllPrim");
} }
@Override @Override
public boolean hasMediaETag(final String entitySetName) { public boolean hasMediaETag(final EdmBindingTarget entitySetOrSingleton) {
return entitySetName.equals("ESMedia"); return entitySetOrSingleton.getName().equals("ESMedia");
}
@Override
public String getMetadataETag() {
return null;
}
@Override
public String getServiceDocumentETag() {
return null;
} }
} }

View File

@ -22,40 +22,35 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
import org.apache.olingo.commons.api.edm.Edm; import org.apache.olingo.commons.api.edm.Edm;
import org.apache.olingo.commons.api.edm.EdmBindingTarget;
import org.apache.olingo.commons.api.http.HttpMethod;
import org.apache.olingo.commons.core.edm.EdmProviderImpl; import org.apache.olingo.commons.core.edm.EdmProviderImpl;
import org.apache.olingo.server.api.CustomETagSupport; import org.apache.olingo.server.api.CustomETagSupport;
import org.apache.olingo.server.api.uri.UriInfo; import org.apache.olingo.server.api.uri.UriInfo;
import org.apache.olingo.server.core.uri.parser.Parser; import org.apache.olingo.server.core.uri.parser.Parser;
import org.apache.olingo.server.core.uri.parser.UriParserException;
import org.apache.olingo.server.core.uri.parser.UriParserSemanticException;
import org.apache.olingo.server.core.uri.validator.UriValidator;
import org.apache.olingo.server.tecsvc.provider.EdmTechProvider; import org.apache.olingo.server.tecsvc.provider.EdmTechProvider;
import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
public class PreconditionsValidatorTest { public class PreconditionsValidatorTest {
// -------------- POSITIVE TESTS --------------------------------------------------------------------------------
@Test @Test
public void simpleEntity() throws Exception { public void simpleEntity() throws Exception {
UriInfo uriInfo = new Parser().parseUri("ESAllPrim(1)", null, null, getEdm()); UriInfo uriInfo = new Parser().parseUri("ESAllPrim(1)", null, null, getEdm());
new PreconditionsValidator(new ETagSupport(), uriInfo, "*", "*").validatePreconditions(false); new PreconditionsValidator(new ETagSupport(), uriInfo, "*", "*").validatePreconditions(false);
} }
@Test
public void boundActionOnEsKeyNav() throws Exception {
UriInfo uriInfo =
new Parser().parseUri("ESKeyNav(1)/Namespace1_Alias.BAETTwoKeyNavRTETTwoKeyNav", null, null, getEdm());
new PreconditionsValidator(new ETagSupport(), uriInfo, "*", "*").validatePreconditions(false);
}
@Test @Test
public void simpleEntityValue() throws Exception { public void simpleEntityValue() throws Exception {
UriInfo uriInfo = new Parser().parseUri("ESMedia(1)/$value", null, null, getEdm()); UriInfo uriInfo = new Parser().parseUri("ESMedia(1)/$value", null, null, getEdm());
new PreconditionsValidator(new ETagSupport(), uriInfo, "*", "*").validatePreconditions(true); new PreconditionsValidator(new ETagSupport(), uriInfo, "*", "*").validatePreconditions(true);
} }
@Test
public void simpleEntityValueValidationNotActiveForMedia() throws Exception {
UriInfo uriInfo = new Parser().parseUri("ESMedia(1)/$value", null, null, getEdm());
new PreconditionsValidator(new ETagSupport(true, false), uriInfo, null, null).validatePreconditions(true);
}
@Test @Test
public void EntityAndToOneNavigation() throws Exception { public void EntityAndToOneNavigation() throws Exception {
UriInfo uriInfo = new Parser().parseUri("ESAllPrim(1)/NavPropertyETTwoPrimOne", null, null, getEdm()); UriInfo uriInfo = new Parser().parseUri("ESAllPrim(1)/NavPropertyETTwoPrimOne", null, null, getEdm());
@ -63,44 +58,164 @@ public class PreconditionsValidatorTest {
} }
@Test @Test
public void simpleEntityPreconditionsReqException() throws Exception { public void EntityAndToManyNavigationWithKey() throws Exception {
UriInfo uriInfo = new Parser().parseUri("ESAllPrim(1)", null, null, getEdm()); UriInfo uriInfo = new Parser().parseUri("ESAllPrim(1)/NavPropertyETTwoPrimMany(1)", null, null, getEdm());
try { new PreconditionsValidator(new ETagSupport("ESTwoPrim"), uriInfo, "*", "*").validatePreconditions(false);
new PreconditionsValidator(new ETagSupport(), uriInfo, null, null).validatePreconditions(false);
fail("Expected a PreconditionRequiredException but was not thrown");
} catch (PreconditionRequiredException e) {
assertEquals(PreconditionRequiredException.MessageKeys.MISSING_HEADER, e.getMessageKey());
}
} }
@Test @Test
public void boundActionOnEsKeyNavPreconditionsRequired() throws Exception { public void EntityAndToOneNavigationValue() throws Exception {
UriInfo uriInfo = new Parser().parseUri("ESKeyNav(1)/NavPropertyETMediaOne/$value", null, null, getEdm());
new PreconditionsValidator(new ETagSupport("ESMedia"), uriInfo, "*", "*").validatePreconditions(true);
}
@Test
public void boundActionOnEsKeyNav() throws Exception {
UriInfo uriInfo = UriInfo uriInfo =
new Parser().parseUri("ESKeyNav(1)/Namespace1_Alias.BAETTwoKeyNavRTETTwoKeyNav", null, null, getEdm()); new Parser().parseUri("ESKeyNav(1)/Namespace1_Alias.BAETTwoKeyNavRTETTwoKeyNav", null, null, getEdm());
try { new PreconditionsValidator(new ETagSupport("ESKeyNav"), uriInfo, "*", "*").validatePreconditions(false);
new PreconditionsValidator(new ETagSupport("ESKeyNav"), uriInfo, null, null).validatePreconditions(false);
fail("Expected a PreconditionRequiredException but was not thrown");
} catch (PreconditionRequiredException e) {
assertEquals(PreconditionRequiredException.MessageKeys.MISSING_HEADER, e.getMessageKey());
}
} }
@Test @Test
public void simpleEntityValuePreconditionsRequired() throws Exception { public void boundActionOnEsKeyNavWithNavigation() throws Exception {
UriInfo uriInfo =
new Parser().parseUri("ESKeyNav(1)/NavPropertyETKeyNavOne/Namespace1_Alias.BAETTwoKeyNavRTETTwoKeyNav", null,
null, getEdm());
new PreconditionsValidator(new ETagSupport("ESKeyNav"), uriInfo, "*", "*").validatePreconditions(false);
}
@Test
public void singleton() throws Exception {
UriInfo uriInfo = new Parser().parseUri("SI", null, null, getEdm());
new PreconditionsValidator(new ETagSupport("SI"), uriInfo, "*", "*").validatePreconditions(false);
}
@Test
public void singletonWithNavigation() throws Exception {
UriInfo uriInfo = new Parser().parseUri("SINav/NavPropertyETKeyNavOne", null, null, getEdm());
new PreconditionsValidator(new ETagSupport("ESKeyNav"), uriInfo, "*", "*").validatePreconditions(false);
}
@Test
public void singletonWithNavigationValue() throws Exception {
UriInfo uriInfo =
new Parser().parseUri("SINav/NavPropertyETKeyNavOne/NavPropertyETMediaOne/$value", null, null, getEdm());
new PreconditionsValidator(new ETagSupport("ESMedia"), uriInfo, "*", "*").validatePreconditions(false);
}
@Test
public void singletonWithAction() throws Exception {
UriInfo uriInfo = new Parser().parseUri("SINav/Namespace1_Alias.BAETTwoKeyNavRTETTwoKeyNav", null, null, getEdm());
new PreconditionsValidator(new ETagSupport("SINav"), uriInfo, "*", "*").validatePreconditions(false);
}
@Test
public void singletonWithActionAndNavigation() throws Exception {
UriInfo uriInfo =
new Parser().parseUri("SINav/NavPropertyETKeyNavOne/Namespace1_Alias.BAETTwoKeyNavRTETTwoKeyNav", null, null,
getEdm());
new PreconditionsValidator(new ETagSupport("ESKeyNav"), uriInfo, "*", "*").validatePreconditions(false);
}
@Test
public void simpleEntityValueValidationNotActiveForMedia() throws Exception {
UriInfo uriInfo = new Parser().parseUri("ESMedia(1)/$value", null, null, getEdm()); UriInfo uriInfo = new Parser().parseUri("ESMedia(1)/$value", null, null, getEdm());
try { new PreconditionsValidator(new ETagSupport(true, false), uriInfo, null, null).validatePreconditions(true);
new PreconditionsValidator(new ETagSupport(), uriInfo, null, null).validatePreconditions(true); }
fail("Expected a PreconditionRequiredException but was not thrown");
} catch (PreconditionRequiredException e) { // -------------- IGNORE VALIDATION TESTS -----------------------------------------------------------------------
assertEquals(PreconditionRequiredException.MessageKeys.MISSING_HEADER, e.getMessageKey());
} @Test
public void entitySetMustNotLeadToException() throws Exception {
UriInfo uriInfo = new Parser().parseUri("ESAllPrim", null, null, getEdm());
new PreconditionsValidator(new ETagSupport(), uriInfo, null, null).validatePreconditions(false);
} }
@Test @Test
public void EntityAndToOneNavigationPreconditionsRequired() throws Exception { public void propertyMustNotLeadToException() throws Exception {
UriInfo uriInfo = new Parser().parseUri("ESAllPrim(1)/NavPropertyETTwoPrimOne", null, null, getEdm()); UriInfo uriInfo = new Parser().parseUri("ESAllPrim(1)/PropertyInt16", null, null, getEdm());
new PreconditionsValidator(new ETagSupport(), uriInfo, null, null).validatePreconditions(false);
}
@Test
public void propertyValueMustNotLeadToException() throws Exception {
UriInfo uriInfo = new Parser().parseUri("ESAllPrim(1)/PropertyInt16/$value", null, null, getEdm());
new PreconditionsValidator(new ETagSupport(), uriInfo, null, null).validatePreconditions(true);
}
@Test
public void navigationToManyMustNotLeadToException() throws Exception {
UriInfo uriInfo = new Parser().parseUri("ESAllPrim(1)/NavPropertyETTwoPrimMany", null, null, getEdm());
new PreconditionsValidator(new ETagSupport(), uriInfo, null, null).validatePreconditions(false);
}
@Test
public void navigationOnPropertyMustNotLeadToException() throws Exception {
UriInfo uriInfo = new Parser().parseUri("ESAllPrim(1)/NavPropertyETTwoPrimOne/PropertyInt16", null, null, getEdm());
new PreconditionsValidator(new ETagSupport(), uriInfo, null, null).validatePreconditions(false);
}
@Test
public void navigationToManyOnActionMustNotLeadToException() throws Exception {
UriInfo uriInfo =
new Parser().parseUri("ESTwoPrim(1)/NavPropertyETAllPrimMany/Namespace1_Alias.BAESAllPrimRTETAllPrim", null,
null, getEdm());
new PreconditionsValidator(new ETagSupport(), uriInfo, null, null).validatePreconditions(false);
}
@Test
public void navigationWithoutBindingMustNotLeadToAnException() throws Exception {
UriInfo uriInfo =
new Parser()
.parseUri(
"ESTwoBaseTwoKeyNav(PropertyInt16=1,PropertyString='test')"
+ "/NavPropertyETBaseTwoKeyNavMany(PropertyInt16=1,PropertyString='test')",
null, null, getEdm());
new PreconditionsValidator(new ETagSupport(), uriInfo, null, null).validatePreconditions(false);
}
// -------------- NEGATIVE TESTS --------------------------------------------------------------------------------
@Test
public void positiveTestsMustLeadToAnExceptionIfNoHeaderIsPresent() throws Exception {
runException("ESAllPrim(1)", null);
runException("ESMedia(1)/$value", null);
runException("ESAllPrim(1)/NavPropertyETTwoPrimOne", null);
runException("ESAllPrim(1)/NavPropertyETTwoPrimMany(1)", null);
runException("ESKeyNav(1)/NavPropertyETMediaOne/$value", null);
runException("ESKeyNav(1)/Namespace1_Alias.BAETTwoKeyNavRTETTwoKeyNav", null);
runException("ESKeyNav(1)/NavPropertyETKeyNavOne/Namespace1_Alias.BAETTwoKeyNavRTETTwoKeyNav", null);
runException("SI", null);
runException("SINav/NavPropertyETKeyNavOne", null);
runException("SINav/NavPropertyETKeyNavOne/NavPropertyETMediaOne/$value", null);
runException("SINav/Namespace1_Alias.BAETTwoKeyNavRTETTwoKeyNav", null);
runException("SINav/NavPropertyETKeyNavOne/Namespace1_Alias.BAETTwoKeyNavRTETTwoKeyNav", null);
}
@Ignore
@Test
public void resourceSegmentAfterActionMustLeadToUriParserException() throws Exception {
//TODO: Check with URI Parser
UriInfo uriInfo =
new Parser().parseUri("ESKeyNav(1)/Namespace1_Alias.BAETTwoKeyNavRTETTwoKeyNav/PropertyInt16", null, null,
getEdm());
new UriValidator().validate(uriInfo, HttpMethod.GET);
new PreconditionsValidator(new ETagSupport("ESKeyNav"), uriInfo, "*", "*").validatePreconditions(false);
}
@Test(expected = UriParserSemanticException.class)
public void valueMustBeLastSegment() throws Exception {
new Parser().parseUri("ESMedia(1)/$value/PropertyInt16", null, null, getEdm());
}
private void runException(String uri, String expectedEntitySet) throws UriParserException {
UriInfo uriInfo = new Parser().parseUri(uri, null, null, getEdm());
try { try {
new PreconditionsValidator(new ETagSupport(), uriInfo, null, null).validatePreconditions(false); CustomETagSupport etagSupport =
expectedEntitySet == null ? new ETagSupport() : new ETagSupport(expectedEntitySet);
boolean isMedia = uri.endsWith("$value");
new PreconditionsValidator(etagSupport, uriInfo, null, null).validatePreconditions(isMedia);
fail("Expected a PreconditionRequiredException but was not thrown"); fail("Expected a PreconditionRequiredException but was not thrown");
} catch (PreconditionRequiredException e) { } catch (PreconditionRequiredException e) {
assertEquals(PreconditionRequiredException.MessageKeys.MISSING_HEADER, e.getMessageKey()); assertEquals(PreconditionRequiredException.MessageKeys.MISSING_HEADER, e.getMessageKey());
@ -117,33 +232,41 @@ public class PreconditionsValidatorTest {
private boolean mediaETag = true; private boolean mediaETag = true;
private String entitySetName; private String entitySetName;
public ETagSupport() { public ETagSupport() {}
}
public ETagSupport(String entitySetName) { public ETagSupport(String entitySetName) {
this.entitySetName = entitySetName; this.entitySetName = entitySetName;
} }
public ETagSupport(boolean eTag, boolean mediaETag) { public ETagSupport(boolean eTag, boolean mediaETag) {
this.eTag = eTag; this.eTag = eTag;
this.mediaETag = mediaETag; this.mediaETag = mediaETag;
} }
@Override @Override
public boolean hasETag(String entitySetName) { public boolean hasETag(EdmBindingTarget entitySetOrSingeton) {
if(this.entitySetName != null){ if (this.entitySetName != null) {
assertEquals(this.entitySetName, entitySetName); assertEquals(this.entitySetName, entitySetOrSingeton.getName());
} }
return eTag; return eTag;
} }
@Override @Override
public boolean hasMediaETag(String entitySetName) { public boolean hasMediaETag(EdmBindingTarget entitySetOrSingelton) {
if(this.entitySetName != null){ if (this.entitySetName != null) {
assertEquals(this.entitySetName, entitySetName); assertEquals(this.entitySetName, entitySetOrSingelton.getName());
} }
return mediaETag; return mediaETag;
} }
@Override
public String getMetadataETag() {
return null;
}
@Override
public String getServiceDocumentETag() {
return null;
}
} }
} }