com.gemstone.gemfire.cache.client.internal.ClientMetadataService Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gemfire-core Show documentation
Show all versions of gemfire-core Show documentation
SnappyData store based off Pivotal GemFireXD
The newest version!
/*
* Copyright (c) 2010-2015 Pivotal Software, Inc. All rights reserved.
*
* Licensed 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. See accompanying
* LICENSE file.
*/
package com.gemstone.gemfire.cache.client.internal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;
import com.gemstone.gemfire.SystemFailure;
import com.gemstone.gemfire.cache.Cache;
import com.gemstone.gemfire.cache.EntryOperation;
import com.gemstone.gemfire.cache.FixedPartitionResolver;
import com.gemstone.gemfire.cache.Operation;
import com.gemstone.gemfire.cache.PartitionResolver;
import com.gemstone.gemfire.cache.Region;
import com.gemstone.gemfire.distributed.internal.ServerLocation;
import com.gemstone.gemfire.i18n.LogWriterI18n;
import com.gemstone.gemfire.internal.cache.BucketServerLocation66;
import com.gemstone.gemfire.internal.cache.EntryOperationImpl;
import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
import com.gemstone.gemfire.internal.cache.LocalRegion;
import com.gemstone.gemfire.internal.cache.PartitionedRegionHelper;
import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
/**
* Maintains {@link ClientPartitionAdvisor} for Partitioned Regions on servers
* Client operations will consult this service to identify the server locations
* on which the data for the client operation is residing
*
* @author Suranjan Kumar
* @author Yogesh Mahajan
*
* @since 6.5
*
*/
public final class ClientMetadataService {
private final LogWriterI18n logger;
private final Cache cache;
private final Set nonPRs = new HashSet();
private boolean HONOUR_SERVER_GROUP_IN_PR_SINGLE_HOP = Boolean.getBoolean("gemfire.PoolImpl.honourServerGroupsInPRSingleHop");
public static final int SIZE_BYTES_ARRAY_RECEIVED = 2;
public static final int INITIAL_VERSION = 0;
/** random number generator used in pruning */
private final Random rand = new Random();
public ClientMetadataService(Cache cache) {
this.cache = cache;
this.logger = ((GemFireCacheImpl)cache).getLoggerI18n();
}
private final Map clientPRAdvisors = new ConcurrentHashMap();
private final Map> colocatedPRAdvisors = new ConcurrentHashMap>();
private PartitionResolver getResolver(Region r, Object key,
Object callbackArgument) {
// First choice is one associated with the region
final String regionFullPath = r.getFullPath();
ClientPartitionAdvisor advisor = this
.getClientPartitionAdvisor(regionFullPath);
PartitionResolver result = null;
if (advisor != null) {
result = advisor.getPartitionResolver();
}
if (result != null) {
return result;
}
// Second is the key
if (key != null && key instanceof PartitionResolver) {
return (PartitionResolver)key;
}
// Third is the callback argument
if (callbackArgument != null
&& callbackArgument instanceof PartitionResolver) {
return (PartitionResolver)callbackArgument;
}
// There is no resolver.
return null;
}
public ServerLocation getBucketServerLocation(Region region,
Operation operation, Object key, Object value, Object callbackArg) {
ClientPartitionAdvisor prAdvisor = this.getClientPartitionAdvisor(region.getFullPath());
if (prAdvisor == null) {
return null;
}
int totalNumberOfBuckets = prAdvisor.getTotalNumBuckets();
final PartitionResolver resolver = getResolver(region, key, callbackArg);
Object resolveKey;
EntryOperation entryOp = null;
if (resolver == null) {
// client has not registered PartitionResolver
// Assuming even PR at server side is not using PartitionResolver
resolveKey = key;
}
else {
entryOp = new EntryOperationImpl(region, operation, key,
value, callbackArg);
resolveKey = resolver.getRoutingObject(entryOp);
if (resolveKey == null) {
throw new IllegalStateException(
LocalizedStrings.PartitionedRegionHelper_THE_ROUTINGOBJECT_RETURNED_BY_PARTITIONRESOLVER_IS_NULL
.toLocalizedString());
}
}
int bucketId;
if (resolver instanceof FixedPartitionResolver) {
if (entryOp == null) {
entryOp = new EntryOperationImpl(region,
Operation.FUNCTION_EXECUTION, key, null, null);
}
String partition = ((FixedPartitionResolver)resolver).getPartitionName(
entryOp, prAdvisor.getFixedPartitionNames());
if (partition == null) {
Object[] prms = new Object[] { region.getName(), resolver };
throw new IllegalStateException(
LocalizedStrings.PartitionedRegionHelper_FOR_REGION_0_PARTITIONRESOLVER_1_RETURNED_PARTITION_NAME_NULL
.toLocalizedString(prms));
}
else {
bucketId = prAdvisor.assignFixedBucketId(region, partition, resolveKey);
if (bucketId == -1) {
// scheduleGetPRMetaData((LocalRegion)region);
return null;
}
}
}else {
bucketId = PartitionedRegionHelper.getHashKey(resolveKey, totalNumberOfBuckets);
}
ServerLocation bucketServerLocation = getServerLocation(region, operation,
bucketId);
ServerLocation location = null;
if (bucketServerLocation != null)
location = new ServerLocation(bucketServerLocation.getHostName(),
bucketServerLocation.getPort());
return location;
}
private ServerLocation getServerLocation(Region region, Operation operation,
int bucketId) {
final String regionFullPath = region.getFullPath();
ClientPartitionAdvisor prAdvisor = this.getClientPartitionAdvisor(regionFullPath);
if (prAdvisor == null) {
if (this.logger.fineEnabled()) {
this.logger.fine(
"ClientMetadataService#getServerLocation : Region "
+ regionFullPath + "prAdvisor does not exist.");
}
return null;
}
// if (prAdvisor.getColocatedWith() != null) {
// prAdvisor = this.getClientPartitionAdvisor(prAdvisor.getColocatedWith());
// if (prAdvisor == null) {
// if (this.logger.fineEnabled()) {
// this.logger.fine(
// "ClientMetadataService#getServerLocation : Region "
// + regionFullPath + "prAdvisor does not exist.");
// }
// return null;
// }
// }
if (operation.isGet()) {
return prAdvisor.adviseServerLocation(bucketId);
}
else {
return prAdvisor.advisePrimaryServerLocation(bucketId);
}
}
public Map getServerToFilterMap(
final Collection routingKeys, final Region region, boolean primaryMembersNeeded) {
final String regionFullPath = region.getFullPath();
ClientPartitionAdvisor prAdvisor = this.getClientPartitionAdvisor(regionFullPath);
if (prAdvisor == null || prAdvisor.adviseRandomServerLocation() == null) {
scheduleGetPRMetaData((LocalRegion)region, false);
return null;
}
HashMap bucketToKeysMap = groupByBucketOnClientSide(
region, prAdvisor, routingKeys);
HashMap serverToKeysMap = new HashMap();
HashMap> serverToBuckets = groupByServerToBuckets(
prAdvisor, bucketToKeysMap.keySet(), primaryMembersNeeded);
if(serverToBuckets == null){
return null;
}
for (Map.Entry entry : serverToBuckets.entrySet()) {
ServerLocation server = (ServerLocation)entry.getKey();
HashSet buckets = (HashSet)entry.getValue();
for (Integer bucket : buckets) {
// use LinkedHashSet to maintain the order of keys
// the keys will be iterated several times
LinkedHashSet keys = (LinkedHashSet)serverToKeysMap.get(server);
if (keys == null) {
keys = new LinkedHashSet();
}
keys.addAll(bucketToKeysMap.get(bucket));
serverToKeysMap.put(server, keys);
}
}
if (this.logger.fineEnabled()) {
this.logger.fine("Returning server to keys map : " + serverToKeysMap);
}
return serverToKeysMap;
}
public HashMap> groupByServerToAllBuckets(Region region, boolean primaryOnly){
final String regionFullPath = region.getFullPath();
ClientPartitionAdvisor prAdvisor = this.getClientPartitionAdvisor(regionFullPath);
if (prAdvisor == null || prAdvisor.adviseRandomServerLocation() == null) {
scheduleGetPRMetaData((LocalRegion)region, false);
return null;
}
int totalNumberOfBuckets = prAdvisor.getTotalNumBuckets();
HashSet allBucketIds = new HashSet();
for(int i =0; i < totalNumberOfBuckets; i++){
allBucketIds.add(i);
}
return groupByServerToBuckets(prAdvisor, allBucketIds, primaryOnly);
}
/**
* This function should make a map of server to buckets it is hosting.
* If for some bucket servers are not available due to mismatch in metadata
* it should fill up a random server for it.
*/
private HashMap> groupByServerToBuckets(
ClientPartitionAdvisor prAdvisor, Set bucketSet,
boolean primaryOnly) {
if (primaryOnly) {
Set bucketsWithoutServer = new HashSet();
HashMap> serverToBucketsMap = new HashMap>();
for (Integer bucketId : bucketSet) {
ServerLocation server = prAdvisor.advisePrimaryServerLocation(bucketId);
if (server == null) {
bucketsWithoutServer.add(bucketId);
continue;
}
HashSet buckets = serverToBucketsMap.get(server);
if (buckets == null) {
buckets = new HashSet(); // faster if this was an ArrayList
serverToBucketsMap.put(server, buckets);
}
buckets.add(bucketId);
}
if (!serverToBucketsMap.isEmpty()) {
serverToBucketsMap.entrySet().iterator().next().getValue().addAll(
bucketsWithoutServer);
}
if (this.logger.fineEnabled()) {
this.logger
.fine("ClientMetadataService: The server to bucket map is : "
+ serverToBucketsMap);
}
return serverToBucketsMap;
}
else {
return pruneNodes(prAdvisor, bucketSet);
}
}
private HashMap> pruneNodes(
ClientPartitionAdvisor prAdvisor, Set buckets) {
if (this.logger.fineEnabled()) {
this.logger.fine("ClientMetadataService: The buckets to be pruned are: "
+ buckets);
}
Set bucketSetWithoutServer = new HashSet();
HashMap> serverToBucketsMap = new HashMap>();
HashMap> prunedServerToBucketsMap = new HashMap>();
for (Integer bucketId : buckets) {
List serversList = prAdvisor
.adviseServerLocations(bucketId);
if (this.logger.fineEnabled()) {
this.logger.fine("ClientMetadataService: For bucketId " + bucketId
+ " the server list is " + serversList);
}
if (serversList == null || serversList.size() == 0) {
bucketSetWithoutServer.add(bucketId);
continue;
}
if (this.logger.fineEnabled()) {
this.logger.fine("ClientMetadataService: The buckets owners of the bucket: "
+ bucketId + " are: " + serversList);
}
for (ServerLocation server : serversList) {
if (serverToBucketsMap.get(server) == null) {
HashSet bucketSet = new HashSet();
bucketSet.add(bucketId);
serverToBucketsMap.put(server, bucketSet);
}
else {
HashSet bucketSet = serverToBucketsMap.get(server);
bucketSet.add(bucketId);
serverToBucketsMap.put(server, bucketSet);
}
}
}
if (this.logger.fineEnabled()) {
this.logger.fine("ClientMetadataService: The server to buckets map is :"
+ serverToBucketsMap);
}
HashSet currentBucketSet = new HashSet();
// ServerLocation randomFirstServer =
// prAdvisor.adviseRandomServerLocation(); // get a random server here
ServerLocation randomFirstServer = null;
if (serverToBucketsMap.isEmpty()) {
return null;
}
else {
int size = serverToBucketsMap.size();
randomFirstServer = (ServerLocation)serverToBucketsMap.keySet().toArray()[rand.nextInt(size)];
}
HashSet bucketSet = serverToBucketsMap.get(randomFirstServer);
if (this.logger.fineEnabled()) {
this.logger.fine("ClientMetadataService: Adding the server :"
+ randomFirstServer + " which is random and buckets " + bucketSet
+ " to prunedMap ");
}
currentBucketSet.addAll(bucketSet);
prunedServerToBucketsMap.put(randomFirstServer, bucketSet);
serverToBucketsMap.remove(randomFirstServer);
while (!currentBucketSet.equals(buckets)) {
ServerLocation server = findNextServer(serverToBucketsMap.entrySet(),
currentBucketSet);
if (server == null) {
// HashSet rBuckets = prunedServerToBucketsMap
// .get(randomFirstServer);
// HashSet remainingBuckets = new HashSet(buckets);
// remainingBuckets.removeAll(currentBucketSet);
// rBuckets.addAll(remainingBuckets);
// prunedServerToBucketsMap.put(randomFirstServer, rBuckets);
break;
}
HashSet bucketSet2 = serverToBucketsMap.get(server);
bucketSet2.removeAll(currentBucketSet);
if(bucketSet2.isEmpty()) {
serverToBucketsMap.remove(server);
continue;
}
currentBucketSet.addAll(bucketSet2);
prunedServerToBucketsMap.put(server, bucketSet2);
if (this.logger.fineEnabled()) {
this.logger.fine("ClientMetadataService: Adding the server :" + server
+ " and buckets " + bucketSet2 + " to prunedServer ");
}
serverToBucketsMap.remove(server);
}
prunedServerToBucketsMap.entrySet().iterator().next().getValue().addAll(
bucketSetWithoutServer);
if (this.logger.fineEnabled()) {
this.logger
.fine("ClientMetadataService: The final prunedServerToBucket calculated is :"
+ prunedServerToBucketsMap);
}
return prunedServerToBucketsMap;
}
private ServerLocation findNextServer(
Set>> entrySet,
HashSet currentBucketSet) {
ServerLocation server = null;
int max = -1;
ArrayList nodesOfEqualSize = new ArrayList();
for (Map.Entry> entry : entrySet) {
HashSet buckets = new HashSet();
buckets.addAll(entry.getValue());
buckets.removeAll(currentBucketSet);
if (max < buckets.size()) {
max = buckets.size();
server = entry.getKey();
nodesOfEqualSize.clear();
nodesOfEqualSize.add(server);
}
else if (max == buckets.size()){
nodesOfEqualSize.add(server);
}
}
//return node;
Random r = new Random();
if(nodesOfEqualSize.size() > 0)
return nodesOfEqualSize.get(r.nextInt(nodesOfEqualSize.size()));
return null;
}
private HashMap groupByBucketOnClientSide(Region region,
ClientPartitionAdvisor prAdvisor, Collection routingKeys) {
HashMap bucketToKeysMap = new HashMap();
Iterator i = routingKeys.iterator();
while (i.hasNext()) {
Object key = i.next();
int totalNumberOfBuckets = prAdvisor.getTotalNumBuckets();
final PartitionResolver resolver = getResolver(region, key, null);
Object resolveKey;
EntryOperation entryOp = null;
if (resolver == null) {
// client has not registered PartitionResolver
// Assuming even PR at server side is not using PartitionResolver
resolveKey = key;
}
else {
entryOp = new EntryOperationImpl(region,
Operation.FUNCTION_EXECUTION, key, null, null);
resolveKey = resolver.getRoutingObject(entryOp);
if (resolveKey == null) {
throw new IllegalStateException(
LocalizedStrings.PartitionedRegionHelper_THE_ROUTINGOBJECT_RETURNED_BY_PARTITIONRESOLVER_IS_NULL
.toLocalizedString());
}
}
int bucketId;
if (resolver instanceof FixedPartitionResolver) {
if (entryOp == null) {
entryOp = new EntryOperationImpl(region,
Operation.FUNCTION_EXECUTION, key, null, null);
}
String partition = ((FixedPartitionResolver)resolver).getPartitionName(
entryOp, prAdvisor.getFixedPartitionNames());
if (partition == null) {
Object[] prms = new Object[] { region.getName(), resolver };
throw new IllegalStateException(
LocalizedStrings.PartitionedRegionHelper_FOR_REGION_0_PARTITIONRESOLVER_1_RETURNED_PARTITION_NAME_NULL
.toLocalizedString(prms));
}
else {
bucketId = prAdvisor.assignFixedBucketId(region, partition, resolveKey);
// This bucketid can be -1 in some circumstances where we don't have information about
// all the partition on the server.
// Do proactive scheduling of metadata fetch
if(bucketId == -1) {
scheduleGetPRMetaData((LocalRegion)region, true);
}
}
}else{
bucketId = PartitionedRegionHelper.getHashKey(resolveKey, totalNumberOfBuckets);
}
HashSet bucketKeys = bucketToKeysMap.get(bucketId);
if (bucketKeys == null) {
bucketKeys = new HashSet(); // faster if this was an ArrayList
bucketToKeysMap.put(bucketId, bucketKeys);
}
bucketKeys.add(key);
}
if (this.logger.fineEnabled()) {
this.logger.fine("Bucket to keys map : " + bucketToKeysMap);
}
return bucketToKeysMap;
}
public void scheduleGetPRMetaData(final LocalRegion region,
final boolean isRecursive) {
if(this.nonPRs.contains(region.getFullPath())){
return;
}
region.getCachePerfStats().incNonSingleHopsCount();
if (isRecursive) {
try {
getClientPRMetadata(region);
}
catch (VirtualMachineError e) {
SystemFailure.initiateFailure(e);
throw e;
}
catch (Throwable e) {
SystemFailure.checkFailure();
if (logger.fineEnabled()) {
logger.fine("An exception occurred while fetching metadata ", e);
}
}
}
else {
Runnable fetchTask = new Runnable() {
@SuppressWarnings("synthetic-access")
public void run() {
try {
getClientPRMetadata(region);
}
catch (VirtualMachineError e) {
SystemFailure.initiateFailure(e);
throw e;
}
catch (Throwable e) {
SystemFailure.checkFailure();
if (logger.fineEnabled()) {
logger.fine("An exception occurred while fetching metadata", e);
}
}
}
};
SingleHopClientExecutor.submitTask(fetchTask);
}
}
public final void getClientPRMetadata(LocalRegion region) {
isMetadataRefreshed_TEST_ONLY = true;
final String regionFullPath = region.getFullPath();
ClientPartitionAdvisor advisor = null;
InternalPool pool = region.getServerProxy().getPool();
// Acquires lock only if it is free, else a request to fetch meta data is in
// progress, so just return
if (region.clientMetaDataLock.tryLock()) {
try {
advisor = this.getClientPartitionAdvisor(regionFullPath);
if (advisor==null) {
advisor = GetClientPartitionAttributesOp
.execute(pool, regionFullPath);
if(advisor == null){
this.nonPRs.add(regionFullPath);
return;
}
addClientPartitionAdvisor(regionFullPath, advisor);
}
else {
if(advisor.getFixedPAMap() != null && !advisor.isFPAAttrsComplete()) {
ClientPartitionAdvisor newAdvisor = GetClientPartitionAttributesOp
.execute(pool, regionFullPath);
advisor.updateFixedPAMap(newAdvisor.getFixedPAMap());
}
}
String colocatedWith = advisor.getColocatedWith();
if (colocatedWith == null) {
GetClientPRMetaDataOp.execute(pool, regionFullPath, this);
region.getCachePerfStats().incMetaDataRefreshCount();
}
else {
ClientPartitionAdvisor colocatedAdvisor = this.getClientPartitionAdvisor(colocatedWith);
LocalRegion leaderRegion = (LocalRegion)region.getCache()
.getRegion(colocatedWith);
if (colocatedAdvisor == null) {
scheduleGetPRMetaData(leaderRegion, true);
return;
}
else {
GetClientPRMetaDataOp.execute(pool, colocatedWith, this);
leaderRegion.getCachePerfStats().incMetaDataRefreshCount();
}
}
}
finally {
region.clientMetaDataLock.unlock();
}
}
}
public void scheduleGetPRMetaData(final LocalRegion region,
final boolean isRecursive, byte nwHopType) {
if(this.nonPRs.contains(region.getFullPath())){
return;
}
ClientPartitionAdvisor advisor = this.getClientPartitionAdvisor(region.getFullPath());
if(advisor!= null && advisor.getServerGroup().length()!= 0 && HONOUR_SERVER_GROUP_IN_PR_SINGLE_HOP){
if (logger.fineEnabled()) {
logger.fine("Scheduling metadata refresh :" + nwHopType);
}
if(nwHopType == (byte)2){
return;
}
}
region.getCachePerfStats().incNonSingleHopsCount();
if (isRecursive) {
try {
getClientPRMetadata(region);
} catch (VirtualMachineError e) {
SystemFailure.initiateFailure(e);
throw e;
} catch (Throwable e) {
SystemFailure.checkFailure();
if (logger.fineEnabled()) {
logger.fine("An exception occurred while fetching metadata", e);
}
}
} else {
Runnable fetchTask = new Runnable() {
@SuppressWarnings("synthetic-access")
public void run() {
try {
getClientPRMetadata(region);
} catch (VirtualMachineError e) {
SystemFailure.initiateFailure(e);
throw e;
} catch (Throwable e) {
SystemFailure.checkFailure();
if (logger.fineEnabled()) {
logger
.fine("An exception occurred while fetching metadata", e);
}
}
}
};
SingleHopClientExecutor.submitTask(fetchTask);
}
}
public void removeBucketServerLocation(ServerLocation serverLocation) {
Set keys = getAllRegionFullPaths();
if (logger.fineEnabled()) {
logger.fine("ClientMetadataService removing a ServerLocation :"
+ serverLocation + keys);
}
if (keys != null) {
for (String regionPath : keys) {
ClientPartitionAdvisor prAdvisor = this
.getClientPartitionAdvisor(regionPath);
if (logger.fineEnabled()) {
logger.fine("ClientMetadataService removing from "
+ regionPath + prAdvisor);
}
if (prAdvisor != null) {
prAdvisor.removeBucketServerLocation(serverLocation);
}
}
}
}
public byte getMetaDataVersion(Region region, Operation operation,
Object key, Object value, Object callbackArg) {
ClientPartitionAdvisor prAdvisor = this.getClientPartitionAdvisor(region
.getFullPath());
if (prAdvisor == null) {
return 0;
}
int totalNumberOfBuckets = prAdvisor.getTotalNumBuckets();
final PartitionResolver resolver = getResolver(region, key, callbackArg);
Object resolveKey;
EntryOperation entryOp = null;
if (resolver == null) {
// client has not registered PartitionResolver
// Assuming even PR at server side is not using PartitionResolver
resolveKey = key;
}
else {
entryOp = new EntryOperationImpl(region, operation, key,
value, callbackArg);
resolveKey = resolver.getRoutingObject(entryOp);
if (resolveKey == null) {
throw new IllegalStateException(
LocalizedStrings.PartitionedRegionHelper_THE_ROUTINGOBJECT_RETURNED_BY_PARTITIONRESOLVER_IS_NULL
.toLocalizedString());
}
}
int bucketId;
if (resolver instanceof FixedPartitionResolver) {
if (entryOp == null) {
entryOp = new EntryOperationImpl(region,
Operation.FUNCTION_EXECUTION, key, null, null);
}
String partition = ((FixedPartitionResolver)resolver).getPartitionName(
entryOp, prAdvisor.getFixedPartitionNames());
if (partition == null) {
Object[] prms = new Object[] { region.getName(), resolver };
throw new IllegalStateException(
LocalizedStrings.PartitionedRegionHelper_FOR_REGION_0_PARTITIONRESOLVER_1_RETURNED_PARTITION_NAME_NULL
.toLocalizedString(prms));
}
else {
bucketId = prAdvisor.assignFixedBucketId(region, partition, resolveKey);
}
}else {
bucketId = PartitionedRegionHelper.getHashKey(resolveKey, totalNumberOfBuckets);
}
BucketServerLocation66 bsl = (BucketServerLocation66)getPrimaryServerLocation(
region, bucketId);
if (bsl == null) {
return 0;
}
return bsl.getVersion();
}
private ServerLocation getPrimaryServerLocation(Region region, int bucketId) {
final String regionFullPath = region.getFullPath();
ClientPartitionAdvisor prAdvisor = this.getClientPartitionAdvisor(regionFullPath);
if (prAdvisor == null) {
if (this.logger.fineEnabled()) {
this.logger.fine("ClientMetadataService#getServerLocation : Region "
+ regionFullPath + " prAdvisor does not exist.");
}
return null;
}
if (prAdvisor.getColocatedWith() != null) {
prAdvisor = this.getClientPartitionAdvisor(prAdvisor.getColocatedWith());
if (prAdvisor == null) {
if (this.logger.fineEnabled()) {
this.logger.fine("ClientMetadataService#getServerLocation : Region "
+ regionFullPath + " prAdvisor does not exist.");
}
return null;
}
}
return prAdvisor.advisePrimaryServerLocation(bucketId);
}
private void addClientPartitionAdvisor(String regionFullPath,
ClientPartitionAdvisor advisor) {
if (this.cache.isClosed() || this.clientPRAdvisors == null) {
return;
}
try {
this.clientPRAdvisors.put(regionFullPath, advisor);
if (advisor.getColocatedWith() != null) {
String parentRegionPath = advisor.getColocatedWith();
Set colocatedAdvisors = this.colocatedPRAdvisors.get(parentRegionPath);
if(colocatedAdvisors == null){
colocatedAdvisors = new CopyOnWriteArraySet();
this.colocatedPRAdvisors.put(parentRegionPath, colocatedAdvisors);
}
colocatedAdvisors.add(advisor);
}
}
catch (Exception npe) {
// ignore, shutdown case
}
}
public ClientPartitionAdvisor getClientPartitionAdvisor(String regionFullPath) {
if (this.cache.isClosed() || this.clientPRAdvisors == null) {
return null;
}
ClientPartitionAdvisor prAdvisor = null;
try {
prAdvisor = this.clientPRAdvisors.get(regionFullPath);
}
catch (Exception npe) {
return null;
}
return prAdvisor;
}
public Set getColocatedClientPartitionAdvisor(String regionFullPath) {
if (this.cache.isClosed() || this.clientPRAdvisors == null || this.colocatedPRAdvisors == null) {
return null;
}
return this.colocatedPRAdvisors.get(regionFullPath);
}
private Set getAllRegionFullPaths() {
if (this.cache.isClosed() || this.clientPRAdvisors == null) {
return null;
}
Set keys = null;
try {
keys = this.clientPRAdvisors.keySet();
}
catch (Exception npe) {
return null;
}
return keys;
}
public void close() {
this.clientPRAdvisors.clear();
this.colocatedPRAdvisors.clear();
}
public boolean isRefreshMetadataTestOnly() {
return isMetadataRefreshed_TEST_ONLY;
}
public void satisfyRefreshMetadata_TEST_ONLY(boolean isRefreshMetadataTestOnly) {
isMetadataRefreshed_TEST_ONLY = isRefreshMetadataTestOnly;
}
public Map getClientPRMetadata_TEST_ONLY() {
return clientPRAdvisors;
}
public Map getClientPartitionAttributesMap() {
return clientPRAdvisors;
}
public boolean honourServerGroup(){
return HONOUR_SERVER_GROUP_IN_PR_SINGLE_HOP;
}
private boolean isMetadataRefreshed_TEST_ONLY = false;
}