You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by ab...@apache.org on 2017/05/10 00:39:10 UTC
[3/5] geode-examples git commit: GEODE-2831 Add cache loader example
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 <ab...@apache.org>
Authored: Thu Apr 27 11:35:17 2017 -0700
Committer: Anthony Baker <ab...@apache.org>
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;
}