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 2017/01/12 23:25:40 UTC
[08/17] geode git commit: GEODE-523: PartitionListener requires tests
and clean up
GEODE-523: PartitionListener requires tests and clean up
* Updated javadoc on the interface about usage
and removed gemstone contact.
* Added tests for afterPrimary and afterRegionCreate
Project: http://git-wip-us.apache.org/repos/asf/geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/geode/commit/a6546624
Tree: http://git-wip-us.apache.org/repos/asf/geode/tree/a6546624
Diff: http://git-wip-us.apache.org/repos/asf/geode/diff/a6546624
Branch: refs/heads/feature/GEODE-1930-2
Commit: a65466247497262cb633dc6b59eacf52b350edca
Parents: feb2a0f
Author: Sai Boorlagadda <sa...@apache.org>
Authored: Sat Jan 7 00:51:29 2017 +0000
Committer: Sai Boorlagadda <sa...@apache.org>
Committed: Thu Jan 12 06:56:17 2017 +0000
----------------------------------------------------------------------
.../cache/partition/PartitionListener.java | 48 ++++-------
.../cache/PartitionListenerDUnitTest.java | 91 +++++++++++++++++++-
2 files changed, 105 insertions(+), 34 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/geode/blob/a6546624/geode-core/src/main/java/org/apache/geode/cache/partition/PartitionListener.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/cache/partition/PartitionListener.java b/geode-core/src/main/java/org/apache/geode/cache/partition/PartitionListener.java
index 2a79459..a534e50 100644
--- a/geode-core/src/main/java/org/apache/geode/cache/partition/PartitionListener.java
+++ b/geode-core/src/main/java/org/apache/geode/cache/partition/PartitionListener.java
@@ -20,59 +20,43 @@ import org.apache.geode.cache.Region;
/**
*
- * A callback for partitioned regions, invoked when a partition region is created or any bucket in a
- * partitioned region becomes primary.<br>
+ * A callback for partitioned regions, invoked when a partition region is created or any bucket is
+ * created/deleted or any bucket in a partitioned region becomes primary.<br>
* <br>
- * A sample implementation of this interface to colocate partition regions using a primary key
- * without having to honor the redundancy contract for every colocate partition regions is as
- * follows : <br>
- *
+ * It is highly recommended that implementations of this listener should be quick and not try to
+ * manipulate regions and data because the the callbacks are invoked while holding locks that may
+ * block region operations. <br>
+ *
* <pre>
- * public class ColocatingPartitionListener extends PartitionListenerAdapter implements Declarable {
- * private Cache cache;
- *
- * private List<String> viewRegionNames = new ArrayList<String>();
- *
- * public ColocatingPartitionListener() {}
+ * package com.myCompany.MyPartitionListener;
+ *
+ * public class MyPartitionListener extends PartitionListenerAdapter implements Declarable {
+ * private String regionName;
+ *
+ * public MyPartitionListener() {}
*
* public void afterPrimary(int bucketId) {
- * for (String viewRegionName : viewRegionNames) {
- * Region viewRegion = cache.getRegion(viewRegionName);
- * PartitionManager.createPrimaryBucket(viewRegion, bucketId, true, true);
- * }
- * }
- *
- * public void init(Properties props) {
- * String viewRegions = props.getProperty("viewRegions");
- * StringTokenizer tokenizer = new StringTokenizer(viewRegions, ",");
- * while (tokenizer.hasMoreTokens()) {
- * viewRegionNames.add(tokenizer.nextToken());
- * }
+ * System.out.println("bucket:" + bucketId + " has become primary on " + this.regionName);
* }
*
* public void afterRegionCreate(Region<?, ?> region) {
- * cache = region.getCache();
+ * this.regionName = region.getName();
* }
* }
* </pre>
*
- * A sample declaration of the ColocatingPartitionListener in cache.xml as follows :<br>
+ * A sample declaration of the MyPartitionListener in cache.xml as follows :<br>
*
* <pre>
* <partition-attributes redundant-copies="1">
* <partition-listener>
- * <class-name>com.myCompany.ColocatingPartitionListener</class-name>
- * <parameter name="viewRegions">
- * <string>/customer/ViewA,/customer/ViewB</string>
- * </parameter>
+ * <class-name>com.myCompany.MyPartitionListener</class-name>
* </partition-listener>
* </partition-attributes>
* </pre>
*
* @see PartitionAttributesFactory#addPartitionListener(PartitionListener)
*
- * Note : Please contact support@gemstone.com before using these APIs
- *
* @since GemFire 6.5
*
*/
http://git-wip-us.apache.org/repos/asf/geode/blob/a6546624/geode-core/src/test/java/org/apache/geode/internal/cache/PartitionListenerDUnitTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/internal/cache/PartitionListenerDUnitTest.java b/geode-core/src/test/java/org/apache/geode/internal/cache/PartitionListenerDUnitTest.java
index 16bac77..11cb2e0 100644
--- a/geode-core/src/test/java/org/apache/geode/internal/cache/PartitionListenerDUnitTest.java
+++ b/geode-core/src/test/java/org/apache/geode/internal/cache/PartitionListenerDUnitTest.java
@@ -17,10 +17,11 @@ package org.apache.geode.internal.cache;
import org.junit.experimental.categories.Category;
import org.junit.Test;
+import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.*;
+import static org.assertj.core.api.Assertions.*;
import org.apache.geode.test.dunit.cache.internal.JUnit4CacheTestCase;
-import org.apache.geode.test.dunit.internal.JUnit4DistributedTestCase;
import org.apache.geode.test.junit.categories.DistributedTest;
import java.util.ArrayList;
@@ -37,7 +38,6 @@ import org.apache.geode.cache.PartitionAttributesFactory;
import org.apache.geode.cache.Region;
import org.apache.geode.cache.control.RebalanceOperation;
import org.apache.geode.cache.partition.PartitionListenerAdapter;
-import org.apache.geode.cache30.CacheTestCase;
import org.apache.geode.distributed.DistributedMember;
import org.apache.geode.test.dunit.Host;
import org.apache.geode.test.dunit.SerializableCallable;
@@ -69,11 +69,29 @@ public class PartitionListenerDUnitTest extends JUnit4CacheTestCase {
createPR(vm0, regionName, true);
createData(vm0, 0, 1000, "A", regionName);
+ // Assert that afterPrimary is invoked for every primary created on the vm
+ List<Integer> vm1PrimariesCreated = getPrimariesCreated(vm1, regionName);
+ List<Integer> vm2PrimariesCreated = getPrimariesCreated(vm2, regionName);
+ List<Integer> vm1ActualPrimaries = getPrimariesOn(vm1, regionName);
+ List<Integer> vm2ActualPrimaries = getPrimariesOn(vm2, regionName);
+
+ vm1PrimariesCreated.removeAll(vm1ActualPrimaries);
+ vm2PrimariesCreated.removeAll(vm2ActualPrimaries);
+
+ assertThat(vm1PrimariesCreated).isEmpty();
+ assertThat(vm2PrimariesCreated).isEmpty();
+
// Create the PR in a third JVM and rebalance
createPR(vm3, regionName, false);
rebalance(vm3);
// Verify listener invocations
+ // Assert afterRegionCreate is invoked on every VM.
+ assertEquals(regionName, getRegionNameFromListener(vm0, regionName));
+ assertEquals(regionName, getRegionNameFromListener(vm1, regionName));
+ assertEquals(regionName, getRegionNameFromListener(vm2, regionName));
+ assertEquals(regionName, getRegionNameFromListener(vm3, regionName));
+
// Get all buckets and keys removed from VM1 and VM2
Map<Integer, List<Integer>> allBucketsAndKeysRemoved = new HashMap<Integer, List<Integer>>();
allBucketsAndKeysRemoved.putAll(getBucketsAndKeysRemoved(vm1, regionName));
@@ -84,6 +102,13 @@ public class PartitionListenerDUnitTest extends JUnit4CacheTestCase {
// Verify that they are equal
assertEquals(allBucketsAndKeysRemoved, vm3BucketsAndKeysAdded);
+
+ // Verify afterPrimary is invoked after rebalance.
+ List<Integer> vm3PrimariesCreated = getPrimariesCreated(vm3, regionName);
+ List<Integer> vm3ActualPrimaries = getPrimariesOn(vm3, regionName);
+
+ vm3ActualPrimaries.removeAll(vm3PrimariesCreated);
+ assertThat(vm3ActualPrimaries).isEmpty();
}
protected DistributedMember createPR(VM vm, final String regionName, final boolean isAccessor)
@@ -124,6 +149,47 @@ public class PartitionListenerDUnitTest extends JUnit4CacheTestCase {
vm.invoke(createData);
}
+ protected List<Integer> getPrimariesOn(VM vm, final String regionName) {
+ SerializableCallable getPrimariesOn = new SerializableCallable("getPrimariesOn") {
+
+ public Object call() {
+ Cache cache = getCache();
+ Region region = cache.getRegion(regionName);
+ return new ArrayList<>(
+ ((PartitionedRegion) region).getDataStore().getAllLocalPrimaryBucketIds());
+ }
+ };
+ return (List<Integer>) vm.invoke(getPrimariesOn);
+ }
+
+ protected List<Integer> getPrimariesCreated(VM vm, final String regionName) {
+ SerializableCallable getPrimariesCreated = new SerializableCallable("getPrimariesCreated") {
+
+ public Object call() {
+ Cache cache = getCache();
+ Region region = cache.getRegion(regionName);
+ TestPartitionListener listener = (TestPartitionListener) region.getAttributes()
+ .getPartitionAttributes().getPartitionListeners()[0];
+ return listener.getPrimariesCreated();
+ }
+ };
+ return (List<Integer>) vm.invoke(getPrimariesCreated);
+ }
+
+ protected String getRegionNameFromListener(VM vm, final String regionName) {
+ SerializableCallable getRegionName = new SerializableCallable("getRegionName") {
+
+ public Object call() {
+ Cache cache = getCache();
+ Region region = cache.getRegion(regionName);
+ TestPartitionListener listener = (TestPartitionListener) region.getAttributes()
+ .getPartitionAttributes().getPartitionListeners()[0];
+ return listener.getRegionName();
+ }
+ };
+ return (String) vm.invoke(getRegionName);
+ }
+
protected Map<Integer, List<Integer>> getBucketsAndKeysRemoved(VM vm, final String regionName) {
SerializableCallable getBucketsAndKeysRemoved =
new SerializableCallable("getBucketsAndKeysRemoved") {
@@ -168,11 +234,16 @@ public class PartitionListenerDUnitTest extends JUnit4CacheTestCase {
protected static class TestPartitionListener extends PartitionListenerAdapter {
+ private String regionName;
+
+ private final List<Integer> primariesCreated;
+
private final Map<Integer, List<Integer>> bucketsAndKeysRemoved;
private final Map<Integer, List<Integer>> bucketsAndKeysAdded;
public TestPartitionListener() {
+ this.primariesCreated = new ArrayList<>();
this.bucketsAndKeysRemoved = new HashMap<Integer, List<Integer>>();
this.bucketsAndKeysAdded = new HashMap<Integer, List<Integer>>();
}
@@ -185,6 +256,22 @@ public class PartitionListenerDUnitTest extends JUnit4CacheTestCase {
return this.bucketsAndKeysAdded;
}
+ public List<Integer> getPrimariesCreated() {
+ return this.primariesCreated;
+ }
+
+ public String getRegionName() {
+ return this.regionName;
+ }
+
+ public void afterRegionCreate(Region<?, ?> region) {
+ this.regionName = region.getName();
+ }
+
+ public void afterPrimary(int bucketId) {
+ this.primariesCreated.add(bucketId);
+ }
+
public void afterBucketRemoved(int bucketId, Iterable<?> keys) {
Collection<Integer> keysCol = (Collection) keys;
// If the keys collection is not empty, create a serializable list to hold