Adapt CacheUtils to identify client LOCAL Regions when collecting (getting) all values from the Region in collectValues(:Region).

Add new isProxyRegion(:Region) method to safely determine if the Region is a PROXY.

Add new isRegionWithPool(:Region) method to safely determine if the Region has been configured with a Pool, imply the Region is owned by a client (i.e. ClientCache).

Edit Javadoc.
This commit is contained in:
John Blum
2020-06-08 12:22:49 -07:00
parent 80c34d2198
commit 6fbc40daa8
2 changed files with 292 additions and 13 deletions

View File

@@ -24,10 +24,12 @@ import java.util.Optional;
import java.util.Set;
import org.apache.geode.cache.Cache;
import org.apache.geode.cache.DataPolicy;
import org.apache.geode.cache.Region;
import org.apache.geode.cache.RegionAttributes;
import org.apache.geode.cache.RegionService;
import org.apache.geode.cache.client.ClientCache;
import org.apache.geode.cache.client.Pool;
import org.apache.geode.internal.cache.GemFireCacheImpl;
/**
@@ -36,9 +38,12 @@ import org.apache.geode.internal.cache.GemFireCacheImpl;
*
* @author John Blum
* @see org.apache.geode.cache.Cache
* @see org.apache.geode.cache.DataPolicy
* @see org.apache.geode.cache.Region
* @see org.apache.geode.cache.RegionAttributes
* @see org.apache.geode.cache.RegionService
* @see org.apache.geode.cache.client.ClientCache
* @see org.apache.geode.cache.client.Pool
* @since 1.3.0
*/
public abstract class CacheUtils {
@@ -63,25 +68,72 @@ public abstract class CacheUtils {
return isClientRegion(region)
? clientRegionValues(region)
: region.values();
: localRegionValues(region);
}
/**
* Collects values from the given {@literal client} {@link Region}.
*
* @param <T> {@link Class type} of the {@link Region Region's} values.
* @param region {@link Region} from which to collect values.
* @return a {@link Collection} of the {@literal client} {@link Region Region's} values.
* @see org.apache.geode.cache.Region
* @see #clientRegionValuesFromServer(Region)
* @see #localRegionValues(Region)
* @see #isProxyRegion(Region)
*/
private static <T> Collection<T> clientRegionValues(Region<?, T> region) {
return isProxyRegion(region)
? clientRegionValuesFromServer(region)
: localRegionValues(region);
}
/**
* Collections all values from the {@literal client} {@link Region} by pulling the values down from the server.
*
* @param <T> {@link Class type} of the {@link Region Region's} values.
* @param region {@link Region} from which to collect values.
* @return a {@link Collection} containing the values from the {@literal client} {@link Region} on the server.
* @see org.apache.geode.cache.Region#keySetOnServer()
* @see #getAll(Region, Set)
*/
private static <T> Collection<T> clientRegionValuesFromServer(Region<?, T> region) {
Set<?> keys = nullSafeSet(region.keySetOnServer());
return !keys.isEmpty() ? getAll(keys, region) : Collections.emptySet();
return !keys.isEmpty() ? getAll(region, keys) : Collections.emptySet();
}
private static <T> Collection<T> getAll(Set<?> keys, Region<?, T> region) {
/**
* Gets all values from the given {@link Region} mapped to the specified {@link Set keys}.
*
* @param <T> {@link Class type} of the {@link Region Region's} values.
* @param region {@link Region} from which to get all values.
* @param keys {@link Set} of keys targeting the values to retrieve.
* @return a {@link Collection} of the {@link Region Region's} values.
* @see org.apache.geode.cache.Region#getAll(Collection)
*/
private static <T> Collection<T> getAll(Region<?, T> region, Set<?> keys) {
return nullSafeMap(region.getAll(keys)).values();
// Fallback procedure if region.getAll(keys) is buggered
//return keys.stream().map(region::get).collect(Collectors.toSet());
}
/**
* Collects values from the given {@link Region}, locally.
*
* @param <T> {@link Class type} of the {@link Region Region's} values.
* @param region {@link Region} from which to collect values.
* @return a {@link Collection} of the {@link Region Region's} values.
* @see org.apache.geode.cache.Region#values()
*/
private static <T> Collection<T> localRegionValues(Region<?, T> region) {
return region.values();
}
private static boolean hasText(String value) {
return !(value == null || value.trim().isEmpty());
return value != null && !value.trim().isEmpty();
}
private static <K, V> Map<K, V> nullSafeMap(Map<K, V> map) {
@@ -125,11 +177,8 @@ public abstract class CacheUtils {
*/
public static boolean isClientRegion(Region<?, ?> region) {
return region != null && (isClientCache(region.getRegionService())
|| Optional.ofNullable(region.getAttributes())
.map(RegionAttributes::getPoolName)
.filter(CacheUtils::hasText)
.isPresent());
return region != null
&& (isClientCache(region.getRegionService()) || isRegionWithPool(region));
}
/**
@@ -168,4 +217,43 @@ public abstract class CacheUtils {
public static boolean isPeerRegion(Region<?, ?> region) {
return region != null && !isClientRegion(region);
}
/**
* Null-safe method to determine whether the given {@link Region} is a [client] {@literal PROXY} {@link Region}.
*
* The {@link Region} is a {@literal PROXY} if the {@link DataPolicy} is {@link DataPolicy#EMPTY}
* or the {@link Region} has a configured {@link Pool}.
*
* @param region {@link Region} to evaluate.
* @return a boolean value to determine whether the {@link Region} is a [client] {@literal PROXY} {@link Region}.
* @see org.apache.geode.cache.Region
* @see #isRegionWithPool(Region)
*/
public static boolean isProxyRegion(Region<?, ?> region) {
return region != null
&& region.getAttributes() != null
&& (DataPolicy.EMPTY.equals(region.getAttributes().getDataPolicy())
|| isRegionWithPool(region));
}
/**
* Null-safe method to determine whether the given {@link Region} was configured with a {@link Pool}.
*
* A {@link Region} configured with a {@link Pool} (by {@link String name} specified in the {@link RegionAttributes})
* is a strong indicator that the {@link Region} is a {@literal client} {@link Region}.
*
* @param region {@link Region} to evaluate.
* @return a boolean to determine whether the given {@link Region} was configured with a {@link Pool}.
* @see org.apache.geode.cache.client.Pool
* @see org.apache.geode.cache.Region
*/
public static boolean isRegionWithPool(Region<?, ?> region) {
return Optional.ofNullable(region)
.map(Region::getAttributes)
.map(RegionAttributes::getPoolName)
.filter(CacheUtils::hasText)
.isPresent();
}
}