You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by zh...@apache.org on 2020/05/22 00:03:47 UTC
[geode] branch feature/GEODE-8171 created (now d14cb54)
This is an automated email from the ASF dual-hosted git repository.
zhouxj pushed a change to branch feature/GEODE-8171
in repository https://gitbox.apache.org/repos/asf/geode.git.
at d14cb54 GEODE-8171: javadoc for putAll need to have accurate exception
This branch includes the following new commits:
new d14cb54 GEODE-8171: javadoc for putAll need to have accurate exception
The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
[geode] 01/01: GEODE-8171: javadoc for putAll need to have accurate
exception
Posted by zh...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
zhouxj pushed a commit to branch feature/GEODE-8171
in repository https://gitbox.apache.org/repos/asf/geode.git
commit d14cb54837f26a72b292b6cadfd82c17633dfb3d
Author: zhouxh <gz...@pivotal.io>
AuthorDate: Thu May 21 17:02:27 2020 -0700
GEODE-8171: javadoc for putAll need to have accurate exception
---
.../main/java/org/apache/geode/cache/Region.java | 24 +++-
.../cache/PutAllClientServerDistributedTest.java | 131 +++++++++++++++++++++
2 files changed, 153 insertions(+), 2 deletions(-)
diff --git a/geode-core/src/main/java/org/apache/geode/cache/Region.java b/geode-core/src/main/java/org/apache/geode/cache/Region.java
index 6413113..7314346 100644
--- a/geode-core/src/main/java/org/apache/geode/cache/Region.java
+++ b/geode-core/src/main/java/org/apache/geode/cache/Region.java
@@ -1359,10 +1359,30 @@ public interface Region<K, V> extends ConcurrentMap<K, V> {
* in the specified map. This operation will be distributed to other caches if the scope is not
* <code>Scope.LOCAL</code>.
*
- * @param map the key/value pairs to put in this region.
- * @since GemFire 5.0
+ * If any exception is thrown due to this call, it can imply that there may have been a partial
+ * update performed on the region. Use putAll from within a transaction to get atomicity with all
+ * the
+ * entries.
+ * <p>
+ *
* @see java.util.Map#putAll(Map map)
+ * @param map the key/value pairs to put in this region.
+ * @throws NullPointerException if key is null or if value is null (use invalidate instead), or if
+ * the key or value do not meet serializability requirements
+ * @throws ClassCastException if key does not satisfy the keyConstraint
+ * @throws org.apache.geode.distributed.LeaseExpiredException if lease expired on distributed lock
+ * for Scope.GLOBAL
+ * @throws TimeoutException if timed out getting distributed lock for Scope.GLOBAL
+ * @throws CacheWriterException if a CacheWriter aborts the operation
+ * @throws PartitionedRegionStorageException if the operation could not be completed on a
+ * partitioned region.
* @throws LowMemoryException if a low memory condition is detected.
+ * @see #invalidate(Object)
+ * @see CacheLoader#load
+ * @see CacheListener#afterCreate
+ * @see CacheListener#afterUpdate
+ * @see CacheWriter#beforeCreate
+ * @see CacheWriter#beforeUpdate
*/
@Override
void putAll(Map<? extends K, ? extends V> map);
diff --git a/geode-cq/src/distributedTest/java/org/apache/geode/internal/cache/PutAllClientServerDistributedTest.java b/geode-cq/src/distributedTest/java/org/apache/geode/internal/cache/PutAllClientServerDistributedTest.java
index 5696fe9..8bd07f5 100755
--- a/geode-cq/src/distributedTest/java/org/apache/geode/internal/cache/PutAllClientServerDistributedTest.java
+++ b/geode-cq/src/distributedTest/java/org/apache/geode/internal/cache/PutAllClientServerDistributedTest.java
@@ -73,6 +73,7 @@ import org.apache.geode.cache.CacheWriterException;
import org.apache.geode.cache.DataPolicy;
import org.apache.geode.cache.DiskStore;
import org.apache.geode.cache.EntryEvent;
+import org.apache.geode.cache.LowMemoryException;
import org.apache.geode.cache.Operation;
import org.apache.geode.cache.PartitionAttributesFactory;
import org.apache.geode.cache.Region;
@@ -101,6 +102,7 @@ import org.apache.geode.cache.server.CacheServer;
import org.apache.geode.cache.util.CacheListenerAdapter;
import org.apache.geode.cache.util.CacheWriterAdapter;
import org.apache.geode.distributed.DistributedSystemDisconnectedException;
+import org.apache.geode.distributed.OplogCancelledException;
import org.apache.geode.internal.cache.persistence.DiskRecoveryStore;
import org.apache.geode.internal.cache.tier.sockets.VersionedObjectList;
import org.apache.geode.internal.cache.versions.VersionTag;
@@ -1828,6 +1830,135 @@ public class PutAllClientServerDistributedTest implements Serializable {
}
/**
+ * Verify all the possible exceptions a putAll/put/removeAll/destroy could return
+ */
+ @Test
+ public void testPutAllReturnsExceptions() {
+ // set <true, false> means <PR=true, notifyBySubscription=false> to test local-invalidates
+ int serverPort1 = server1.invoke(() -> new ServerBuilder()
+ .regionShortcut(REPLICATE)
+ .create());
+ server2.invoke(() -> new ServerBuilder()
+ .regionShortcut(REPLICATE)
+ .create());
+
+ client1.invoke(() -> new ClientBuilder()
+ .concurrencyChecksEnabled()
+ .prSingleHopEnabled(true)
+ .serverPorts(serverPort1)
+ .subscriptionAckInterval()
+ .subscriptionEnabled(true)
+ .subscriptionRedundancy()
+ .create());
+
+ // server1 add cacheWriter
+ server1.invoke(() -> {
+ Region<String, TickerData> region = getCache().getRegion(regionName);
+ // let the server to trigger exception after created 15 keys
+ region.getAttributesMutator()
+ .setCacheWriter(new ActionCacheWriter<>(new Action<>(Operation.CREATE,
+ creates -> {
+ if (creates >= 15) {
+ throw new CacheWriterException("Expected by test");
+ }
+ })));
+
+ Throwable thrown = catchThrowable(() -> doPutAll(region, "key-", ONE_HUNDRED));
+ assertThat(thrown)
+ .isInstanceOf(CacheWriterException.class);
+ });
+
+ // client1 putAll
+ client1.invoke(() -> {
+ Region<String, TickerData> region = getClientCache().getRegion(regionName);
+
+ String message =
+ String.format("Region %s putAll at server applied partial keys due to exception.",
+ region.getFullPath());
+
+ Throwable thrown = catchThrowable(() -> doPutAll(region, "key-", ONE_HUNDRED));
+
+ assertThat(thrown)
+ .isInstanceOf(ServerOperationException.class)
+ .hasMessageContaining(message);
+ assertThat(thrown.getCause())
+ .isInstanceOf(CacheWriterException.class);
+ });
+
+ // let server1 to throw CancelException
+ server1.invoke(() -> {
+ Region<String, TickerData> region = getCache().getRegion(regionName);
+ // let the server to trigger exception after created 15 keys
+ region.getAttributesMutator()
+ .setCacheWriter(new ActionCacheWriter<>(new Action<>(Operation.CREATE,
+ creates -> {
+ throw new OplogCancelledException("Expected by test");
+ })));
+
+ Throwable thrown = catchThrowable(() -> doPutAll(region, "key-", ONE_HUNDRED));
+ assertThat(thrown)
+ .isInstanceOf(OplogCancelledException.class);
+
+ thrown = catchThrowable(() -> region.put("dummyKey", new TickerData(0)));
+ assertThat(thrown)
+ .isInstanceOf(OplogCancelledException.class);
+ });
+
+ // client1 putAll
+ client1.invoke(() -> {
+ Region<String, TickerData> region = getClientCache().getRegion(regionName);
+
+ Throwable thrown = catchThrowable(() -> doPutAll(region, "key-", ONE_HUNDRED));
+ assertThat(thrown)
+ .isInstanceOf(ServerConnectivityException.class);
+ assertThat(thrown.getCause())
+ .isInstanceOf(OplogCancelledException.class);
+
+ thrown = catchThrowable(() -> region.put("dummyKey", new TickerData(0)));
+ assertThat(thrown)
+ .isInstanceOf(ServerConnectivityException.class);
+ assertThat(thrown.getCause())
+ .isInstanceOf(OplogCancelledException.class);
+ });
+
+ // let server1 to throw LowMemoryException
+ server1.invoke(() -> {
+ Region<String, TickerData> region = getCache().getRegion(regionName);
+ // let the server to trigger exception after created 15 keys
+ region.getAttributesMutator()
+ .setCacheWriter(new ActionCacheWriter<>(new Action<>(Operation.CREATE,
+ creates -> {
+ throw new LowMemoryException();
+ })));
+
+ Throwable thrown = catchThrowable(() -> doPutAll(region, "key-", ONE_HUNDRED));
+ assertThat(thrown)
+ .isInstanceOf(LowMemoryException.class);
+
+ thrown = catchThrowable(() -> region.put("dummyKey", new TickerData(0)));
+ assertThat(thrown)
+ .isInstanceOf(LowMemoryException.class);
+ });
+
+ // client1 putAll
+ client1.invoke(() -> {
+ Region<String, TickerData> region = getClientCache().getRegion(regionName);
+
+ Throwable thrown = catchThrowable(() -> doPutAll(region, "key-", ONE_HUNDRED));
+ assertThat(thrown)
+ .isInstanceOf(ServerOperationException.class);
+ assertThat(thrown.getCause())
+ .isInstanceOf(LowMemoryException.class);
+
+ thrown = catchThrowable(() -> region.put("dummyKey", new TickerData(0)));
+ assertThat(thrown)
+ .isInstanceOf(ServerOperationException.class);
+ assertThat(thrown.getCause())
+ .isInstanceOf(LowMemoryException.class);
+ });
+ }
+
+ /**
* Tests partial key putAll to 2 PR servers, because putting data at server side is different
* between PR and LR. PR does it in postPutAll. It's not running in singleHop putAll
*/