You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by ch...@apache.org on 2015/09/30 15:12:05 UTC

[3/3] olingo-odata4 git commit: [OLINGO-780] The URI Parser validates if a function is composable or not

[OLINGO-780] The URI Parser validates if a function is composable or not


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

Branch: refs/heads/master
Commit: b9403cd39433ba6d66054c92d02974e3187f401f
Parents: b7dcae8
Author: Christia Holzer <c....@sap.com>
Authored: Wed Sep 30 11:22:29 2015 +0200
Committer: Christia Holzer <c....@sap.com>
Committed: Wed Sep 30 15:04:24 2015 +0200

----------------------------------------------------------------------
 .../uri/validator/UriValidationException.java   |  4 +-
 .../server/core/uri/validator/UriValidator.java | 36 ++++++++++-
 .../server-core-exceptions-i18n.properties      |  1 +
 .../tecsvc/provider/FunctionProvider.java       |  2 +-
 .../olingo/server/core/ODataHandlerTest.java    | 24 ++++---
 .../core/uri/antlr/TestFullResourcePath.java    | 66 ++++++++++++++++++++
 6 files changed, 120 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b9403cd3/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/validator/UriValidationException.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/validator/UriValidationException.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/validator/UriValidationException.java
index 5760e88..d883b0c 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/validator/UriValidationException.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/validator/UriValidationException.java
@@ -52,7 +52,9 @@ public class UriValidationException extends ODataLibraryException {
     /** parameter: unallowed kind before $value */
     UNALLOWED_KIND_BEFORE_VALUE,
     /** parameter: unallowed kind before $count */
-    UNALLOWED_KIND_BEFORE_COUNT;
+    UNALLOWED_KIND_BEFORE_COUNT, 
+    /** parameter: unallowed resource path */
+    UNALLOWED_RESOURCE_PATH;
 
     @Override
     public String getKey() {

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b9403cd3/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 8693f1e..feb52ec 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
@@ -222,7 +222,14 @@ public class UriValidator {
 
   private RowIndexForUriType rowIndexForResourceKind(final UriInfo uriInfo) throws UriValidationException {
     RowIndexForUriType idx;
-
+    
+    final int nonComposableFunctionIndex = getIndexOfLastNonComposableFunction(uriInfo);
+    if(nonComposableFunctionIndex != -1 && (uriInfo.getUriResourceParts().size() - 1) > nonComposableFunctionIndex) {
+      throw new UriValidationException("Non composable functions followed by further resource parts are not allowed", 
+          UriValidationException.MessageKeys.UNALLOWED_RESOURCE_PATH, 
+          uriInfo.getUriResourceParts().get(nonComposableFunctionIndex + 1).getSegmentValue());
+    }
+    
     int lastPathSegmentIndex = uriInfo.getUriResourceParts().size() - 1;
     UriResource lastPathSegment = uriInfo.getUriResourceParts().get(lastPathSegmentIndex);
 
@@ -241,7 +248,11 @@ public class UriValidator {
       idx = rowIndexForEntitySet(lastPathSegment);
       break;
     case function:
-      idx = rowIndexForFunction(lastPathSegment);
+      if(nonComposableFunctionIndex == -1) {
+        idx = rowIndexForFunction(lastPathSegment);
+      } else {
+        idx = RowIndexForUriType.none;
+      }
       break;
     case primitiveProperty:
       idx = rowIndexForPrimitiveProperty(lastPathSegment);
@@ -266,6 +277,21 @@ public class UriValidator {
     return idx;
   }
 
+  private int getIndexOfLastNonComposableFunction(final UriInfo uriInfo) {
+    for(int i = 0; i < uriInfo.getUriResourceParts().size(); i++) {
+      final UriResource resourcePath = uriInfo.getUriResourceParts().get(i);
+      
+      if(resourcePath instanceof UriResourceFunction) {
+        final UriResourceFunction resourceFuntion = (UriResourceFunction) resourcePath;
+        if(!resourceFuntion.getFunction().isComposable()) {
+          return i;
+        }
+      }
+    }
+    
+    return -1;
+  }
+
   private RowIndexForUriType rowIndexForValue(final UriInfo uriInfo) throws UriValidationException {
     RowIndexForUriType idx;
     int secondLastPathSegmentIndex = uriInfo.getUriResourceParts().size() - 2;
@@ -327,6 +353,12 @@ public class UriValidator {
     RowIndexForUriType idx;
     UriResourceFunction urf = (UriResourceFunction) lastPathSegment;
     EdmReturnType rt = urf.getFunction().getReturnType();
+
+    if(!urf.getFunction().isComposable()) {
+      return RowIndexForUriType.none;
+    }
+    
+    
     switch (rt.getType().getKind()) {
     case ENTITY:
       idx = rt.isCollection() && urf.getKeyPredicates().isEmpty() ?

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b9403cd3/lib/server-core/src/main/resources/server-core-exceptions-i18n.properties
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/resources/server-core-exceptions-i18n.properties b/lib/server-core/src/main/resources/server-core-exceptions-i18n.properties
index f7c2894..de14eb0 100644
--- a/lib/server-core/src/main/resources/server-core-exceptions-i18n.properties
+++ b/lib/server-core/src/main/resources/server-core-exceptions-i18n.properties
@@ -81,6 +81,7 @@ UriValidationException.LAST_SEGMENT_NOT_TYPED=The last segment '%1$s' is not typ
 UriValidationException.SECOND_LAST_SEGMENT_NOT_TYPED=The second last segment '%1$s' is not typed.
 UriValidationException.UNALLOWED_KIND_BEFORE_VALUE=The kind '%1$s' is not allowed before '$value'.
 UriValidationException.UNALLOWED_KIND_BEFORE_COUNT=The kind '%1$s' is not allowed before '$count'.
+UriValidationException.UNALLOWED_RESOURCE_PATH=The resource part '%1$s' is not allowed.
 
 ContentNegotiatorException.UNSUPPORTED_ACCEPT_TYPES=The content-type range '%1$s' is not supported as value of the Accept header.
 ContentNegotiatorException.UNSUPPORTED_CONTENT_TYPE=The content type '%1$s' is not supported.

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b9403cd3/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/FunctionProvider.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/FunctionProvider.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/FunctionProvider.java
index df4cfbd..a83abab 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/FunctionProvider.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/FunctionProvider.java
@@ -574,7 +574,7 @@ public class FunctionProvider {
               .setParameters(Arrays.asList(
                   new CsdlParameter().setName("BindingParam").setType(EntityTypeProvider.nameETBaseTwoKeyNav)
                       .setCollection(true).setNullable(false)))
-              .setComposable(true)
+              .setComposable(false)
               .setReturnType(
                   new CsdlReturnType().setType(EntityTypeProvider.nameETBaseTwoKeyNav).setCollection(true)
                       .setNullable(false))

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b9403cd3/lib/server-test/src/test/java/org/apache/olingo/server/core/ODataHandlerTest.java
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/ODataHandlerTest.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/ODataHandlerTest.java
index 76b7b50..d4b87d4 100644
--- a/lib/server-test/src/test/java/org/apache/olingo/server/core/ODataHandlerTest.java
+++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/ODataHandlerTest.java
@@ -318,17 +318,16 @@ public class ODataHandlerTest {
     dispatch(HttpMethod.GET, "FICRTString()", primitiveProcessor);
     verify(primitiveProcessor).readPrimitive(
         any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class));
-
+    
+    // FINRTInt16 is not composable so /$value is not allowed
     final String valueUri = "FINRTInt16()/$value";
     final PrimitiveValueProcessor primitiveValueProcessor = mock(PrimitiveValueProcessor.class);
-    dispatch(HttpMethod.GET, valueUri, primitiveValueProcessor);
-    verify(primitiveValueProcessor).readPrimitiveValue(
-        any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class));
-    dispatchMethodNotAllowed(HttpMethod.POST, valueUri, primitiveValueProcessor);
-    dispatchMethodNotAllowed(HttpMethod.PATCH, valueUri, primitiveValueProcessor);
-    dispatchMethodNotAllowed(HttpMethod.PUT, valueUri, primitiveValueProcessor);
-    dispatchMethodNotAllowed(HttpMethod.DELETE, valueUri, primitiveValueProcessor);
-
+    dispatchMethodWithError(HttpMethod.GET, valueUri, primitiveValueProcessor, HttpStatusCode.BAD_REQUEST);
+    dispatchMethodWithError(HttpMethod.POST, valueUri, primitiveValueProcessor, HttpStatusCode.BAD_REQUEST);
+    dispatchMethodWithError(HttpMethod.PATCH, valueUri, primitiveValueProcessor, HttpStatusCode.BAD_REQUEST);
+    dispatchMethodWithError(HttpMethod.PUT, valueUri, primitiveValueProcessor, HttpStatusCode.BAD_REQUEST);
+    dispatchMethodWithError(HttpMethod.DELETE, valueUri, primitiveValueProcessor, HttpStatusCode.BAD_REQUEST);
+    
     final String primitiveCollectionUri = "FICRTCollString()";
     PrimitiveCollectionProcessor primitiveCollectionProcessor = mock(PrimitiveCollectionProcessor.class);
     dispatch(HttpMethod.GET, primitiveCollectionUri, primitiveCollectionProcessor);
@@ -759,4 +758,11 @@ public class ODataHandlerTest {
     assertEquals(HttpStatusCode.METHOD_NOT_ALLOWED.getStatusCode(), response.getStatusCode());
     assertNotNull(response.getContent());
   }
+  
+  private void dispatchMethodWithError(final HttpMethod method, final String path, final Processor processor, 
+      final HttpStatusCode statusCode) {
+    final ODataResponse response = dispatch(method, path, processor);
+    assertEquals(statusCode.getStatusCode(), response.getStatusCode());
+    assertNotNull(response.getContent());
+  }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b9403cd3/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 9c859db..5c06e2c 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
@@ -1145,6 +1145,72 @@ public class TestFullResourcePath {
   }
   
   @Test
+  public void runNonComposableFunctions() throws Exception {
+    testUri.run("FICRTCollETMixPrimCollCompTwoParam(ParameterInt16=1,ParameterString='1')")
+      .isKind(UriInfoKind.resource)
+      .goPath().first()
+      .isFunctionImport("FICRTCollETMixPrimCollCompTwoParam")
+      .isFunction("UFCRTCollETMixPrimCollCompTwoParam")
+      .isParameter(0, "ParameterInt16", "1")
+      .isParameter(1, "ParameterString", "'1'");
+    
+    testUri.run("FICRTCollETMixPrimCollCompTwoParam(ParameterInt16=1,ParameterString='1')(0)")
+      .isKind(UriInfoKind.resource)
+      .goPath().first()
+      .isFunctionImport("FICRTCollETMixPrimCollCompTwoParam")
+      .isFunction("UFCRTCollETMixPrimCollCompTwoParam")
+      .isParameter(0, "ParameterInt16", "1")
+      .isParameter(1, "ParameterString", "'1'");
+    
+    testUri.runEx("FICRTCollETMixPrimCollCompTwoParam(ParameterInt16=1,ParameterString='1')(0)/PropertyInt16")
+      .isExValidation(UriValidationException.MessageKeys.UNALLOWED_RESOURCE_PATH);
+    
+    testUri.runEx("FICRTCollETMixPrimCollCompTwoParam(ParameterInt16=1,ParameterString='1')", "$skip=1")
+      .isExValidation(UriValidationException.MessageKeys.SYSTEM_QUERY_OPTION_NOT_ALLOWED);
+    
+    testUri.runEx("FICRTCollETMixPrimCollCompTwoParam(ParameterInt16=1,ParameterString='1')", "$top=1")
+    .isExValidation(UriValidationException.MessageKeys.SYSTEM_QUERY_OPTION_NOT_ALLOWED);
+    
+    testUri.runEx("FICRTCollETMixPrimCollCompTwoParam(ParameterInt16=1,ParameterString='1')", 
+        "$filter=PropertyInt16 eq 1")
+    .isExValidation(UriValidationException.MessageKeys.SYSTEM_QUERY_OPTION_NOT_ALLOWED);
+    
+    testUri.runEx("FICRTCollETMixPrimCollCompTwoParam(ParameterInt16=1,ParameterString='1')", "$skip=1")
+    .isExValidation(UriValidationException.MessageKeys.SYSTEM_QUERY_OPTION_NOT_ALLOWED);
+    
+    testUri.runEx("FICRTCollETMixPrimCollCompTwoParam(ParameterInt16=1,ParameterString='1')", "$count=true")
+    .isExValidation(UriValidationException.MessageKeys.SYSTEM_QUERY_OPTION_NOT_ALLOWED);
+    
+    testUri.runEx("FICRTCollETMixPrimCollCompTwoParam(ParameterInt16=1,ParameterString='1')", "$skiptoken=5")
+    .isExValidation(UriValidationException.MessageKeys.SYSTEM_QUERY_OPTION_NOT_ALLOWED);
+    
+    // $search is currently not implemented. Please change this exception if the implementation is done.
+    testUri.runEx("FICRTCollETMixPrimCollCompTwoParam(ParameterInt16=1,ParameterString='1')", "$search=test")
+      .isExSemantic(MessageKeys.NOT_IMPLEMENTED);
+    
+    testUri.run("ESBaseTwoKeyNav/olingo.odata.test1.BFCESBaseTwoKeyNavRTESBaseTwoKey()")
+      .isKind(UriInfoKind.resource)
+      .goPath().first()
+      .isEntitySet("ESBaseTwoKeyNav")
+      .at(1)
+      .isFunction("BFCESBaseTwoKeyNavRTESBaseTwoKey");
+    
+    testUri.run("ESBaseTwoKeyNav/olingo.odata.test1.BFCESBaseTwoKeyNavRTESBaseTwoKey()" 
+        + "(PropertyInt16=1,PropertyString='1')")
+      .isKind(UriInfoKind.resource)
+      .goPath().first()
+      .isEntitySet("ESBaseTwoKeyNav")
+      .at(1)
+      .isFunction("BFCESBaseTwoKeyNavRTESBaseTwoKey")
+      .isKeyPredicate(0, "PropertyInt16", "1")
+      .isKeyPredicate(1, "PropertyString", "'1'");
+    
+    testUri.runEx("ESBaseTwoKeyNav/olingo.odata.test1.BFCESBaseTwoKeyNavRTESBaseTwoKey()" 
+          + "(PropertyInt16=1,PropertyString='1')/NavPropertyETBaseTwoKeyNavOne")
+      .isExValidation(UriValidationException.MessageKeys.UNALLOWED_RESOURCE_PATH);
+  }
+  
+  @Test
   public void runEsNameCast() throws Exception {
     testUri.run("ESTwoPrim/olingo.odata.test1.ETBase")
     .isKind(UriInfoKind.resource).goPath()