Repository: geode Updated Branches: refs/heads/develop 07da582d0 -> 3db075c32
GEODE-2298: Executing a Function via Swagger without parameters throws an exception Project: http://git-wip-us.apache.org/repos/asf/geode/repo Commit: http://git-wip-us.apache.org/repos/asf/geode/commit/3db075c3 Tree: http://git-wip-us.apache.org/repos/asf/geode/tree/3db075c3 Diff: http://git-wip-us.apache.org/repos/asf/geode/diff/3db075c3 Branch: refs/heads/develop Commit: 3db075c328cd099934dc19a610e527c66d8c5242 Parents: 07da582 Author: Kevin J. Duling <[email protected]> Authored: Fri Jan 20 10:50:26 2017 -0800 Committer: Kevin J. Duling <[email protected]> Committed: Fri Jan 27 12:46:22 2017 -0800 ---------------------------------------------------------------------- .../web/RestSecurityIntegrationTest.java | 5 +- .../web/controllers/NoArgumentFunction.java | 114 +++++++++++++++++++ .../RestAPIsQueryAndFEJUnitTest.java | 18 ++- .../web/controllers/AbstractBaseController.java | 5 +- .../controllers/FunctionAccessController.java | 13 ++- 5 files changed, 142 insertions(+), 13 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/geode/blob/3db075c3/geode-assembly/src/test/java/org/apache/geode/rest/internal/web/RestSecurityIntegrationTest.java ---------------------------------------------------------------------- diff --git a/geode-assembly/src/test/java/org/apache/geode/rest/internal/web/RestSecurityIntegrationTest.java b/geode-assembly/src/test/java/org/apache/geode/rest/internal/web/RestSecurityIntegrationTest.java index fc2da8b..f0b6bb3 100644 --- a/geode-assembly/src/test/java/org/apache/geode/rest/internal/web/RestSecurityIntegrationTest.java +++ b/geode-assembly/src/test/java/org/apache/geode/rest/internal/web/RestSecurityIntegrationTest.java @@ -133,9 +133,8 @@ public class RestSecurityIntegrationTest { response = restClient.doPost("/queries/id", "stranger", "1234567", "{\"id\" : \"foo\"}"); assertEquals(403, restClient.getCode(response)); response = restClient.doPost("/queries/id", "dataReader", "1234567", "{\"id\" : \"foo\"}"); - // because we're only testing the security of the endpoint, not the endpoint functionality, a - // 500 is acceptable - assertEquals(500, restClient.getCode(response)); + // We should get a 404 because we're trying to update a query that doesn't exist + assertEquals(404, restClient.getCode(response)); } @Test http://git-wip-us.apache.org/repos/asf/geode/blob/3db075c3/geode-assembly/src/test/java/org/apache/geode/rest/internal/web/controllers/NoArgumentFunction.java ---------------------------------------------------------------------- diff --git a/geode-assembly/src/test/java/org/apache/geode/rest/internal/web/controllers/NoArgumentFunction.java b/geode-assembly/src/test/java/org/apache/geode/rest/internal/web/controllers/NoArgumentFunction.java new file mode 100644 index 0000000..f15e819 --- /dev/null +++ b/geode-assembly/src/test/java/org/apache/geode/rest/internal/web/controllers/NoArgumentFunction.java @@ -0,0 +1,114 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license + * agreements. See the NOTICE file distributed with this work for additional information regarding + * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. You may obtain a + * copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package org.apache.geode.rest.internal.web.controllers; + +import org.apache.geode.cache.Region; +import org.apache.geode.cache.execute.Function; +import org.apache.geode.cache.execute.FunctionContext; + +import java.util.Set; + +public class NoArgumentFunction implements Function { + /** + * Specifies whether the function sends results while executing. The method returns false if no + * result is expected.<br> + * <p> + * If {@link Function#hasResult()} returns false, {@link ResultCollector#getResult()} throws + * {@link FunctionException}. + * </p> + * <p> + * If {@link Function#hasResult()} returns true, {@link ResultCollector#getResult()} blocks and + * waits for the result of function execution + * </p> + * + * @return whether this function returns a Result back to the caller. + * + * @since GemFire 6.0 + */ + @Override + public boolean hasResult() { + return false; + } + + /** + * The method which contains the logic to be executed. This method should be thread safe and may + * be invoked more than once on a given member for a single {@link Execution}. The context + * provided to this function is the one which was built using {@linkplain Execution}. The contexts + * can be data dependent or data-independent so user should check to see if the context provided + * in parameter is instance of {@link RegionFunctionContext}. + * + * @param context as created by {@link Execution} + * + * @since GemFire 6.0 + */ + @Override + public void execute(final FunctionContext context) { + // do nothing + } + + /** + * Return a unique function identifier, used to register the function with {@link FunctionService} + * + * @return string identifying this function + * + * @since GemFire 6.0 + */ + @Override + public String getId() { + return "NoArgFunction"; + } + + /** + * <p> + * Return true to indicate to GemFire the method requires optimization for writing the targeted + * {@link FunctionService#onRegion(Region)} and any associated + * {@linkplain Execution#withFilter(Set) routing objects}. + * </p> + * + * <p> + * Returning false will optimize for read behavior on the targeted + * {@link FunctionService#onRegion(Region)} and any associated + * {@linkplain Execution#withFilter(Set) routing objects}. + * </p> + * + * <p> + * This method is only consulted when Region passed to + * FunctionService#onRegion(org.apache.geode.cache.Region) is a partitioned region + * </p> + * + * @return false if the function is read only, otherwise returns true + * + * @see FunctionService + * @since GemFire 6.0 + */ + @Override + public boolean optimizeForWrite() { + return false; + } + + /** + * Specifies whether the function is eligible for re-execution (in case of failure). + * + * @return whether the function is eligible for re-execution. + * + * @see RegionFunctionContext#isPossibleDuplicate() + * @since GemFire 6.5 + */ + @Override + public boolean isHA() { + return false; + } +} http://git-wip-us.apache.org/repos/asf/geode/blob/3db075c3/geode-assembly/src/test/java/org/apache/geode/rest/internal/web/controllers/RestAPIsQueryAndFEJUnitTest.java ---------------------------------------------------------------------- diff --git a/geode-assembly/src/test/java/org/apache/geode/rest/internal/web/controllers/RestAPIsQueryAndFEJUnitTest.java b/geode-assembly/src/test/java/org/apache/geode/rest/internal/web/controllers/RestAPIsQueryAndFEJUnitTest.java index f054110..1b2ab47 100644 --- a/geode-assembly/src/test/java/org/apache/geode/rest/internal/web/controllers/RestAPIsQueryAndFEJUnitTest.java +++ b/geode-assembly/src/test/java/org/apache/geode/rest/internal/web/controllers/RestAPIsQueryAndFEJUnitTest.java @@ -324,6 +324,9 @@ public class RestAPIsQueryAndFEJUnitTest { + "\"itemNo\": \"599\"," + "\"description\": \"Part X Free on Bumper Offer\"," + "\"quantity\": \"2\"," + "\"unitprice\": \"5\"," + "\"totalprice\": \"10.00\"" + "}" + "]"; + final String FUNCTION_NO_ARGS = "{ }"; + final String FUNCTION_NO_ARGS_ARRAY = "[{ }]"; + public final int METHOD_INDEX = 0; public final int URL_INDEX = 1; public final int REQUEST_BODY_INDEX = 2; @@ -517,7 +520,13 @@ public class RestAPIsQueryAndFEJUnitTest { HttpMethod.PUT, "/queries/" + PARAMETERIZED_QUERIES[3][0], PARAMETERIZED_QUERIES[4][1], HttpStatus.OK, null, false, false}, { // 52.5. update parameterized named query "testQuery" - HttpMethod.GET, "/queries", null, HttpStatus.OK, null, true, false},}; + HttpMethod.GET, "/queries", null, HttpStatus.OK, null, true, false}, + { // 53 + HttpMethod.POST, "/functions/NoArgFunction", FUNCTION_NO_ARGS, HttpStatus.OK, null, false, + false}, + { // 53 + HttpMethod.POST, "/functions/NoArgFunction", FUNCTION_NO_ARGS_ARRAY, HttpStatus.OK, null, + false, false}}; // TEST_DATA_END final int LIST_ALL_NAMED_QUERIES_INDEX = 45; @@ -644,6 +653,7 @@ public class RestAPIsQueryAndFEJUnitTest { FunctionService.registerFunction(new PutKeyFunction()); FunctionService.registerFunction(new GetDeliveredOrders()); FunctionService.registerFunction(new AddFreeItemToOrders()); + FunctionService.registerFunction(new NoArgumentFunction()); } @After @@ -818,9 +828,9 @@ public class RestAPIsQueryAndFEJUnitTest { // index=11, put- 500, [While doing R.put, CacheWriter.beforeCreate() has thrown // CacheWriterException] // .... and more test cases - assertEquals(se.getStatusCode(), TEST_DATA[index][STATUS_CODE_INDEX]); - assertEquals(StringUtils.hasText(se.getResponseBodyAsString()), - ((Boolean) TEST_DATA[index][RESPONSE_HAS_BODY_INDEX]).booleanValue()); + assertEquals(TEST_DATA[index][STATUS_CODE_INDEX], se.getStatusCode()); + assertEquals(TEST_DATA[index][RESPONSE_HAS_BODY_INDEX], + StringUtils.hasText(se.getResponseBodyAsString())); } catch (Exception e) { caught("caught Exception in executeQueryTestCases " + "Index:" + index + " " http://git-wip-us.apache.org/repos/asf/geode/blob/3db075c3/geode-web-api/src/main/java/org/apache/geode/rest/internal/web/controllers/AbstractBaseController.java ---------------------------------------------------------------------- diff --git a/geode-web-api/src/main/java/org/apache/geode/rest/internal/web/controllers/AbstractBaseController.java b/geode-web-api/src/main/java/org/apache/geode/rest/internal/web/controllers/AbstractBaseController.java index b9d2bf4..dab4cd9 100644 --- a/geode-web-api/src/main/java/org/apache/geode/rest/internal/web/controllers/AbstractBaseController.java +++ b/geode-web-api/src/main/java/org/apache/geode/rest/internal/web/controllers/AbstractBaseController.java @@ -709,9 +709,10 @@ public abstract class AbstractBaseController { return (T) rawDataBinding; } else { final String typeValue = (String) rawDataBinding.get(TYPE_META_DATA_PROPERTY); - + if (typeValue == null) + return (T) new JSONObject(); // Added for the primitive types put. Not supporting primitive types - if (NumberUtils.isPrimitiveOrObject(typeValue.toString())) { + if (NumberUtils.isPrimitiveOrObject(typeValue)) { final Object primitiveValue = rawDataBinding.get("@value"); try { return (T) NumberUtils.convertToActualType(primitiveValue.toString(), typeValue); http://git-wip-us.apache.org/repos/asf/geode/blob/3db075c3/geode-web-api/src/main/java/org/apache/geode/rest/internal/web/controllers/FunctionAccessController.java ---------------------------------------------------------------------- diff --git a/geode-web-api/src/main/java/org/apache/geode/rest/internal/web/controllers/FunctionAccessController.java b/geode-web-api/src/main/java/org/apache/geode/rest/internal/web/controllers/FunctionAccessController.java index 2169cb2..e9b61f4 100644 --- a/geode-web-api/src/main/java/org/apache/geode/rest/internal/web/controllers/FunctionAccessController.java +++ b/geode-web-api/src/main/java/org/apache/geode/rest/internal/web/controllers/FunctionAccessController.java @@ -25,6 +25,7 @@ import org.apache.geode.cache.execute.Function; import org.apache.geode.cache.execute.FunctionException; import org.apache.geode.cache.execute.FunctionService; import org.apache.geode.cache.execute.ResultCollector; +import org.apache.geode.internal.cache.execute.NoResult; import org.apache.geode.internal.logging.LogService; import org.apache.geode.rest.internal.web.exception.GemfireRestException; import org.apache.geode.rest.internal.web.util.ArrayUtils; @@ -225,12 +226,16 @@ public class FunctionAccessController extends AbstractBaseController { } try { - Object functionResult = results.getResult(); + final HttpHeaders headers = new HttpHeaders(); + headers.setLocation(toUri("functions", functionId)); - if (functionResult instanceof List<?>) { - final HttpHeaders headers = new HttpHeaders(); - headers.setLocation(toUri("functions", functionId)); + Object functionResult = null; + if (results instanceof NoResult) + return new ResponseEntity<>("", headers, HttpStatus.OK); + + functionResult = results.getResult(); + if (functionResult instanceof List<?>) { try { @SuppressWarnings("unchecked") String functionResultAsJson =
