Merge pull request #66 from dihardman/feature/GEODE-5414-2

GEODE-5414 Updated WAN example with sleep added to start.gfsh to pass runAll
diff --git a/build.gradle b/build.gradle
index e8e1db6..525b37e 100644
--- a/build.gradle
+++ b/build.gradle
@@ -75,8 +75,14 @@
     task cleanServer {
         doLast {
             delete 'locator'
+            delete 'locator-ln'
+            delete 'locator-ny'
             delete 'server1'
             delete 'server2'
+            delete 'server-ln-1'
+            delete 'server-ln-2'
+            delete 'server-ny-1'
+            delete 'server-ny-2'
         }
     }
     clean.finalizedBy cleanServer
diff --git a/gradle/rat.gradle b/gradle/rat.gradle
index 63e8d7b..bc0c2ab 100644
--- a/gradle/rat.gradle
+++ b/gradle/rat.gradle
@@ -64,7 +64,13 @@
     // working directories
     '**/locator/**',
     '**/server1/**',
-    '**/server2/**'
+    '**/server2/**',
+    '**/locator-ln/**',
+    '**/server-ln-1/**',
+    '**/server-ln-2/**',
+    '**/locator-ny/**',
+    '**/server-ny-1/**',
+    '**/server-ny-2/**'
   ]
 }
 
diff --git a/settings.gradle b/settings.gradle
index d5857ee..c283d8c 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -35,3 +35,4 @@
 include 'expiration'
 include 'indexes'
 include 'transaction'
+include 'wan'
diff --git a/wan/README.md b/wan/README.md
new file mode 100644
index 0000000..3b05717
--- /dev/null
+++ b/wan/README.md
@@ -0,0 +1,125 @@
+<!--
+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 WAN replication example
+
+This example demonstrates Geode support for asynchronous WAN 
+replication between clusters.  WAN replication allows remote Geode 
+clusters to automatically keep their region data consistent through
+the use of gateway senders and receivers. A gateway sender distributes 
+region events to another, remote Geode cluster. A gateway receiver 
+configures a physical connection for receiving region events from 
+gateway senders in remote Geode clusters. The gateway senders and 
+receivers can be configured in several different topologies based on 
+specific business needs. For more information on example topologies 
+and associated use cases see Geode documentation on 
+[Multi-site WAN Configuration](http://geode.apache.org/docs/guide/topologies_and_comm/multi_site_configuration/chapter_overview.html)
+
+In this example, two clusters are created on your local machine, each
+with a unique distributed system id and the WAN gateway configured
+for active-active, bidirectional region updates. The New York cluster (ny) 
+has id=1 and the London cluster (ln) has id=2. Each cluster contains the same 
+partitioned region (example-region) and each has parallel gateway senders, 
+which means each server in the cluster will send data updates for 
+the primary region buckets they hold.  Alternately, you can configure 
+serial gateway senders, where only one server in each cluster sends all data 
+updates across the WAN. Serial gateway senders are typically used for 
+replicated regions or when the order of events between different keys in
+a partitioned region needs to be preserved.
+
+This example runs a single client that connects to the London cluster and 
+puts 10 entries into the example-region and prints them.  After the client
+app has run, both clusters will contain the data.
+
+**Special Note**
+The gfsh scripts and gradle tasks for this example do not follow the standard
+used by other geode-examples in order to create 2 separate clusters. Due to
+this, you must follow the steps outlined below, as this example will not
+run using the runAll gradle task.
+
+This example assumes that Java and Geode are installed.
+
+## Steps
+
+1. From the `geode-examples/wan` directory, build the client app example 
+
+        $ ../gradlew build
+
+2. Run the script that starts the London cluster (1 locator and 2 servers) and
+   creates the gateway senders and receivers.  
+
+        $ gfsh run --file=scripts/start-ln.gfsh
+
+3. Run the script that starts the New York cluster (1 locator and 2 servers) and
+   creates the gateway senders and receivers.  
+
+        $ gfsh run --file=scripts/start-ny.gfsh
+
+4. Run the script that creates the example-region in each cluster and associates the 
+   gateway senders to this region.
+
+        $ gfsh run --file=scripts/start-wan.gfsh
+
+5. Run the client example app that connects to the London cluster and puts 10 entries 
+into the `example-region`. The data will be automatically sent to the New York cluster,
+as well as printed to the console.
+
+        $ ../gradlew run
+
+6. In one terminal, run a `gfsh` command, connect to the New York cluster, and verify
+   the region contents
+
+        $ gfsh
+        ...
+        Cluster-1 gfsh>connect --locator=localhost[10331]
+        Cluster-1 gfsh>query --query="select e.key from /example-region.entries e"
+        ...
+
+7. In another terminal, run a `gfsh` command, connect to the London cluster, and verify
+   the region contents
+
+        $ gfsh
+        ...
+        Cluster-2 gfsh>connect --locator=localhost[10332]
+        Cluster-2 gfsh>query --query="select e.key from /example-region.entries e"
+        ...
+
+8. Use other gfsh commands to learn statistics about the regions, gateway senders,
+   and gateway receivers for each cluster.
+
+        Cluster-1 gfsh>describe region --name=example-region
+        Cluster-1 gfsh>list gateways
+
+9. In the terminal connected to the New York cluster, put another entry in the region 
+   and verify it is in the region on this cluster.
+
+   	Cluster-1 gfsh>put --key=20 --value="value20" --region=example-region
+   	Cluster-1 gfsh>query --query="select e.key from /example-region.entries e"
+
+10. In the terminal connected to the London cluster, verify the new entry has also 
+    been added to the region on this cluster.
+
+   	Cluster-2 gfsh>query --query="select e.key from /example-region.entries e"
+
+11. Exit gfsh in each terminal and shutdown the cluster using the stop.gfsh script
+ 
+        $ gfsh run --file=scripts/stop.gfsh
+
+12. Clean up any generated directories and files.
+
+    	$ ../gradlew cleanServer
+
diff --git a/wan/scripts/start-ln.gfsh b/wan/scripts/start-ln.gfsh
new file mode 100644
index 0000000..59ce76f
--- /dev/null
+++ b/wan/scripts/start-ln.gfsh
@@ -0,0 +1,43 @@
+#
+# 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 for London (ln) cluster
+start locator --name=locator-ln --port=10332 --locators=localhost[10332] --mcast-port=0 --log-level=config \
+	--J=-Dgemfire.remote-locators=localhost[10331] --J=-Dgemfire.distributed-system-id=2 \
+	--J=-Dgemfire.jmx-manager-start=true --J=-Dgemfire.jmx-manager-http-port=8082 \
+	--J=-Dgemfire.jmx-manager-port=1092
+
+start server --name=server-ln-1 --locators=localhost[10332] --mcast-port=0 --log-level=config \
+	--enable-time-statistics=true --statistic-archive-file=cacheserver.gfs --server-port=0 \
+	--classpath=../build/classes/main --J=-Dgemfire.statistic-sampling-enabled=true \
+	--J=-Dgemfire.distributed-system-id=2 --J=-Dgemfire.conserve-sockets=false \
+	--J=-Dgemfire.log-file=cacheserver.log
+
+start server --name=server-ln-2 --locators=localhost[10332] --mcast-port=0 --log-level=config \
+	--enable-time-statistics=true --statistic-archive-file=cacheserver.gfs --server-port=0 \
+	--classpath=../build/classes/main --J=-Dgemfire.statistic-sampling-enabled=true \
+	--J=-Dgemfire.distributed-system-id=2 --J=-Dgemfire.conserve-sockets=false \
+	--J=-Dgemfire.log-file=cacheserver.log
+
+# Create gateway receivers for all servers in the London site
+create gateway-receiver
+
+# Create gateway senders to send updates to the New York site
+create gateway-sender --id="ny" --parallel="true" --remote-distributed-system-id="1" 
+
+list members
+
diff --git a/wan/scripts/start-ny.gfsh b/wan/scripts/start-ny.gfsh
new file mode 100644
index 0000000..5b8e9e8
--- /dev/null
+++ b/wan/scripts/start-ny.gfsh
@@ -0,0 +1,43 @@
+#
+# 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 for New York (ny) cluster
+start locator --name=locator-ny --port=10331 --locators=localhost[10331] --mcast-port=0 --log-level=config \
+	--J=-Dgemfire.remote-locators=localhost[10332] --J=-Dgemfire.distributed-system-id=1 \
+	--J=-Dgemfire.jmx-manager-start=true --J=-Dgemfire.jmx-manager-http-port=8081 \
+	--J=-Dgemfire.jmx-manager-port=1091
+
+start server --name=server-ny-1 --locators=localhost[10331] --mcast-port=0 --log-level=config \
+	--enable-time-statistics=true --statistic-archive-file=cacheserver.gfs --server-port=0 \
+	--classpath=../build/classes/main --J=-Dgemfire.statistic-sampling-enabled=true \
+	--J=-Dgemfire.distributed-system-id=1 --J=-Dgemfire.conserve-sockets=false \
+	--J=-Dgemfire.log-file=cacheserver.log
+
+start server --name=server-ny-2 --locators=localhost[10331] --mcast-port=0 --log-level=config \
+	--enable-time-statistics=true --statistic-archive-file=cacheserver.gfs --server-port=0 \
+	--classpath=../build/classes/main --J=-Dgemfire.statistic-sampling-enabled=true \
+	--J=-Dgemfire.distributed-system-id=1 --J=-Dgemfire.conserve-sockets=false \
+	--J=-Dgemfire.log-file=cacheserver.log
+
+# Create gateway receivers for all servers in the New York cluster
+create gateway-receiver
+
+# Create gateway senders for servers to send updates to the London site
+create gateway-sender --id="ln" --parallel="true" --remote-distributed-system-id="2" 
+
+list members
+
diff --git a/wan/scripts/start-wan.gfsh b/wan/scripts/start-wan.gfsh
new file mode 100644
index 0000000..abdfc3f
--- /dev/null
+++ b/wan/scripts/start-wan.gfsh
@@ -0,0 +1,38 @@
+#
+# 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 to New York site and create gateway sender
+connect --locator=localhost[10331]
+
+# Create the region that will share data with the London site
+create region --name=example-region --type=PARTITION_REDUNDANT --gateway-sender-id="ln"
+
+# Check the status of the London site
+list members
+describe region --name=example-region
+
+# Disconnect from New York site and connect to London site
+disconnect
+connect --locator=localhost[10332]
+
+# Create the region that will share data with the New York site
+create region --name=example-region --type=PARTITION_REDUNDANT --gateway-sender-id="ny"
+
+# Check the status of the London site
+list members
+describe region --name=example-region
+
diff --git a/wan/scripts/start.gfsh b/wan/scripts/start.gfsh
new file mode 100644
index 0000000..27ffa36
--- /dev/null
+++ b/wan/scripts/start.gfsh
@@ -0,0 +1,29 @@
+#
+# 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 the London (ln) cluster
+run --file=./scripts/start-ln.gfsh
+disconnect
+
+# Start the New York (ny) cluster
+run --file=./scripts/start-ny.gfsh
+disconnect
+sh sleep 5
+
+# Create the region on each cluster and bind the gateway senders/receivers to region
+run --file=./scripts/start-wan.gfsh
+
diff --git a/wan/scripts/stop.gfsh b/wan/scripts/stop.gfsh
new file mode 100644
index 0000000..a482d63
--- /dev/null
+++ b/wan/scripts/stop.gfsh
@@ -0,0 +1,26 @@
+#
+# 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.
+#
+
+#shutdown london site
+connect --locator=localhost[10332]
+shutdown --include-locators=true
+disconnect
+
+#shutdown ny site
+connect --locator=localhost[10331]
+shutdown --include-locators=true
+
diff --git a/wan/src/main/java/org/apache/geode_examples/wan/Example.java b/wan/src/main/java/org/apache/geode_examples/wan/Example.java
new file mode 100644
index 0000000..9b87ccd
--- /dev/null
+++ b/wan/src/main/java/org/apache/geode_examples/wan/Example.java
@@ -0,0 +1,61 @@
+/*
+ * 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.wan;
+
+import java.util.HashSet;
+import java.util.Set;
+import java.util.stream.IntStream;
+
+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 {
+  private final Region<Integer, String> region;
+
+  public Example(Region<Integer, String> region) {
+    this.region = region;
+  }
+
+  public static void main(String[] args) {
+    // connect to the locator in London cluster using port 10332
+    ClientCache cache = new ClientCacheFactory().addPoolLocator("127.0.0.1", 10332)
+        .set("log-level", "WARN").create();
+
+    // create a local region that matches the server region
+    Region<Integer, String> region =
+        cache.<Integer, String>createClientRegionFactory(ClientRegionShortcut.PROXY)
+            .create("example-region");
+
+    Example example = new Example(region);
+    example.insertValues(10);
+    example.printValues(example.getValues());
+
+    cache.close();
+  }
+
+  Set<Integer> getValues() {
+    return new HashSet<>(region.keySetOnServer());
+  }
+
+  void insertValues(int upperLimit) {
+    IntStream.rangeClosed(1, upperLimit).forEach(i -> region.put(i, "value" + i));
+  }
+
+  void printValues(Set<Integer> values) {
+    values.forEach(key -> System.out.println(String.format("%d:%s", key, region.get(key))));
+  }
+}