olingo-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From chr...@apache.org
Subject [1/3] olingo-odata4 git commit: [OLINGO-782] Functions with key predicates get validated
Date Wed, 30 Sep 2015 13:12:03 GMT
Repository: olingo-odata4
Updated Branches:
  refs/heads/master c66b65922 -> b9403cd39


[OLINGO-782] Functions with key predicates get validated


Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/64388ecf
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/64388ecf
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/64388ecf

Branch: refs/heads/master
Commit: 64388ecf2bda2d4ed0854cc0addc8d2d65c62475
Parents: c66b659
Author: Christia Holzer <c.holzer@sap.com>
Authored: Tue Sep 29 15:34:47 2015 +0200
Committer: Christia Holzer <c.holzer@sap.com>
Committed: Wed Sep 30 15:04:22 2015 +0200

----------------------------------------------------------------------
 .../core/uri/parser/UriParseTreeVisitor.java    | 280 +++++++++++--------
 .../server/core/uri/validator/UriValidator.java |  23 +-
 .../server/core/PreconditionsValidatorTest.java |   2 +-
 .../core/uri/antlr/TestFullResourcePath.java    | 127 ++++++++-
 4 files changed, 305 insertions(+), 127 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/64388ecf/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriParseTreeVisitor.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriParseTreeVisitor.java
b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriParseTreeVisitor.java
index bedfaf2..edd6058 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriParseTreeVisitor.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriParseTreeVisitor.java
@@ -40,16 +40,19 @@ import org.apache.olingo.commons.api.edm.EdmNavigationProperty;
 import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
 import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
 import org.apache.olingo.commons.api.edm.EdmProperty;
+import org.apache.olingo.commons.api.edm.EdmReturnType;
 import org.apache.olingo.commons.api.edm.EdmSingleton;
 import org.apache.olingo.commons.api.edm.EdmStructuredType;
 import org.apache.olingo.commons.api.edm.EdmType;
 import org.apache.olingo.commons.api.edm.FullQualifiedName;
+import org.apache.olingo.commons.api.edm.constants.EdmTypeKind;
 import org.apache.olingo.commons.api.ex.ODataRuntimeException;
 import org.apache.olingo.commons.core.edm.primitivetype.EdmPrimitiveTypeFactory;
 import org.apache.olingo.server.api.uri.UriInfoKind;
 import org.apache.olingo.server.api.uri.UriInfoResource;
 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.UriResourceNavigation;
 import org.apache.olingo.server.api.uri.UriResourcePartTyped;
 import org.apache.olingo.server.api.uri.UriResourceRoot;
@@ -77,7 +80,9 @@ import org.apache.olingo.server.core.uri.UriResourceStartingTypeFilterImpl;
 import org.apache.olingo.server.core.uri.UriResourceTypedImpl;
 import org.apache.olingo.server.core.uri.UriResourceValueImpl;
 import org.apache.olingo.server.core.uri.UriResourceWithKeysImpl;
-import org.apache.olingo.server.core.uri.antlr.*;
+import org.apache.olingo.server.core.uri.antlr.UriLexer;
+import org.apache.olingo.server.core.uri.antlr.UriParserBaseVisitor;
+import org.apache.olingo.server.core.uri.antlr.UriParserParser;
 import org.apache.olingo.server.core.uri.antlr.UriParserParser.AllEOFContext;
 import org.apache.olingo.server.core.uri.antlr.UriParserParser.AllExprContext;
 import org.apache.olingo.server.core.uri.antlr.UriParserParser.AltAddContext;
@@ -1564,6 +1569,7 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object>
{
   @Override
   public Object visitNameValueOptList(final NameValueOptListContext ctx) {
     if (ctx.vVO != null) {
+      // This branch is chosen if the key predicate is a common expression e.g. EntitySet(0)
 
       // is single key predicate without a name
       String valueText = ctx.vVO.getText();
@@ -1580,67 +1586,98 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object>
{
       if (!(last instanceof UriResourcePartTyped)) {
         throw wrap(new UriParserSemanticException("Parameters list on untyped resource path
segment not allowed",
             UriParserSemanticException.MessageKeys.PARAMETERS_LIST_ONLY_FOR_TYPED_PARTS));
-      }
-      EdmEntityType lastType = (EdmEntityType) ((UriResourcePartTyped) last).getType();
-
-      // get list of keys for lastType
-      List<String> lastKeyPredicates = lastType.getKeyPredicateNames();
-
-      // If there is exactly one key defined in the EDM, then this key is the key written
in the URI,
-      // so fill the keylist with this key and return.
-      if (lastKeyPredicates.size() == 1) {
-        return Collections.singletonList(new UriParameterImpl()
-            .setName(lastKeyPredicates.get(0))
-            .setText(valueText)
-            .setExpression(expression));
-      }
 
-      // There are more keys defined in the EDM, but only one is written in the URI. This
is allowed only if
-      // referential constraints are defined on this navigation property which can be used
to fill up all
-      // required keys.
-      // For using referential constraints the last resource part must be a navigation property.
-      if (!(context.contextUriInfo.getLastResourcePart() instanceof UriResourceNavigationPropertyImpl))
{
-        throw wrap(new UriParserSemanticException("Wrong number of key properties.",
-            UriParserSemanticException.MessageKeys.WRONG_NUMBER_OF_KEY_PROPERTIES,
-            Integer.toString(lastKeyPredicates.size()), "1"));
-      }
-      UriResourceNavigationPropertyImpl lastNav = (UriResourceNavigationPropertyImpl) last;
+      } else if (last instanceof UriResourceFunction) {
+        // Handle functions
+        final UriResourceFunction uriResourceFunction =
+            (UriResourceFunction) context.contextUriInfo.getLastResourcePart();
+        final EdmReturnType returnType = uriResourceFunction.getFunction().getReturnType();
 
-      // get the partner of the navigation property
-      EdmNavigationProperty partner = lastNav.getProperty().getPartner();
-      if (partner == null) {
-        throw wrap(new UriParserSemanticException("Wrong number of key properties.",
-            UriParserSemanticException.MessageKeys.WRONG_NUMBER_OF_KEY_PROPERTIES,
-            Integer.toString(lastKeyPredicates.size()), "1"));
-      }
+        if (returnType.getType().getKind() != EdmTypeKind.ENTITY || !returnType.isCollection())
{
+          throw wrap(new UriParserSemanticException("No keys allowed",
+              UriParserSemanticException.MessageKeys.KEY_NOT_ALLOWED));
+        } else {
+          // The functions returns a collection of entities
+          // Get the EDM Type and determine how many key predicates are needed. In this case
only one 
+          // key predicate is allowed. If the entity type needs more than one key predicate,
the client
+          // has to use the key value syntax e.g. EntitySet(ID=1,Order=2)
+          final EdmEntityType entityType = (EdmEntityType) uriResourceFunction.getFunction().getReturnType().getType();
+          final List<String> lastKeyPredicates = entityType.getKeyPredicateNames();
+
+          if (lastKeyPredicates.size() == 1) {
+            return Collections.singletonList(new UriParameterImpl()
+                .setName(lastKeyPredicates.get(0))
+                .setText(valueText)
+                .setExpression(expression));
+          } else {
+            throw wrap(new UriParserSemanticException("Wrong number of key properties.",
+                UriParserSemanticException.MessageKeys.WRONG_NUMBER_OF_KEY_PROPERTIES,
+                Integer.toString(lastKeyPredicates.size()), "1"));
+          }
+        }
+      } else {
+        // Handle EntitySets
+        EdmEntityType lastType = (EdmEntityType) ((UriResourcePartTyped) last).getType();
+
+        // get list of keys for lastType
+        List<String> lastKeyPredicates = lastType.getKeyPredicateNames();
+
+        // If there is exactly one key defined in the EDM, then this key is the key written
in the URI,
+        // so fill the keylist with this key and return.
+        if (lastKeyPredicates.size() == 1) {
+          return Collections.singletonList(new UriParameterImpl()
+              .setName(lastKeyPredicates.get(0))
+              .setText(valueText)
+              .setExpression(expression));
+        }
 
-      // create the keylist
-      List<UriParameterImpl> list = new ArrayList<UriParameterImpl>();
+        // There are more keys defined in the EDM, but only one is written in the URI. This
is allowed only if
+        // referential constraints are defined on this navigation property which can be used
to fill up all
+        // required keys.
+        // For using referential constraints the last resource part must be a navigation
property.
+        if (!(context.contextUriInfo.getLastResourcePart() instanceof UriResourceNavigationPropertyImpl))
{
+          throw wrap(new UriParserSemanticException("Wrong number of key properties.",
+              UriParserSemanticException.MessageKeys.WRONG_NUMBER_OF_KEY_PROPERTIES,
+              Integer.toString(lastKeyPredicates.size()), "1"));
+        }
+        UriResourceNavigationPropertyImpl lastNav = (UriResourceNavigationPropertyImpl) last;
+
+        // get the partner of the navigation property
+        EdmNavigationProperty partner = lastNav.getProperty().getPartner();
+        if (partner == null) {
+          throw wrap(new UriParserSemanticException("Wrong number of key properties.",
+              UriParserSemanticException.MessageKeys.WRONG_NUMBER_OF_KEY_PROPERTIES,
+              Integer.toString(lastKeyPredicates.size()), "1"));
+        }
 
-      // Find the keys not filled by referential constraints
-      // and collect the other keys filled by referential constraints.
-      String missedKey = null;
-      for (String item : lastKeyPredicates) {
-        String property = partner.getReferencingPropertyName(item);
-        if (property != null) {
-          list.add(new UriParameterImpl().setName(item).setRefencedProperty(property));
-        } else {
-          if (missedKey == null) {
-            missedKey = item;
+        // create the keylist
+        List<UriParameterImpl> list = new ArrayList<UriParameterImpl>();
+
+        // Find the keys not filled by referential constraints
+        // and collect the other keys filled by referential constraints.
+        String missedKey = null;
+        for (String item : lastKeyPredicates) {
+          String property = partner.getReferencingPropertyName(item);
+          if (property != null) {
+            list.add(new UriParameterImpl().setName(item).setRefencedProperty(property));
           } else {
-            // two of more keys are missing
-            throw wrap(new UriParserSemanticException("Not enough referential constraints
defined",
-                UriParserSemanticException.MessageKeys.NOT_ENOUGH_REFERENTIAL_CONSTRAINTS));
+            if (missedKey == null) {
+              missedKey = item;
+            } else {
+              // two of more keys are missing
+              throw wrap(new UriParserSemanticException("Not enough referential constraints
defined",
+                  UriParserSemanticException.MessageKeys.NOT_ENOUGH_REFERENTIAL_CONSTRAINTS));
+            }
           }
         }
-      }
 
-      // the missing key is the one which is defined in the URI
-      list.add(new UriParameterImpl().setName(missedKey).setText(valueText).setExpression(expression));
+        // the missing key is the one which is defined in the URI
+        list.add(new UriParameterImpl().setName(missedKey).setText(valueText).setExpression(expression));
 
-      return list;
+        return list;
+      }
     } else if (ctx.vNVL != null) {
-
+      // The client provided a list of key values pairs e.g. EntitySet(ID=1,Order=2)
       List<UriParameterImpl> list = new ArrayList<UriParameterImpl>();
 
       for (ParseTree c : ctx.vNVL.vlNVP) {
@@ -1652,83 +1689,102 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object>
{
       }
 
       UriResource last = context.contextUriInfo.getLastResourcePart();
-      // if the last resource part is a function
-      /*
-       * if (last instanceof UriResourceFunctionImpl) {
-       * UriResourceFunctionImpl function = (UriResourceFunctionImpl) last;
-       * if (!function.isParameterListFilled()) {
-       * return list;
-       * }
-       * }
-       */
 
       // get type of last resource part
       if (!(last instanceof UriResourcePartTyped)) {
         throw wrap(new UriParserSemanticException("Parameters list on untyped resource path
segment not allowed",
             UriParserSemanticException.MessageKeys.PARAMETERS_LIST_ONLY_FOR_TYPED_PARTS));
       }
-      EdmEntityType lastType = (EdmEntityType) ((UriResourcePartTyped) last).getType();
-
-      // get list of keys for lastType
-      List<String> lastKeyPredicates = lastType.getKeyPredicateNames();
-
-      // check if all key are filled from the URI
-      if (list.size() == lastKeyPredicates.size()) {
-        return list;
-      }
+      if(last instanceof UriResourceFunction) {
+        final UriResourceFunction uriResourceFunction = (UriResourceFunction) context.contextUriInfo
+            .getLastResourcePart();
+        final EdmReturnType returnType = uriResourceFunction.getFunction().getReturnType();
 
-      // if not, check if the missing key predicates can be satisfied with help of the defined
-      // referential constraints
-      // for using referential constraints the last resource part must be a navigation property
-      if (!(context.contextUriInfo.getLastResourcePart() instanceof UriResourceNavigationPropertyImpl))
{
-        throw wrap(new UriParserSemanticException("Wrong number of key properties.",
-            UriParserSemanticException.MessageKeys.WRONG_NUMBER_OF_KEY_PROPERTIES,
-            Integer.toString(lastKeyPredicates.size()), Integer.toString(list.size())));
-      }
-      UriResourceNavigationPropertyImpl lastNav = (UriResourceNavigationPropertyImpl) last;
-
-      // get the partner of the navigation property
-      EdmNavigationProperty partner = lastNav.getProperty().getPartner();
-      if (partner == null) {
-        throw wrap(new UriParserSemanticException("Wrong number of key properties.",
-            UriParserSemanticException.MessageKeys.WRONG_NUMBER_OF_KEY_PROPERTIES,
-            Integer.toString(lastKeyPredicates.size()), Integer.toString(list.size())));
-      }
-
-      // fill missing keys from referential constraints
-      for (String key : lastKeyPredicates) {
-        boolean found = false;
-        for (UriParameterImpl item : list) {
-          if (item.getName().equals(key)) {
-            found = true;
-            break;
+        if (returnType.getType().getKind() != EdmTypeKind.ENTITY || !returnType.isCollection())
{
+          throw wrap(new UriParserSemanticException("No keys allowed",
+              UriParserSemanticException.MessageKeys.KEY_NOT_ALLOWED));
+        } else {
+          // The functions returns a collection of entities
+          // Get the EDM Type and determine how many key predicates are needed. 
+          // In case of functions all key predicates must be provided by the client.
+          final EdmEntityType entityType = (EdmEntityType) uriResourceFunction.getFunction().getReturnType().getType();
+          final List<String> lastKeyPredicates = entityType.getKeyPredicateNames();
+          
+          if(lastKeyPredicates.size() == list.size()) {
+            return list;
+          } else {
+            throw wrap(new UriParserSemanticException("Wrong number of key properties.",
+                UriParserSemanticException.MessageKeys.WRONG_NUMBER_OF_KEY_PROPERTIES,
+                Integer.toString(lastKeyPredicates.size()), "1"));
           }
         }
-
-        if (!found) {
-          String property = partner.getReferencingPropertyName(key);
-          if (property != null) {
-            // store the key name as referenced property
-            list.add(0, new UriParameterImpl().setName(key).setRefencedProperty(property));
+      } else {
+        // Handle entity sets
+        EdmEntityType lastType = (EdmEntityType) ((UriResourcePartTyped) last).getType();
+  
+        // get list of keys for lastType
+        List<String> lastKeyPredicates = lastType.getKeyPredicateNames();
+  
+        // check if all key are filled from the URI
+        if (list.size() == lastKeyPredicates.size()) {
+          return list;
+        }
+  
+        // if not, check if the missing key predicates can be satisfied with help of the
defined
+        // referential constraints
+        // for using referential constraints the last resource part must be a navigation
property
+        if (!(context.contextUriInfo.getLastResourcePart() instanceof UriResourceNavigationPropertyImpl))
{
+          throw wrap(new UriParserSemanticException("Wrong number of key properties.",
+              UriParserSemanticException.MessageKeys.WRONG_NUMBER_OF_KEY_PROPERTIES,
+              Integer.toString(lastKeyPredicates.size()), Integer.toString(list.size())));
+        }
+        UriResourceNavigationPropertyImpl lastNav = (UriResourceNavigationPropertyImpl) last;
+  
+        // get the partner of the navigation property
+        EdmNavigationProperty partner = lastNav.getProperty().getPartner();
+        if (partner == null) {
+          throw wrap(new UriParserSemanticException("Wrong number of key properties.",
+              UriParserSemanticException.MessageKeys.WRONG_NUMBER_OF_KEY_PROPERTIES,
+              Integer.toString(lastKeyPredicates.size()), Integer.toString(list.size())));
+        }
+  
+        // fill missing keys from referential constraints
+        for (String key : lastKeyPredicates) {
+          boolean found = false;
+          for (UriParameterImpl item : list) {
+            if (item.getName().equals(key)) {
+              found = true;
+              break;
+            }
+          }
+  
+          if (!found) {
+            String property = partner.getReferencingPropertyName(key);
+            if (property != null) {
+              // store the key name as referenced property
+              list.add(0, new UriParameterImpl().setName(key).setRefencedProperty(property));
+            }
           }
         }
-      }
-
-      // check again if all key predicates are filled from the URI
-      if (list.size() == lastKeyPredicates.size()) {
-        return list;
-      } else {
-        throw wrap(new UriParserSemanticException("Wrong number of key properties.",
-            UriParserSemanticException.MessageKeys.WRONG_NUMBER_OF_KEY_PROPERTIES,
-            Integer.toString(lastKeyPredicates.size()), Integer.toString(list.size())));
+  
+        // check again if all key predicates are filled from the URI
+        if (list.size() == lastKeyPredicates.size()) {
+          return list;
+        } else {
+          throw wrap(new UriParserSemanticException("Wrong number of key properties.",
+              UriParserSemanticException.MessageKeys.WRONG_NUMBER_OF_KEY_PROPERTIES,
+              Integer.toString(lastKeyPredicates.size()), Integer.toString(list.size())));
+        }
       }
     } else {
+      // No key predicates are provided by the client
+      
       if (context.contextReadingFunctionParameters) {
         return Collections.emptyList();
       } else {
         final UriResource last = context.contextUriInfo.getLastResourcePart();
-        final int number = last instanceof UriResourcePartTyped ?
-            ((EdmEntityType) ((UriResourcePartTyped) last).getType()).getKeyPredicateNames().size()
: 0;
+        final int number = last instanceof UriResourcePartTyped ? ((EdmEntityType) ((UriResourcePartTyped)
last)
+            .getType()).getKeyPredicateNames().size() : 0;
         throw wrap(new UriParserSemanticException("Wrong number of key properties.",
             UriParserSemanticException.MessageKeys.WRONG_NUMBER_OF_KEY_PROPERTIES, Integer.toString(number),
"0"));
       }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/64388ecf/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/validator/UriValidator.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/validator/UriValidator.java
b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/validator/UriValidator.java
index d793b5c..8693f1e 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/validator/UriValidator.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/validator/UriValidator.java
@@ -527,16 +527,20 @@ public class UriValidator {
   private void validateKeyPredicates(final UriInfo uriInfo) throws UriValidationException
{
     for (UriResource pathSegment : uriInfo.getUriResourceParts()) {
       final boolean isEntitySet = pathSegment.getKind() == UriResourceKind.entitySet;
-      if (isEntitySet || pathSegment.getKind() == UriResourceKind.navigationProperty) {
+      final boolean isEntityColFunction = isEntityColFunction(pathSegment);
+      
+      if (isEntitySet || pathSegment.getKind() == UriResourceKind.navigationProperty || isEntityColFunction)
{
         final List<UriParameter> keyPredicates = isEntitySet ?
             ((UriResourceEntitySet) pathSegment).getKeyPredicates() :
-            ((UriResourceNavigation) pathSegment).getKeyPredicates();
-
+              isEntityColFunction ? ((UriResourceFunction) pathSegment).getKeyPredicates()
+              : ((UriResourceNavigation) pathSegment).getKeyPredicates();
+            
         if (keyPredicates != null) {
 
           final EdmEntityType entityType = isEntitySet ?
               ((UriResourceEntitySet) pathSegment).getEntityType() :
-              (EdmEntityType) ((UriResourceNavigation) pathSegment).getType();
+              isEntityColFunction ? (EdmEntityType) ((UriResourceFunction) pathSegment).getType()

+              : (EdmEntityType) ((UriResourceNavigation) pathSegment).getType();
           final List<String> keyPredicateNames = entityType.getKeyPredicateNames();
           Map<String, EdmKeyPropertyRef> edmKeys = new HashMap<String, EdmKeyPropertyRef>();
           for (EdmKeyPropertyRef key : entityType.getKeyPropertyRefs()) {
@@ -590,6 +594,17 @@ public class UriValidator {
     }
   }
 
+  private boolean isEntityColFunction(final UriResource pathSegment) {
+    if(pathSegment.getKind() == UriResourceKind.function) {
+      final UriResourceFunction resourceFunction = (UriResourceFunction) pathSegment;
+      final EdmReturnType returnType = resourceFunction.getFunction().getReturnType();
+      
+      return returnType.isCollection() && returnType.getType().getKind() == EdmTypeKind.ENTITY;
+    } else {
+      return false;
+    }
+  }
+  
   private void validatePropertyOperations(final UriInfo uriInfo, final HttpMethod method)
       throws UriValidationException {
     final List<UriResource> parts = uriInfo.getUriResourceParts();

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/64388ecf/lib/server-test/src/test/java/org/apache/olingo/server/core/PreconditionsValidatorTest.java
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/PreconditionsValidatorTest.java
b/lib/server-test/src/test/java/org/apache/olingo/server/core/PreconditionsValidatorTest.java
index e2fe3ac..cf56edf 100644
--- a/lib/server-test/src/test/java/org/apache/olingo/server/core/PreconditionsValidatorTest.java
+++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/PreconditionsValidatorTest.java
@@ -96,7 +96,7 @@ public class PreconditionsValidatorTest {
 
   @Test
   public void navigationOnFunction() throws Exception {
-    assertTrue(mustValidate("FICRTESTwoKeyNav()(PropertyInt16=1,PropertyString='1')/NavPropertySINav",
"SINav"));
+    assertTrue(mustValidate("FICRTESTwoKeyNav()/NavPropertySINav", "SINav"));
   }
 
   @Test

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/64388ecf/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/antlr/TestFullResourcePath.java
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/antlr/TestFullResourcePath.java
b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/antlr/TestFullResourcePath.java
index 4cd015a..9c859db 100644
--- a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/antlr/TestFullResourcePath.java
+++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/antlr/TestFullResourcePath.java
@@ -1033,6 +1033,118 @@ public class TestFullResourcePath {
   }
   
   @Test
+  public void runFunctionsWithKeyPredicates() throws Exception {
+    testUri.run("FICRTCollETMixPrimCollCompTwoParam(ParameterString='1',ParameterInt16=1)")
+      .isKind(UriInfoKind.resource)
+      .goPath().first()
+      .isFunctionImport("FICRTCollETMixPrimCollCompTwoParam")
+      .isFunction("UFCRTCollETMixPrimCollCompTwoParam")
+      .isParameter(0, "ParameterString", "'1'")
+      .isParameter(1, "ParameterInt16", "1");
+    
+    testUri.run("FICRTCollETMixPrimCollCompTwoParam(ParameterString='1',ParameterInt16=1)(PropertyInt16=0)")
+     .isKind(UriInfoKind.resource)
+     .goPath().first()
+     .isFunctionImport("FICRTCollETMixPrimCollCompTwoParam")
+     .isFunction("UFCRTCollETMixPrimCollCompTwoParam")
+     .isParameter(0, "ParameterString", "'1'")
+     .isParameter(1, "ParameterInt16", "1")
+     .isKeyPredicate(0, "PropertyInt16", "0");
+    
+    testUri.run("FICRTCollETMixPrimCollCompTwoParam(ParameterString='1',ParameterInt16=1)(0)")
+      .isKind(UriInfoKind.resource)
+      .goPath().first()
+      .isFunctionImport("FICRTCollETMixPrimCollCompTwoParam")
+      .isFunction("UFCRTCollETMixPrimCollCompTwoParam")
+      .isParameter(0, "ParameterString", "'1'")
+      .isParameter(1, "ParameterInt16", "1")
+      .isKeyPredicate(0, "PropertyInt16", "0");
+    
+    testUri.runEx("FICRTCollETMixPrimCollCompTwoParam(ParameterString='1',ParameterInt16=1)(PropertyInt16
eq 0)")
+      .isExSemantic(MessageKeys.INVALID_KEY_VALUE);
+    
+    // PropertyInt32 does not exist
+    testUri.runEx("FICRTCollETMixPrimCollCompTwoParam(ParameterString='1',ParameterInt16=1)(PropertyInt32=0)")
+      .isExValidation(UriValidationException.MessageKeys.INVALID_KEY_PROPERTY);
+    
+    testUri.runEx("FICRTCollETMixPrimCollCompTwoParam(ParameterString='1',ParameterInt16=1)"

+        + "(PropertyInt16=0,PropertyInt16=1)")
+    .isExSemantic(MessageKeys.WRONG_NUMBER_OF_KEY_PROPERTIES);
+  
+    testUri.run("FICRTCollCTTwoPrimTwoParam(ParameterString='1',ParameterInt16=1)")
+      .isKind(UriInfoKind.resource)
+      .goPath().first()
+      .isFunctionImport("FICRTCollCTTwoPrimTwoParam")
+      .isFunction("UFCRTCollCTTwoPrimTwoParam")
+      .isParameter(0, "ParameterString", "'1'")
+      .isParameter(1, "ParameterInt16", "1");
+    
+    testUri.runEx("FICRTCollCTTwoPrimTwoParam(ParameterString='1',ParameterInt16=1)(PropertyInt16=1)")
+      .isExSemantic(MessageKeys.KEY_NOT_ALLOWED);
+    
+    testUri.runEx("FICRTCollCTTwoPrimTwoParam(ParameterString='1',ParameterInt16=1)(1)")
+      .isExSemantic(MessageKeys.KEY_NOT_ALLOWED);
+    
+    testUri.runEx("FICRTCollCTTwoPrimTwoParam(ParameterString='1',ParameterInt16=1)(PropertyInt32=1)")
+      .isExSemantic(MessageKeys.KEY_NOT_ALLOWED);
+    
+    testUri.runEx("FICRTCollCTTwoPrimTwoParam(ParameterString='1',ParameterInt16=1)(PropertyInt32=1,PropertyInt16=2)")
+      .isExSemantic(MessageKeys.KEY_NOT_ALLOWED);
+    
+    testUri.run("FICRTCollESTwoKeyNavParam(ParameterInt16=1)")
+      .isKind(UriInfoKind.resource)
+      .goPath().first()
+      .isFunctionImport("FICRTCollESTwoKeyNavParam")
+      .isFunction("UFCRTCollETTwoKeyNavParam")
+      .isParameter(0, "ParameterInt16", "1");
+    
+    testUri.run("FICRTCollESTwoKeyNavParam(ParameterInt16=1)(PropertyInt16=1,PropertyString='1')")
+      .isKind(UriInfoKind.resource)
+      .goPath().first()
+      .isFunctionImport("FICRTCollESTwoKeyNavParam")
+      .isFunction("UFCRTCollETTwoKeyNavParam")
+      .isParameter(0, "ParameterInt16", "1")
+      .isKeyPredicate(0, "PropertyInt16", "1")
+      .isKeyPredicate(1,"PropertyString", "'1'");
+    
+    testUri.runEx("FICRTCollESTwoKeyNavParam(ParameterInt16=1)(PropertyInt16 eq 1)")
+      .isExSemantic(MessageKeys.INVALID_KEY_VALUE);
+    
+    testUri.runEx("FICRTCollESTwoKeyNavParam(ParameterInt16=1)(PropertyInt16=1)")
+      .isExSemantic(MessageKeys.WRONG_NUMBER_OF_KEY_PROPERTIES);
+    
+    testUri.runEx("FICRTCollESTwoKeyNavParam(ParameterInt16=1)(PropertyInt16=1,PropertyInt32=1,PropertyString='1')")
+      .isExSemantic(MessageKeys.WRONG_NUMBER_OF_KEY_PROPERTIES);
+    
+    testUri.runEx("FICRTCollESTwoKeyNavParam(ParameterInt16=1)()")
+      .isExSemantic(MessageKeys.WRONG_NUMBER_OF_KEY_PROPERTIES);
+    
+    testUri.runEx("FICRTCollESTwoKeyNavParam(ParameterInt16=1)(PropertyInt16=1,PropertyInt32=1)")
+      .isExValidation(UriValidationException.MessageKeys.INVALID_KEY_PROPERTY);
+    
+    testUri.runEx("FICRTCollESTwoKeyNavParam(ParameterInt16=1)(PropertyInt16=1,Unkown=1)")
+    .isExValidation(UriValidationException.MessageKeys.INVALID_KEY_PROPERTY);
+    
+    testUri.run("FICRTCollString()")
+      .isKind(UriInfoKind.resource)
+      .goPath().first()
+      .isFunctionImport("FICRTCollString")
+      .isFunction("UFCRTCollString");
+    
+    testUri.run("FICRTString()")
+      .isKind(UriInfoKind.resource)
+      .goPath().first()
+      .isFunctionImport("FICRTString")
+      .isFunction("UFCRTString");
+    
+    testUri.runEx("FICRTCollString()(0)")
+      .isExSemantic(MessageKeys.KEY_NOT_ALLOWED);
+    
+    testUri.runEx("FICRTString()(0)")
+      .isExSemantic(MessageKeys.KEY_NOT_ALLOWED);
+  }
+  
+  @Test
   public void runEsNameCast() throws Exception {
     testUri.run("ESTwoPrim/olingo.odata.test1.ETBase")
     .isKind(UriInfoKind.resource).goPath()
@@ -1759,14 +1871,12 @@ public class TestFullResourcePath {
     .isFunctionImport("FICRTETKeyNav")
     .isFunction("UFCRTETKeyNav")
     .isType(EntityTypeProvider.nameETKeyNav);
-
-    testUri.run("FICRTETTwoKeyNavParam(ParameterInt16=1)(PropertyInt16=2,PropertyString='3')")
+    
+    testUri.run("FICRTETTwoKeyNavParam(ParameterInt16=1)")
     .isKind(UriInfoKind.resource).goPath()
     .first()
     .isFunctionImport("FICRTETTwoKeyNavParam")
-    .isParameter(0, "ParameterInt16", "1")
-    .isKeyPredicate(0, "PropertyInt16", "2")
-    .isKeyPredicate(1, "PropertyString", "'3'");
+    .isParameter(0, "ParameterInt16", "1");
 
     testUri.run("FICRTESMedia(ParameterInt16=1)/$value")
     .isKind(UriInfoKind.resource).goPath()
@@ -1799,16 +1909,13 @@ public class TestFullResourcePath {
     .isParameter(0, "ParameterInt16", "1")
     .isType(EntityTypeProvider.nameETTwoKeyNav)
     .isTypeFilterOnEntry(EntityTypeProvider.nameETBaseTwoKeyNav);
-
-    testUri.run("FICRTETTwoKeyNavParam(ParameterInt16=1)(PropertyInt16=2,PropertyString='3')"
-            + "/olingo.odata.test1.ETBaseTwoKeyNav")
+    
+    testUri.run("FICRTETTwoKeyNavParam(ParameterInt16=1)/olingo.odata.test1.ETBaseTwoKeyNav")
         .isKind(UriInfoKind.resource).goPath()
         .first()
         .isFunctionImport("FICRTETTwoKeyNavParam")
         .isFunction("UFCRTETTwoKeyNavParam")
         .isParameter(0, "ParameterInt16", "1")
-        .isKeyPredicate(0, "PropertyInt16", "2")
-        .isKeyPredicate(1, "PropertyString", "'3'")
         .isType(EntityTypeProvider.nameETTwoKeyNav)
         .isTypeFilterOnEntry(EntityTypeProvider.nameETBaseTwoKeyNav);
 


Mime
View raw message