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:20 UTC

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

adding unit tests for REST API

A number of unit tests were still sitting in the work queue to be moved to
open-source including all of the REST API tests.  This change set shows the
build changes and AgentUtil changes needed to accomodate the new tests but
does not show the new tests.  The tests are being added to the
geode-assembly project, and all of the support classes in geode-core's
com.gemstone.gemfire.rest.internal.web.controllers package are being moved
to that project.

The tests will not run in Eclipse since a WAR file is not being created by
the Eclipse projects.  I've opened a JIRA ticket about that.


Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/9b55879e
Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/9b55879e
Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/9b55879e

Branch: refs/heads/feature/GEODE-949-2
Commit: 9b55879e872a52282b10a279cd8e9aa9669147ef
Parents: 5f98f31
Author: Bruce Schuchardt <bs...@pivotal.io>
Authored: Thu Feb 25 15:46:31 2016 -0800
Committer: Bruce Schuchardt <bs...@pivotal.io>
Committed: Thu Feb 25 15:49:13 2016 -0800

----------------------------------------------------------------------
 geode-assembly/build.gradle                     |    3 +
 .../internal/web/RestInterfaceJUnitTest.java    |  442 +++++
 .../web/controllers/AddFreeItemToOrders.java    |  153 ++
 .../rest/internal/web/controllers/Customer.java |  109 ++
 .../internal/web/controllers/DateTimeUtils.java |   40 +
 .../rest/internal/web/controllers/Gender.java   |   30 +
 .../internal/web/controllers/GetAllEntries.java |   68 +
 .../web/controllers/GetDeliveredOrders.java     |  106 ++
 .../internal/web/controllers/GetRegions.java    |   76 +
 .../web/controllers/GetValueForKey.java         |   77 +
 .../rest/internal/web/controllers/Item.java     |  160 ++
 .../rest/internal/web/controllers/Order.java    |  189 ++
 .../rest/internal/web/controllers/Person.java   |  185 ++
 .../web/controllers/PutKeyFunction.java         |   63 +
 ...stAPIOnRegionFunctionExecutionDUnitTest.java |  617 +++++++
 .../web/controllers/RestAPITestBase.java        |  133 ++
 .../RestAPIsAndInterOpsDUnitTest.java           |  915 ++++++++++
 ...tAPIsOnGroupsFunctionExecutionDUnitTest.java |  306 ++++
 ...APIsOnMembersFunctionExecutionDUnitTest.java |  328 ++++
 .../RestAPIsQueryAndFEJUnitTest.java            | 1715 ++++++++++++++++++
 .../controllers/RestAPIsWithSSLDUnitTest.java   |  653 +++++++
 .../internal/web/controllers/RestTestUtils.java |  110 ++
 .../gemfire/management/internal/AgentUtil.java  |    0
 .../web/controllers/AddFreeItemToOrders.java    |  153 --
 .../rest/internal/web/controllers/Customer.java |  109 --
 .../internal/web/controllers/DateTimeUtils.java |   40 -
 .../rest/internal/web/controllers/Gender.java   |   30 -
 .../internal/web/controllers/GetAllEntries.java |   68 -
 .../web/controllers/GetDeliveredOrders.java     |  106 --
 .../internal/web/controllers/GetRegions.java    |   76 -
 .../web/controllers/GetValueForKey.java         |   77 -
 .../rest/internal/web/controllers/Item.java     |  160 --
 .../rest/internal/web/controllers/Order.java    |  189 --
 .../rest/internal/web/controllers/Person.java   |  185 --
 .../web/controllers/PutKeyFunction.java         |   63 -
 .../web/controllers/RestAPITestBase.java        |  123 --
 .../internal/web/controllers/RestTestUtils.java |  110 --
 gradle/dependency-versions.properties           |    2 +
 38 files changed, 6480 insertions(+), 1489 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9b55879e/geode-assembly/build.gradle
----------------------------------------------------------------------
diff --git a/geode-assembly/build.gradle b/geode-assembly/build.gradle
index cf75135..14febbd 100755
--- a/geode-assembly/build.gradle
+++ b/geode-assembly/build.gradle
@@ -58,6 +58,9 @@ dependencies {
   testCompile project(':geode-junit')
   testCompile project(path: ':geode-core', configuration: 'testOutput')
 
+  testCompile 'org.apache.httpcomponents:httpclient:' + project.'httpclient.version'
+  testCompile 'org.apache.httpcomponents:httpcore:' + project.'httpcore.version'
+
   testRuntime files("${System.getProperty('java.home')}/../lib/tools.jar")
 }
 

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9b55879e/geode-assembly/src/test/java/com/gemstone/gemfire/rest/internal/web/RestInterfaceJUnitTest.java
----------------------------------------------------------------------
diff --git a/geode-assembly/src/test/java/com/gemstone/gemfire/rest/internal/web/RestInterfaceJUnitTest.java b/geode-assembly/src/test/java/com/gemstone/gemfire/rest/internal/web/RestInterfaceJUnitTest.java
new file mode 100644
index 0000000..a1c843f
--- /dev/null
+++ b/geode-assembly/src/test/java/com/gemstone/gemfire/rest/internal/web/RestInterfaceJUnitTest.java
@@ -0,0 +1,442 @@
+package com.gemstone.gemfire.rest.internal.web;
+
+import static org.junit.Assert.*;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+
+import javax.annotation.Resource;
+
+import com.fasterxml.jackson.core.JsonParser.Feature;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+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.RegionFactory;
+import com.gemstone.gemfire.cache.RegionService;
+import com.gemstone.gemfire.internal.AvailablePortHelper;
+import com.gemstone.gemfire.internal.GemFireVersion;
+import com.gemstone.gemfire.internal.util.IOUtils;
+import com.gemstone.gemfire.management.internal.AgentUtil;
+import com.gemstone.gemfire.pdx.PdxInstance;
+import com.gemstone.gemfire.pdx.PdxReader;
+import com.gemstone.gemfire.pdx.PdxSerializable;
+import com.gemstone.gemfire.pdx.PdxWriter;
+import com.gemstone.gemfire.pdx.ReflectionBasedAutoSerializer;
+import com.gemstone.gemfire.test.junit.categories.IntegrationTest;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.client.ClientHttpResponse;
+import org.springframework.http.converter.HttpMessageConverter;
+import org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean;
+import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
+import org.springframework.util.Assert;
+import org.springframework.util.ObjectUtils;
+import org.springframework.util.StringUtils;
+import org.springframework.web.client.ResponseErrorHandler;
+import org.springframework.web.client.RestTemplate;
+
+/**
+ * The GemFireRestInterfaceTest class is a test suite of test cases testing the contract and functionality of the
+ * GemFire Developer REST API, mixing Java clients, this test GemFire's Cache Region API, along with
+ * a REST-based client, also this test using Spring's RestTemplate, testing the proper interaction, especially
+ * in the case of an application domain object type having a java.util.Date property.
+ *
+ * @author John Blum
+ * @see org.junit.Test
+ * @see org.junit.runner.RunWith
+ * @see org.springframework.test.context.ContextConfiguration
+ * @see org.springframework.test.context.junit4.SpringJUnit4ClassRunner
+ * @see org.springframework.web.client.RestTemplate
+ * @see com.gemstone.gemfire.cache.Cache
+ * @see com.gemstone.gemfire.cache.Region
+ * @see com.gemstone.gemfire.pdx.PdxInstance
+ * @see com.gemstone.gemfire.pdx.ReflectionBasedAutoSerializer
+ * @since 1.0.0
+ */
+//@RunWith(SpringJUnit4ClassRunner.class)
+//@ContextConfiguration
+@SuppressWarnings("unused")
+@Category(IntegrationTest.class)
+public class RestInterfaceJUnitTest {
+
+  protected static int DEFAULT_HTTP_SERVICE_PORT = 8189;
+
+  protected static final String REST_API_SERVICE_ENDPOINT = "http://localhost:%1$d/gemfire-api/v1/%2$s/%3$s";
+  protected static final String UTF_8 = "UTF-8";
+
+  @Autowired
+  private Cache gemfireCache;
+
+  @Autowired
+  private ObjectMapper objectMapper;
+
+  @Resource(name = "gemfireProperties")
+  private Properties gemfireProperties;
+
+  @Resource(name = "People")
+  private Region<String, Object> people;
+
+  @Before
+  public void setupGemFire() {
+    AgentUtil agentUtil = new AgentUtil(GemFireVersion.getGemFireVersion());
+    if (agentUtil.findWarLocation("geode-web-api") == null) {
+      fail("unable to locate geode-web-api WAR file");
+    }
+
+    if (gemfireCache == null) {
+      gemfireProperties = (gemfireProperties != null ? gemfireProperties : new Properties());
+
+      gemfireCache = new CacheFactory()
+        //.setPdxSerializer(new ReflectionBasedAutoSerializer(Person.class.getPackage().getName().concat(".*")))
+        .setPdxSerializer(new ReflectionBasedAutoSerializer(Person.class.getName().replaceAll("\\$", ".")))
+        .setPdxReadSerialized(true)
+        .setPdxIgnoreUnreadFields(false)
+        .set("name", getClass().getSimpleName())
+        .set("mcast-port", "0")
+        .set("log-level", "config")
+        .set("http-service-bind-address", "localhost")
+        .set("http-service-port", String.valueOf(getHttpServicePort()))
+        //.set("http-service-ssl-enabled", "false")
+        .set("start-dev-rest-api", "true")
+        .create();
+
+      RegionFactory<String, Object> peopleRegionFactory = gemfireCache.createRegionFactory();
+
+      peopleRegionFactory.setDataPolicy(DataPolicy.PARTITION);
+      peopleRegionFactory.setKeyConstraint(String.class);
+      peopleRegionFactory.setValueConstraint(Object.class);
+
+      people = peopleRegionFactory.create("People");
+    }
+  }
+
+  @After
+  public void tearDown() {
+    gemfireCache.close();
+  }
+
+  protected synchronized int getHttpServicePort() {
+    try {
+      return Integer.parseInt(StringUtils.trimWhitespace(gemfireProperties.getProperty("http-service-port")));
+    }
+    catch (NumberFormatException ignore) {
+      int httpServicePort = getHttpServicePort(DEFAULT_HTTP_SERVICE_PORT);
+      gemfireProperties.setProperty("http-service-port", String.valueOf(httpServicePort));
+      return httpServicePort;
+    }
+  }
+
+  private int getHttpServicePort(final int defaultHttpServicePort) {
+    int httpServicePort = AvailablePortHelper.getRandomAvailableTCPPort();
+    return (httpServicePort > 1024 && httpServicePort < 65536 ? httpServicePort : defaultHttpServicePort);
+  }
+
+  protected ObjectMapper getObjectMapper() {
+    if (objectMapper == null) {
+      Jackson2ObjectMapperFactoryBean objectMapperFactoryBean = new Jackson2ObjectMapperFactoryBean();
+
+      objectMapperFactoryBean.setFailOnEmptyBeans(true);
+      objectMapperFactoryBean.setFeaturesToEnable(Feature.ALLOW_COMMENTS);
+      objectMapperFactoryBean.setFeaturesToEnable(Feature.ALLOW_SINGLE_QUOTES);
+      objectMapperFactoryBean.setFeaturesToEnable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);
+      objectMapperFactoryBean.setFeaturesToDisable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
+      objectMapperFactoryBean.setIndentOutput(true);
+      objectMapperFactoryBean.setSimpleDateFormat("MM/dd/yyyy");
+      objectMapperFactoryBean.afterPropertiesSet();
+
+      objectMapper = objectMapperFactoryBean.getObject();
+    }
+
+    return objectMapper;
+  }
+
+  protected Region<String, Object> getPeopleRegion() {
+    assertNotNull("The 'People' Region was not properly initialized!", people);
+    return people;
+  }
+
+  protected String getAdhocQueryRestApiEndpoint(final String query) {
+    return getAdhocQueryRestApiEndpoint(getHttpServicePort(), query);
+  }
+
+  protected String getAdhocQueryRestApiEndpoint(final int httpServicePort, final String query) {
+    return String.format(REST_API_SERVICE_ENDPOINT, httpServicePort, "queries", String.format("adhoc?q=%1$s", query));
+  }
+
+  protected String getRegionGetRestApiEndpoint(final Region<?, ?> region, final String key) {
+    return getRegionGetRestApiEndpoint(getHttpServicePort(), region, key);
+  }
+
+  protected String getRegionGetRestApiEndpoint(final int httpServicePort, final Region<?, ?> region, final String key) {
+    return String.format(REST_API_SERVICE_ENDPOINT, httpServicePort, region.getName(), key);
+  }
+
+  protected Date createDate(final int year, final int month, final int dayOfMonth) {
+    Calendar dateTime = Calendar.getInstance();
+    dateTime.clear();
+    dateTime.set(Calendar.YEAR, year);
+    dateTime.set(Calendar.MONTH, month);
+    dateTime.set(Calendar.DAY_OF_MONTH, dayOfMonth);
+    return dateTime.getTime();
+  }
+
+  protected Person createPerson(final String firstName, final String lastName) {
+    return createPerson(firstName, lastName, null);
+  }
+
+  protected Person createPerson(final String firstName, final String lastName, final Date birthDate) {
+    return new Person(firstName, lastName, birthDate);
+  }
+
+  protected RestTemplate createRestTemplate() {
+    MappingJackson2HttpMessageConverter httpMessageConverter = new MappingJackson2HttpMessageConverter();
+
+    httpMessageConverter.setObjectMapper(getObjectMapper());
+
+    return setErrorHandler(new RestTemplate(Collections.<HttpMessageConverter<?>>singletonList(
+      httpMessageConverter)));
+  }
+
+  private RestTemplate setErrorHandler(final RestTemplate restTemplate) {
+    restTemplate.setErrorHandler(new ResponseErrorHandler() {
+      private final Set<HttpStatus> errorStatuses = new HashSet<>();
+
+      /* non-static */ {
+        errorStatuses.add(HttpStatus.BAD_REQUEST);
+        errorStatuses.add(HttpStatus.UNAUTHORIZED);
+        errorStatuses.add(HttpStatus.FORBIDDEN);
+        errorStatuses.add(HttpStatus.NOT_FOUND);
+        errorStatuses.add(HttpStatus.METHOD_NOT_ALLOWED);
+        errorStatuses.add(HttpStatus.NOT_ACCEPTABLE);
+        errorStatuses.add(HttpStatus.REQUEST_TIMEOUT);
+        errorStatuses.add(HttpStatus.CONFLICT);
+        errorStatuses.add(HttpStatus.REQUEST_ENTITY_TOO_LARGE);
+        errorStatuses.add(HttpStatus.REQUEST_URI_TOO_LONG);
+        errorStatuses.add(HttpStatus.UNSUPPORTED_MEDIA_TYPE);
+        errorStatuses.add(HttpStatus.TOO_MANY_REQUESTS);
+        errorStatuses.add(HttpStatus.INTERNAL_SERVER_ERROR);
+        errorStatuses.add(HttpStatus.NOT_IMPLEMENTED);
+        errorStatuses.add(HttpStatus.BAD_GATEWAY);
+        errorStatuses.add(HttpStatus.SERVICE_UNAVAILABLE);
+      }
+
+      @Override
+      public boolean hasError(final ClientHttpResponse response) throws IOException {
+        return errorStatuses.contains(response.getStatusCode());
+      }
+
+      @Override
+      public void handleError(final ClientHttpResponse response) throws IOException {
+        System.err.printf("%1$d - %2$s%n", response.getRawStatusCode(),
+          response.getStatusText());
+        System.err.println(readBody(response));
+      }
+
+      private String readBody(final ClientHttpResponse response) throws IOException {
+        BufferedReader responseBodyReader = null;
+
+        try {
+          responseBodyReader = new BufferedReader(new InputStreamReader(response.getBody()));
+
+          StringBuilder buffer = new StringBuilder();
+          String line;
+
+          while ((line = responseBodyReader.readLine()) != null) {
+            buffer.append(line).append(System.getProperty("line.separator"));
+          }
+
+          return buffer.toString().trim();
+        }
+        finally {
+          IOUtils.close(responseBodyReader);
+        }
+      }
+    });
+
+    return restTemplate;
+  }
+
+  @Test
+  public void testRegionObjectWithDatePropertyAccessedWithRestApi() throws Exception {
+    String key = "1";
+    Person jonDoe = createPerson("Jon", "Doe", createDate(1977, Calendar.OCTOBER, 31));
+
+    assertTrue(getPeopleRegion().isEmpty());
+
+    getPeopleRegion().put(key, jonDoe);
+
+    assertFalse(getPeopleRegion().isEmpty());
+    assertEquals(1, getPeopleRegion().size());
+    assertTrue(getPeopleRegion().containsKey(key));
+
+    Object jonDoeRef = getPeopleRegion().get(key);
+
+    assertTrue(jonDoeRef instanceof PdxInstance);
+    assertEquals(jonDoe.getClass().getName(), ((PdxInstance) jonDoeRef).getClassName());
+    assertEquals(jonDoe.getFirstName(), ((PdxInstance) jonDoeRef).getField("firstName"));
+    assertEquals(jonDoe.getLastName(), ((PdxInstance) jonDoeRef).getField("lastName"));
+    assertEquals(jonDoe.getBirthDate(), ((PdxInstance) jonDoeRef).getField("birthDate"));
+
+    RestTemplate restTemplate = createRestTemplate();
+
+    Person jonDoeResource = restTemplate.getForObject(getRegionGetRestApiEndpoint(getPeopleRegion(), key), Person.class);
+
+    assertNotNull(jonDoeResource);
+    assertNotSame(jonDoe, jonDoeResource);
+    assertEquals(jonDoe, jonDoeResource);
+
+    /*
+    Object result = runQueryUsingApi(getPeopleRegion().getRegionService(), String.format("SELECT * FROM %1$s",
+      getPeopleRegion().getFullPath()));
+
+    System.out.printf("(OQL Query using API) Person is (%1$s)%n", result);
+    */
+
+    String url = getAdhocQueryRestApiEndpoint(String.format("SELECT * FROM %1$s", getPeopleRegion().getFullPath()));
+
+    System.out.printf("URL (%1$s)%n", url);
+
+    List<?> queryResults = restTemplate.getForObject(url, List.class);
+
+    assertNotNull(queryResults);
+    assertFalse(queryResults.isEmpty());
+    assertEquals(1, queryResults.size());
+
+    jonDoeResource = objectMapper.convertValue(queryResults.get(0), Person.class);
+
+    assertNotNull(jonDoeResource);
+    assertNotSame(jonDoe, jonDoeResource);
+    assertEquals(jonDoe, jonDoeResource);
+  }
+
+  private Object runQueryUsingApi(final RegionService regionService, final String queryString) throws Exception {
+    return regionService.getQueryService().newQuery(queryString).execute();
+  }
+
+  //@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.NONE)
+  //@JsonIgnoreProperties(ignoreUnknown = true)
+  //@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "@type")
+  public static class Person implements PdxSerializable {
+
+    protected static final String DEFAULT_BIRTH_DATE_FORMAT_PATTERN = "MM/dd/yyyy";
+
+    private Date birthDate;
+
+    private String firstName;
+    private String lastName;
+
+    public Person() {
+    }
+
+    public Person(final String firstName, final String lastName) {
+      this(firstName, lastName, null);
+    }
+
+    public Person(final String firstName, final String lastName, final Date birthDate) {
+      setFirstName(firstName);
+      setLastName(lastName);
+      setBirthDate(birthDate);
+    }
+
+    public Date getBirthDate() {
+      return birthDate;
+    }
+
+    public void setBirthDate(final Date birthDate) {
+      Assert.isTrue(birthDate == null || birthDate.compareTo(Calendar.getInstance().getTime()) <= 0,
+        "A Person's date of birth cannot be after today!");
+      this.birthDate = birthDate;
+    }
+
+    public String getFirstName() {
+      return firstName;
+    }
+
+    public void setFirstName(final String firstName) {
+      Assert.hasText(firstName, "The Person must have a first name!");
+      this.firstName = firstName;
+    }
+
+    public String getLastName() {
+      return lastName;
+    }
+
+    public void setLastName(final String lastName) {
+      Assert.hasText(firstName, "The Person must have a last name!");
+      this.lastName = lastName;
+    }
+
+    protected final String format(final Date dateTime) {
+      return format(dateTime, DEFAULT_BIRTH_DATE_FORMAT_PATTERN);
+    }
+
+    protected String format(final Date dateTime, final String dateFormatPattern) {
+      return (dateTime == null ? null : new SimpleDateFormat(StringUtils.hasText(dateFormatPattern) ? dateFormatPattern
+        : DEFAULT_BIRTH_DATE_FORMAT_PATTERN).format(dateTime));
+    }
+
+    @Override
+    public void toData(final PdxWriter writer) {
+      writer.writeString("firstName", getFirstName());
+      writer.writeString("lastName", getLastName());
+      writer.writeDate("birthDate", getBirthDate());
+    }
+
+    @Override
+    public void fromData(final PdxReader reader) {
+      setFirstName(reader.readString("firstName"));
+      setLastName(reader.readString("lastName"));
+      setBirthDate(reader.readDate("birthDate"));
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+      if (obj == this) {
+        return true;
+      }
+
+      if (!(obj instanceof Person)) {
+        return false;
+      }
+
+      Person that = (Person) obj;
+
+      return ObjectUtils.nullSafeEquals(this.getFirstName(), that.getFirstName())
+        && ObjectUtils.nullSafeEquals(this.getLastName(), that.getLastName())
+        && ObjectUtils.nullSafeEquals(this.getBirthDate(), that.getBirthDate());
+    }
+
+    @Override
+    public int hashCode() {
+      int hashValue = 17;
+      hashValue = 37 * hashValue + ObjectUtils.nullSafeHashCode(getFirstName());
+      hashValue = 37 * hashValue + ObjectUtils.nullSafeHashCode(getLastName());
+      hashValue = 37 * hashValue + ObjectUtils.nullSafeHashCode(getBirthDate());
+      return hashValue;
+    }
+
+    @Override
+    public String toString() {
+      return String.format("{ @type = %1$s, firstName = %2$s, lastName = %3$s, birthDate = %4$s }",
+        getClass().getName(), getFirstName(), getLastName(), format(getBirthDate()));
+    }
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9b55879e/geode-assembly/src/test/java/com/gemstone/gemfire/rest/internal/web/controllers/AddFreeItemToOrders.java
----------------------------------------------------------------------
diff --git a/geode-assembly/src/test/java/com/gemstone/gemfire/rest/internal/web/controllers/AddFreeItemToOrders.java b/geode-assembly/src/test/java/com/gemstone/gemfire/rest/internal/web/controllers/AddFreeItemToOrders.java
new file mode 100644
index 0000000..c8a2ce3
--- /dev/null
+++ b/geode-assembly/src/test/java/com/gemstone/gemfire/rest/internal/web/controllers/AddFreeItemToOrders.java
@@ -0,0 +1,153 @@
+/*
+ * 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.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.Vector;
+
+import com.gemstone.gemfire.cache.Cache;
+import com.gemstone.gemfire.cache.CacheClosedException;
+import com.gemstone.gemfire.cache.CacheFactory;
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.cache.execute.Function;
+import com.gemstone.gemfire.cache.execute.FunctionContext;
+import com.gemstone.gemfire.cache.query.FunctionDomainException;
+import com.gemstone.gemfire.cache.query.NameResolutionException;
+import com.gemstone.gemfire.cache.query.Query;
+import com.gemstone.gemfire.cache.query.QueryInvocationTargetException;
+import com.gemstone.gemfire.cache.query.SelectResults;
+import com.gemstone.gemfire.cache.query.TypeMismatchException;
+import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
+import com.gemstone.gemfire.pdx.PdxInstance;
+
+/**
+ * Gemfire function to add free items in the existing order
+ * if the total price for that order is greater then the argument
+ * @author Nilkanth Patel
+ */
+
+public class AddFreeItemToOrders implements Function  {
+  
+  public void execute(FunctionContext context) {
+
+    Cache c = null;
+    Region r = null;
+    List<Object> vals = new ArrayList<Object>();
+    List<Object> keys = new ArrayList<Object>();
+    List<Object> argsList = new ArrayList<Object>();
+    Object[] argsArray = null;
+    
+    if (context.getArguments() instanceof Boolean) {
+    
+    } else if (context.getArguments() instanceof String) {
+      String arg = (String) context.getArguments();
+    }else if(context.getArguments() instanceof Vector ) {
+      
+    }else if (context.getArguments() instanceof Object[]) {
+      argsArray = (Object[]) context.getArguments();
+      argsList = Arrays.asList(argsArray);
+    }else {
+      System.out.println("AddFreeItemToOrders : Invalid Arguments");
+    }
+    
+    try {
+      c = CacheFactory.getAnyInstance();
+      ((GemFireCacheImpl)c).getCacheConfig().setPdxReadSerialized(true);
+      r = c.getRegion("orders");
+    } catch (CacheClosedException ex) {
+      vals.add("NoCacheFoundResult");
+      context.getResultSender().lastResult(vals);
+    }
+
+    String oql = "SELECT DISTINCT entry.key FROM /orders.entries entry WHERE entry.value.totalPrice > $1";
+    Object queryArgs[] = new Object[1];
+    queryArgs[0] = argsList.get(0);
+    
+    final Query query = c.getQueryService().newQuery(oql);
+
+    SelectResults result = null;
+    try {
+      result = (SelectResults) query.execute(queryArgs);
+      int resultSize = result.size();
+      
+      if (result instanceof Collection<?>)  
+        for (Object item : result) {
+          keys.add(item);
+        }
+    } catch (FunctionDomainException e) {
+     if(c != null)
+      c.getLogger().info("Caught FunctionDomainException while executing function AddFreeItemToOrders: " + e.getMessage());
+      
+    } catch (TypeMismatchException e) {
+      if(c != null)
+        c.getLogger().info("Caught TypeMismatchException while executing function AddFreeItemToOrders: " + e.getMessage()); 
+    } catch (NameResolutionException e) {
+      if(c != null)
+        c.getLogger().info("Caught NameResolutionException while executing function AddFreeItemToOrders: "  + e.getMessage());
+    } catch (QueryInvocationTargetException e) {
+      if(c != null)
+        c.getLogger().info("Caught QueryInvocationTargetException while executing function AddFreeItemToOrders" + e.getMessage());
+    }
+    
+    //class has to be in classpath.
+    try {
+      Item it = (Item)(argsList.get(1));
+      for(Object key : keys)
+      {
+        Object obj = r.get(key);
+        if(obj instanceof PdxInstance) {
+          PdxInstance pi = (PdxInstance)obj;
+          Order receivedOrder = (Order)pi.getObject();
+          receivedOrder.addItem(it);
+              
+          r.put(key, receivedOrder);
+        }
+      }
+      
+      context.getResultSender().lastResult("success");
+      
+    }catch (ClassCastException e) {
+      
+      context.getResultSender().lastResult("failure");
+    }catch (Exception e) {
+      context.getResultSender().lastResult("failure");
+    }
+    
+  }
+
+  public String getId() {
+    return "AddFreeItemToOrders";
+  }
+
+  @Override
+  public boolean hasResult() {
+    return true;
+  }
+
+  @Override
+  public boolean optimizeForWrite() {
+    return false;
+  }
+
+  @Override
+  public boolean isHA() {
+    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/Customer.java
----------------------------------------------------------------------
diff --git a/geode-assembly/src/test/java/com/gemstone/gemfire/rest/internal/web/controllers/Customer.java b/geode-assembly/src/test/java/com/gemstone/gemfire/rest/internal/web/controllers/Customer.java
new file mode 100644
index 0000000..93ac63d
--- /dev/null
+++ b/geode-assembly/src/test/java/com/gemstone/gemfire/rest/internal/web/controllers/Customer.java
@@ -0,0 +1,109 @@
+/*
+ * 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 com.gemstone.gemfire.internal.lang.ObjectUtils;
+
+/**
+ * The Customer class models a customer entity.
+ * <p/>
+ * @author Nilkanth Patel
+ * @since 8.0
+ */
+
+public class Customer implements Serializable {
+
+  private Long customerId;
+  private String firstName;
+  private String lastName;
+
+  public Customer() {
+  }
+
+  public Customer(final Long custId) {
+    this.customerId = custId;
+  }
+
+  public Customer(final Long custId, final String fname, final String lname) {
+    this.customerId = custId;
+    this.firstName = fname;
+    this.lastName = lname;
+  }
+
+  public Long getCustomerId() {
+    return customerId;
+  }
+
+  public void setCustomerId(Long customerId) {
+    this.customerId = customerId;
+  }
+
+  public String getFirstName() {
+    return firstName;
+  }
+
+  public void setFirstName(String firstName) {
+    this.firstName = firstName;
+  }
+
+  public String getLastName() {
+    return lastName;
+  }
+
+  public void setLastName(String lastName) {
+    this.lastName = lastName;
+  }
+
+  @Override
+  public boolean equals(final Object obj) {
+    if (obj == this) {
+      return true;
+    }
+
+    if (!(obj instanceof Customer)) {
+      return false;
+    }
+
+    final Customer that = (Customer) obj;
+
+    return (ObjectUtils.equals(this.getCustomerId(), that.getCustomerId())
+        && ObjectUtils.equals(this.getLastName(), that.getLastName()) && ObjectUtils
+          .equals(this.getFirstName(), that.getFirstName()));
+  }
+
+  @Override
+  public int hashCode() {
+    int hashValue = 17;
+    hashValue = 37 * hashValue + ObjectUtils.hashCode(getCustomerId());
+    hashValue = 37 * hashValue + ObjectUtils.hashCode(getLastName());
+    hashValue = 37 * hashValue + ObjectUtils.hashCode(getFirstName());
+    return hashValue;
+  }
+
+  @Override
+  public String toString() {
+    final StringBuilder buffer = new StringBuilder("{ type = ");
+    buffer.append(getClass().getName());
+    buffer.append(", customerId = ").append(getCustomerId());
+    buffer.append(", firstName = ").append(getFirstName());
+    buffer.append(", lastName = ").append(getLastName());
+    buffer.append(" }");
+    return buffer.toString();
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9b55879e/geode-assembly/src/test/java/com/gemstone/gemfire/rest/internal/web/controllers/DateTimeUtils.java
----------------------------------------------------------------------
diff --git a/geode-assembly/src/test/java/com/gemstone/gemfire/rest/internal/web/controllers/DateTimeUtils.java b/geode-assembly/src/test/java/com/gemstone/gemfire/rest/internal/web/controllers/DateTimeUtils.java
new file mode 100644
index 0000000..3a92df3
--- /dev/null
+++ b/geode-assembly/src/test/java/com/gemstone/gemfire/rest/internal/web/controllers/DateTimeUtils.java
@@ -0,0 +1,40 @@
+/*
+ * 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.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+
+public class DateTimeUtils {
+  public static Calendar createCalendar(final int year, final int month, final int day) {
+    final Calendar dateTime = Calendar.getInstance();
+    dateTime.clear();
+    dateTime.set(Calendar.YEAR, year);
+    dateTime.set(Calendar.MONTH, month);
+    dateTime.set(Calendar.DAY_OF_MONTH, day);
+    return dateTime;
+  }
+
+  public static Date createDate(final int year, final int month, final int day) {
+    return createCalendar(year, month, day).getTime();
+  }
+
+  public static String format(final Date dateTime, final String formatPattern) {
+    return (dateTime != null ? new SimpleDateFormat(formatPattern).format(dateTime) : null);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9b55879e/geode-assembly/src/test/java/com/gemstone/gemfire/rest/internal/web/controllers/Gender.java
----------------------------------------------------------------------
diff --git a/geode-assembly/src/test/java/com/gemstone/gemfire/rest/internal/web/controllers/Gender.java b/geode-assembly/src/test/java/com/gemstone/gemfire/rest/internal/web/controllers/Gender.java
new file mode 100644
index 0000000..9b00108
--- /dev/null
+++ b/geode-assembly/src/test/java/com/gemstone/gemfire/rest/internal/web/controllers/Gender.java
@@ -0,0 +1,30 @@
+/*
+ * 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;
+
+/**
+ * The Gender enum is a enumeration of genders (sexes).
+ * <p/>
+ * @author Nilkanth Patel, John Blum
+ * @since 8.0
+ */
+
+@SuppressWarnings("unused")
+public enum Gender {
+  FEMALE,
+  MALE
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9b55879e/geode-assembly/src/test/java/com/gemstone/gemfire/rest/internal/web/controllers/GetAllEntries.java
----------------------------------------------------------------------
diff --git a/geode-assembly/src/test/java/com/gemstone/gemfire/rest/internal/web/controllers/GetAllEntries.java b/geode-assembly/src/test/java/com/gemstone/gemfire/rest/internal/web/controllers/GetAllEntries.java
new file mode 100644
index 0000000..cb85687
--- /dev/null
+++ b/geode-assembly/src/test/java/com/gemstone/gemfire/rest/internal/web/controllers/GetAllEntries.java
@@ -0,0 +1,68 @@
+/*
+ * 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.HashMap;
+import java.util.Map;
+
+import com.gemstone.gemfire.cache.execute.Function;
+import com.gemstone.gemfire.cache.execute.FunctionContext;
+
+/**
+ * The GetAllEntries is function that will return a map as a result of its execution.
+ * <p/>
+ * @author Nilkanth Patel
+ * @since 8.0
+ */
+
+public class GetAllEntries implements Function {
+
+  @Override
+  public void execute(FunctionContext context) {
+    Map<String, String> myMap = new HashMap();
+    myMap.put("k11", "v1");
+    myMap.put("k12", "v2");
+    myMap.put("k13", "v3");
+    myMap.put("k14", "v4");
+    myMap.put("k15", "v5");
+     
+    //return map as a function result
+    context.getResultSender().lastResult(myMap);
+  }
+
+  @Override
+  public String getId() {
+    return "GetAllEntries";
+  }
+
+  @Override
+  public boolean hasResult() {
+    return true;
+  }
+
+  @Override
+  public boolean optimizeForWrite() {
+    return false;
+  }
+
+  @Override
+  public boolean isHA() {
+    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/GetDeliveredOrders.java
----------------------------------------------------------------------
diff --git a/geode-assembly/src/test/java/com/gemstone/gemfire/rest/internal/web/controllers/GetDeliveredOrders.java b/geode-assembly/src/test/java/com/gemstone/gemfire/rest/internal/web/controllers/GetDeliveredOrders.java
new file mode 100644
index 0000000..3a150a3
--- /dev/null
+++ b/geode-assembly/src/test/java/com/gemstone/gemfire/rest/internal/web/controllers/GetDeliveredOrders.java
@@ -0,0 +1,106 @@
+/*
+ * 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.ArrayList;
+import java.util.Collection;
+
+import com.gemstone.gemfire.cache.Cache;
+import com.gemstone.gemfire.cache.CacheClosedException;
+import com.gemstone.gemfire.cache.CacheFactory;
+import com.gemstone.gemfire.cache.execute.Function;
+import com.gemstone.gemfire.cache.execute.FunctionContext;
+import com.gemstone.gemfire.cache.query.FunctionDomainException;
+import com.gemstone.gemfire.cache.query.NameResolutionException;
+import com.gemstone.gemfire.cache.query.Query;
+import com.gemstone.gemfire.cache.query.QueryInvocationTargetException;
+import com.gemstone.gemfire.cache.query.SelectResults;
+import com.gemstone.gemfire.cache.query.TypeMismatchException;
+
+
+/**
+* The GetDeliveredOrders class is a gemfire function that gives details about delivered orders.
+* <p/>
+* @author Nilkanth Patel
+* @since 8.0
+*/
+
+public class GetDeliveredOrders  implements Function {
+  public void execute(FunctionContext context) {
+    
+    Cache c = null;
+    ArrayList<Object> vals = new ArrayList<Object>();
+    try {
+      c = CacheFactory.getAnyInstance();
+    } catch (CacheClosedException ex) {
+      vals.add("NoCacheFoundResult");
+      context.getResultSender().lastResult(vals);
+    }
+    
+    String oql = "SELECT o.purchaseOrderNo, o.deliveryDate  FROM /orders o WHERE o.deliveryDate != NULL";
+    final Query query = c.getQueryService().newQuery(oql);
+   
+    SelectResults result = null;
+    try {
+      result = (SelectResults) query.execute();
+      int resultSize = result.size();
+      
+      if(result instanceof Collection<?>)
+        for(Object item : result){
+          vals.add(item);
+        }
+    } catch (FunctionDomainException e) {
+      if(c != null)
+        c.getLogger().info("Caught FunctionDomainException while executing function GetDeliveredOrders: " + e.getMessage());
+        
+    } catch (TypeMismatchException e) {
+      if(c != null)
+        c.getLogger().info("Caught TypeMismatchException while executing function GetDeliveredOrders: " + e.getMessage());
+      
+    } catch (NameResolutionException e) {
+      if(c != null)
+        c.getLogger().info("Caught NameResolutionException while executing function GetDeliveredOrders: " + e.getMessage());
+      
+    } catch (QueryInvocationTargetException e) {
+      if(c != null)
+        c.getLogger().info("Caught QueryInvocationTargetException while executing function GetDeliveredOrders: " + e.getMessage());
+      
+    }
+    
+    context.getResultSender().lastResult(vals);
+  }
+
+  public String getId() {
+    return "GetDeliveredOrders";
+  }
+
+  @Override
+  public boolean hasResult() {
+    return true;
+  }
+
+  @Override
+  public boolean optimizeForWrite() {
+    return false;
+  }
+
+  @Override
+  public boolean isHA() {
+    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/GetRegions.java
----------------------------------------------------------------------
diff --git a/geode-assembly/src/test/java/com/gemstone/gemfire/rest/internal/web/controllers/GetRegions.java b/geode-assembly/src/test/java/com/gemstone/gemfire/rest/internal/web/controllers/GetRegions.java
new file mode 100644
index 0000000..d9e039b
--- /dev/null
+++ b/geode-assembly/src/test/java/com/gemstone/gemfire/rest/internal/web/controllers/GetRegions.java
@@ -0,0 +1,76 @@
+/*
+ * 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.ArrayList;
+import java.util.Set;
+
+import com.gemstone.gemfire.cache.Cache;
+import com.gemstone.gemfire.cache.CacheClosedException;
+import com.gemstone.gemfire.cache.CacheFactory;
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.cache.execute.Function;
+import com.gemstone.gemfire.cache.execute.FunctionContext;
+
+/**
+* The GetRegions class is an gemfire function that gives data about available regions.
+* <p/>
+* @author Nilkanth Patel
+* @since 8.0
+*/
+
+public class GetRegions implements Function  {
+
+  public void execute(FunctionContext context) {
+    
+    ArrayList<String> vals = new ArrayList<String>();
+    
+    Cache c = null;
+    try {
+      c = CacheFactory.getAnyInstance();
+    } catch (CacheClosedException ex) {
+      vals.add("NoCacheResult");
+      context.getResultSender().lastResult(vals);
+    }
+
+    final Set<Region<?, ?>> regionSet = c.rootRegions();
+    for (Region<?, ?> r : regionSet) {
+      vals.add(r.getName());
+    }
+    
+    context.getResultSender().lastResult(vals);
+  }
+
+  public String getId() {
+    return "GetRegions";
+  }
+
+  @Override
+  public boolean hasResult() {
+    return true;
+  }
+
+  @Override
+  public boolean optimizeForWrite() {
+    return false;
+  }
+
+  @Override
+  public boolean isHA() {
+    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/GetValueForKey.java
----------------------------------------------------------------------
diff --git a/geode-assembly/src/test/java/com/gemstone/gemfire/rest/internal/web/controllers/GetValueForKey.java b/geode-assembly/src/test/java/com/gemstone/gemfire/rest/internal/web/controllers/GetValueForKey.java
new file mode 100644
index 0000000..25e87b6
--- /dev/null
+++ b/geode-assembly/src/test/java/com/gemstone/gemfire/rest/internal/web/controllers/GetValueForKey.java
@@ -0,0 +1,77 @@
+/*
+ * 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 com.gemstone.gemfire.cache.Cache;
+import com.gemstone.gemfire.cache.CacheClosedException;
+import com.gemstone.gemfire.cache.CacheFactory;
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.cache.execute.Function;
+import com.gemstone.gemfire.cache.execute.FunctionContext;
+
+public class GetValueForKey implements Function {
+  
+  @Override
+  public void execute(FunctionContext context) {  
+    Object args = context.getArguments();
+    
+    Cache cache = null;
+    
+    try{
+      cache = CacheFactory.getAnyInstance();
+      
+      if(args.toString().equalsIgnoreCase("1") ){
+        Region<String, Object> r = cache.getRegion("Products");
+        Object result = r.get("1");
+        context.getResultSender().lastResult(result);
+      
+      }else if(args.toString().equalsIgnoreCase("2")){
+        Region<String, Object> r = cache.getRegion("People");
+        Object result = r.get("2");
+        context.getResultSender().lastResult(result);      
+      }else{
+        //Default case
+        int i=10;
+        context.getResultSender().lastResult(i);
+      }
+    }catch(CacheClosedException e){
+      context.getResultSender().lastResult("Error: CacheClosedException");
+    }
+    
+  }
+
+  @Override
+  public String getId() {    
+    return "GetValueForKey";
+  }
+
+  @Override
+  public boolean hasResult() {
+    return true;
+  }
+
+  @Override
+  public boolean optimizeForWrite() {
+    return false;
+  }
+
+  @Override
+  public boolean isHA() {
+    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/Item.java
----------------------------------------------------------------------
diff --git a/geode-assembly/src/test/java/com/gemstone/gemfire/rest/internal/web/controllers/Item.java b/geode-assembly/src/test/java/com/gemstone/gemfire/rest/internal/web/controllers/Item.java
new file mode 100644
index 0000000..450ffda
--- /dev/null
+++ b/geode-assembly/src/test/java/com/gemstone/gemfire/rest/internal/web/controllers/Item.java
@@ -0,0 +1,160 @@
+/*
+ * 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 com.gemstone.gemfire.internal.lang.ObjectUtils;
+import com.gemstone.gemfire.pdx.PdxReader;
+import com.gemstone.gemfire.pdx.PdxSerializable;
+import com.gemstone.gemfire.pdx.PdxWriter;
+
+/**
+ * The Item class models item entity in the real world.
+ * <p/>
+ * @author Nilkanth Patel
+ * @since 8.0
+ */
+
+
+public class Item implements PdxSerializable {
+
+  private Long itemNo;
+  private String description;
+  private int quantity;
+  private float unitPrice;
+  private float totalPrice;
+
+  public Long getItemNo() {
+    return itemNo;
+  }
+
+  public void setItemNo(Long itemNo) {
+    this.itemNo = itemNo;
+  }
+
+  public String getDescription() {
+    return description;
+  }
+
+  public void setDescription(String description) {
+    this.description = description;
+  }
+
+  public int getQuantity() {
+    return quantity;
+  }
+
+  public void setQuantity(int quantity) {
+    this.quantity = quantity;
+  }
+
+  public float getUnitPrice() {
+    return unitPrice;
+  }
+
+  public void setUnitPrice(final float unitprice) {
+    this.unitPrice = unitprice;
+  }
+
+  public float getTotalPrice() {
+    return totalPrice;
+  }
+
+  public void setTotalPrice(final float totalprice) {
+    this.totalPrice = totalprice;
+  }
+
+  public Item() {
+
+  }
+
+  public Item(final Long itemNumber) {
+    this.itemNo = itemNumber;
+  }
+
+  public Item(final Long itemNumber, final String desc, final int qty, final float uprice, final float tprice) {
+    this.itemNo = itemNumber;
+    this.description = desc;
+    this.quantity = qty;
+    this.unitPrice = uprice;
+    this.totalPrice = tprice;
+  }
+  
+  @Override
+  public boolean equals(final Object obj) {
+    if (obj == this) {
+      return true;
+    }
+
+    if (!(obj instanceof Item)) {
+      return false;
+    }
+
+    final Item that = (Item) obj;
+
+    return (ObjectUtils.equals(this.getItemNo(), that.getItemNo())
+        && ObjectUtils.equals(this.getDescription(), that.getDescription())
+        && ObjectUtils.equals(this.getQuantity(), that.getQuantity())
+        && ObjectUtils.equals(this.getQuantity(), that.getUnitPrice())
+        && ObjectUtils.equals(this.getQuantity(), that.getTotalPrice()));
+  }
+
+  @Override
+  public int hashCode() {
+    int hashValue = 17;
+    hashValue = 37 * hashValue + ObjectUtils.hashCode(getItemNo());
+    hashValue = 37 * hashValue + ObjectUtils.hashCode(getDescription());
+    hashValue = 37 * hashValue + ObjectUtils.hashCode(getQuantity());
+    hashValue = 37 * hashValue + ObjectUtils.hashCode(getUnitPrice());
+    hashValue = 37 * hashValue + ObjectUtils.hashCode(getTotalPrice());
+    return hashValue;
+  }
+
+  @Override
+  public String toString() {
+    final StringBuilder buffer = new StringBuilder("{ type = ");
+    buffer.append(getClass().getName());
+    buffer.append(", itemNo = ").append(getItemNo());
+    buffer.append(", description = ").append(getDescription());
+    buffer.append(", quantity = ").append(getQuantity());
+    buffer.append(", unitPrice = ").append(getUnitPrice());
+    buffer.append(", totalPrice = ").append(getTotalPrice());
+    buffer.append(" }");
+    return buffer.toString();
+  }
+
+  @Override
+  public void toData(PdxWriter writer) {
+    writer.writeLong("itemNo", itemNo);
+    writer.writeString("description", description);
+    writer.writeInt("quantity", quantity);
+    writer.writeFloat("unitPrice", unitPrice);
+    writer.writeFloat("totalPrice", totalPrice);
+  }
+
+  @Override
+  public void fromData(PdxReader reader) {
+    itemNo = reader.readLong("itemNo");
+    description = reader.readString("description");
+    quantity = reader.readInt("quantity");
+    unitPrice = reader.readFloat("unitPrice");
+    totalPrice = reader.readFloat("totalPrice");
+    
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9b55879e/geode-assembly/src/test/java/com/gemstone/gemfire/rest/internal/web/controllers/Order.java
----------------------------------------------------------------------
diff --git a/geode-assembly/src/test/java/com/gemstone/gemfire/rest/internal/web/controllers/Order.java b/geode-assembly/src/test/java/com/gemstone/gemfire/rest/internal/web/controllers/Order.java
new file mode 100644
index 0000000..34aefb2
--- /dev/null
+++ b/geode-assembly/src/test/java/com/gemstone/gemfire/rest/internal/web/controllers/Order.java
@@ -0,0 +1,189 @@
+/*
+ * 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.Date;
+import java.util.List;
+
+import com.gemstone.gemfire.pdx.PdxReader;
+import com.gemstone.gemfire.pdx.PdxSerializable;
+import com.gemstone.gemfire.pdx.PdxWriter;
+
+/**
+* The Order class is an abstraction modeling a order.
+* <p/>
+* @author Nilkanth Patel
+* @since 8.0
+*/
+
+public class Order implements PdxSerializable {
+  
+  private Long purchaseOrderNo;
+  private Long customerId;
+  private String description;
+  private Date orderDate;
+  private Date deliveryDate;
+  private String contact;
+  private String email;
+  private String phone;
+  private List<Item> items; 
+  private double totalPrice; 
+
+  public Order() {
+    items = new ArrayList<Item>();
+  }
+
+  public Order(final Long orderNo) {
+    this.purchaseOrderNo = orderNo;
+  }
+
+  public Order(final Long orderNo, final Long custId, final String desc,
+    final Date odate, final Date ddate, final String contact, final String email,
+    final String phone, final List<Item> items, final double tprice) {
+    this.purchaseOrderNo = orderNo;
+    this.customerId = custId;
+    this.description = desc;
+    this.orderDate = odate;
+    this.deliveryDate = ddate;
+    this.contact = contact;
+    this.email = email;
+    this.phone = phone;
+    this.items = items;
+    this.totalPrice = tprice;
+  }
+
+  public void addItem(final Item item) {
+    if (item != null)
+      this.items.add(item);
+  }
+
+  public Long getPurchaseOrderNo() {
+    return purchaseOrderNo;
+  }
+
+  public void setPurchaseOrderNo(Long purchaseOrderNo) {
+    this.purchaseOrderNo = purchaseOrderNo;
+  }
+
+  public Long getCustomerId() {
+    return customerId;
+  }
+
+  public void setCustomerId(Long customerId) {
+    this.customerId = customerId;
+  }
+
+  public String getDescription() {
+    return description;
+  }
+
+  public void setDescription(String description) {
+    this.description = description;
+  }
+
+  public Date getDeliveryDate() {
+    return deliveryDate;
+  }
+
+  public void setDeliveryDate(Date date) {
+    this.deliveryDate = date;
+  }
+
+  public String getContact() {
+    return contact;
+  }
+
+  public void setContact(String contact) {
+    this.contact = contact;
+  }
+
+  public String getEmail() {
+    return email;
+  }
+
+  public void setEmail(String email) {
+    this.email = email;
+  }
+
+  public String getPhone() {
+    return phone;
+  }
+
+  public void setPhone(String phone) {
+    this.phone = phone;
+  }
+
+  public List<Item> getItems() {
+    return items;
+  }
+  
+  public void setItems(List<Item> items) {
+    if(this.items == null)
+      this.items = new ArrayList<Item>();
+    
+    for (Item it : items)
+      this.items.add(it);
+  }
+
+  public Date getOrderDate() {
+    return orderDate;
+  }
+
+  public void setOrderDate(Date orderDate) {
+    this.orderDate = orderDate;
+  }
+
+  public double getTotalPrice() {
+    return totalPrice;
+  }
+
+  public void setTotalPrice(double totalPrice) {
+    this.totalPrice = totalPrice;
+  }
+
+  @Override
+  public void toData(PdxWriter writer) {
+    writer.writeLong("purchaseOrderNo", purchaseOrderNo);
+    writer.writeLong("customerId", customerId);
+    writer.writeString("description", description);
+    writer.writeDate("orderDate", orderDate);
+    writer.writeDate("deliveryDate", deliveryDate);
+    writer.writeString("contact", contact);
+    writer.writeString("email", email);
+    writer.writeString("phone", phone);
+    writer.writeObject("items", items);
+    writer.writeDouble("totalPrice", totalPrice);
+  }
+
+  @Override
+  public void fromData(PdxReader reader) {
+    purchaseOrderNo = reader.readLong("purchaseOrderNo");
+    customerId = reader.readLong("customerId");
+    description = reader.readString("description");
+    orderDate = reader.readDate("orderDate");
+    deliveryDate = reader.readDate("deliveryDate");
+    contact = reader.readString("contact");
+    email = reader.readString("email");
+    phone = reader.readString("phone");
+    items = (List<Item>)reader.readObject("items");
+    totalPrice = reader.readDouble("totalPrice");
+    
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9b55879e/geode-assembly/src/test/java/com/gemstone/gemfire/rest/internal/web/controllers/Person.java
----------------------------------------------------------------------
diff --git a/geode-assembly/src/test/java/com/gemstone/gemfire/rest/internal/web/controllers/Person.java b/geode-assembly/src/test/java/com/gemstone/gemfire/rest/internal/web/controllers/Person.java
new file mode 100644
index 0000000..b5b5459
--- /dev/null
+++ b/geode-assembly/src/test/java/com/gemstone/gemfire/rest/internal/web/controllers/Person.java
@@ -0,0 +1,185 @@
+/*
+ * 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.Date;
+import com.gemstone.gemfire.internal.lang.ObjectUtils;
+import com.gemstone.gemfire.pdx.PdxReader;
+import com.gemstone.gemfire.pdx.PdxSerializable;
+import com.gemstone.gemfire.pdx.PdxWriter;
+
+import java.io.Serializable;
+
+/**
+* The Person class is an abstraction modeling a person.
+* <p/>
+* @author Nilkanth Patel, John Blum
+* @since 8.0
+*/
+@SuppressWarnings("unused")
+public class Person implements PdxSerializable {
+
+  private static final long serialVersionUID = 42108163264l;
+  
+  protected static final String DOB_FORMAT_PATTERN = "MM/dd/yyyy";
+  
+  private  Long id;
+  
+  private Date birthDate;
+  
+  private Gender gender;
+  
+  private String firstName;
+  private String middleName;
+  private String lastName;
+  
+  public Person() {
+  }
+  
+  public Person(final Long id) {
+    this.id = id;
+  }
+  
+  public Person(final String firstName, final String lastName) {
+    this.firstName = firstName;
+    this.lastName = lastName;
+  }
+  
+  public Person(Long id, String fn, String mn, String ln, Date bDate, Gender g) {
+    this.id = id;
+    this.firstName = fn;
+    this.middleName = mn;
+    this.lastName = ln;
+    this.birthDate = bDate;
+    this.gender = g;
+  }
+  
+  public Long getId() {
+    return id;
+  }
+  
+  public void setId(final Long id) {
+    this.id = id;
+  }
+  
+  public String getFirstName() {
+    return firstName;
+  }
+  
+  public void setFirstName(final String firstName) {
+    this.firstName = firstName;
+  }
+  
+  public String getLastName() {
+    return lastName;
+  }
+  
+  public void setLastName(final String lastName) {
+    this.lastName = lastName;
+  }
+  
+  public String getMiddleName() {
+    return middleName;
+  }
+  
+  public void setMiddleName(final String middleName) {
+    this.middleName = middleName;
+  }
+  
+  public Date getBirthDate() {
+    return birthDate;
+  }
+  
+  public void setBirthDate(final Date birthDate) {
+    this.birthDate = birthDate;
+  }
+  
+  public Gender getGender() {
+    return gender;
+  }
+  
+  public void setGender(final Gender gender) {
+    this.gender = gender;
+  }
+  
+  @Override
+  public boolean equals(final Object obj) {
+    if (obj == this) {
+      return true;
+    }
+  
+    if (!(obj instanceof Person)) {
+      return false;
+    }
+  
+    final Person that = (Person) obj;
+  
+    return (ObjectUtils.equals(this.getId(), that.getId())
+      || (ObjectUtils.equals(this.getBirthDate(), that.getBirthDate())
+      && ObjectUtils.equals(this.getLastName(), that.getLastName())
+      && ObjectUtils.equals(this.getFirstName(), that.getFirstName())));
+  }
+  
+  @Override
+  public int hashCode() {
+    int hashValue = 17;
+    hashValue = 37 * hashValue + ObjectUtils.hashCode(getId());
+    hashValue = 37 * hashValue + ObjectUtils.hashCode(getBirthDate());
+    hashValue = 37 * hashValue + ObjectUtils.hashCode(getLastName());
+    hashValue = 37 * hashValue + ObjectUtils.hashCode(getFirstName());
+    return hashValue;
+  }
+  
+  @Override
+  public String toString() {
+    final StringBuilder buffer = new StringBuilder("{ type = ");
+    buffer.append(getClass().getName());
+    buffer.append(", id = ").append(getId());
+    buffer.append(", firstName = ").append(getFirstName());
+    buffer.append(", middleName = ").append(getMiddleName());
+    buffer.append(", lastName = ").append(getLastName());
+    buffer.append(", birthDate = ").append(DateTimeUtils.format(getBirthDate(), DOB_FORMAT_PATTERN));
+    buffer.append(", gender = ").append(getGender());
+    buffer.append(" }");
+    return buffer.toString();
+  }
+  
+  @Override
+  public void toData(PdxWriter writer) {
+    writer.writeString("@type", getClass().getName());
+    writer.writeLong("id", id);
+    writer.writeString("firstName", firstName);
+    writer.writeString("middleName", middleName);
+    writer.writeString("lastName", lastName);
+    writer.writeObject("gender", gender);
+    writer.writeDate("birthDate", birthDate);
+    
+  }
+  
+  @Override
+  public void fromData(PdxReader reader) {
+    String type = reader.readString("@type");
+    id = reader.readLong("id");
+    firstName = reader.readString("firstName");
+    middleName = reader.readString("middleName");
+    lastName = reader.readString("lastName");
+    gender = (Gender)reader.readObject("gender");
+    birthDate = reader.readDate("birthDate");
+    
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9b55879e/geode-assembly/src/test/java/com/gemstone/gemfire/rest/internal/web/controllers/PutKeyFunction.java
----------------------------------------------------------------------
diff --git a/geode-assembly/src/test/java/com/gemstone/gemfire/rest/internal/web/controllers/PutKeyFunction.java b/geode-assembly/src/test/java/com/gemstone/gemfire/rest/internal/web/controllers/PutKeyFunction.java
new file mode 100644
index 0000000..e75d9fc
--- /dev/null
+++ b/geode-assembly/src/test/java/com/gemstone/gemfire/rest/internal/web/controllers/PutKeyFunction.java
@@ -0,0 +1,63 @@
+/*
+ * 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.Region;
+import com.gemstone.gemfire.cache.execute.Function;
+import com.gemstone.gemfire.cache.execute.FunctionContext;
+import com.gemstone.gemfire.cache.execute.RegionFunctionContext;
+
+
+/**
+ * Function that puts the value from the argument at the key passed in through
+ * the filter.
+ */
+
+public class PutKeyFunction implements Function {
+
+  private static final String ID = "PutKeyFunction";
+
+  public void execute(FunctionContext context) {
+    RegionFunctionContext regionContext = (RegionFunctionContext)context;
+    Region dataSet = regionContext.getDataSet();
+    Object key = regionContext.getFilter().iterator().next();
+    Object value = regionContext.getArguments();
+    dataSet.put(key, value);
+    context.getResultSender().lastResult(Boolean.TRUE);
+  }
+
+  public String getId() {
+    return ID;
+  }
+
+  public boolean hasResult() {
+    return true;
+  }
+
+  public void init(Properties p) {
+  }
+
+  public boolean optimizeForWrite() {
+    return true;
+  }
+  public boolean isHA() {
+    return true;
+  }
+}
+