This is an automated email from the ASF dual-hosted git repository. jasonhuynh pushed a commit to branch develop in repository https://gitbox.apache.org/repos/asf/geode.git
The following commit(s) were added to refs/heads/develop by this push: new 49cb2eb GEODE-3813: Deprecating RegisterInterest ALL_KEYS and List behavior (#1438) 49cb2eb is described below commit 49cb2eb6fb18966d9fc6c49548edfaf6047a51cc Author: Jason Huynh <huyn...@gmail.com> AuthorDate: Tue Feb 13 08:47:47 2018 -0800 GEODE-3813: Deprecating RegisterInterest ALL_KEYS and List behavior (#1438) * Now with lazy default pool initialization from GEODE-4511, readyForEvents will throw IllegalStateException if no pools available. * Modified tests based on new behavior introduced in GEODE-4511 --- .../main/java/org/apache/geode/cache/Region.java | 342 ++++++++++++++++++-- .../cache/client/internal/ServerRegionProxy.java | 3 +- .../apache/geode/internal/cache/LocalRegion.java | 4 + .../geode/internal/cache/PoolManagerImpl.java | 3 + .../sockets/RegisterInterestIntegrationTest.java | 347 +++++++++++++++++++++ 5 files changed, 677 insertions(+), 22 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 5073b8b..a933e51 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 @@ -1510,22 +1510,29 @@ public interface Region<K, V> extends ConcurrentMap<K, V> { * cleared from the client and current value for this key is inserted into the local cache before * this call returns. * - * @param key The key on which to register interest. If the key is a <code>List</code>, then all - * the keys in the <code>List</code> will be registered. The key can also be the special - * token 'ALL_KEYS', which will register interest in all keys in the region. In effect, - * this will cause an update to any key in this region in the CacheServer to be pushed to - * the client. + * @param key The key on which to register interest. + * + * The following <code>List</code> and 'ALL_KEYS' behavior is now deprecated. As an + * alternative, please use {@link #registerInterestForKeys(Iterable)} and + * {@link #registerInterestForAllKeys()} + * + * Deprecated behavior: If the key is a <code>List</code>, then all the keys in the + * <code>List</code> will be registered. The key can also be the special token 'ALL_KEYS', + * which will register interest in all keys in the region. In effect, this will cause an + * update to any key in this region in the CacheServer to be pushed to the client. * * <p> * This method uses the default <code>InterestResultPolicy</code>. * </p> * * <p> - * <i>Using 'ALL_KEYS' is the same as calling {@link #registerInterestRegex(String)} with + * <i> Using 'ALL_KEYS' is the same as calling {@link #registerInterestRegex(String)} with * ".*" as the argument. This means that all keys any type are pushed to the client and * inserted into the local cache.</i> * </p> * + * End of deprecation + * * <p> * If you locally-destroy a key and your region has concurrency-checks-enabled turned off * you will not receive invalidation events from your interest subscription for that key. @@ -1558,17 +1565,22 @@ public interface Region<K, V> extends ConcurrentMap<K, V> { * events to your client cache. * </p> * - * @param key The key on which to register interest. If the key is a <code>List</code>, then all - * the keys in the <code>List</code> will be registered. The key can also be the special - * token 'ALL_KEYS', which will register interest in all keys in the region. In effect, - * this will cause an update to any key in this region in the CacheServer to be pushed to - * the client. + * @param key The key on which to register interest. The following <code>List</code> and + * 'ALL_KEYS' behavior is now deprecated. As an alternative, please use + * {@link #registerInterestForKeys(Iterable, InterestResultPolicy)} and + * {@link #registerInterestForAllKeys(InterestResultPolicy)} + * + * Deprecated behavior: If the key is a <code>List</code>, then all the keys in the + * <code>List</code> will be registered. The key can also be the special token 'ALL_KEYS', + * which will register interest in all keys in the region. In effect, this will cause an + * update to any key in this region in the CacheServer to be pushed to the client. * * <p> * <i>Using 'ALL_KEYS' is the same as calling {@link #registerInterestRegex(String)} with * ".*" as the argument. This means that all keys of any type are pushed to the client and * inserted into the local cache.</i> * </p> + * End of deprecation * * @param policy The interest result policy. This can be one of: * <ul> @@ -1589,6 +1601,271 @@ public interface Region<K, V> extends ConcurrentMap<K, V> { */ void registerInterest(K key, InterestResultPolicy policy); + + /** + * Sends a request to the CacheServer to register interest in all keys for this client. Updates to + * any key by other clients will be pushed to this client by the CacheServer. This method is + * currently supported only on clients in a client server topology. The keys are first locally + * cleared from the client and current value for the keys are inserted into the local cache before + * this call returns. + * + * @since Geode 1.5 + * + * @throws UnsupportedOperationException if the region is not configured with a pool name. + * @throws SubscriptionNotEnabledException if the region's pool does not have subscriptions + * enabled. + * @throws UnsupportedOperationException if the region is a replicate with distributed scope. + */ + default void registerInterestForAllKeys() { + registerInterestRegex(".*"); + } + + + /** + * Sends a request to the CacheServer to register interest in for all keys for this client. + * Updates to any key by other clients will be pushed to this client by the CacheServer. This + * method is currently supported only on clients in a client server topology. The keys are first + * locally cleared from the client and current value for the keys are inserted into the local + * cache before this call returns. (if requested). + * + * <p> + * If you locally-destroy a key and your region has concurrency-checks-enabled turned off you will + * not receive invalidation events from your interest subscription for that key. When + * concurrency-checks-enabled is turned on GemFire will accept invalidation and deliver these + * events to your client cache. + * </p> + * + * @param policy The interest result policy. This can be one of: + * <ul> + * <li>InterestResultPolicy.NONE - does not initialize the local cache</li> + * <li>InterestResultPolicy.KEYS - initializes the local cache with the keys satisfying the + * request</li> + * <li>InterestResultPolicy.KEYS_VALUES - initializes the local cache with the keys and + * current values satisfying the request</li> + * </ul> + * @throws UnsupportedOperationException if the region is not configured with a pool name. + * @throws SubscriptionNotEnabledException if the region's pool does not have subcriptions + * enabled. + * @throws UnsupportedOperationException if the region is a replicate with distributed scope. + * + * @see InterestResultPolicy + * + * @since Geode 1.5 + */ + default void registerInterestForAllKeys(InterestResultPolicy policy) { + registerInterestRegex(".*", policy); + } + + /** + * Sends a request to the CacheServer to register interest in all keys for this client. Updates to + * any key by other clients will be pushed to this client by the CacheServer. This method is + * currently supported only on clients in a client server topology. The keys are first locally + * cleared from the client and the current value for the keys are inserted into the local cache + * before this call returns (if requested). + * + * @param policy The interest result policy. This can be one of: + * <ul> + * <li>InterestResultPolicy.NONE - does not initialize the local cache</li> + * <li>InterestResultPolicy.KEYS - initializes the local cache with the keys satisfying the + * request</li> + * <li>InterestResultPolicy.KEYS_VALUES - initializes the local cache with the keys and + * current values satisfying the request</li> + * </ul> + * @param isDurable true if the register interest is durable + * @throws UnsupportedOperationException if the region is not configured with a pool name. + * @throws SubscriptionNotEnabledException if the region's pool does not have subscriptions + * enabled. + * @throws UnsupportedOperationException if the region is a replicate with distributed scope. + * + * @see InterestResultPolicy + * + * @since Geode 1.5 + */ + default void registerInterestForAllKeys(InterestResultPolicy policy, boolean isDurable) { + registerInterestRegex(".*", policy, isDurable); + } + + + /** + * Sends a request to the CacheServer to register interest in all keys for this client. Updates to + * any key by other clients will be pushed to this client by the CacheServer. This method is + * currently supported only on clients in a client server topology. The keys are first locally + * cleared from the client and the current value for the keys are inserted into the local cache + * before this call returns (if requested). + * + * <p> + * If you locally-destroy a key and your region has concurrency-checks-enabled turned off you will + * not receive invalidation events from your interest subscription for that key. When + * concurrency-checks-enabled is turned on GemFire will accept invalidation and deliver these + * events to your client cache. + * </p> + * + * @param policy The interest result policy. This can be one of: + * <ul> + * <li>InterestResultPolicy.NONE - does not initialize the local cache</li> + * <li>InterestResultPolicy.KEYS - initializes the local cache with the keys satisfying the + * request</li> + * <li>InterestResultPolicy.KEYS_VALUES - initializes the local cache with the keys and + * current values satisfying the request</li> + * </ul> + * @param isDurable true if the register interest is durable + * @param receiveValues defaults to true. set to false to receive create or update events as + * invalidates similar to notify-by-subscription false. + * @throws UnsupportedOperationException if the region is not configured with a pool name. + * @throws SubscriptionNotEnabledException if the region's pool does not have subscriptions + * enabled. + * @throws UnsupportedOperationException if the region is a replicate with distributed scope. + * + * @see InterestResultPolicy + * + * @since Geode 1.5 + */ + default void registerInterestForAllKeys(InterestResultPolicy policy, boolean isDurable, + boolean receiveValues) { + registerInterestRegex(".*", policy, isDurable, receiveValues); + } + + /** + * Sends a request to the CacheServer to register interest for all key in the iterable for this + * client. Updates to any of the keys in the iterable by other clients will be pushed to this + * client by the CacheServer. This method is currently supported only on clients in a client + * server topology. The keys are first locally cleared from the client and current value for the + * keys are inserted into the local cache before this call returns. (if requested). + * + * <p> + * If you locally-destroy a key and your region has concurrency-checks-enabled turned off you will + * not receive invalidation events from your interest subscription for that key. When + * concurrency-checks-enabled is turned on GemFire will accept invalidation and deliver these + * events to your client cache. + * </p> + * + * @param iterable The <code>Iterable</code> of keys on which to register interest. + * @throws UnsupportedOperationException if the region is not configured with a pool name. + * @throws SubscriptionNotEnabledException if the region's pool does not have subcriptions + * enabled. + * @throws UnsupportedOperationException if the region is a replicate with distributed scope. + ** + * @since Geode 1.5 + */ + default void registerInterestForKeys(Iterable<K> iterable) { + iterable.forEach(k -> registerInterest(k)); + } + + /** + * Sends a request to the CacheServer to register interest for all key in the iterable for this + * client. Updates to any of the keys in the iterable by other clients will be pushed to this + * client by the CacheServer. This method is currently supported only on clients in a client + * server topology. The keys are first locally cleared from the client and current value for the + * keys are inserted into the local cache before this call returns. (if requested). + * + * <p> + * If you locally-destroy a key and your region has concurrency-checks-enabled turned off you will + * not receive invalidation events from your interest subscription for that key. When + * concurrency-checks-enabled is turned on GemFire will accept invalidation and deliver these + * events to your client cache. + * </p> + * + * @param iterable The <code>Iterable</code> of keys on which to register interest. + * @param policy The interest result policy. This can be one of: + * <ul> + * <li>InterestResultPolicy.NONE - does not initialize the local cache</li> + * <li>InterestResultPolicy.KEYS - initializes the local cache with the keys satisfying the + * request</li> + * <li>InterestResultPolicy.KEYS_VALUES - initializes the local cache with the keys and + * current values satisfying the request</li> + * </ul> + * @throws UnsupportedOperationException if the region is not configured with a pool name. + * @throws SubscriptionNotEnabledException if the region's pool does not have subcriptions + * enabled. + * @throws UnsupportedOperationException if the region is a replicate with distributed scope. + * + * @see InterestResultPolicy + * + * @since Geode 1.5 + */ + default void registerInterestForKeys(Iterable<K> iterable, InterestResultPolicy policy) { + iterable.forEach(k -> registerInterest(k, policy)); + } + + /** + * Sends a request to the CacheServer to register interest for all key in the iterable for this + * client. Updates to any of the keys in the iterable by other clients will be pushed to this + * client by the CacheServer. This method is currently supported only on clients in a client + * server topology. The keys are first locally cleared from the client and current value for the + * keys are inserted into the local cache before this call returns. (if requested). + * + * <p> + * If you locally-destroy a key and your region has concurrency-checks-enabled turned off you will + * not receive invalidation events from your interest subscription for that key. When + * concurrency-checks-enabled is turned on GemFire will accept invalidation and deliver these + * events to your client cache. + * </p> + * + * @param iterable The <code>Iterable</code> of keys on which to register interest. + * @param policy The interest result policy. This can be one of: + * <ul> + * <li>InterestResultPolicy.NONE - does not initialize the local cache</li> + * <li>InterestResultPolicy.KEYS - initializes the local cache with the keys satisfying the + * request</li> + * <li>InterestResultPolicy.KEYS_VALUES - initializes the local cache with the keys and + * current values satisfying the request</li> + * </ul> + * @param isDurable true if the register interest is durable + * @throws UnsupportedOperationException if the region is not configured with a pool name. + * @throws SubscriptionNotEnabledException if the region's pool does not have subcriptions + * enabled. + * @throws UnsupportedOperationException if the region is a replicate with distributed scope. + * + * @see InterestResultPolicy + * + * @since Geode 1.5 + */ + default void registerInterestForKeys(Iterable<K> iterable, InterestResultPolicy policy, + boolean isDurable) { + iterable.forEach(k -> registerInterest(k, policy, isDurable)); + } + + /** + * Sends a request to the CacheServer to register interest for all key in the iterable for this + * client. Updates to any of the keys in the iterable by other clients will be pushed to this + * client by the CacheServer. This method is currently supported only on clients in a client + * server topology. The keys are first locally cleared from the client and current value for the + * keys are inserted into the local cache before this call returns. (if requested). + * + * <p> + * If you locally-destroy a key and your region has concurrency-checks-enabled turned off you will + * not receive invalidation events from your interest subscription for that key. When + * concurrency-checks-enabled is turned on GemFire will accept invalidation and deliver these + * events to your client cache. + * </p> + * + * @param iterable The <code>Iterable</code> of keys on which to register interest. + * @param policy The interest result policy. This can be one of: + * <ul> + * <li>InterestResultPolicy.NONE - does not initialize the local cache</li> + * <li>InterestResultPolicy.KEYS - initializes the local cache with the keys satisfying the + * request</li> + * <li>InterestResultPolicy.KEYS_VALUES - initializes the local cache with the keys and + * current values satisfying the request</li> + * </ul> + * @param isDurable true if the register interest is durable + * @param receiveValues defaults to true. set to false to receive create or update events as + * invalidates similar to notify-by-subscription false. + * @throws UnsupportedOperationException if the region is not configured with a pool name. + * @throws SubscriptionNotEnabledException if the region's pool does not have subcriptions + * enabled. + * @throws UnsupportedOperationException if the region is a replicate with distributed scope. + * + * @see InterestResultPolicy + * + * @since Geode 1.5 + */ + default void registerInterestForKeys(Iterable<K> iterable, InterestResultPolicy policy, + boolean isDurable, boolean receiveValues) { + iterable.forEach(k -> registerInterest(k, policy, isDurable, receiveValues)); + } + + /** * Sends a request to the CacheServer to register interest in a regular expression pattern for * this client. Updates to any keys of type {@link String} satisfying this regular expression by @@ -1809,17 +2086,28 @@ public interface Region<K, V> extends ConcurrentMap<K, V> { * events to your client cache. * </p> * - * @param key The key on which to register interest. If the key is a <code>List</code>, then all - * the keys in the <code>List</code> will be registered. The key can also be the special - * token 'ALL_KEYS', which will register interest in all keys in the region. In effect, - * this will cause an update to any key in this region in the CacheServer to be pushed to - * the client. + * @param key The key on which to register interest. + * + * The following <code>List</code> and 'ALL_KEYS' behavior is now deprecated. As an + * alternative, please use + * {@link #registerInterestForKeys(Iterable, InterestResultPolicy, boolean, boolean)} and + * {@link #registerInterestForAllKeys(InterestResultPolicy, boolean, boolean)} + * + * Deprecated behavior: If the key is a <code>List</code>, then all the keys in the + * <code>List</code> will be registered. The key can also be the special token 'ALL_KEYS', + * which will register interest in all keys in the region. In effect, this will cause an + * update to any key in this region in the CacheServer to be pushed to the client. + * + * <p> + * This method uses the default <code>InterestResultPolicy</code>. + * </p> * * <p> * <i>Using 'ALL_KEYS' is the same as calling {@link #registerInterestRegex(String)} with * ".*" as the argument. This means that all keys of any type are pushed to the client and * inserted into the local cache.</i> * </p> + * End of deprecation. * * @param policy The interest result policy. This can be one of: * <ul> @@ -1851,11 +2139,21 @@ public interface Region<K, V> extends ConcurrentMap<K, V> { * cleared from the client and the current value for this key is inserted into the local cache * before this call returns (if requested). * - * @param key The key on which to register interest. If the key is a <code>List</code>, then all - * the keys in the <code>List</code> will be registered. The key can also be the special - * token 'ALL_KEYS', which will register interest in all keys in the region. In effect, - * this will cause an update to any key in this region in the CacheServer to be pushed to - * the client. + * @param key The key on which to register interest. + * + * The following <code>List</code> and 'ALL_KEYS' behavior is now deprecated. As an + * alternative, please use + * {@link #registerInterestForKeys(Iterable, InterestResultPolicy, boolean)} and + * {@link #registerInterestForAllKeys(InterestResultPolicy, boolean)} + * + * Deprecated behavior: If the key is a <code>List</code>, then all the keys in the + * <code>List</code> will be registered. The key can also be the special token 'ALL_KEYS', + * which will register interest in all keys in the region. In effect, this will cause an + * update to any key in this region in the CacheServer to be pushed to the client. + * + * <p> + * This method uses the default <code>InterestResultPolicy</code>. + * </p> * * <p> * <i>Using 'ALL_KEYS' is the same as calling {@link #registerInterestRegex(String)} with @@ -1863,6 +2161,8 @@ public interface Region<K, V> extends ConcurrentMap<K, V> { * inserted into the local cache.</i> * </p> * + * End of deprecation. + * * <p> * If you locally-destroy a key and your region has concurrency-checks-enabled turned off * you will not receive invalidation events from your interest subscription for that key. diff --git a/geode-core/src/main/java/org/apache/geode/cache/client/internal/ServerRegionProxy.java b/geode-core/src/main/java/org/apache/geode/cache/client/internal/ServerRegionProxy.java index 96a6e51..69bcd91 100644 --- a/geode-core/src/main/java/org/apache/geode/cache/client/internal/ServerRegionProxy.java +++ b/geode-core/src/main/java/org/apache/geode/cache/client/internal/ServerRegionProxy.java @@ -345,10 +345,11 @@ public class ServerRegionProxy extends ServerProxy implements ServerRegionDataAc final InterestResultPolicy policy, final boolean isDurable, final boolean receiveUpdatesAsInvalidates, final byte regionDataPolicy) { if (interestType == InterestType.KEY && key instanceof List) { + logger.warn( + "Usage of registerInterest(List) has been deprecated. Please use registerInterestForKeys(Iterable)"); return registerInterestList((List) key, policy, isDurable, receiveUpdatesAsInvalidates, regionDataPolicy); } else { - final RegisterInterestTracker rit = this.pool.getRITracker(); List result = null; boolean finished = false; diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/LocalRegion.java b/geode-core/src/main/java/org/apache/geode/internal/cache/LocalRegion.java index 914ce5d..77dc518 100644 --- a/geode-core/src/main/java/org/apache/geode/internal/cache/LocalRegion.java +++ b/geode-core/src/main/java/org/apache/geode/internal/cache/LocalRegion.java @@ -3747,10 +3747,14 @@ public class LocalRegion extends AbstractRegion implements LoaderHelperFactory, case InterestType.KEY: if (key instanceof String && key.equals("ALL_KEYS")) { + logger.warn( + "Usage of registerInterest('ALL_KEYS') has been deprecated. Please use registerInterestForAllKeys()"); serverKeys = proxy.registerInterest(".*", InterestType.REGULAR_EXPRESSION, interestResultPolicy, isDurable, receiveUpdatesAsInvalidates, regionDataPolicy); } else { if (key instanceof List) { + logger.warn( + "Usage of registerInterest(List) has been deprecated. Please use registerInterestForKeys(Iterable)"); serverKeys = proxy.registerInterestList((List) key, interestResultPolicy, isDurable, receiveUpdatesAsInvalidates, regionDataPolicy); } else { diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/PoolManagerImpl.java b/geode-core/src/main/java/org/apache/geode/internal/cache/PoolManagerImpl.java index 82f3178..ffc62ea 100644 --- a/geode-core/src/main/java/org/apache/geode/internal/cache/PoolManagerImpl.java +++ b/geode-core/src/main/java/org/apache/geode/internal/cache/PoolManagerImpl.java @@ -206,6 +206,9 @@ public class PoolManagerImpl { } } } + if (pools.size() == 0) { + throw new IllegalStateException("Ready for Events called, but no pool to execute on"); + } if (pools.size() > 0 && !foundDurablePool) { throw new IllegalStateException( LocalizedStrings.PoolManagerImpl_ONLY_DURABLE_CLIENTS_SHOULD_CALL_READYFOREVENTS diff --git a/geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/RegisterInterestIntegrationTest.java b/geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/RegisterInterestIntegrationTest.java new file mode 100644 index 0000000..d234c96 --- /dev/null +++ b/geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/RegisterInterestIntegrationTest.java @@ -0,0 +1,347 @@ +/* + * 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.internal.cache.tier.sockets; + +import static junit.framework.TestCase.assertEquals; +import static org.junit.Assert.fail; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Properties; +import java.util.Set; +import java.util.concurrent.TimeUnit; + +import org.awaitility.Awaitility; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +import org.apache.geode.cache.Cache; +import org.apache.geode.cache.InterestResultPolicy; +import org.apache.geode.cache.Region; +import org.apache.geode.cache.RegionShortcut; +import org.apache.geode.cache.client.ClientCache; +import org.apache.geode.cache.client.ClientCacheFactory; +import org.apache.geode.cache.client.ClientRegionShortcut; +import org.apache.geode.test.dunit.rules.ClusterStartupRule; +import org.apache.geode.test.dunit.rules.MemberVM; +import org.apache.geode.test.junit.categories.IntegrationTest; + +@Category({IntegrationTest.class}) +public class RegisterInterestIntegrationTest { + + private MemberVM locator; + private int locatorPort; + private MemberVM server; + + @Rule + public ClusterStartupRule locatorServerStartupRule = new ClusterStartupRule(); + + @Before + public void before() throws Exception { + locator = locatorServerStartupRule.startLocatorVM(1, new Properties()); + locatorPort = locator.getPort(); + server = locatorServerStartupRule.startServerVM(3, locatorPort); + createServerRegion(server, RegionShortcut.PARTITION); + } + + @Test + public void registerInterestAllKeysShouldRegisterForAllKeys() throws Exception { + + ClientCache clientCache = createClientCache(locatorPort); + + Region region = + clientCache.createClientRegionFactory(ClientRegionShortcut.CACHING_PROXY).create("region"); + region.registerInterestForAllKeys(); + + server.invoke(() -> { + Region regionOnServer = ClusterStartupRule.getCache().getRegion("region"); + regionOnServer.put("some key", "some value"); + regionOnServer.put(new ArrayList(), new ArrayList()); + regionOnServer.put(1, 2); + }); + + Awaitility.await().atMost(10, TimeUnit.SECONDS).until(() -> assertEquals(3, region.size())); + } + + @Test + public void registerInterestAllKeysWithInterestPolicyShouldRegisterForAllKeys() throws Exception { + + ClientCache clientCache = createClientCache(locatorPort); + + Region region = + clientCache.createClientRegionFactory(ClientRegionShortcut.CACHING_PROXY).create("region"); + region.registerInterestForAllKeys(InterestResultPolicy.KEYS); + + server.invoke(() -> { + Region regionOnServer = ClusterStartupRule.getCache().getRegion("region"); + regionOnServer.put("some key", "some value"); + regionOnServer.put(new ArrayList(), new ArrayList()); + regionOnServer.put(1, 2); + }); + + Awaitility.await().atMost(10, TimeUnit.SECONDS) + .until(() -> assertEquals(3, region.keySet().size())); + } + + @Test + public void nonDurableClientRegisterInterestForAllKeysWithDurableFlagShouldThrowException() + throws Exception { + + ClientCache clientCache = createClientCache(locatorPort); + + try { + Region region = clientCache.createClientRegionFactory(ClientRegionShortcut.CACHING_PROXY) + .create("region"); + region.registerInterestForAllKeys(InterestResultPolicy.KEYS, true); + fail(); + } catch (IllegalStateException e) { + assertEquals("Durable flag only applicable for durable clients.", e.getMessage()); + } + } + + @Test + public void durableClientRegisterInterestAllKeysWithDurableFlagShouldRegisterInterest() + throws Exception { + + ClientCache clientCache = createClientCache(locatorPort, true); + + Region region = + clientCache.createClientRegionFactory(ClientRegionShortcut.CACHING_PROXY).create("region"); + region.registerInterestForAllKeys(InterestResultPolicy.NONE, true); + clientCache.readyForEvents(); + + server.invoke(() -> { + Region regionOnServer = ClusterStartupRule.getCache().getRegion("region"); + regionOnServer.put("some key", "some value"); + regionOnServer.put(new ArrayList(), new ArrayList()); + regionOnServer.put(1, 2); + }); + + Awaitility.await().atMost(10, TimeUnit.SECONDS) + .until(() -> assertEquals(3, region.keySet().size())); + } + + @Test + public void durableClientRegisterInterestAllKeysAndReceiveValuesFalseShouldRegisterForAllKeys() + throws Exception { + + ClientCache clientCache = createClientCache(locatorPort, true); + + Region region = + clientCache.createClientRegionFactory(ClientRegionShortcut.CACHING_PROXY).create("region"); + region.registerInterestForAllKeys(InterestResultPolicy.NONE, true, false); + clientCache.readyForEvents(); + + server.invoke(() -> { + Region regionOnServer = ClusterStartupRule.getCache().getRegion("region"); + regionOnServer.put("some key", "some value"); + regionOnServer.put(new ArrayList(), new ArrayList()); + regionOnServer.put(1, 2); + }); + + Awaitility.await().atMost(10, TimeUnit.SECONDS) + .until(() -> assertEquals(3, region.keySet().size())); + } + + + @Test + public void registerInterestForKeysShouldRegisterInterestForEachObjectInTheIterable() + throws Exception { + + ClientCache clientCache = createClientCache(locatorPort); + + Set keysList = new HashSet(); + keysList.add("some key"); + keysList.add(1); + + Region region = + clientCache.createClientRegionFactory(ClientRegionShortcut.CACHING_PROXY).create("region"); + region.registerInterestForKeys(keysList); + + server.invoke(() -> { + Region regionOnServer = ClusterStartupRule.getCache().getRegion("region"); + regionOnServer.put("some key", "some value"); + regionOnServer.put(1, 2); + regionOnServer.put("should not be interested", "in this key/value"); + }); + + Awaitility.await().atMost(10, TimeUnit.SECONDS).until(() -> assertEquals(2, region.size())); + } + + @Test + public void registerInterestForKeysWithInterestPolicyShouldRegisterInterestForEachObjectInTheIterable() + throws Exception { + + ClientCache clientCache = createClientCache(locatorPort); + + Set keysList = new HashSet(); + keysList.add("some key"); + keysList.add(1); + + Region region = + clientCache.createClientRegionFactory(ClientRegionShortcut.CACHING_PROXY).create("region"); + region.registerInterestForKeys(keysList, InterestResultPolicy.KEYS); + + server.invoke(() -> { + Region regionOnServer = ClusterStartupRule.getCache().getRegion("region"); + regionOnServer.put("some key", "some value"); + regionOnServer.put(1, 2); + regionOnServer.put("should not be interested", "in this key/value"); + }); + + Awaitility.await().atMost(10, TimeUnit.SECONDS).until(() -> assertEquals(2, region.size())); + } + + @Test + public void registerInterestForKeysOnTypedRegionShouldRegisterInterestForEachObjectInIterable() + throws Exception { + ClientCache clientCache = createClientCache(locatorPort); + + Set<String> keysList = new HashSet<>(); + keysList.add("some key"); + keysList.add("other key"); + + Region<String, String> region = + clientCache.<String, String>createClientRegionFactory(ClientRegionShortcut.CACHING_PROXY) + .create("region"); + region.registerInterestForKeys(keysList); + + server.invoke(() -> { + Region regionOnServer = ClusterStartupRule.getCache().getRegion("region"); + regionOnServer.put("some key", "some value"); + regionOnServer.put("other key", "other value"); + regionOnServer.put("should not be interested", "in this key/value"); + }); + + Awaitility.await().atMost(10, TimeUnit.SECONDS).until(() -> assertEquals(2, region.size())); + } + + @Test + public void nonDurableClientWhenRegisterInterestForKeysShouldThrowException() throws Exception { + + ClientCache clientCache = createClientCache(locatorPort); + + Set keysList = new HashSet(); + keysList.add("some key"); + keysList.add(1); + + try { + Region region = clientCache.createClientRegionFactory(ClientRegionShortcut.CACHING_PROXY) + .create("region"); + region.registerInterestForKeys(keysList, InterestResultPolicy.KEYS, true); + fail(); + } catch (IllegalStateException e) { + assertEquals("Durable flag only applicable for durable clients.", e.getMessage()); + } + } + + @Test + public void durableClientWhenRegisterInterestForKeyShouldCorrectlyRegisterInterest() + throws Exception { + + ClientCache clientCache = createClientCache(locatorPort, true); + + Set keysList = new HashSet(); + keysList.add("some key"); + keysList.add(1); + + Region region = + clientCache.createClientRegionFactory(ClientRegionShortcut.CACHING_PROXY).create("region"); + region.registerInterestForKeys(keysList, InterestResultPolicy.KEYS, true); + clientCache.readyForEvents(); + + server.invoke(() -> { + Region regionOnServer = ClusterStartupRule.getCache().getRegion("region"); + regionOnServer.put("some key", "some value"); + regionOnServer.put(1, 2); + regionOnServer.put("should not be interested", "in this key/value"); + }); + + Awaitility.await().atMost(10, TimeUnit.SECONDS).until(() -> assertEquals(2, region.size())); + } + + @Test + public void durableClientWhenRegisterInterestForKeysAndReturnValueFalseShouldCorrectlyRegisterInterest() + throws Exception { + + ClientCache clientCache = createClientCache(locatorPort, true); + + Set keysList = new HashSet(); + keysList.add("some key"); + keysList.add(1); + + Region region = + clientCache.createClientRegionFactory(ClientRegionShortcut.CACHING_PROXY).create("region"); + region.registerInterestForKeys(keysList, InterestResultPolicy.KEYS, true, false); + clientCache.readyForEvents(); + + server.invoke(() -> { + Region regionOnServer = ClusterStartupRule.getCache().getRegion("region"); + regionOnServer.put("some key", "some value"); + regionOnServer.put(1, 2); + regionOnServer.put("should not be interested", "in this key/value"); + }); + + Awaitility.await().atMost(10, TimeUnit.SECONDS).until(() -> assertEquals(2, region.size())); + } + + @Test + public void readyForEventsBeforeAnyPoolsAreCreatedShouldResultInIllegalStateException() + throws Exception { + + ClientCache clientCache = createClientCache(locatorPort, true); + + try { + clientCache.readyForEvents(); + fail(); + } catch (IllegalStateException e) { + assertEquals("Ready for Events called, but no pool to execute on", e.getMessage()); + } + + } + + private ClientCache createClientCache(Integer locatorPort) { + return createClientCache(locatorPort, false); + } + + + private ClientCache createClientCache(Integer locatorPort, boolean isDurable) { + ClientCacheFactory ccf = null; + if (isDurable) { + Properties props = new Properties(); + props.setProperty("durable-client-id", "31"); + props.setProperty("durable-client-timeout", "" + 200); + ccf = new ClientCacheFactory(props); + } else { + ccf = new ClientCacheFactory(); + } + + ccf.addPoolLocator("localhost", locatorPort); + ccf.setPoolSubscriptionEnabled(true); + ClientCache cache = ccf.create(); + return cache; + } + + private void createServerRegion(MemberVM server, RegionShortcut regionShortcut) { + server.invoke(() -> { + Region regionOnServer = + ClusterStartupRule.getCache().createRegionFactory(regionShortcut).create("region"); + }); + } + + +} -- To stop receiving notification emails like this one, please contact jasonhu...@apache.org.