GEODE-2831 Add cache loader example

Add a cache loader example.  Fix a few path issues and an eclipse
project dependency.


Project: http://git-wip-us.apache.org/repos/asf/geode-examples/repo
Commit: http://git-wip-us.apache.org/repos/asf/geode-examples/commit/4a678e44
Tree: http://git-wip-us.apache.org/repos/asf/geode-examples/tree/4a678e44
Diff: http://git-wip-us.apache.org/repos/asf/geode-examples/diff/4a678e44

Branch: refs/heads/develop
Commit: 4a678e448b6580075ac23ce58864875c4eadeeaa
Parents: c21e76b
Author: Anthony Baker <[email protected]>
Authored: Thu Apr 27 11:35:17 2017 -0700
Committer: Anthony Baker <[email protected]>
Committed: Thu Apr 27 17:12:58 2017 -0700

----------------------------------------------------------------------
 .gitignore                                      |   4 +-
 build.gradle                                    |  27 +++--
 gradle.properties                               |   2 +-
 gradle/ide.gradle                               |   6 ++
 gradle/rat.gradle                               |   7 +-
 loader/README.md                                |  58 +++++++++++
 loader/scripts/start.gfsh                       |  25 +++++
 loader/scripts/stop.gfsh                        |  18 ++++
 .../apache/geode/examples/loader/Example.java   |  71 +++++++++++++
 .../geode/examples/loader/QuoteLoader.java      | 102 +++++++++++++++++++
 .../geode/examples/loader/ExampleTest.java      |  56 ++++++++++
 partitioned/README.md                           |   6 +-
 partitioned/scripts/start.gfsh                  |   6 +-
 replicated/README.md                            |  20 ++--
 replicated/scripts/start.gfsh                   |   2 +-
 settings.gradle                                 |   1 +
 .../java/org/geode/examples/util/Mocks.java     |   8 ++
 17 files changed, 396 insertions(+), 23 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/geode-examples/blob/4a678e44/.gitignore
----------------------------------------------------------------------
diff --git a/.gitignore b/.gitignore
index 88e27ec..bc00815 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,7 +13,9 @@ build/
 build-eclipse/
 /tags
 
-
+locator
+server1
+server2
 
 *.iml
 *.ipr

http://git-wip-us.apache.org/repos/asf/geode-examples/blob/4a678e44/build.gradle
----------------------------------------------------------------------
diff --git a/build.gradle b/build.gradle
index 8289ead..3f4a569 100644
--- a/build.gradle
+++ b/build.gradle
@@ -73,23 +73,38 @@ allprojects {
   }
 }
 
+configurations {
+  testArchives
+}
+
+dependencies {
+  testArchives sourceSets.test.output
+}
+
 subprojects {
   dependencies {
-    runtime "org.slf4j:slf4j-log4j12:$slf4jVersion"
-    
-    testCompile project.parent.sourceSets.test.output
+    compile "org.apache.logging.log4j:log4j-core:$log4jVersion"
+    runtime "org.apache.logging.log4j:log4j-slf4j-impl:$log4jVersion"
+    testCompile project(path: ':', configuration: 'testArchives') 
   }
   
+  task cleanServer << {
+    delete 'locator'
+    delete 'server1'
+    delete 'server2'
+  }
+  clean.finalizedBy cleanServer
+
   def geodePath = 
"${System.env.PATH}${System.getProperty('path.separator')}${installDir}/bin"
-  task start(type: Exec, dependsOn: [installGeode, build]) {
-    workingDir buildDir
+  task start(type: Exec, dependsOn: [installGeode, build, cleanServer]) {
+    workingDir projectDir
     environment 'GEODE_HOME', installDir
     environment 'PATH', geodePath
     commandLine 'sh', '-c', "gfsh run --file=${projectDir}/scripts/start.gfsh"
   }
 
   task stop(type: Exec, dependsOn: installGeode) {
-    workingDir buildDir
+    workingDir projectDir
     environment 'GEODE_HOME', installDir
     environment 'PATH', geodePath
     commandLine 'sh', '-c', "gfsh run --file=${projectDir}/scripts/stop.gfsh"

http://git-wip-us.apache.org/repos/asf/geode-examples/blob/4a678e44/gradle.properties
----------------------------------------------------------------------
diff --git a/gradle.properties b/gradle.properties
index 83479a1..60428c3 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -22,5 +22,5 @@ assertjVersion = 3.6.2
 awaitilityVersion = 1.7.0
 junitVersion = 4.12
 mockitocoreVersion = 1.10.19
-slf4jVersion = 1.7.22
+log4jVersion = 2.7
 systemrulesVersion = 1.16.1

http://git-wip-us.apache.org/repos/asf/geode-examples/blob/4a678e44/gradle/ide.gradle
----------------------------------------------------------------------
diff --git a/gradle/ide.gradle b/gradle/ide.gradle
index b3da6ab..4d3d808 100644
--- a/gradle/ide.gradle
+++ b/gradle/ide.gradle
@@ -20,6 +20,12 @@ allprojects {
     classpath {
       defaultOutputDir = file('build-eclipse')
       downloadSources = true
+      file {
+        whenMerged { classpath ->
+          // Remove missing resource dirs
+          classpath.entries.removeAll { entry -> 
(entry.path.contains('geode-examples/build/resources')) }
+        }
+      }  
     }
   }
 

http://git-wip-us.apache.org/repos/asf/geode-examples/blob/4a678e44/gradle/rat.gradle
----------------------------------------------------------------------
diff --git a/gradle/rat.gradle b/gradle/rat.gradle
index 33d95ca..fe73400 100644
--- a/gradle/rat.gradle
+++ b/gradle/rat.gradle
@@ -58,7 +58,12 @@ rat {
     '**/*.patch',
     '**/*.diff',
     '**/*.rej',
-    '**/*.orig'
+    '**/*.orig',
+
+    // working directories
+    '**/locator/**',
+    '**/server1/**',
+    '**/server2/**'
   ]
 }
 

http://git-wip-us.apache.org/repos/asf/geode-examples/blob/4a678e44/loader/README.md
----------------------------------------------------------------------
diff --git a/loader/README.md b/loader/README.md
new file mode 100644
index 0000000..db61cfb
--- /dev/null
+++ b/loader/README.md
@@ -0,0 +1,58 @@
+<!--
+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.
+-->
+
+# Geode cache loader example
+
+This is a simple example that demonstrates loading values using a
+`CacheLoader`.  Invoking `Region.get()` causes the `CacheLoader` to
+produce a value that is stored in the region.  This approach is
+commonly used to fetch data from other systems like a database.
+
+This example assumes you have installed Java and Geode.
+
+## Steps
+
+1. From the `geode-examples/loader` directory, build the example and
+   run unit tests
+
+        $ ../gradlew build
+
+2. Next start the locator and two servers
+
+        $ gfsh run --file=scripts/start.gfsh
+
+3. Run the example to load the entries
+
+        $ ../gradlew run
+
+    The example fetches the entries twice.  The first retrieval is slow,
+    simulating a network call.  Subsequent retrievals are much faster since the
+    values are stored in the cache.  The loader logs requests into the Geode
+    server logs.  You can find those at `build/server1/server1.log` or
+    `build/server2/server2.log`.
+
+4. Kill one of the servers
+
+        $ gfsh -e "connect --locator=127.0.0.1[10334]" -e "stop server 
--name=server1"
+
+5. Run the example a second time, and notice that all the entries are still 
available due to replication
+
+        $ ../gradlew run 
+
+6. Shut down the system:
+
+        $ gfsh run --file=scripts/stop.gfsh

http://git-wip-us.apache.org/repos/asf/geode-examples/blob/4a678e44/loader/scripts/start.gfsh
----------------------------------------------------------------------
diff --git a/loader/scripts/start.gfsh b/loader/scripts/start.gfsh
new file mode 100644
index 0000000..a078862
--- /dev/null
+++ b/loader/scripts/start.gfsh
@@ -0,0 +1,25 @@
+#
+# 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.
+#
+start locator --name=locator --bind-address=127.0.0.1
+
+start server --name=server1 --locators=127.0.0.1[10334] --server-port=0 
--classpath=../build/classes/main
+start server --name=server2 --locators=127.0.0.1[10334] --server-port=0 
--classpath=../build/classes/main
+
+create region --name=example-region --type=REPLICATE 
--cache-loader=org.apache.geode.examples.loader.QuoteLoader
+
+list members
+describe region --name=example-region
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/geode-examples/blob/4a678e44/loader/scripts/stop.gfsh
----------------------------------------------------------------------
diff --git a/loader/scripts/stop.gfsh b/loader/scripts/stop.gfsh
new file mode 100644
index 0000000..9281b31
--- /dev/null
+++ b/loader/scripts/stop.gfsh
@@ -0,0 +1,18 @@
+#
+# 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.
+#
+connect --locator=127.0.0.1[10334]
+shutdown --include-locators=true
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/geode-examples/blob/4a678e44/loader/src/main/java/org/apache/geode/examples/loader/Example.java
----------------------------------------------------------------------
diff --git a/loader/src/main/java/org/apache/geode/examples/loader/Example.java 
b/loader/src/main/java/org/apache/geode/examples/loader/Example.java
new file mode 100644
index 0000000..c80676f
--- /dev/null
+++ b/loader/src/main/java/org/apache/geode/examples/loader/Example.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more 
contributor license
+ * agreements. See the NOTICE file distributed with this work for additional 
information regarding
+ * copyright ownership. The ASF licenses this file to You under the Apache 
License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the 
License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software 
distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 
KIND, either express
+ * or implied. See the License for the specific language governing permissions 
and limitations under
+ * the License.
+ */
+package org.apache.geode.examples.loader;
+
+import java.util.Arrays;
+import java.util.function.Consumer;
+
+import org.apache.geode.cache.Region;
+import org.apache.geode.cache.client.ClientCache;
+import org.apache.geode.cache.client.ClientCacheFactory;
+import org.apache.geode.cache.client.ClientRegionShortcut;
+
+public class Example implements Consumer<Region<String, String>> {
+  private static final String[] AUTHORS =
+      ("Anton Chekhov,C. J. Cherryh,Dorothy Parker,Douglas Adams,Emily 
Dickinson,"
+          + "Ernest Hemingway,F. Scott Fitzgerald,Henry David Thoreau,Henry 
Wadsworth Longfellow,"
+          + "Herman Melville,Jean-Paul Sartre,Mark Twain,Orson Scott Card,Ray 
Bradbury,Robert Benchley,"
+          + "Somerset Maugham,Stephen King,Terry Pratchett,Ursula K. Le 
Guin,William Faulkner")
+              .split(",");
+
+  public static void main(String[] args) {
+    // connect to the locator using default port 10334
+    ClientCache cache = new ClientCacheFactory().addPoolLocator("127.0.0.1", 
10334)
+        .set("log-level", "WARN").create();
+
+    // create a local region that matches the server region
+    Region<String, String> region =
+        cache.<String, 
String>createClientRegionFactory(ClientRegionShortcut.CACHING_PROXY)
+            .create("example-region");
+
+    new Example().accept(region);
+    cache.close();
+  }
+
+  @Override
+  public void accept(Region<String, String> region) {
+    // initial fetch invokes the cache loader
+    {
+      long start = System.currentTimeMillis();
+      Arrays.stream(AUTHORS)
+          .forEach(author -> System.out.println(author + ": " + 
region.get(author)));
+
+      long elapsed = System.currentTimeMillis() - start;
+      System.out.println(
+          String.format("\n\nLoaded %d definitions in %d ms\n\n", 
AUTHORS.length, elapsed));
+    }
+
+    // fetch from cache, really fast!
+    {
+      long start = System.currentTimeMillis();
+      Arrays.stream(AUTHORS)
+          .forEach(author -> System.out.println(author + ": " + 
region.get(author)));
+
+      long elapsed = System.currentTimeMillis() - start;
+      System.out.println(
+          String.format("\n\nFetched %d cached definitions in %d ms\n\n", 
AUTHORS.length, elapsed));
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/geode-examples/blob/4a678e44/loader/src/main/java/org/apache/geode/examples/loader/QuoteLoader.java
----------------------------------------------------------------------
diff --git 
a/loader/src/main/java/org/apache/geode/examples/loader/QuoteLoader.java 
b/loader/src/main/java/org/apache/geode/examples/loader/QuoteLoader.java
new file mode 100644
index 0000000..bc28bca
--- /dev/null
+++ b/loader/src/main/java/org/apache/geode/examples/loader/QuoteLoader.java
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more 
contributor license
+ * agreements. See the NOTICE file distributed with this work for additional 
information regarding
+ * copyright ownership. The ASF licenses this file to You under the Apache 
License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the 
License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software 
distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 
KIND, either express
+ * or implied. See the License for the specific language governing permissions 
and limitations under
+ * the License.
+ */
+package org.apache.geode.examples.loader;
+
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.geode.cache.CacheLoader;
+import org.apache.geode.cache.CacheLoaderException;
+import org.apache.geode.cache.Declarable;
+import org.apache.geode.cache.LoaderHelper;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+public class QuoteLoader implements CacheLoader<String, String>, Declarable {
+  private static final Logger log = LogManager.getLogger(QuoteLoader.class);
+
+  private final Map<String, String> quotes;
+
+  public QuoteLoader() {
+    quotes = getQuotes();
+  }
+
+  @Override
+  public void init(Properties props) {}
+
+  @Override
+  public void close() {}
+
+  @Override
+  public String load(LoaderHelper<String, String> helper) throws 
CacheLoaderException {
+
+    log.info("Loading quote for {} into region {}", helper.getKey(), 
helper.getRegion().getName());
+    String quote = quotes.get(helper.getKey());
+
+    try {
+      // simulate network delay for a REST call or a database query
+      Thread.sleep(100);
+      return quote;
+
+    } catch (InterruptedException e) {
+      Thread.currentThread().interrupt();
+      throw new CacheLoaderException(e);
+    }
+  }
+
+  Map<String, String> getQuotes() {
+    Map<String, String> quotes = new ConcurrentHashMap<String, String>();
+
+    // sourced from http://www.writersdigest.com/writing-quotes
+    quotes.put("Anton Chekhov",
+        "My own experience is that once a story has been written, one has to 
cross out the beginning and the end. It is there that we authors do most of our 
lying");
+    quotes.put("C. J. Cherryh",
+        "It is perfectly okay to write garbage—as long as you edit 
brilliantly");
+    quotes.put("Dorothy Parker", "I can’t write five words but that I change 
seven");
+    quotes.put("Douglas Adams",
+        "I love deadlines. I like the whooshing sound they make as they fly 
by");
+    quotes.put("Emily Dickinson", "A wounded deer leaps the highest");
+    quotes.put("Ernest Hemingway", "Prose is architecture, not interior 
decoration");
+    quotes.put("F. Scott Fitzgerald",
+        "Begin with an individual, and before you know it you have created a 
type; begin with a type, and you find you have created – nothing");
+    quotes.put("Henry David Thoreau",
+        "Not that the story need be long, but it will take a long while to 
make it short");
+    quotes.put("Henry Wadsworth Longfellow",
+        "Great is the art of beginning, but greater is the art of ending");
+    quotes.put("Herman Melville", "To produce a mighty book, you must choose a 
mighty theme");
+    quotes.put("Jean-Paul Sartre", "Poetry creates the myth, the prose writer 
draws its portrait");
+    quotes.put("Mark Twain",
+        "Most writers regard the truth as their most valuable possession, and 
therefore are most economical in its use");
+    quotes.put("Orson Scott Card",
+        "Everybody walks past a thousand story ideas every day. The good 
writers are the ones who see five or six of them. Most people don’t see any");
+    quotes.put("Ray Bradbury",
+        "Any man who keeps working is not a failure. He may not be a great 
writer, but if he applies the old-fashioned virtues of hard, constant labor, 
he’ll eventually make some kind of career for himself as writer");
+    quotes.put("Robert Benchley",
+        "It took me fifteen years to discover I had no talent for writing, but 
I couldn’t give it up because by that time I was too famous");
+    quotes.put("Somerset Maugham",
+        "If you can tell stories, create characters, devise incidents, and 
have sincerity and passion, it doesn’t matter a damn how you write");
+    quotes.put("Stephen King",
+        "I try to create sympathy for my characters, then turn the monsters 
loose");
+    quotes.put("Terry Pratchett",
+        "There’s no such thing as writer’s block. That was invented by 
people in California who couldn’t write");
+    quotes.put("Ursula K. Le Guin",
+        "The unread story is not a story; it is little black marks on wood 
pulp. The reader, reading it, makes it live: a live thing, a story");
+    quotes.put("William Faulkner",
+        "Get it down. Take chances. It may be bad, but it’s the only way you 
can do anything really good");
+
+    return quotes;
+  }
+}

http://git-wip-us.apache.org/repos/asf/geode-examples/blob/4a678e44/loader/src/test/java/org/apache/geode/examples/loader/ExampleTest.java
----------------------------------------------------------------------
diff --git 
a/loader/src/test/java/org/apache/geode/examples/loader/ExampleTest.java 
b/loader/src/test/java/org/apache/geode/examples/loader/ExampleTest.java
new file mode 100644
index 0000000..158cef7
--- /dev/null
+++ b/loader/src/test/java/org/apache/geode/examples/loader/ExampleTest.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more 
contributor license
+ * agreements. See the NOTICE file distributed with this work for additional 
information regarding
+ * copyright ownership. The ASF licenses this file to You under the Apache 
License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the 
License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software 
distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 
KIND, either express
+ * or implied. See the License for the specific language governing permissions 
and limitations under
+ * the License.
+ */
+package org.apache.geode.examples.loader;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import org.apache.geode.cache.LoaderHelper;
+import org.apache.geode.cache.Region;
+import org.geode.examples.util.Mocks;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.contrib.java.lang.system.SystemOutRule;
+
+public class ExampleTest {
+
+  @Rule
+  public SystemOutRule systemOutRule = new SystemOutRule().enableLog();
+
+  @Test
+  public void testExample() throws Exception {
+    QuoteLoader loader = new QuoteLoader();
+    Region<String, String> region = Mocks.region("example-region");
+
+    @SuppressWarnings("unchecked")
+    LoaderHelper<String, String> helper = mock(LoaderHelper.class);
+    when(helper.getRegion()).thenReturn(region);
+
+    when(region.get(any())).then(inv -> {
+      String key = inv.getArgumentAt(0, String.class);
+      when(helper.getKey()).thenReturn(key);
+
+      return loader.load(helper);
+    });
+
+    new Example().accept(region);
+
+    assertThat(systemOutRule.getLog()).contains("Anton Chekhov");
+    assertThat(systemOutRule.getLog()).contains("Loaded 20 definitions");
+    assertThat(systemOutRule.getLog()).contains("Fetched 20 cached 
definitions");
+  }
+}

http://git-wip-us.apache.org/repos/asf/geode-examples/blob/4a678e44/partitioned/README.md
----------------------------------------------------------------------
diff --git a/partitioned/README.md b/partitioned/README.md
index 1643d06..db960bf 100644
--- a/partitioned/README.md
+++ b/partitioned/README.md
@@ -39,7 +39,7 @@ Each step in this example specifies paths relative to that 
directory.
 
 1. Build the example (with the `EmployeeKey` and `EmployeeData` classes)
 
-        $ ./gradlew build
+        $ ../gradlew build
 
 2. Run a script that starts a locator and two servers.  Each of the servers
 hosts the partitioned region.  The example classes will be placed onto the
@@ -50,7 +50,7 @@ classpath when the script starts the servers.
 3. Run the example to put 10 entries into the `example-region`. The data
 will also be retrieved from the region and printed to the console.
 
-        $ ./gradlew run
+        $ ../gradlew run
 
 4. Run a `gfsh` command to see the contents of the region
 
@@ -101,7 +101,7 @@ the entries of the ```EmployeeRegion``` are still available 
on the
 remaining server.
 Those hosted by the server that was stopped were lost.
 
-        $ ./gradlew run
+        $ ../gradlew run
 
 7. Shut down the cluster
 

http://git-wip-us.apache.org/repos/asf/geode-examples/blob/4a678e44/partitioned/scripts/start.gfsh
----------------------------------------------------------------------
diff --git a/partitioned/scripts/start.gfsh b/partitioned/scripts/start.gfsh
index 0da16d8..84f95a7 100644
--- a/partitioned/scripts/start.gfsh
+++ b/partitioned/scripts/start.gfsh
@@ -14,10 +14,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #
-start locator --bind-address=127.0.0.1
+start locator --name=locator --bind-address=127.0.0.1
 
-start server --name=server1 --locators=127.0.0.1[10334] --server-port=0 
--classpath=../classes/main
-start server --name=server2 --locators=127.0.0.1[10334] --server-port=0 
--classpath=../classes/main
+start server --name=server1 --locators=127.0.0.1[10334] --server-port=0 
--classpath=../build/classes/main
+start server --name=server2 --locators=127.0.0.1[10334] --server-port=0 
--classpath=../build/classes/main
 
 create region --name=example-region --type=PARTITION
 

http://git-wip-us.apache.org/repos/asf/geode-examples/blob/4a678e44/replicated/README.md
----------------------------------------------------------------------
diff --git a/replicated/README.md b/replicated/README.md
index 696c48a..4d0d32e 100644
--- a/replicated/README.md
+++ b/replicated/README.md
@@ -23,22 +23,28 @@ replicated region, checking the size, and retrieving the 
values.
 This example assumes you have installed Java and Geode.
 
 ## Steps
-1. From the ```geode-examples/replicated``` directory, start the locator and 
two servers
+
+1. From the `geode-examples/replicated` directory, build the example and
+   run unit tests
+
+        $ ../gradlew build
+
+2. Next start the locator and two servers
 
         $ gfsh run --file=scripts/start.gfsh
 
-2. Run the example to create entries in the region
+3. Run the example to create entries in the region
 
-        $ ./gradlew run
+        $ ../gradlew run
 
-3. Kill one of the servers
+4. Kill one of the servers
 
         $ gfsh -e "connect --locator=127.0.0.1[10334]" -e "stop server 
--name=server1"
 
-4. Run the example a second time, and notice that all the entries are still 
available due to replication
+5. Run the example a second time, and notice that all the entries are still 
available due to replication
 
-        $ ./gradlew run 
+        $ ../gradlew run 
 
-5. Shut down the system:
+6. Shut down the system:
 
         $ gfsh run --file=scripts/stop.gfsh

http://git-wip-us.apache.org/repos/asf/geode-examples/blob/4a678e44/replicated/scripts/start.gfsh
----------------------------------------------------------------------
diff --git a/replicated/scripts/start.gfsh b/replicated/scripts/start.gfsh
index 3399719..acc58a5 100644
--- a/replicated/scripts/start.gfsh
+++ b/replicated/scripts/start.gfsh
@@ -14,7 +14,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #
-start locator --bind-address=127.0.0.1
+start locator --name=locator --bind-address=127.0.0.1
 
 start server --name=server1 --locators=127.0.0.1[10334] --server-port=0
 start server --name=server2 --locators=127.0.0.1[10334] --server-port=0

http://git-wip-us.apache.org/repos/asf/geode-examples/blob/4a678e44/settings.gradle
----------------------------------------------------------------------
diff --git a/settings.gradle b/settings.gradle
index 28a63f8..7c07f23 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -18,3 +18,4 @@ rootProject.name = 'geode-examples'
 
 include 'replicated'
 include 'partitioned'
+include 'loader'

http://git-wip-us.apache.org/repos/asf/geode-examples/blob/4a678e44/src/test/java/org/geode/examples/util/Mocks.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/geode/examples/util/Mocks.java 
b/src/test/java/org/geode/examples/util/Mocks.java
index ec36681..d5007f7 100644
--- a/src/test/java/org/geode/examples/util/Mocks.java
+++ b/src/test/java/org/geode/examples/util/Mocks.java
@@ -17,6 +17,7 @@ package org.geode.examples.util;
 import static org.mockito.Matchers.any;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.doAnswer;
 
 import java.util.HashMap;
 import java.util.Map;
@@ -39,6 +40,13 @@ public class Mocks {
     when(region.values()).thenReturn(data.values());
     when(region.size()).thenReturn(data.size());
     when(region.keySetOnServer()).thenReturn(data.keySet());
+    when(region.containsKey(any())).then(inv -> data.containsKey(getKey(inv)));
+    when(region.containsKeyOnServer(any())).then(inv -> 
data.containsKey(getKey(inv)));
+    
+    doAnswer(inv -> {
+      data.putAll((Map<? extends K, ? extends V>) inv.getArguments()[0]);
+      return inv.getArguments();
+    }).when(region).putAll(any());
 
     return region;
   }

Reply via email to