[OLINGO-663] Generic Precondition Required Handling
This commit is contained in:
parent
fd71b7ebdd
commit
53881c2acf
|
@ -18,6 +18,8 @@
|
|||
*/
|
||||
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
|
||||
* 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.
|
||||
* 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.
|
||||
* @param entitySetName
|
||||
* @param entitySetOrSingleton
|
||||
* @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.
|
||||
* 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.
|
||||
* 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
|
||||
*/
|
||||
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();
|
||||
|
||||
}
|
||||
|
|
|
@ -24,7 +24,8 @@ public class PreconditionRequiredException extends ODataTranslatedException {
|
|||
private static final long serialVersionUID = -8112658467394158700L;
|
||||
|
||||
public static enum MessageKeys implements MessageKey {
|
||||
MISSING_HEADER;
|
||||
MISSING_HEADER,
|
||||
INVALID_URI;
|
||||
|
||||
@Override
|
||||
public String getKey() {
|
||||
|
|
|
@ -18,9 +18,7 @@
|
|||
*/
|
||||
package org.apache.olingo.server.core;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.olingo.commons.api.edm.EdmEntitySet;
|
||||
import org.apache.olingo.commons.api.edm.EdmBindingTarget;
|
||||
import org.apache.olingo.commons.api.edm.EdmFunctionImport;
|
||||
import org.apache.olingo.commons.api.edm.EdmNavigationProperty;
|
||||
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.UriResourceEntitySet;
|
||||
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.UriResourceSingleton;
|
||||
|
||||
public class PreconditionsValidator {
|
||||
|
||||
|
@ -48,10 +46,10 @@ public class PreconditionsValidator {
|
|||
}
|
||||
|
||||
public void validatePreconditions(boolean isMediaValue) throws PreconditionRequiredException {
|
||||
EdmEntitySet affectedEntitySet = extractInformation();
|
||||
if (affectedEntitySet != null) {
|
||||
if ((isMediaValue && customETagSupport.hasMediaETag(affectedEntitySet.getName())) ||
|
||||
(!isMediaValue && customETagSupport.hasETag(affectedEntitySet.getName()))) {
|
||||
EdmBindingTarget affectedEntitySetOrSingleton = extractInformation();
|
||||
if (affectedEntitySetOrSingleton != null) {
|
||||
if ((isMediaValue && customETagSupport.hasMediaETag(affectedEntitySetOrSingleton)) ||
|
||||
(!isMediaValue && customETagSupport.hasETag(affectedEntitySetOrSingleton))) {
|
||||
checkETagHeaderPresent();
|
||||
}
|
||||
}
|
||||
|
@ -64,75 +62,69 @@ public class PreconditionsValidator {
|
|||
}
|
||||
}
|
||||
|
||||
private EdmEntitySet extractInformation() {
|
||||
EdmEntitySet affectedEntitySet = null;
|
||||
List<UriResource> uriResourceParts = uriInfo.getUriResourceParts();
|
||||
if (uriResourceParts.size() > 0) {
|
||||
UriResource uriResourcePart = uriResourceParts.get(uriResourceParts.size() - 1);
|
||||
private EdmBindingTarget extractInformation() throws PreconditionRequiredException {
|
||||
EdmBindingTarget lastFoundEntitySetOrSingleton = null;
|
||||
int counter = 0;
|
||||
for (UriResource uriResourcePart : uriInfo.getUriResourceParts()) {
|
||||
switch (uriResourcePart.getKind()) {
|
||||
case function:
|
||||
lastFoundEntitySetOrSingleton = getEnitySetFromFunctionImport(uriResourcePart);
|
||||
break;
|
||||
case singleton:
|
||||
lastFoundEntitySetOrSingleton = ((UriResourceSingleton) uriResourcePart).getSingleton();
|
||||
break;
|
||||
case entitySet:
|
||||
affectedEntitySet = ((UriResourceEntitySet) uriResourcePart).getEntitySet();
|
||||
lastFoundEntitySetOrSingleton = getEntitySet(uriResourcePart);
|
||||
break;
|
||||
case navigationProperty:
|
||||
affectedEntitySet = getEntitySetFromBeginning();
|
||||
lastFoundEntitySetOrSingleton = getEntitySetFromNavigation(lastFoundEntitySetOrSingleton, uriResourcePart);
|
||||
break;
|
||||
case value:
|
||||
affectedEntitySet = getEntitySetOrNavigationEntitySet(uriResourceParts);
|
||||
break;
|
||||
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;
|
||||
default:
|
||||
// TODO: Cannot happen but should we throw an exception?
|
||||
lastFoundEntitySetOrSingleton = null;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// TODO: Cannot happen but should we throw an exception?
|
||||
}
|
||||
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;
|
||||
if (lastFoundEntitySetOrSingleton == null) {
|
||||
// Once we loose track of the entity set there is no way to retrieve it.
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,17 +18,28 @@
|
|||
*/
|
||||
package org.apache.olingo.server.tecsvc;
|
||||
|
||||
import org.apache.olingo.commons.api.edm.EdmBindingTarget;
|
||||
import org.apache.olingo.server.api.CustomETagSupport;
|
||||
|
||||
public class ETagSupport implements CustomETagSupport {
|
||||
|
||||
@Override
|
||||
public boolean hasETag(final String entitySetName) {
|
||||
return entitySetName.equals("ESCompAllPrim");
|
||||
public boolean hasETag(final EdmBindingTarget entitySetOrSingleton) {
|
||||
return entitySetOrSingleton.getName().equals("ESCompAllPrim");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasMediaETag(final String entitySetName) {
|
||||
return entitySetName.equals("ESMedia");
|
||||
public boolean hasMediaETag(final EdmBindingTarget entitySetOrSingleton) {
|
||||
return entitySetOrSingleton.getName().equals("ESMedia");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMetadataETag() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getServiceDocumentETag() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,40 +22,35 @@ import static org.junit.Assert.assertEquals;
|
|||
import static org.junit.Assert.fail;
|
||||
|
||||
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.server.api.CustomETagSupport;
|
||||
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.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.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
public class PreconditionsValidatorTest {
|
||||
|
||||
// -------------- POSITIVE TESTS --------------------------------------------------------------------------------
|
||||
|
||||
@Test
|
||||
public void simpleEntity() throws Exception {
|
||||
UriInfo uriInfo = new Parser().parseUri("ESAllPrim(1)", null, null, getEdm());
|
||||
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
|
||||
public void simpleEntityValue() throws Exception {
|
||||
UriInfo uriInfo = new Parser().parseUri("ESMedia(1)/$value", null, null, getEdm());
|
||||
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
|
||||
public void EntityAndToOneNavigation() throws Exception {
|
||||
UriInfo uriInfo = new Parser().parseUri("ESAllPrim(1)/NavPropertyETTwoPrimOne", null, null, getEdm());
|
||||
|
@ -63,44 +58,164 @@ public class PreconditionsValidatorTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void simpleEntityPreconditionsReqException() throws Exception {
|
||||
UriInfo uriInfo = new Parser().parseUri("ESAllPrim(1)", null, null, getEdm());
|
||||
try {
|
||||
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());
|
||||
}
|
||||
public void EntityAndToManyNavigationWithKey() throws Exception {
|
||||
UriInfo uriInfo = new Parser().parseUri("ESAllPrim(1)/NavPropertyETTwoPrimMany(1)", null, null, getEdm());
|
||||
new PreconditionsValidator(new ETagSupport("ESTwoPrim"), uriInfo, "*", "*").validatePreconditions(false);
|
||||
}
|
||||
|
||||
@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 =
|
||||
new Parser().parseUri("ESKeyNav(1)/Namespace1_Alias.BAETTwoKeyNavRTETTwoKeyNav", null, null, getEdm());
|
||||
try {
|
||||
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());
|
||||
}
|
||||
new PreconditionsValidator(new ETagSupport("ESKeyNav"), uriInfo, "*", "*").validatePreconditions(false);
|
||||
}
|
||||
|
||||
@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());
|
||||
try {
|
||||
new PreconditionsValidator(new ETagSupport(), uriInfo, null, null).validatePreconditions(true);
|
||||
fail("Expected a PreconditionRequiredException but was not thrown");
|
||||
} catch (PreconditionRequiredException e) {
|
||||
assertEquals(PreconditionRequiredException.MessageKeys.MISSING_HEADER, e.getMessageKey());
|
||||
}
|
||||
new PreconditionsValidator(new ETagSupport(true, false), uriInfo, null, null).validatePreconditions(true);
|
||||
}
|
||||
|
||||
// -------------- IGNORE VALIDATION TESTS -----------------------------------------------------------------------
|
||||
|
||||
@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
|
||||
public void EntityAndToOneNavigationPreconditionsRequired() throws Exception {
|
||||
UriInfo uriInfo = new Parser().parseUri("ESAllPrim(1)/NavPropertyETTwoPrimOne", null, null, getEdm());
|
||||
public void propertyMustNotLeadToException() throws Exception {
|
||||
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 {
|
||||
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");
|
||||
} catch (PreconditionRequiredException e) {
|
||||
assertEquals(PreconditionRequiredException.MessageKeys.MISSING_HEADER, e.getMessageKey());
|
||||
|
@ -117,33 +232,41 @@ public class PreconditionsValidatorTest {
|
|||
private boolean mediaETag = true;
|
||||
private String entitySetName;
|
||||
|
||||
public ETagSupport() {
|
||||
}
|
||||
public ETagSupport() {}
|
||||
|
||||
public ETagSupport(String entitySetName) {
|
||||
this.entitySetName = entitySetName;
|
||||
}
|
||||
}
|
||||
|
||||
public ETagSupport(boolean eTag, boolean mediaETag) {
|
||||
this.eTag = eTag;
|
||||
this.mediaETag = mediaETag;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean hasETag(String entitySetName) {
|
||||
if(this.entitySetName != null){
|
||||
assertEquals(this.entitySetName, entitySetName);
|
||||
public boolean hasETag(EdmBindingTarget entitySetOrSingeton) {
|
||||
if (this.entitySetName != null) {
|
||||
assertEquals(this.entitySetName, entitySetOrSingeton.getName());
|
||||
}
|
||||
return eTag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasMediaETag(String entitySetName) {
|
||||
if(this.entitySetName != null){
|
||||
assertEquals(this.entitySetName, entitySetName);
|
||||
public boolean hasMediaETag(EdmBindingTarget entitySetOrSingelton) {
|
||||
if (this.entitySetName != null) {
|
||||
assertEquals(this.entitySetName, entitySetOrSingelton.getName());
|
||||
}
|
||||
return mediaETag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMetadataETag() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getServiceDocumentETag() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue