You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by kl...@apache.org on 2016/03/01 01:09:19 UTC

[10/34] incubator-geode git commit: adding unit tests for REST API

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9b55879e/geode-assembly/src/test/java/com/gemstone/gemfire/rest/internal/web/controllers/RestAPIOnRegionFunctionExecutionDUnitTest.java
----------------------------------------------------------------------
diff --git a/geode-assembly/src/test/java/com/gemstone/gemfire/rest/internal/web/controllers/RestAPIOnRegionFunctionExecutionDUnitTest.java b/geode-assembly/src/test/java/com/gemstone/gemfire/rest/internal/web/controllers/RestAPIOnRegionFunctionExecutionDUnitTest.java
new file mode 100644
index 0000000..4a958ce
--- /dev/null
+++ b/geode-assembly/src/test/java/com/gemstone/gemfire/rest/internal/web/controllers/RestAPIOnRegionFunctionExecutionDUnitTest.java
@@ -0,0 +1,617 @@
+/*
+ * 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 com.gemstone.gemfire.rest.internal.web.controllers;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+import java.util.Set;
+
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+
+import com.gemstone.gemfire.LogWriter;
+import com.gemstone.gemfire.cache.AttributesFactory;
+import com.gemstone.gemfire.cache.DataPolicy;
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.cache.RegionAttributes;
+import com.gemstone.gemfire.cache.Scope;
+import com.gemstone.gemfire.cache.execute.Function;
+import com.gemstone.gemfire.cache.execute.FunctionContext;
+import com.gemstone.gemfire.cache.execute.FunctionService;
+import com.gemstone.gemfire.cache.execute.RegionFunctionContext;
+import com.gemstone.gemfire.cache.partition.PartitionRegionHelper;
+import com.gemstone.gemfire.distributed.DistributedSystem;
+import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
+import com.gemstone.gemfire.internal.cache.PartitionAttributesImpl;
+import com.gemstone.gemfire.internal.cache.PartitionedRegion;
+import com.gemstone.gemfire.internal.cache.PartitionedRegionTestHelper;
+import com.gemstone.gemfire.internal.cache.functions.DistributedRegionFunction;
+import com.gemstone.gemfire.test.dunit.Host;
+import com.gemstone.gemfire.test.dunit.IgnoredException;
+import com.gemstone.gemfire.test.dunit.SerializableCallable;
+import com.gemstone.gemfire.test.dunit.VM;
+
+/**
+ * Dunit Test to validate OnRegion function execution with REST APIs
+ * 
+ * @author Nilkanth Patel
+ * @since 8.0
+ */
+
+public class RestAPIOnRegionFunctionExecutionDUnitTest extends RestAPITestBase {
+
+  private static final long serialVersionUID = 1L;
+
+  public static final String REGION_NAME = "DistributedRegionFunctionExecutionDUnitTest";
+
+  public static final String PR_REGION_NAME = "samplePRRegion";
+
+  public static Region region = null;
+
+  public static List<String> restURLs = new ArrayList<String>();
+
+  public static String restEndPoint = null;
+
+  public static String getRestEndPoint() {
+    return restEndPoint;
+  }
+
+  public static void setRestEndPoint(String restEndPoint) {
+    RestAPIOnRegionFunctionExecutionDUnitTest.restEndPoint = restEndPoint;
+  }
+
+  public static final Function function = new DistributedRegionFunction();
+
+  public static final Function functionWithNoResultThrowsException = new MyFunctionException();
+
+  public RestAPIOnRegionFunctionExecutionDUnitTest(String name) {
+    super(name);
+  }
+
+  public void setUp() throws Exception {
+    super.setUp();
+    final Host host = Host.getHost(0);
+  }
+
+  static class FunctionWithNoLastResult implements Function {
+    private static final long serialVersionUID = -1032915440862585532L;
+    public static final String Id = "FunctionWithNoLastResult";
+    public static int invocationCount;
+
+    @Override
+    public void execute(FunctionContext context) {
+      invocationCount++;
+      InternalDistributedSystem
+          .getConnectedInstance()
+          .getLogWriter()
+          .info(
+              "<ExpectedException action=add>did not send last result"
+                  + "</ExpectedException>");
+      context.getResultSender().sendResult(
+          (Serializable) context.getArguments());
+    }
+
+    @Override
+    public String getId() {
+      return Id;
+    }
+
+    @Override
+    public boolean hasResult() {
+      return true;
+    }
+
+    @Override
+    public boolean optimizeForWrite() {
+      return false;
+    }
+
+    @Override
+    public boolean isHA() {
+      return false;
+    }
+  }
+
+  static class SampleFunction implements Function {
+    private static final long serialVersionUID = -1032915440862585534L;
+    public static final String Id = "SampleFunction";
+    public static int invocationCount;
+
+    @Override
+    public void execute(FunctionContext context) {
+      invocationCount++;
+      if (context instanceof RegionFunctionContext) {
+        RegionFunctionContext rfContext = (RegionFunctionContext) context;
+        rfContext.getDataSet().getCache().getLogger()
+            .info("Executing function :  TestFunction2.execute " + rfContext);
+        if (rfContext.getArguments() instanceof Boolean) {
+          /* return rfContext.getArguments(); */
+          if (hasResult()) {
+            rfContext.getResultSender().lastResult(
+                (Serializable) rfContext.getArguments());
+          } else {
+            rfContext
+                .getDataSet()
+                .getCache()
+                .getLogger()
+                .info(
+                    "Executing function :  TestFunction2.execute " + rfContext);
+            while (true && !rfContext.getDataSet().isDestroyed()) {
+              rfContext.getDataSet().getCache().getLogger()
+                  .info("For Bug43513 ");
+              try {
+                Thread.sleep(100);
+              } catch (InterruptedException ie) {
+                Thread.currentThread().interrupt();
+                return;
+              }
+            }
+          }
+        } else if (rfContext.getArguments() instanceof String) {
+          String key = (String) rfContext.getArguments();
+          if (key.equals("TestingTimeOut")) { // for test
+                                              // PRFunctionExecutionDUnitTest#testRemoteMultiKeyExecution_timeout
+            try {
+              Thread.sleep(2000);
+            } catch (InterruptedException e) {
+              rfContext.getDataSet().getCache().getLogger()
+                  .warning("Got Exception : Thread Interrupted" + e);
+            }
+          }
+          if (PartitionRegionHelper.isPartitionedRegion(rfContext.getDataSet())) {
+            /*
+             * return
+             * (Serializable)PartitionRegionHelper.getLocalDataForContext(
+             * rfContext).get(key);
+             */
+            rfContext.getResultSender().lastResult(
+                (Serializable) PartitionRegionHelper.getLocalDataForContext(
+                    rfContext).get(key));
+          } else {
+            rfContext.getResultSender().lastResult(
+                (Serializable) rfContext.getDataSet().get(key));
+          }
+          /* return (Serializable)rfContext.getDataSet().get(key); */
+        } else if (rfContext.getArguments() instanceof Set) {
+          Set origKeys = (Set) rfContext.getArguments();
+          ArrayList vals = new ArrayList();
+          for (Object key : origKeys) {
+            Object val = PartitionRegionHelper
+                .getLocalDataForContext(rfContext).get(key);
+            if (val != null) {
+              vals.add(val);
+            }
+          }
+          rfContext.getResultSender().lastResult(vals);
+          /* return vals; */
+        } else if (rfContext.getArguments() instanceof HashMap) {
+          HashMap putData = (HashMap) rfContext.getArguments();
+          for (Iterator i = putData.entrySet().iterator(); i.hasNext();) {
+            Map.Entry me = (Map.Entry) i.next();
+            rfContext.getDataSet().put(me.getKey(), me.getValue());
+          }
+          rfContext.getResultSender().lastResult(Boolean.TRUE);
+        } else {
+          rfContext.getResultSender().lastResult(Boolean.FALSE);
+        }
+      } else {
+        if (hasResult()) {
+          context.getResultSender().lastResult(Boolean.FALSE);
+        } else {
+          DistributedSystem ds = InternalDistributedSystem.getAnyInstance();
+          LogWriter logger = ds.getLogWriter();
+          logger.info("Executing in TestFunction on Server : "
+              + ds.getDistributedMember() + "with Context : " + context);
+          while (ds.isConnected()) {
+            logger
+                .fine("Just executing function in infinite loop for Bug43513");
+            try {
+              Thread.sleep(250);
+            } catch (InterruptedException e) {
+              return;
+            }
+          }
+        }
+      }
+    }
+
+    @Override
+    public String getId() {
+      return Id;
+    }
+
+    @Override
+    public boolean hasResult() {
+      return true;
+    }
+
+    @Override
+    public boolean optimizeForWrite() {
+      return false;
+    }
+
+    @Override
+    public boolean isHA() {
+      return false;
+    }
+  }
+
+  private int getInvocationCount(VM vm) {
+    return (Integer) vm.invoke(new SerializableCallable() {
+      /**
+       * 
+       */
+      private static final long serialVersionUID = 1L;
+
+      @Override
+      public Object call() throws Exception {
+        SampleFunction f = (SampleFunction) FunctionService
+            .getFunction(SampleFunction.Id);
+        int count = f.invocationCount;
+        f.invocationCount = 0;
+        return count;
+      }
+    });
+  }
+
+  private void verifyAndResetInvocationCount(VM vm, final int count) {
+    vm.invoke(new SerializableCallable() {
+      /**
+       * 
+       */
+      private static final long serialVersionUID = 1L;
+
+      @Override
+      public Object call() throws Exception {
+        SampleFunction f = (SampleFunction) FunctionService
+            .getFunction(SampleFunction.Id);
+        assertEquals(count, f.invocationCount);
+        // assert succeeded, reset count
+        f.invocationCount = 0;
+        return null;
+      }
+    });
+  }
+
+  public static void createPeer(DataPolicy policy) {
+    AttributesFactory factory = new AttributesFactory();
+    factory.setScope(Scope.DISTRIBUTED_ACK);
+    factory.setDataPolicy(policy);
+    assertNotNull(cache);
+    region = cache.createRegion(REGION_NAME, factory.create());
+    com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("Region Created :" + region);
+    assertNotNull(region);
+  }
+
+  public static boolean createPeerWithPR() {
+    RegionAttributes ra = PartitionedRegionTestHelper.createRegionAttrsForPR(0,
+        10);
+    AttributesFactory raf = new AttributesFactory(ra);
+    PartitionAttributesImpl pa = new PartitionAttributesImpl();
+    pa.setAll(ra.getPartitionAttributes());
+    pa.setTotalNumBuckets(17);
+    raf.setPartitionAttributes(pa);
+
+    if (cache == null || cache.isClosed()) {
+      // Cache not available
+    }
+    assertNotNull(cache);
+
+    region = cache.createRegion(PR_REGION_NAME, raf.create());
+    com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("Region Created :" + region);
+    assertNotNull(region);
+    return Boolean.TRUE;
+  }
+
+  public static void populateRegion() {
+    assertNotNull(cache);
+    region = cache.getRegion(REGION_NAME);
+    assertNotNull(region);
+    for (int i = 1; i <= 200; i++) {
+      region.put("execKey-" + i, new Integer(i));
+    }
+  }
+
+  public static void populatePRRegion() {
+    assertNotNull(cache);
+    region = cache.getRegion(REGION_NAME);
+
+    PartitionedRegion pr = (PartitionedRegion) cache.getRegion(PR_REGION_NAME);
+    DistributedSystem.setThreadsSocketPolicy(false);
+    final HashSet testKeys = new HashSet();
+
+    for (int i = (pr.getTotalNumberOfBuckets() * 3); i > 0; i--) {
+      testKeys.add("execKey-" + i);
+    }
+    int j = 0;
+    for (Iterator i = testKeys.iterator(); i.hasNext();) {
+      Integer val = new Integer(j++);
+      pr.put(i.next(), val);
+    }
+    // Assert there is data in each bucket
+    for (int bid = 0; bid < pr.getTotalNumberOfBuckets(); bid++) {
+      assertTrue(pr.getBucketKeys(bid).size() > 0);
+    }
+  }
+
+  public static void populateRRRegion() {
+    assertNotNull(cache);
+    region = cache.getRegion(REGION_NAME);
+    assertNotNull(region);
+
+    final HashSet testKeys = new HashSet();
+    for (int i = 17 * 3; i > 0; i--) {
+      testKeys.add("execKey-" + i);
+    }
+    int j = 0;
+    for (Iterator i = testKeys.iterator(); i.hasNext();) {
+      Integer val = new Integer(j++);
+      region.put(i.next(), val);
+    }
+
+  }
+
+  public static void executeFunction_NoLastResult(String regionName) {
+
+    try {
+      CloseableHttpClient httpclient = HttpClients.createDefault();
+      CloseableHttpResponse response = null;
+      Random randomGenerator = new Random();
+      int index = randomGenerator.nextInt(restURLs.size());
+      HttpPost post = new HttpPost(restURLs.get(index) + "/functions/"
+          + "FunctionWithNoLastResult" + "?onRegion=" + regionName);
+      post.addHeader("Content-Type", "application/json");
+      post.addHeader("Accept", "application/json");
+      response = httpclient.execute(post);
+    } catch (Exception e) {
+      throw new RuntimeException("unexpected exception", e);
+    }
+
+  }
+
+  public static void executeFunctionThroughRestCall(String regionName) {
+    com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("Entering executeFunctionThroughRestCall");
+    try {
+      CloseableHttpClient httpclient = HttpClients.createDefault();
+      CloseableHttpResponse response = null;
+      Random randomGenerator = new Random();
+      int index = randomGenerator.nextInt(restURLs.size());
+      
+      HttpPost post = new HttpPost(restURLs.get(index) + "/functions/"
+          + "SampleFunction" + "?onRegion=" + regionName);
+      post.addHeader("Content-Type", "application/json");
+      post.addHeader("Accept", "application/json");
+      
+      com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("Request: POST " + post.toString());
+      response = httpclient.execute(post);
+      com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("Response: POST " + response.toString());
+      
+      assertEquals(response.getStatusLine().getStatusCode(), 200);
+      assertNotNull(response.getEntity());
+    } catch (Exception e) {
+      throw new RuntimeException("unexpected exception", e);
+    }
+    com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("Exiting executeFunctionThroughRestCall");
+
+  }
+
+  private void registerFunction(VM vm) {
+    vm.invoke(new SerializableCallable() {
+      private static final long serialVersionUID = 1L;
+      @Override
+      public Object call() throws Exception {
+        FunctionService.registerFunction(new FunctionWithNoLastResult());
+        return null;
+      }
+    });
+  }
+
+  private void registerSampleFunction(VM vm) {
+    vm.invoke(new SerializableCallable() {
+      private static final long serialVersionUID = 1L;
+
+      @Override
+      public Object call() throws Exception {
+        FunctionService.registerFunction(new SampleFunction());
+        return null;
+      }
+    });
+  }
+
+  public void __testOnRegionExecutionOnDataPolicyEmpty_NoLastResult() {
+    // Step-1 : create cache on each VM, this will start HTTP service in
+    // embedded mode and deploy REST APIs web app on it.
+
+    fail("This test is trying to invoke non existent methods");
+//    String url1 = (String) vm3.invoke(() -> createCacheInVm( vm3 ));
+//    restURLs.add(url1);
+//
+//    String url2 = (String) vm0.invoke(() -> createCacheInVm( vm0 ));
+//    restURLs.add(url2);
+//
+//    String url3 = (String) vm1.invoke(() -> createCacheInVm( vm1 ));
+//    restURLs.add(url3);
+//
+//    String url4 = (String) vm2.invoke(() -> createCacheInVm( vm2 ));
+//    restURLs.add(url4);
+
+    // Step-2: Register function in all VMs
+    registerFunction(vm3);
+    registerFunction(vm0);
+    registerFunction(vm1);
+    registerFunction(vm2);
+
+    // Step-3: Create and configure Region on all VMs
+    vm3.invoke(() -> createPeer( DataPolicy.EMPTY ));
+    vm0.invoke(() -> createPeer( DataPolicy.REPLICATE ));
+    vm1.invoke(() -> createPeer( DataPolicy.REPLICATE ));
+    vm2.invoke(() -> createPeer( DataPolicy.REPLICATE ));
+
+    // Step-4 : Do some puts on region created earlier
+    vm3.invoke(() -> populateRegion());
+
+    // add expected exception to avoid suspect strings
+    final IgnoredException ex = IgnoredException.addIgnoredException("did not send last result");
+
+    // Step-5 : Execute function randomly (in iteration) on all available (per
+    // VM) REST end-points and verify its result
+    for (int i = 0; i < 10; i++) {
+      executeFunction_NoLastResult(REGION_NAME);
+    }
+    ex.remove();
+
+    restURLs.clear();
+  }
+
+  public void testOnRegionExecutionWithRR() {
+    // Step-1 : create cache on each VM, this will start HTTP service in
+    // embedded mode and deploy REST APIs web app on it.
+    //
+    String url1 = (String) vm3.invoke(() -> RestAPITestBase.createCache( vm3 ));
+    restURLs.add(url1);
+
+    String url2 = (String) vm0.invoke(() -> RestAPITestBase.createCache( vm0 ));
+    restURLs.add(url2);
+
+    String url3 = (String) vm1.invoke(() -> RestAPITestBase.createCache( vm1 ));
+    restURLs.add(url3);
+
+    String url4 = (String) vm2.invoke(() -> RestAPITestBase.createCache( vm2 ));
+    restURLs.add(url4);
+
+    // Step-2: Register function in all VMs
+    registerSampleFunction(vm3);
+    registerSampleFunction(vm0);
+    registerSampleFunction(vm1);
+    registerSampleFunction(vm2);
+
+    // Step-3: Create and configure PR on all VMs
+    vm3.invoke(() -> createPeer( DataPolicy.EMPTY ));
+    vm0.invoke(() -> createPeer( DataPolicy.REPLICATE ));
+    vm1.invoke(() -> createPeer( DataPolicy.REPLICATE ));
+    vm2.invoke(() -> createPeer( DataPolicy.REPLICATE ));
+
+    // Step-4 : Do some puts in Replicated region on vm3
+    vm3.invoke(() -> populateRRRegion());
+
+    // Step-5 : Execute function randomly (in iteration) on all available (per
+    // VM) REST end-points and verify its result
+    executeFunctionThroughRestCall(REGION_NAME);
+    int c0 = getInvocationCount(vm0);
+    int c1 = getInvocationCount(vm1);
+    int c2 = getInvocationCount(vm2);
+    int c3 = getInvocationCount(vm3);
+
+    assertEquals(1, c0 + c1 + c2 + c3);
+
+    // remove the expected exception
+    restURLs.clear();
+  }
+
+  public void testOnRegionExecutionWithPR() throws Exception {
+    final String rName = getUniqueName();
+
+    // Step-1 : create cache on each VM, this will start HTTP service in
+    // embedded mode and deploy REST APIs web app on it.
+    String url1 = (String) vm3.invoke(() -> RestAPITestBase.createCache( vm3 ));
+    restURLs.add(url1);
+
+    String url2 = (String) vm0.invoke(() -> RestAPITestBase.createCache( vm0 ));
+    restURLs.add(url2);
+
+    String url3 = (String) vm1.invoke(() -> RestAPITestBase.createCache( vm1 ));
+    restURLs.add(url3);
+
+    String url4 = (String) vm2.invoke(() -> RestAPITestBase.createCache( vm2 ));
+    restURLs.add(url4);
+
+    // Step-2: Register function in all VMs
+    registerSampleFunction(vm3);
+    registerSampleFunction(vm0);
+    registerSampleFunction(vm1);
+    registerSampleFunction(vm2);
+
+    // Step-3: Create and configure PR on all VMs
+    vm3.invoke(() -> createPeerWithPR());
+    vm0.invoke(() -> createPeerWithPR());
+    vm1.invoke(() -> createPeerWithPR());
+    vm2.invoke(() -> createPeerWithPR());
+
+    // Step-4: Do some puts such that data exist in each bucket
+    vm3.invoke(() -> populatePRRegion());
+
+    // Step-5 : Execute function randomly (in iteration) on all available (per
+    // VM) REST end-points and verify its result
+    executeFunctionThroughRestCall(PR_REGION_NAME);
+
+    // Assert that each node has executed the function once.
+    verifyAndResetInvocationCount(vm0, 1);
+    verifyAndResetInvocationCount(vm1, 1);
+    verifyAndResetInvocationCount(vm2, 1);
+    verifyAndResetInvocationCount(vm3, 1);
+
+    int c0 = getInvocationCount(vm0);
+    int c1 = getInvocationCount(vm1);
+    int c2 = getInvocationCount(vm2);
+    int c3 = getInvocationCount(vm3);
+
+    restURLs.clear();
+  }
+
+}
+
+class MyFunctionException implements Function {
+
+  /**
+   * 
+   */
+  private static final long serialVersionUID = 1L;
+
+  @Override
+  public void execute(FunctionContext context) {
+    throw new RuntimeException("failure");
+  }
+
+  @Override
+  public String getId() {
+    return this.getClass().getName();
+  }
+
+  @Override
+  public boolean hasResult() {
+    return true;
+  }
+
+  @Override
+  public boolean isHA() {
+    return false;
+  }
+
+  @Override
+  public boolean optimizeForWrite() {
+    return false;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9b55879e/geode-assembly/src/test/java/com/gemstone/gemfire/rest/internal/web/controllers/RestAPITestBase.java
----------------------------------------------------------------------
diff --git a/geode-assembly/src/test/java/com/gemstone/gemfire/rest/internal/web/controllers/RestAPITestBase.java b/geode-assembly/src/test/java/com/gemstone/gemfire/rest/internal/web/controllers/RestAPITestBase.java
new file mode 100644
index 0000000..3709475
--- /dev/null
+++ b/geode-assembly/src/test/java/com/gemstone/gemfire/rest/internal/web/controllers/RestAPITestBase.java
@@ -0,0 +1,133 @@
+/*
+ * 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 com.gemstone.gemfire.rest.internal.web.controllers;
+
+import java.util.Properties;
+
+import com.gemstone.gemfire.cache.Cache;
+import com.gemstone.gemfire.cache.CacheClosedException;
+import com.gemstone.gemfire.cache.CacheFactory;
+import com.gemstone.gemfire.cache.RegionShortcut;
+import com.gemstone.gemfire.distributed.internal.DistributionConfig;
+import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
+import com.gemstone.gemfire.internal.AvailablePortHelper;
+import com.gemstone.gemfire.internal.GemFireVersion;
+import com.gemstone.gemfire.management.internal.AgentUtil;
+import com.gemstone.gemfire.test.dunit.DistributedTestCase;
+import com.gemstone.gemfire.test.dunit.Host;
+import com.gemstone.gemfire.test.dunit.Invoke;
+import com.gemstone.gemfire.test.dunit.VM;
+import com.gemstone.gemfire.test.dunit.Wait;
+
+public class RestAPITestBase extends DistributedTestCase {
+  private static final long serialVersionUID = 1L;
+  public static Cache cache = null;
+  VM vm0 = null;
+  VM vm1 = null;
+  VM vm2 = null;
+  VM vm3 = null;
+  
+  public RestAPITestBase(String name) {
+    super(name);
+  }
+  
+  
+  @Override
+  public void setUp() throws Exception {
+    super.setUp();
+    disconnectAllFromDS();
+    AgentUtil agentUtil = new AgentUtil(GemFireVersion.getGemFireVersion());
+    if (agentUtil.findWarLocation("geode-web-api") == null) {
+      fail("unable to locate geode-web-api WAR file");
+    }
+    Wait.pause(5000);
+    final Host host = Host.getHost(0);
+    vm0 = host.getVM(0);
+    vm1 = host.getVM(1);
+    vm2 = host.getVM(2);
+    vm3 = host.getVM(3);
+    // gradle sets a property telling us where the build is located
+    final String buildDir = System.getProperty("geode.build.dir", System.getProperty("user.dir"));
+    Invoke.invokeInEveryVM(()-> System.setProperty("geode.build.dir", buildDir));
+  }  
+  
+  /**
+   * close the clients and teh servers
+   */
+  @Override
+  protected final void preTearDown() throws Exception {
+    vm0.invoke(() -> closeCache());
+    vm1.invoke(() -> closeCache());
+    vm2.invoke(() -> closeCache());
+    vm3.invoke(() -> closeCache());
+  }
+
+  /**
+   * close the cache
+   * 
+   */
+  public static void closeCache() {
+    if (cache != null && !cache.isClosed()) {
+      cache.close();
+      cache.getDistributedSystem().disconnect();
+    }
+  }
+  
+  protected static String createCache(VM currentVM) {
+    
+    RestAPITestBase test = new RestAPITestBase(getTestMethodName());
+    
+    final String hostName = currentVM.getHost().getHostName();
+    final int serverPort = AvailablePortHelper.getRandomAvailableTCPPort();
+    
+    Properties props = new Properties();
+    
+    props.setProperty(DistributionConfig.START_DEV_REST_API_NAME, "true");
+    props.setProperty(DistributionConfig.HTTP_SERVICE_BIND_ADDRESS_NAME, hostName);
+    props.setProperty(DistributionConfig.HTTP_SERVICE_PORT_NAME,String.valueOf(serverPort));
+    
+
+    InternalDistributedSystem ds = test.getSystem(props);
+    cache = CacheFactory.create(ds);
+    return "http://" + hostName + ":" + serverPort + "/gemfire-api/v1";
+    
+  }
+  
+  public static String createCacheWithGroups (VM vm, final String groups, final String regionName ) {
+    RestAPITestBase test = new RestAPITestBase(getTestMethodName());
+    
+    final String hostName = vm.getHost().getHostName(); 
+    final int serverPort = AvailablePortHelper.getRandomAvailableTCPPort();
+    
+    Properties props = new Properties();
+    
+    if(groups != null) {
+      props.put("groups", groups);
+    }
+    
+    props.setProperty(DistributionConfig.START_DEV_REST_API_NAME, "true");
+    props.setProperty(DistributionConfig.HTTP_SERVICE_BIND_ADDRESS_NAME, hostName);
+    props.setProperty(DistributionConfig.HTTP_SERVICE_PORT_NAME, String.valueOf(serverPort));
+    
+    InternalDistributedSystem ds = test.getSystem(props);
+    cache = CacheFactory.create(ds);
+    
+    String restEndPoint =  "http://" + hostName + ":" + serverPort + "/gemfire-api/v1";
+    return restEndPoint; 
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9b55879e/geode-assembly/src/test/java/com/gemstone/gemfire/rest/internal/web/controllers/RestAPIsAndInterOpsDUnitTest.java
----------------------------------------------------------------------
diff --git a/geode-assembly/src/test/java/com/gemstone/gemfire/rest/internal/web/controllers/RestAPIsAndInterOpsDUnitTest.java b/geode-assembly/src/test/java/com/gemstone/gemfire/rest/internal/web/controllers/RestAPIsAndInterOpsDUnitTest.java
new file mode 100644
index 0000000..0245fa0
--- /dev/null
+++ b/geode-assembly/src/test/java/com/gemstone/gemfire/rest/internal/web/controllers/RestAPIsAndInterOpsDUnitTest.java
@@ -0,0 +1,915 @@
+/*
+ * 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 com.gemstone.gemfire.rest.internal.web.controllers;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpDelete;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.methods.HttpPut;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import com.gemstone.gemfire.cache.AttributesFactory;
+import com.gemstone.gemfire.cache.Cache;
+import com.gemstone.gemfire.cache.CacheFactory;
+import com.gemstone.gemfire.cache.DataPolicy;
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.cache.RegionAttributes;
+import com.gemstone.gemfire.cache.RegionFactory;
+import com.gemstone.gemfire.cache.RegionShortcut;
+import com.gemstone.gemfire.cache.client.ClientCache;
+import com.gemstone.gemfire.cache.client.ClientCacheFactory;
+import com.gemstone.gemfire.cache.client.ClientRegionFactory;
+import com.gemstone.gemfire.cache.client.ClientRegionShortcut;
+import com.gemstone.gemfire.cache.client.internal.LocatorTestBase;
+import com.gemstone.gemfire.cache.server.CacheServer;
+import com.gemstone.gemfire.cache.server.ServerLoadProbe;
+import com.gemstone.gemfire.distributed.DistributedSystem;
+import com.gemstone.gemfire.distributed.internal.DistributionConfig;
+import com.gemstone.gemfire.internal.AvailablePort;
+import com.gemstone.gemfire.internal.AvailablePortHelper;
+import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
+import com.gemstone.gemfire.management.ManagementTestBase;
+import com.gemstone.gemfire.pdx.PdxInstance;
+import com.gemstone.gemfire.test.dunit.Host;
+import com.gemstone.gemfire.test.dunit.NetworkUtils;
+import com.gemstone.gemfire.test.dunit.SerializableCallable;
+import com.gemstone.gemfire.test.dunit.SerializableRunnable;
+import com.gemstone.gemfire.test.dunit.VM;
+
+/**
+ * Dunit Test containing inter - operations between REST Client and Gemfire cache client
+ * @author Nilkanth Patel
+ * @since 8.0
+ */
+
+public class RestAPIsAndInterOpsDUnitTest extends LocatorTestBase {
+  
+  private static final long serialVersionUID = -254776154266339226L;
+
+  private ManagementTestBase helper;
+
+  public static final String PEOPLE_REGION_NAME = "People";
+
+  //private static RestTemplate restTemplate;
+
+  private static final String findAllPeopleQuery = "/queries?id=findAllPeople&q=SELECT%20*%20FROM%20/People";
+  private static final String findPeopleByGenderQuery = "/queries?id=filterByGender&q=SELECT%20*%20from%20/People%20where%20gender=$1";
+  private static final String findPeopleByLastNameQuery = "/queries?id=filterByLastName&q=SELECT%20*%20from%20/People%20where%20lastName=$1";
+
+  private static final String[] PARAM_QUERY_IDS_ARRAY = { "findAllPeople",
+      "filterByGender", "filterByLastName" };
+  
+  final static String QUERY_ARGS = "["
+      + "{"
+      + "\"@type\": \"string\","
+      + "\"@value\": \"Patel\""
+      + "}"
+      + "]";
+
+  final static String PERSON_AS_JSON_CAS = "{"
+      + "\"@old\" :" 
+      + "{"
+      + "\"@type\": \"com.gemstone.gemfire.rest.internal.web.controllers.Person\","
+      + "\"id\": 101," + " \"firstName\": \"Mithali\","
+      + " \"middleName\": \"Dorai\"," + " \"lastName\": \"Raj\","
+      + " \"birthDate\": \"12/04/1982\"," + "\"gender\": \"FEMALE\"" 
+      + "},"
+      + "\"@new\" :" 
+      + "{"
+      + "\"@type\": \"com.gemstone.gemfire.rest.internal.web.controllers.Person\","
+      + "\"id\": 1101," + " \"firstName\": \"Virat\","
+      + " \"middleName\": \"Premkumar\"," + " \"lastName\": \"Kohli\","
+      + " \"birthDate\": \"08/11/1988\"," + "\"gender\": \"MALE\"" 
+      + "}"
+      + "}";
+    
+  final static String PERSON_AS_JSON_REPLACE = "{"
+      + "\"@type\": \"com.gemstone.gemfire.rest.internal.web.controllers.Person\","
+      + "\"id\": 501," + " \"firstName\": \"Barack\","
+      + " \"middleName\": \"Hussein\"," + " \"lastName\": \"Obama\","
+      + " \"birthDate\": \"04/08/1961\"," + "\"gender\": \"MALE\"" 
+      + "}";
+  
+  private static final String PERSON_LIST_AS_JSON = "[" + "{"
+      + "\"@type\": \"com.gemstone.gemfire.rest.internal.web.controllers.Person\","
+      + "\"id\": 3," + " \"firstName\": \"Nishka3\","
+      + " \"middleName\": \"Nilkanth3\"," + " \"lastName\": \"Patel3\","
+      + " \"birthDate\": \"07/31/2009\"," + "\"gender\": \"FEMALE\"" + "},"
+      + "{" + "\"@type\": \"com.gemstone.gemfire.rest.internal.web.controllers.Person\","
+      + "\"id\": 4," + " \"firstName\": \"Tanay4\","
+      + " \"middleName\": \"kiran4\"," + " \"lastName\": \"Patel4\","
+      + " \"birthDate\": \"23/08/2012\"," + "\"gender\": \"MALE\"" + "}," + "{"
+      + "\"@type\": \"com.gemstone.gemfire.rest.internal.web.controllers.Person\","
+      + "\"id\": 5," + " \"firstName\": \"Nishka5\","
+      + " \"middleName\": \"Nilkanth5\"," + " \"lastName\": \"Patel5\","
+      + " \"birthDate\": \"31/09/2009\"," + "\"gender\": \"FEMALE\"" + "},"
+      + "{" + "\"@type\": \"com.gemstone.gemfire.rest.internal.web.controllers.Person\","
+      + "\"id\": 6," + " \"firstName\": \"Tanay6\","
+      + " \"middleName\": \"Kiran6\"," + " \"lastName\": \"Patel\","
+      + " \"birthDate\": \"23/08/2012\"," + "\"gender\": \"MALE\"" + "}," + "{"
+      + "\"@type\": \"com.gemstone.gemfire.rest.internal.web.controllers.Person\","
+      + "\"id\": 7," + " \"firstName\": \"Nishka7\","
+      + " \"middleName\": \"Nilkanth7\"," + " \"lastName\": \"Patel\","
+      + " \"birthDate\": \"31/09/2009\"," + "\"gender\": \"FEMALE\"" + "},"
+      + "{" + "\"@type\": \"com.gemstone.gemfire.rest.internal.web.controllers.Person\","
+      + "\"id\": 8," + " \"firstName\": \"Tanay8\","
+      + " \"middleName\": \"kiran8\"," + " \"lastName\": \"Patel\","
+      + " \"birthDate\": \"23/08/2012\"," + "\"gender\": \"MALE\"" + "}," + "{"
+      + "\"@type\": \"com.gemstone.gemfire.rest.internal.web.controllers.Person\","
+      + "\"id\": 9," + " \"firstName\": \"Nishka9\","
+      + " \"middleName\": \"Nilkanth9\"," + " \"lastName\": \"Patel\","
+      + " \"birthDate\": \"31/09/2009\"," + "\"gender\": \"FEMALE\"" + "},"
+      + "{" + "\"@type\": \"com.gemstone.gemfire.rest.internal.web.controllers.Person\","
+      + "\"id\": 10," + " \"firstName\": \"Tanay10\","
+      + " \"middleName\": \"kiran10\"," + " \"lastName\": \"Patel\","
+      + " \"birthDate\": \"23/08/2012\"," + "\"gender\": \"MALE\"" + "}," + "{"
+      + "\"@type\": \"com.gemstone.gemfire.rest.internal.web.controllers.Person\","
+      + "\"id\": 11," + " \"firstName\": \"Nishka11\","
+      + " \"middleName\": \"Nilkanth11\"," + " \"lastName\": \"Patel\","
+      + " \"birthDate\": \"31/09/2009\"," + "\"gender\": \"FEMALE\"" + "},"
+      + "{" + "\"@type\": \"com.gemstone.gemfire.rest.internal.web.controllers.Person\","
+      + "\"id\": 12," + " \"firstName\": \"Tanay12\","
+      + " \"middleName\": \"kiran12\"," + " \"lastName\": \"Patel\","
+      + " \"birthDate\": \"23/08/2012\"," + "\"gender\": \"MALE\"" + "}" + "]";
+
+  public RestAPIsAndInterOpsDUnitTest(String name) {
+    super(name);
+    this.helper = new ManagementTestBase(name);
+
+  }
+
+  public void setUp() throws Exception {
+    disconnectAllFromDS();
+    super.setUp();
+  }
+
+  @Override
+  protected final void postTearDownLocatorTestBase() throws Exception {
+    disconnectAllFromDS();
+  }
+  
+  public static String startBridgeServerWithRestServiceOnInVM(VM vm, final String[] groups, final String locators, final String[] regions, final ServerLoadProbe probe) {
+    
+    final String hostName = vm.getHost().getHostName(); 
+    final int serverPort = AvailablePortHelper.getRandomAvailableTCPPort();
+    
+    //create Cache of given VM and start HTTP service with REST APIs service
+    new RestAPIsAndInterOpsDUnitTest("temp").startBridgeServer(hostName, serverPort, groups, locators, regions, probe);
+   
+    String restEndPoint =  "http://" + hostName + ":" + serverPort + "/gemfire-api/v1";
+    return restEndPoint;
+  }
+  
+  @SuppressWarnings("deprecation")
+  protected int startBridgeServer(String hostName, int restServicerPort, final String[] groups, final String locators, final String[] regions, final ServerLoadProbe probe) {
+            
+    Properties props = new Properties();
+    props.setProperty(DistributionConfig.MCAST_PORT_NAME, String.valueOf(0));
+    props.setProperty(DistributionConfig.LOCATORS_NAME, locators);
+    props.setProperty(DistributionConfig.START_DEV_REST_API_NAME, "true");
+    props.setProperty(DistributionConfig.HTTP_SERVICE_BIND_ADDRESS_NAME, hostName);
+    props.setProperty(DistributionConfig.HTTP_SERVICE_PORT_NAME, String.valueOf(restServicerPort));
+    
+    DistributedSystem ds = getSystem(props);
+    Cache cache = CacheFactory.create(ds);
+    ((GemFireCacheImpl)cache).setReadSerialized(true);
+    AttributesFactory factory = new AttributesFactory();
+    
+    factory.setEnableBridgeConflation(true);
+    factory.setDataPolicy(DataPolicy.REPLICATE);
+    RegionAttributes attrs = factory.create();
+    for(int i = 0; i < regions.length; i++) {
+      cache.createRegion(regions[i], attrs);
+    }
+    
+    CacheServer server = cache.addCacheServer();
+    final int serverPort = AvailablePortHelper.getRandomAvailableTCPPort();
+    server.setPort(serverPort);
+    server.setGroups(groups);
+    server.setLoadProbe(probe);
+    try {
+      server.start();
+    } catch (IOException e) {
+      e.printStackTrace();
+    }
+    remoteObjects.put(CACHE_KEY, cache);
+    return new Integer(serverPort);
+  }
+  
+  public static void doPutsInClientCache() {
+    ClientCache cache = GemFireCacheImpl.getInstance();
+    assertNotNull(cache);
+    Region<String, Object> region = cache.getRegion(PEOPLE_REGION_NAME);
+   
+    //put person object
+    final Person person1 = new Person(101L, "Mithali", "Dorai", "Raj", DateTimeUtils.createDate(1982, Calendar.DECEMBER, 4), Gender.FEMALE);
+    final Person person2 = new Person(102L, "Sachin", "Ramesh", "Tendulkar", DateTimeUtils.createDate(1975, Calendar.DECEMBER, 14), Gender.MALE);
+    final Person person3 = new Person(103L, "Saurabh", "Baburav", "Ganguly", DateTimeUtils.createDate(1972, Calendar.AUGUST, 29), Gender.MALE);
+    final Person person4 = new Person(104L, "Rahul", "subrymanyam", "Dravid", DateTimeUtils.createDate(1979, Calendar.MARCH, 17), Gender.MALE);
+    final Person person5 = new Person(105L, "Jhulan", "Chidambaram", "Goswami", DateTimeUtils.createDate(1983, Calendar.NOVEMBER, 25), Gender.FEMALE);
+   
+    region.put("1", person1);
+    region.put("2", person2);
+    region.put("3", person3);
+    region.put("4", person4);
+    region.put("5", person5);
+    
+    final Person person6 = new Person(101L, "Rahul", "Rajiv", "Gndhi", DateTimeUtils.createDate(1970, Calendar.MAY, 14), Gender.MALE);
+    final Person person7 = new Person(102L, "Narendra", "Damodar", "Modi", DateTimeUtils.createDate(1945, Calendar.DECEMBER, 24), Gender.MALE);
+    final Person person8 = new Person(103L, "Atal", "Bihari", "Vajpayee", DateTimeUtils.createDate(1920, Calendar.AUGUST, 9), Gender.MALE);
+    final Person person9 = new Person(104L, "Soniya", "Rajiv", "Gandhi", DateTimeUtils.createDate(1929, Calendar.MARCH, 27), Gender.FEMALE);
+    final Person person10 = new Person(104L, "Priyanka", "Robert", "Gandhi", DateTimeUtils.createDate(1973, Calendar.APRIL, 15), Gender.FEMALE);
+    
+    final Person person11 = new Person(104L, "Murali", "Manohar", "Joshi", DateTimeUtils.createDate(1923, Calendar.APRIL, 25), Gender.MALE);
+    final Person person12 = new Person(104L, "Lalkrishna", "Parmhansh", "Advani", DateTimeUtils.createDate(1910, Calendar.JANUARY, 01), Gender.MALE);
+    final Person person13 = new Person(104L, "Shushma", "kumari", "Swaraj", DateTimeUtils.createDate(1943, Calendar.AUGUST, 10), Gender.FEMALE);
+    final Person person14 = new Person(104L, "Arun", "raman", "jetly", DateTimeUtils.createDate(1942, Calendar.OCTOBER, 27), Gender.MALE);
+    final Person person15 = new Person(104L, "Amit", "kumar", "shah", DateTimeUtils.createDate(1958, Calendar.DECEMBER, 21), Gender.MALE);
+    final Person person16 = new Person(104L, "Shila", "kumari", "Dixit", DateTimeUtils.createDate(1927, Calendar.FEBRUARY, 15), Gender.FEMALE);
+    
+    Map<String, Object> userMap = new HashMap<String, Object>();
+    userMap.put("6", person6);
+    userMap.put("7", person7);
+    userMap.put("8", person8);
+    userMap.put("9", person9);
+    userMap.put("10", person10);
+    userMap.put("11", person11);
+    userMap.put("12", person12);
+    userMap.put("13", person13);
+    userMap.put("14", person14);
+    userMap.put("15", person15);
+    userMap.put("16", person16);
+    
+    region.putAll(userMap);
+    
+    if (cache != null)
+      cache.getLogger().info("Gemfire Cache Client: Puts successfully done");
+    
+  }
+
+  public static void doQueryOpsUsingRestApis(String restEndpoint) {
+    String currentQueryOp = null;
+    try {
+      // Query TestCase-1 :: Prepare parameterized Queries
+      {
+        currentQueryOp = "findAllPeopleQuery";
+        CloseableHttpClient httpclient = HttpClients.createDefault();
+        HttpPost post = new HttpPost(restEndpoint + findAllPeopleQuery);
+        post.addHeader("Content-Type", "application/json");
+        post.addHeader("Accept", "application/json");
+        CloseableHttpResponse createNamedQueryResponse = httpclient.execute(post);
+        assertEquals(createNamedQueryResponse.getStatusLine().getStatusCode(), 201);
+        assertNotNull(createNamedQueryResponse.getEntity());
+        createNamedQueryResponse.close();        
+        
+
+        post = new HttpPost(restEndpoint + findPeopleByGenderQuery);
+        post.addHeader("Content-Type", "application/json");
+        post.addHeader("Accept", "application/json");
+        createNamedQueryResponse = httpclient.execute(post);
+        assertEquals(createNamedQueryResponse.getStatusLine().getStatusCode(), 201);
+        assertNotNull(createNamedQueryResponse.getEntity());
+        createNamedQueryResponse.close();
+        
+
+        post = new HttpPost(restEndpoint + findPeopleByLastNameQuery);
+        post.addHeader("Content-Type", "application/json");
+        post.addHeader("Accept", "application/json");
+        createNamedQueryResponse = httpclient.execute(post);
+        assertEquals(createNamedQueryResponse.getStatusLine().getStatusCode(), 201);
+        assertNotNull(createNamedQueryResponse.getEntity());
+        createNamedQueryResponse.close();
+      }
+      
+      // Query TestCase-2 :: List all parameterized queries
+      {
+        currentQueryOp = "listAllQueries";
+        HttpGet get = new HttpGet(restEndpoint + "/queries");
+        CloseableHttpClient httpclient = HttpClients.createDefault();
+        CloseableHttpResponse listAllQueriesResponse = httpclient.execute(get);
+        assertEquals(listAllQueriesResponse.getStatusLine().getStatusCode(), 200);
+        assertNotNull(listAllQueriesResponse.getEntity());
+        
+        HttpEntity entity = listAllQueriesResponse.getEntity();
+        InputStream content = entity.getContent();
+        BufferedReader reader = new BufferedReader(new InputStreamReader(
+            content));
+        String line;
+        StringBuffer sb = new StringBuffer();
+        while ((line = reader.readLine()) != null) {
+          sb.append(line);
+        }
+        listAllQueriesResponse.close();
+      
+        // Check whether received response contains expected query IDs.
+
+        JSONObject jsonObject = new JSONObject(sb.toString());
+        JSONArray jsonArray = jsonObject.getJSONArray("queries");
+        for (int i = 0; i < jsonArray.length(); i++) {
+          assertTrue(
+            "PREPARE_PARAMETERIZED_QUERY: function IDs are not matched",
+            Arrays.asList(PARAM_QUERY_IDS_ARRAY).contains(
+                jsonArray.getJSONObject(i).getString("id")));
+        }
+      }  
+      
+      // Query TestCase-3 :: Run the specified named query passing in scalar values for query parameters.
+      {
+        currentQueryOp = "filterByLastName";
+        CloseableHttpClient httpclient = HttpClients.createDefault();
+        HttpPost post = new HttpPost(restEndpoint + "/queries/filterByLastName");
+        post.addHeader("Content-Type", "application/json");
+        post.addHeader("Accept", "application/json");
+        StringEntity entity = new StringEntity(QUERY_ARGS);       
+        post.setEntity(entity);
+        CloseableHttpResponse runNamedQueryResponse = httpclient.execute(post);
+
+        assertEquals(200, runNamedQueryResponse.getStatusLine().getStatusCode());
+        assertNotNull(runNamedQueryResponse.getEntity());
+      }
+    } catch ( Exception e ) {
+      throw new RuntimeException("unexpected exception", e);
+    }
+  }
+  
+  public static void verifyUpdatesInClientCache() {
+    ClientCache cache = GemFireCacheImpl.getInstance();
+    assertNotNull(cache);
+    Region<String, Object> region = cache.getRegion(PEOPLE_REGION_NAME);
+    
+    {
+      Person expectedPerson = new Person(3L, "Nishka3", "Nilkanth3", "Patel3", DateTimeUtils.createDate(2009, Calendar.JULY, 31), Gender.FEMALE );
+      Object value = region.get("3");
+      if (value instanceof PdxInstance) {
+        PdxInstance pi3  = (PdxInstance) value;
+        Person actualPerson = (Person) pi3.getObject();
+        assertEquals(actualPerson.getId(), expectedPerson.getId());
+        assertEquals(actualPerson.getFirstName(), expectedPerson.getFirstName());
+        assertEquals(actualPerson.getMiddleName(), expectedPerson.getMiddleName());
+        assertEquals(actualPerson.getLastName(), expectedPerson.getLastName());
+        assertEquals(actualPerson.getBirthDate(), expectedPerson.getBirthDate());
+        assertEquals(actualPerson.getGender(), expectedPerson.getGender());
+      } else if (value instanceof Person) {
+        fail("VerifyUpdatesInClientCache, Get on key 3, Expected to get value of type PdxInstance ");
+      }
+    }
+     
+    
+    //TODO: uncomment it once following issue encountered in put?op=CAS is fixed or document the issue
+    // CAS functionality is not working in following test case
+    // step-1: Java client, Region.put("K", A);
+    //Step-2: Rest CAS request for key "K" with data "@old" = A. CAS is failing as existing PdxInstance in cache and
+    //        PdxInstance generated from JSON (CAS request) does not match as their value's type are getting changed 
+    /*
+    //verify update on key "1"
+    {
+      Object obj = region.get("1");
+      if (obj instanceof PdxInstance) {
+        PdxInstance pi = (PdxInstance)obj;
+        Person p1 = (Person)pi.getObject();
+        System.out.println("Nilkanth1 : verifyUpdatesInClientCache() : GET ON KEY=1" + p1.toString());
+      }else {
+        System.out.println("Nilkanth1 : verifyUpdatesInClientCache() GET ON KEY=1  returned OBJECT: " + obj.toString());
+      }
+    }
+    */
+    
+    //verify update on key "2"
+    {
+      Person expectedPerson = new Person(501L, "Barack", "Hussein", "Obama", DateTimeUtils.createDate(1961, Calendar.APRIL, 8), Gender.MALE );
+      Object value = region.get("2");
+      if (value instanceof PdxInstance) {
+        PdxInstance pi3  = (PdxInstance) value;
+        Person actualPerson = (Person) pi3.getObject();
+        assertEquals(actualPerson.getId(), expectedPerson.getId());
+        assertEquals(actualPerson.getFirstName(), expectedPerson.getFirstName());
+        assertEquals(actualPerson.getMiddleName(), expectedPerson.getMiddleName());
+        assertEquals(actualPerson.getLastName(), expectedPerson.getLastName());
+        assertEquals(actualPerson.getBirthDate(), expectedPerson.getBirthDate());
+        assertEquals(actualPerson.getGender(), expectedPerson.getGender());
+      }else {
+        fail("VerifyUpdatesInClientCache, Get on key 2, Expected to get value of type PdxInstance ");
+      }
+    }
+    
+    //verify Deleted key "13"
+    {
+      Object obj = region.get("13");
+      assertEquals(obj, null);
+      
+      obj = region.get("14");
+      assertEquals(obj, null);
+      
+      obj = region.get("15");
+      assertEquals(obj, null);
+      
+      obj = region.get("16");
+      assertEquals(obj, null);
+    }
+    
+  }
+  
+  public static void doUpdatesUsingRestApis(String restEndpoint) {
+    //UPdate keys using REST calls
+    {
+
+      try {
+        CloseableHttpClient httpclient = HttpClients.createDefault();
+        HttpPut put = new HttpPut(restEndpoint
+            + "/People/3,4,5,6,7,8,9,10,11,12");
+        put.addHeader("Content-Type", "application/json");
+        put.addHeader("Accept", "application/json");
+        StringEntity entity = new StringEntity(PERSON_LIST_AS_JSON);
+        put.setEntity(entity);
+        CloseableHttpResponse result = httpclient.execute(put);
+      } catch (Exception e) {
+        throw new RuntimeException("unexpected exception", e);
+      }
+    }
+    
+    //Delete Single keys
+    {
+      try {
+        CloseableHttpClient httpclient = HttpClients.createDefault();
+        HttpDelete delete = new HttpDelete(restEndpoint + "/People/13");
+        delete.addHeader("Content-Type", "application/json");
+        delete.addHeader("Accept", "application/json");
+        CloseableHttpResponse result = httpclient.execute(delete);
+      } catch (Exception e) {
+        throw new RuntimeException("unexpected exception", e);
+      }
+    }
+    
+    //Delete set of keys
+    {
+      try {
+        CloseableHttpClient httpclient = HttpClients.createDefault();
+        HttpDelete delete = new HttpDelete(restEndpoint + "/People/14,15,16");
+        delete.addHeader("Content-Type", "application/json");
+        delete.addHeader("Accept", "application/json");
+        CloseableHttpResponse result = httpclient.execute(delete);
+      } catch (Exception e) {
+        throw new RuntimeException("unexpected exception", e);
+      }
+    }
+    
+    //REST put?op=CAS for key 1
+    /*
+    try {   
+    {  
+      HttpEntity<Object> entity = new HttpEntity<Object>(PERSON_AS_JSON_CAS, headers);
+      ResponseEntity<String> result = RestTestUtils.getRestTemplate().exchange(
+        restEndpoint + "/People/1?op=cas",
+        HttpMethod.PUT, entity, String.class);
+    }
+    } catch (HttpClientErrorException e) {
+      
+      fail("Caught HttpClientErrorException while doing put with op=cas");
+    }catch (HttpServerErrorException se) {
+      fail("Caught HttpServerErrorException while doing put with op=cas");
+    }
+    */ 
+    
+    //REST put?op=REPLACE for key 2
+    {
+      /*HttpEntity<Object> entity = new HttpEntity<Object>(PERSON_AS_JSON_REPLACE, headers);
+      ResponseEntity<String> result = RestTestUtils.getRestTemplate().exchange(
+        restEndpoint + "/People/2?op=replace",
+      HttpMethod.PUT, entity, String.class);*/
+      
+      try {
+        CloseableHttpClient httpclient = HttpClients.createDefault();
+        HttpPut put = new HttpPut(restEndpoint
+            + "/People/2?op=replace");
+        put.addHeader("Content-Type", "application/json");
+        put.addHeader("Accept", "application/json");
+        StringEntity entity = new StringEntity(PERSON_AS_JSON_REPLACE);
+        put.setEntity(entity);
+        CloseableHttpResponse result = httpclient.execute(put);
+      } catch (Exception e) {
+        throw new RuntimeException("unexpected exception", e);
+      }
+    }
+  }
+  
+  public static void fetchRestServerEndpoints(String restEndpoint) {
+    HttpGet get = new HttpGet(restEndpoint + "/servers");
+    get.addHeader("Content-Type", "application/json");
+    get.addHeader("Accept", "application/json");
+    CloseableHttpClient httpclient = HttpClients.createDefault();
+    CloseableHttpResponse response;
+    
+    try {
+      response = httpclient.execute(get);
+      HttpEntity entity = response.getEntity();
+      InputStream content = entity.getContent();
+      BufferedReader reader = new BufferedReader(new InputStreamReader(
+          content));
+      String line;
+      StringBuffer str = new StringBuffer();
+      while ((line = reader.readLine()) != null) {
+        str.append(line);
+      }
+      
+      //validate the satus code
+      assertEquals(response.getStatusLine().getStatusCode(), 200);
+      
+      if(response.getStatusLine().getStatusCode() == 200) {
+        JSONArray jsonArray = new JSONArray(str.toString());
+        
+        //verify total number of REST service endpoints in DS
+        assertEquals(jsonArray.length(), 2);
+      }
+      
+    } catch (ClientProtocolException e) { 
+      e.printStackTrace();
+      fail(" Rest Request should not have thrown ClientProtocolException!");
+    } catch (IOException e) {
+      e.printStackTrace();
+      fail(" Rest Request should not have thrown IOException!");
+    } catch (JSONException e) {
+      e.printStackTrace();
+      fail(" Rest Request should not have thrown  JSONException!");
+    }
+    
+  }
+  
+  public static void doGetsUsingRestApis(String restEndpoint) {
+    
+    //HttpHeaders headers = setAcceptAndContentTypeHeaders(); 
+    String currentOperation = null;
+    JSONObject jObject;
+    JSONArray jArray;
+    try {    
+      //1. Get on key="1" and validate result.
+      {
+        currentOperation = "GET on key 1";
+        
+        HttpGet get = new HttpGet(restEndpoint + "/People/1");
+        get.addHeader("Content-Type", "application/json");
+        get.addHeader("Accept", "application/json");
+        CloseableHttpClient httpclient = HttpClients.createDefault();
+        CloseableHttpResponse response = httpclient.execute(get);
+        
+        HttpEntity entity = response.getEntity();
+        InputStream content = entity.getContent();
+        BufferedReader reader = new BufferedReader(new InputStreamReader(
+            content));
+        String line;
+        StringBuffer str = new StringBuffer();
+        while ((line = reader.readLine()) != null) {
+          str.append(line);
+        }
+        
+        jObject = new JSONObject(str.toString());
+      
+        assertEquals(jObject.get("id"), 101);
+        assertEquals(jObject.get("firstName"), "Mithali");
+        assertEquals(jObject.get("middleName"), "Dorai");
+        assertEquals(jObject.get("lastName"), "Raj");
+        assertEquals(jObject.get("gender"), Gender.FEMALE.name());
+      }
+      
+      //2. Get on key="16" and validate result.
+      {
+        currentOperation = "GET on key 16";
+
+        
+        HttpGet get = new HttpGet(restEndpoint + "/People/16");
+        get.addHeader("Content-Type", "application/json");
+        get.addHeader("Accept", "application/json");
+        CloseableHttpClient httpclient = HttpClients.createDefault();
+        CloseableHttpResponse response = httpclient.execute(get);
+        
+        HttpEntity entity = response.getEntity();
+        InputStream content = entity.getContent();
+        BufferedReader reader = new BufferedReader(new InputStreamReader(
+            content));
+        String line;
+        StringBuffer str = new StringBuffer();
+        while ((line = reader.readLine()) != null) {
+          str.append(line);
+        }
+        
+        jObject = new JSONObject(str.toString());
+        
+      
+        assertEquals(jObject.get("id"), 104);
+        assertEquals(jObject.get("firstName"), "Shila");
+        assertEquals(jObject.get("middleName"), "kumari");
+        assertEquals(jObject.get("lastName"), "Dixit");
+        assertEquals(jObject.get("gender"), Gender.FEMALE.name());
+      }
+      
+      //3. Get all (getAll) entries in Region
+      {
+
+        HttpGet get = new HttpGet(restEndpoint + "/People");
+        get.addHeader("Content-Type", "application/json");
+        get.addHeader("Accept", "application/json");
+        CloseableHttpClient httpclient = HttpClients.createDefault();
+        CloseableHttpResponse result = httpclient.execute(get);
+        assertEquals(result.getStatusLine().getStatusCode(), 200);
+        assertNotNull(result.getEntity());
+      
+        HttpEntity entity = result.getEntity();
+        InputStream content = entity.getContent();
+        BufferedReader reader = new BufferedReader(new InputStreamReader(
+            content));
+        String line;
+        StringBuffer sb = new StringBuffer();
+        while ((line = reader.readLine()) != null) {
+          sb.append(line);
+        }
+        result.close();
+        
+        try {
+          jObject = new JSONObject(sb.toString());
+          jArray = jObject.getJSONArray("People");
+          assertEquals(jArray.length(), 16);
+        } catch (JSONException e) {
+          fail(" Rest Request ::" + currentOperation +  " :: should not have thrown JSONException ");
+        }
+      }
+      
+      //4. GetAll?limit=10 (10 entries) and verify results
+      {
+        HttpGet get = new HttpGet(restEndpoint + "/People?limit=10");
+        get.addHeader("Content-Type", "application/json");
+        get.addHeader("Accept", "application/json");
+        CloseableHttpClient httpclient = HttpClients.createDefault();
+        CloseableHttpResponse response = httpclient.execute(get);
+        assertEquals(response.getStatusLine().getStatusCode(), 200);
+        assertNotNull(response.getEntity());
+        
+        HttpEntity entity = response.getEntity();
+        InputStream content = entity.getContent();
+        BufferedReader reader = new BufferedReader(new InputStreamReader(
+            content));
+        String line;
+        StringBuffer str = new StringBuffer();
+        while ((line = reader.readLine()) != null) {
+          str.append(line);
+        }
+        
+        try {
+          jObject = new JSONObject(str.toString());
+          jArray = jObject.getJSONArray("People");
+          assertEquals(jArray.length(), 10);
+        } catch (JSONException e) {
+          fail(" Rest Request ::" + currentOperation +  " :: should not have thrown JSONException ");
+        }
+      }
+      
+      //5. Get keys - List all keys in region
+      {  
+        
+        HttpGet get = new HttpGet(restEndpoint + "/People/keys");
+        get.addHeader("Content-Type", "application/json");
+        get.addHeader("Accept", "application/json");
+        CloseableHttpClient httpclient = HttpClients.createDefault();
+        CloseableHttpResponse response = httpclient.execute(get);
+        assertEquals(response.getStatusLine().getStatusCode(), 200);
+        assertNotNull(response.getEntity());
+        
+        HttpEntity entity = response.getEntity();
+        InputStream content = entity.getContent();
+        BufferedReader reader = new BufferedReader(new InputStreamReader(
+            content));
+        String line;
+        StringBuffer str = new StringBuffer();
+        while ((line = reader.readLine()) != null) {
+          str.append(line);
+        }
+        
+        try {
+          jObject = new JSONObject(str.toString());
+          jArray = jObject.getJSONArray("keys"); 
+          assertEquals(jArray.length(), 16);
+        } catch (JSONException e) {
+          fail(" Rest Request ::" + currentOperation +  " :: should not have thrown JSONException ");
+        }
+      } 
+      
+      //6. Get data for specific keys
+      {  
+       
+        HttpGet get = new HttpGet(restEndpoint + "/People/1,3,5,7,9,11");
+        get.addHeader("Content-Type", "application/json");
+        get.addHeader("Accept", "application/json");
+        CloseableHttpClient httpclient = HttpClients.createDefault();
+        CloseableHttpResponse response = httpclient.execute(get);
+        assertEquals(response.getStatusLine().getStatusCode(), 200);
+        assertNotNull(response.getEntity());
+        
+        HttpEntity entity = response.getEntity();
+        InputStream content = entity.getContent();
+        BufferedReader reader = new BufferedReader(new InputStreamReader(
+            content));
+        String line;
+        StringBuffer str = new StringBuffer();
+        while ((line = reader.readLine()) != null) {
+          str.append(line);
+        }
+        
+        try {
+          jObject = new JSONObject(str.toString());
+          jArray = jObject.getJSONArray("People");
+          assertEquals(jArray.length(), 6);
+          
+        } catch (JSONException e) {
+          fail(" Rest Request ::" + currentOperation +  " :: should not have thrown JSONException ");
+        }
+      } 
+    }catch ( Exception e ) {
+      throw new RuntimeException("unexpected exception", e); 
+    }
+  }
+
+  public static void createRegionInClientCache() {
+    ClientCache cache = GemFireCacheImpl.getInstance();
+    assertNotNull(cache);
+    ClientRegionFactory<String, Object> crf = cache
+        .createClientRegionFactory(ClientRegionShortcut.PROXY);
+    Region<String, Object> region = crf.create(PEOPLE_REGION_NAME);
+
+  }
+
+  public static void createRegionInManager() {
+    Cache cache = GemFireCacheImpl.getInstance();
+    assertNotNull(cache);
+
+    RegionFactory<String, Object> rf = cache
+        .createRegionFactory(RegionShortcut.REPLICATE);
+    Region<String, Object> region = rf.create(PEOPLE_REGION_NAME);
+  }
+
+  public static void createRegionInPeerServer() {
+    Cache cache = GemFireCacheImpl.getInstance();
+    assertNotNull(cache);
+
+    RegionFactory<String, Object> rf = cache
+        .createRegionFactory(RegionShortcut.REPLICATE);
+    Region<String, Object> region = rf.create(PEOPLE_REGION_NAME);
+  }
+
+  /**
+   * InterOps Test between REST-client, Peer Cache Client and Client Cache 
+   * @throws Exception
+   */
+ 
+  public void testInterOpsWithReplicatedRegion() throws Exception {
+
+    final Host host = Host.getHost(0);
+    VM locator = host.getVM(0);
+    VM manager = host.getVM(1);
+    VM server = host.getVM(2);
+    VM client = host.getVM(3);
+
+    // start locator
+    int locatorPort = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
+    
+    startLocatorInVM(locator, locatorPort, "");
+    
+    // find locators
+    String locators = NetworkUtils.getServerHostName(locator.getHost()) + "[" + locatorPort
+        + "]";
+
+    // start manager (peer cache)
+    int managerPort = startManagerInVM(manager,/* groups */null, locators,
+        new String[] {REGION_NAME}, CacheServer.DEFAULT_LOAD_PROBE);
+    
+    //start startCacheServer With RestService enabled
+    String restEndpoint = (String)server.invoke(RestAPIsAndInterOpsDUnitTest.class,
+        "startBridgeServerWithRestServiceOnInVM", new Object[] { server ,  null, locators, new String[] {REGION_NAME}, CacheServer.DEFAULT_LOAD_PROBE });
+    
+    // create a client cache
+    createClientCacheInVM(client, NetworkUtils.getServerHostName(locator.getHost()),
+        locatorPort);
+    
+    // create region in Manager, peer cache and Client cache nodes
+    manager.invoke(() -> RestAPIsAndInterOpsDUnitTest.createRegionInManager());
+    server.invoke(() -> RestAPIsAndInterOpsDUnitTest.createRegionInPeerServer());
+    client.invoke(() -> RestAPIsAndInterOpsDUnitTest.createRegionInClientCache());
+    
+    // do some person puts from clientcache
+    client.invoke(() -> RestAPIsAndInterOpsDUnitTest.doPutsInClientCache());
+
+    //TEST: fetch all available REST endpoints
+    RestAPIsAndInterOpsDUnitTest.fetchRestServerEndpoints(restEndpoint);
+   
+    // Controller VM - config REST Client and make HTTP calls
+    RestAPIsAndInterOpsDUnitTest.doGetsUsingRestApis(restEndpoint);
+    
+    //update Data using REST APIs
+    RestAPIsAndInterOpsDUnitTest.doUpdatesUsingRestApis(restEndpoint);
+    
+    client.invoke(() -> RestAPIsAndInterOpsDUnitTest.verifyUpdatesInClientCache());
+
+    //Querying
+    RestAPIsAndInterOpsDUnitTest.doQueryOpsUsingRestApis(restEndpoint);
+    
+    // stop the client and make sure the bridge server notifies
+    // stopBridgeMemberVM(client);
+    helper.closeCache(locator);
+    helper.closeCache(manager);
+    helper.closeCache(server);
+    helper.closeCache(client);
+
+  }
+
+  private void createClientCacheInVM(VM vm, final String host, final int port) throws Exception {
+    SerializableRunnable connect = new SerializableRunnable(
+        "Start Cache client") {
+      public void run() {
+        // Connect using the GemFire locator and create a Caching_Proxy cache
+        ClientCache c = new ClientCacheFactory().setPdxReadSerialized(true).addPoolLocator(host, port)
+            .create();
+       
+        Region r = c.createClientRegionFactory(
+            ClientRegionShortcut.PROXY).create(REGION_NAME);
+      }
+    };
+
+    if (vm == null) {
+      connect.run();
+    } else {
+      vm.invoke(connect);
+    }
+  }
+
+  private int startManagerInVM(VM vm, final String[] groups,
+      final String locators, final String[] regions, final ServerLoadProbe probe) {
+    SerializableCallable connect = new SerializableCallable("Start Manager ") {
+      public Object call() throws IOException {
+        Properties props = new Properties();
+        props
+            .setProperty(DistributionConfig.MCAST_PORT_NAME, String.valueOf(0));
+        props.setProperty(DistributionConfig.LOCATORS_NAME, locators);
+
+        props.setProperty("jmx-manager", "true");
+        props.setProperty("jmx-manager-start", "true");
+        props.setProperty(DistributionConfig.JMX_MANAGER_PORT_NAME, "0");
+        
+        final int httpPort = AvailablePortHelper.getRandomAvailableTCPPort();
+        //Set REST service related configuration
+        props.setProperty(DistributionConfig.START_DEV_REST_API_NAME, "true");
+        props.setProperty(DistributionConfig.HTTP_SERVICE_BIND_ADDRESS_NAME, "localhost");
+        props.setProperty(DistributionConfig.HTTP_SERVICE_PORT_NAME, String.valueOf(httpPort));
+
+        DistributedSystem ds = getSystem(props);
+        Cache cache = CacheFactory.create(ds);
+        AttributesFactory factory = new AttributesFactory();
+        
+        factory.setEnableBridgeConflation(true);
+        factory.setDataPolicy(DataPolicy.REPLICATE);
+        RegionAttributes attrs = factory.create();
+        for (int i = 0; i < regions.length; i++) {
+          cache.createRegion(regions[i], attrs);
+        }
+        CacheServer server = cache.addCacheServer();
+        final int serverPort = AvailablePortHelper.getRandomAvailableTCPPort();
+        server.setPort(serverPort);
+        server.setGroups(groups);
+        server.setLoadProbe(probe);
+        server.start();
+        
+        return new Integer(serverPort);
+      }
+    };
+    Integer port = (Integer) vm.invoke(connect);
+    return port.intValue();
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9b55879e/geode-assembly/src/test/java/com/gemstone/gemfire/rest/internal/web/controllers/RestAPIsOnGroupsFunctionExecutionDUnitTest.java
----------------------------------------------------------------------
diff --git a/geode-assembly/src/test/java/com/gemstone/gemfire/rest/internal/web/controllers/RestAPIsOnGroupsFunctionExecutionDUnitTest.java b/geode-assembly/src/test/java/com/gemstone/gemfire/rest/internal/web/controllers/RestAPIsOnGroupsFunctionExecutionDUnitTest.java
new file mode 100644
index 0000000..1ae3810
--- /dev/null
+++ b/geode-assembly/src/test/java/com/gemstone/gemfire/rest/internal/web/controllers/RestAPIsOnGroupsFunctionExecutionDUnitTest.java
@@ -0,0 +1,306 @@
+/*
+ * 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 com.gemstone.gemfire.rest.internal.web.controllers;
+
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Random;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.json.JSONArray;
+
+import com.gemstone.gemfire.cache.execute.Function;
+import com.gemstone.gemfire.cache.execute.FunctionContext;
+import com.gemstone.gemfire.cache.execute.FunctionService;
+import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
+import com.gemstone.gemfire.test.dunit.Host;
+import com.gemstone.gemfire.test.dunit.IgnoredException;
+import com.gemstone.gemfire.test.dunit.LogWriterUtils;
+import com.gemstone.gemfire.test.dunit.SerializableCallable;
+import com.gemstone.gemfire.test.dunit.VM;
+
+public class RestAPIsOnGroupsFunctionExecutionDUnitTest extends RestAPITestBase {
+
+  public RestAPIsOnGroupsFunctionExecutionDUnitTest(String name) {
+    super(name);
+  }
+  
+  public void setUp() throws Exception {
+    super.setUp();
+    final Host host = Host.getHost(0);
+  }
+  
+  private void registerFunction(VM vm) {
+    vm.invoke(new SerializableCallable() {
+      private static final long serialVersionUID = 1L;
+      
+      @Override
+      public Object call() throws Exception {
+        FunctionService.registerFunction(new OnGroupsFunction());
+        return null;
+      }
+    });
+  }
+  
+  static class OnGroupsFunction implements Function {
+    private static final long serialVersionUID = -1032915440862585532L;
+    public static final String Id = "OnGroupsFunction";
+    public static int invocationCount;
+
+    @Override
+    public void execute(FunctionContext context) {
+      LogWriterUtils.getLogWriter().fine("SWAP:1:executing OnGroupsFunction:"+invocationCount);
+      InternalDistributedSystem ds = InternalDistributedSystem.getConnectedInstance();
+      invocationCount++;
+      ArrayList<String> l = (ArrayList<String>) context.getArguments();
+      if (l != null) {
+        assertFalse(Collections.disjoint(l, ds.getDistributedMember().getGroups()));
+      }
+      context.getResultSender().lastResult(Boolean.TRUE);
+    }
+
+    @Override
+    public String getId() {
+      return Id;
+    }
+
+    @Override
+    public boolean hasResult() {
+      return true;
+    }
+
+    @Override
+    public boolean optimizeForWrite() {
+      return false;
+    }
+
+    @Override
+    public boolean isHA() {
+      return false;
+    }
+  }
+  
+  
+  public static void executeFunctionThroughRestCall(List<String> restURLs) {
+    Random randomGenerator = new Random();
+    int index = randomGenerator.nextInt(restURLs.size());
+    
+    try {
+      
+      CloseableHttpClient httpclient = HttpClients.createDefault();
+      CloseableHttpResponse response = null;
+      HttpPost post = new HttpPost(restURLs.get(index) + "/functions/OnGroupsFunction?onGroups=g0,g1");
+      post.addHeader("Content-Type", "application/json");
+      post.addHeader("Accept", "application/json");
+      LogWriterUtils.getLogWriter().info("Request POST : " + post.toString());
+      response = httpclient.execute(post);
+      
+      HttpEntity entity = response.getEntity();
+      InputStream content = entity.getContent();
+      BufferedReader reader = new BufferedReader(new InputStreamReader(
+          content));
+      String line;
+      StringBuffer sb = new StringBuffer();
+      while ((line = reader.readLine()) != null) {
+        sb.append(line);
+      }      
+      LogWriterUtils.getLogWriter().info("Response : " + sb.toString());
+    
+      //verify response status code. expected status code is 200 OK.
+      assertEquals(response.getStatusLine().getStatusCode(), 200);
+      
+      
+      //verify response hasbody flag, expected is true.
+      assertNotNull(response.getEntity());
+      
+      
+      response.close();
+      
+      //verify function execution result
+      JSONArray resultArray = new JSONArray(sb.toString());
+      assertEquals(resultArray.length(), 3);
+      
+    } catch (Exception e) {
+      throw new RuntimeException("unexpected exception", e);
+    }
+    
+  }
+  
+  public static void executeFunctionOnMemberThroughRestCall(List<String> restURLs) {
+    Random randomGenerator = new Random();
+    int index = randomGenerator.nextInt(restURLs.size());
+    
+    //Testcase-1: Executing function on non-existing group. 
+    final IgnoredException ex = IgnoredException.addIgnoredException("com.gemstone.gemfire.cache.execute.FunctionException");
+    try {
+      
+      CloseableHttpClient httpclient = HttpClients.createDefault();
+      CloseableHttpResponse response = null;
+      HttpPost post = new HttpPost(restURLs.get(index) + "/functions/OnGroupsFunction?onGroups=no%20such%20group");
+      post.addHeader("Content-Type", "application/json");
+      post.addHeader("Accept", "application/json");
+      response = httpclient.execute(post);
+      
+      if ( response.getStatusLine().getStatusCode() == 200 ) {
+        fail("FunctionException expected : no member(s) are found belonging to the provided group(s)");
+      }
+    } catch (Exception e) {
+      throw new RuntimeException("unexpected exception", e);
+      
+    } finally {
+      ex.remove();
+    }
+    
+    //Testcase-2: Executing function on group with args.
+    
+    final String FUNCTION_ARGS1 =  "{"
+        +        "\"@type\": \"string\","
+        +        "\"@value\": \"gm\""
+        +    "}";
+    
+    try {
+     
+      CloseableHttpClient httpclient = HttpClients.createDefault();
+      CloseableHttpResponse response = null;
+      HttpPost post = new HttpPost(restURLs.get(index) + "/functions/OnGroupsFunction?onGroups=gm");
+      post.addHeader("Content-Type", "application/json");
+      post.addHeader("Accept", "application/json");
+      response = httpclient.execute(post);
+      
+      //verify response status code
+      assertEquals(response.getStatusLine().getStatusCode(), 200);
+      
+      //verify response hasbody flag
+      assertNotNull(response.getEntity());
+      
+      HttpEntity entity = response.getEntity();
+      InputStream content = entity.getContent();
+      BufferedReader reader = new BufferedReader(new InputStreamReader(
+          content));
+      String line;
+      StringBuffer sb = new StringBuffer();
+      while ((line = reader.readLine()) != null) {
+        sb.append(line);
+      }
+      response.close();
+      
+      //verify function execution result
+      JSONArray resultArray = new JSONArray(sb.toString());
+      assertEquals(resultArray.length(), 1);
+      
+    } catch (Exception e) {
+      throw new RuntimeException("unexpected exception", e);
+    }   
+  }
+  
+  private void verifyAndResetInvocationCount(VM vm, final int count) {
+    vm.invoke(new SerializableCallable() {
+      @Override
+      public Object call() throws Exception {
+        OnGroupsFunction f = (OnGroupsFunction) FunctionService.getFunction(OnGroupsFunction.Id);
+        assertEquals(count, f.invocationCount);
+        // assert succeeded, reset count
+        f.invocationCount = 0;
+        return null;
+      }
+    });
+  }
+  
+  private void resetInvocationCount(VM vm) {
+    vm.invoke(new SerializableCallable() {
+      @Override
+      public Object call() throws Exception {
+        OnGroupsFunction f = (OnGroupsFunction) FunctionService.getFunction(OnGroupsFunction.Id);
+        f.invocationCount = 0;
+        return null;
+      }
+    });
+  }
+  
+  public void testonGroupsExecutionOnAllMembers() {
+  
+    List<String> restURLs = new ArrayList<String>(); 
+    //Step-1 : create cache on each VM, this will start HTTP service in embedded mode and deploy REST APIs web app on it.
+    //         Create and configure Region on all VMs. Add Rest end-point into the restURLs list.
+    
+    String url1 = (String)vm0.invoke(() -> RestAPITestBase.createCacheWithGroups(vm0, "g0,gm", "TEST_REGION"));
+    restURLs.add(url1);
+    
+    String url2 = (String)vm1.invoke(() -> RestAPITestBase.createCacheWithGroups(vm1, "g1", "TEST_REGION" ));
+    restURLs.add(url2);
+    
+    String url3 = (String)vm2.invoke(() -> RestAPITestBase.createCacheWithGroups(vm2, "g0,g1", "TEST_REGION"));
+    restURLs.add(url3);
+    
+    //Step-2: Register function in all VMs
+    registerFunction(vm0);
+    registerFunction(vm1);
+    registerFunction(vm2);
+    
+    //Step-3 : Execute function randomly (in iteration) on all available (per VM) REST end-points and verify its result
+    for (int i=0; i< 10; i++)
+      executeFunctionThroughRestCall(restURLs);
+    
+    //Verify that each node belonging to specified group has run the function
+    verifyAndResetInvocationCount(vm0, 10);
+    verifyAndResetInvocationCount(vm1, 10);
+    verifyAndResetInvocationCount(vm2, 10);
+   
+    restURLs.clear();
+  }
+  
+  
+  public void testBasicP2PFunctionSelectedGroup() {
+  
+    List<String> restURLs = new ArrayList<String>(); 
+    
+    //Step-1 : create cache on each VM, this will start HTTP service in embedded mode and deploy REST APIs web app on it.
+    //         Create and configure Region on all VMs. Add Rest end-point into the restURLs list.
+    String url1 = (String)vm0.invoke(() -> RestAPITestBase.createCacheWithGroups(vm0, "g0,gm", "null" ));
+    restURLs.add(url1);
+    
+    String url2 = (String)vm1.invoke(() -> RestAPITestBase.createCacheWithGroups(vm1, "g1", "null"  ));
+    restURLs.add(url2);
+    
+    String url3 = (String)vm2.invoke(() -> RestAPITestBase.createCacheWithGroups(vm2, "g0,g1", "null" ));
+    restURLs.add(url3);
+    
+    //Step-2: Register function in all VMs
+    registerFunction(vm0);
+    registerFunction(vm1);
+    registerFunction(vm2);
+    
+    //Step-3 : Execute function randomly (in iteration) on all available (per VM) REST end-points and verify its result
+    for (int i=0; i< 5; i++)
+      executeFunctionOnMemberThroughRestCall(restURLs);
+    
+    resetInvocationCount(vm0);
+    resetInvocationCount(vm1);
+    resetInvocationCount(vm2);
+    
+    restURLs.clear();
+  }
+}
+