| /* |
| * 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.management.internal.cli.functions; |
| |
| import java.io.IOException; |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| |
| import com.fasterxml.jackson.core.JsonProcessingException; |
| import com.fasterxml.jackson.databind.ObjectMapper; |
| import org.apache.commons.lang3.StringUtils; |
| import org.apache.logging.log4j.Logger; |
| |
| import org.apache.geode.cache.DataPolicy; |
| import org.apache.geode.cache.Region; |
| import org.apache.geode.cache.execute.FunctionContext; |
| import org.apache.geode.cache.partition.PartitionRegionHelper; |
| import org.apache.geode.cache.query.FunctionDomainException; |
| import org.apache.geode.cache.query.NameResolutionException; |
| import org.apache.geode.cache.query.Query; |
| import org.apache.geode.cache.query.QueryInvocationTargetException; |
| import org.apache.geode.cache.query.QueryService; |
| import org.apache.geode.cache.query.SelectResults; |
| import org.apache.geode.cache.query.Struct; |
| import org.apache.geode.cache.query.TypeMismatchException; |
| import org.apache.geode.cache.query.internal.DefaultQuery; |
| import org.apache.geode.cache.query.internal.IndexTrackingQueryObserver; |
| import org.apache.geode.cache.query.internal.QueryObserver; |
| import org.apache.geode.cache.query.internal.QueryObserverHolder; |
| import org.apache.geode.distributed.DistributedMember; |
| import org.apache.geode.internal.ClassPathLoader; |
| import org.apache.geode.internal.NanoTimer; |
| import org.apache.geode.internal.cache.InternalCache; |
| import org.apache.geode.internal.cache.PartitionedRegion; |
| import org.apache.geode.internal.cache.execute.InternalFunction; |
| import org.apache.geode.internal.security.SecurityService; |
| import org.apache.geode.logging.internal.log4j.api.LogService; |
| import org.apache.geode.management.internal.cli.domain.DataCommandRequest; |
| import org.apache.geode.management.internal.cli.domain.DataCommandResult; |
| import org.apache.geode.management.internal.cli.domain.DataCommandResult.SelectResultRow; |
| import org.apache.geode.management.internal.cli.i18n.CliStrings; |
| import org.apache.geode.management.internal.cli.util.JsonUtil; |
| import org.apache.geode.pdx.JSONFormatter; |
| import org.apache.geode.pdx.PdxInstance; |
| import org.apache.geode.util.internal.GeodeJsonMapper; |
| |
| /** |
| * @since GemFire 7.0 |
| */ |
| public class DataCommandFunction implements InternalFunction { |
| private static final Logger logger = LogService.getLogger(); |
| |
| private static final long serialVersionUID = 1L; |
| |
| private boolean optimizeForWrite = false; |
| |
| private static final int NESTED_JSON_LENGTH = 20; |
| |
| @Override |
| public String getId() { |
| return DataCommandFunction.class.getName(); |
| } |
| |
| @Override |
| public boolean hasResult() { |
| return true; |
| } |
| |
| @Override |
| |
| public boolean isHA() { |
| return false; |
| } |
| |
| /** |
| * Read only function |
| */ |
| @Override |
| public boolean optimizeForWrite() { |
| return optimizeForWrite; |
| } |
| |
| public void setOptimizeForWrite(boolean optimizeForWrite) { |
| this.optimizeForWrite = optimizeForWrite; |
| } |
| |
| @Override |
| public void execute(FunctionContext functionContext) { |
| try { |
| InternalCache cache = |
| ((InternalCache) functionContext.getCache()).getCacheForProcessingClientRequests(); |
| DataCommandRequest request = (DataCommandRequest) functionContext.getArguments(); |
| if (logger.isDebugEnabled()) { |
| logger.debug("Executing function : \n{}\n on member {}", request, |
| System.getProperty("memberName")); |
| } |
| DataCommandResult result = null; |
| if (request.isGet()) { |
| result = get(request, cache); |
| } else if (request.isLocateEntry()) { |
| result = locateEntry(request, cache); |
| } else if (request.isPut()) { |
| result = put(request, cache); |
| } else if (request.isRemove()) { |
| result = remove(request, cache); |
| } else if (request.isSelect()) { |
| result = select(request, cache); |
| } |
| if (logger.isDebugEnabled()) { |
| logger.debug("Result is {}", result); |
| } |
| functionContext.getResultSender().lastResult(result); |
| } catch (Exception e) { |
| logger.info("Exception occurred:", e); |
| functionContext.getResultSender().sendException(e); |
| } |
| } |
| |
| public DataCommandResult remove(DataCommandRequest request, InternalCache cache) { |
| String key = request.getKey(); |
| String keyClass = request.getKeyClass(); |
| String regionName = request.getRegionName(); |
| String removeAllKeys = request.getRemoveAllKeys(); |
| return remove(key, keyClass, regionName, removeAllKeys, cache); |
| } |
| |
| public DataCommandResult get(DataCommandRequest request, InternalCache cache) { |
| String key = request.getKey(); |
| String keyClass = request.getKeyClass(); |
| String valueClass = request.getValueClass(); |
| String regionName = request.getRegionName(); |
| Boolean loadOnCacheMiss = request.isLoadOnCacheMiss(); |
| return get(request.getPrincipal(), key, keyClass, valueClass, regionName, loadOnCacheMiss, |
| cache); |
| } |
| |
| public DataCommandResult locateEntry(DataCommandRequest request, InternalCache cache) { |
| String key = request.getKey(); |
| String keyClass = request.getKeyClass(); |
| String valueClass = request.getValueClass(); |
| String regionName = request.getRegionName(); |
| boolean recursive = request.isRecursive(); |
| return locateEntry(key, keyClass, valueClass, regionName, recursive, cache); |
| } |
| |
| public DataCommandResult put(DataCommandRequest request, InternalCache cache) { |
| String key = request.getKey(); |
| String value = request.getValue(); |
| boolean putIfAbsent = request.isPutIfAbsent(); |
| String keyClass = request.getKeyClass(); |
| String valueClass = request.getValueClass(); |
| String regionName = request.getRegionName(); |
| return put(key, value, putIfAbsent, keyClass, valueClass, regionName, cache); |
| } |
| |
| public DataCommandResult select(DataCommandRequest request, InternalCache cache) { |
| String query = request.getQuery(); |
| return select(cache, request.getPrincipal(), query); |
| } |
| |
| /** |
| * To catch trace output |
| */ |
| public static class WrappedIndexTrackingQueryObserver extends IndexTrackingQueryObserver { |
| |
| @Override |
| public void reset() { |
| // NOOP |
| } |
| |
| public void reset2() { |
| super.reset(); |
| } |
| } |
| |
| @SuppressWarnings("rawtypes") |
| private DataCommandResult select(InternalCache cache, Object principal, String queryString) { |
| |
| if (StringUtils.isEmpty(queryString)) { |
| return DataCommandResult.createSelectInfoResult(null, null, -1, null, |
| CliStrings.QUERY__MSG__QUERY_EMPTY, false); |
| } |
| |
| QueryService qs = cache.getQueryService(); |
| |
| Query query = qs.newQuery(queryString); |
| DefaultQuery tracedQuery = (DefaultQuery) query; |
| WrappedIndexTrackingQueryObserver queryObserver = null; |
| String queryVerboseMsg = null; |
| long startTime = -1; |
| if (tracedQuery.isTraced()) { |
| startTime = NanoTimer.getTime(); |
| queryObserver = new WrappedIndexTrackingQueryObserver(); |
| QueryObserverHolder.setInstance(queryObserver); |
| } |
| List<SelectResultRow> list = new ArrayList<>(); |
| |
| try { |
| Object results = query.execute(); |
| if (tracedQuery.isTraced()) { |
| queryVerboseMsg = getLogMessage(queryObserver, startTime, queryString); |
| queryObserver.reset2(); |
| } |
| if (results instanceof SelectResults) { |
| select_SelectResults((SelectResults) results, principal, list, cache); |
| } else { |
| select_NonSelectResults(results, list); |
| } |
| return DataCommandResult.createSelectResult(queryString, list, queryVerboseMsg, null, null, |
| true); |
| |
| } catch (FunctionDomainException | QueryInvocationTargetException | NameResolutionException |
| | TypeMismatchException e) { |
| logger.warn(e.getMessage(), e); |
| return DataCommandResult.createSelectResult(queryString, null, queryVerboseMsg, e, |
| e.getMessage(), false); |
| } finally { |
| if (queryObserver != null) { |
| QueryObserverHolder.reset(); |
| } |
| } |
| } |
| |
| private void select_NonSelectResults(Object results, List<SelectResultRow> list) { |
| if (logger.isDebugEnabled()) { |
| logger.debug("BeanResults : Bean Results class is {}", results.getClass()); |
| } |
| list.add(createSelectResultRow(results)); |
| } |
| |
| private void select_SelectResults(SelectResults selectResults, Object principal, |
| List<SelectResultRow> list, InternalCache cache) { |
| for (Object object : selectResults) { |
| // Post processing |
| object = cache.getSecurityService().postProcess(principal, null, null, object, false); |
| |
| list.add(createSelectResultRow(object)); |
| } |
| } |
| |
| private SelectResultRow createSelectResultRow(Object object) { |
| int rowType; |
| if (object instanceof Struct) { |
| rowType = DataCommandResult.ROW_TYPE_STRUCT_RESULT; |
| } else if (JsonUtil.isPrimitiveOrWrapper(object.getClass())) { |
| rowType = DataCommandResult.ROW_TYPE_PRIMITIVE; |
| } else { |
| rowType = DataCommandResult.ROW_TYPE_BEAN; |
| } |
| |
| return new SelectResultRow(rowType, object); |
| } |
| |
| @SuppressWarnings({"rawtypes"}) |
| public DataCommandResult remove(String key, String keyClass, String regionName, |
| String removeAllKeys, InternalCache cache) { |
| |
| if (StringUtils.isEmpty(regionName)) { |
| return DataCommandResult.createRemoveResult(key, null, null, |
| CliStrings.REMOVE__MSG__REGIONNAME_EMPTY, false); |
| } |
| |
| if (StringUtils.isEmpty(removeAllKeys) && (key == null)) { |
| return DataCommandResult.createRemoveResult(null, null, null, |
| CliStrings.REMOVE__MSG__KEY_EMPTY, false); |
| } |
| |
| Region region = cache.getRegion(regionName); |
| if (region == null) { |
| return DataCommandResult.createRemoveInfoResult(key, null, null, |
| CliStrings.format(CliStrings.REMOVE__MSG__REGION_NOT_FOUND, regionName), false); |
| } else { |
| if (removeAllKeys == null) { |
| Object keyObject; |
| try { |
| keyObject = getClassObject(key, keyClass); |
| } catch (ClassNotFoundException e) { |
| return DataCommandResult.createRemoveResult(key, null, null, |
| "ClassNotFoundException " + keyClass, false); |
| } catch (IllegalArgumentException e) { |
| return DataCommandResult.createRemoveResult(key, null, null, |
| "Error in converting JSON " + e.getMessage(), false); |
| } |
| |
| if (region.containsKey(keyObject)) { |
| Object value = region.remove(keyObject); |
| if (logger.isDebugEnabled()) { |
| logger.debug("Removed key {} successfully", key); |
| } |
| Object array[] = getClassAndJson(value); |
| DataCommandResult result = |
| DataCommandResult.createRemoveResult(key, array[1], null, null, true); |
| if (array[0] != null) { |
| result.setValueClass((String) array[0]); |
| } |
| return result; |
| } else { |
| return DataCommandResult.createRemoveInfoResult(key, null, null, |
| CliStrings.REMOVE__MSG__KEY_NOT_FOUND_REGION, false); |
| } |
| } else { |
| DataPolicy policy = region.getAttributes().getDataPolicy(); |
| if (!policy.withPartitioning()) { |
| region.clear(); |
| if (logger.isDebugEnabled()) { |
| logger.debug("Cleared all keys in the region - {}", regionName); |
| } |
| return DataCommandResult.createRemoveInfoResult(key, null, null, |
| CliStrings.format(CliStrings.REMOVE__MSG__CLEARED_ALL_CLEARS, regionName), true); |
| } else { |
| return DataCommandResult.createRemoveInfoResult(key, null, null, |
| CliStrings.REMOVE__MSG__CLEARALL_NOT_SUPPORTED_FOR_PARTITIONREGION, false); |
| } |
| } |
| } |
| } |
| |
| @SuppressWarnings({"rawtypes"}) |
| public DataCommandResult get(Object principal, String key, String keyClass, String valueClass, |
| String regionName, Boolean loadOnCacheMiss, InternalCache cache) { |
| |
| SecurityService securityService = cache.getSecurityService(); |
| |
| if (StringUtils.isEmpty(regionName)) { |
| return DataCommandResult.createGetResult(key, null, null, |
| CliStrings.GET__MSG__REGIONNAME_EMPTY, false); |
| } |
| |
| if (StringUtils.isEmpty(key)) { |
| return DataCommandResult.createGetResult(key, null, null, CliStrings.GET__MSG__KEY_EMPTY, |
| false); |
| } |
| |
| Region region = cache.getRegion(regionName); |
| |
| if (region == null) { |
| if (logger.isDebugEnabled()) { |
| logger.debug("Region Not Found - {}", regionName); |
| } |
| return DataCommandResult.createGetResult(key, null, null, |
| CliStrings.format(CliStrings.GET__MSG__REGION_NOT_FOUND, regionName), false); |
| } else { |
| Object keyObject; |
| try { |
| keyObject = getClassObject(key, keyClass); |
| } catch (ClassNotFoundException e) { |
| return DataCommandResult.createGetResult(key, null, null, |
| "ClassNotFoundException " + keyClass, false); |
| } catch (IllegalArgumentException e) { |
| return DataCommandResult.createGetResult(key, null, null, |
| "Error in converting JSON " + e.getMessage(), false); |
| } |
| |
| boolean doGet = Boolean.TRUE.equals(loadOnCacheMiss); |
| |
| if (doGet || region.containsKey(keyObject)) { |
| Object value = region.get(keyObject); |
| |
| // run it through post processor. region.get will return the deserialized object already, so |
| // we don't need to |
| // deserialize it anymore to pass it to the postProcessor |
| value = securityService.postProcess(principal, regionName, keyObject, value, false); |
| |
| if (logger.isDebugEnabled()) { |
| logger.debug("Get for key {} value {}", key, value); |
| } |
| Object array[] = getClassAndJson(value); |
| if (value != null) { |
| DataCommandResult result = |
| DataCommandResult.createGetResult(key, array[1], null, null, true); |
| if (array[0] != null) { |
| result.setValueClass((String) array[0]); |
| } |
| return result; |
| } else { |
| return DataCommandResult.createGetResult(key, array[1], null, null, false); |
| } |
| } else { |
| if (logger.isDebugEnabled()) { |
| logger.debug("Key is not present in the region {}", regionName); |
| } |
| return DataCommandResult.createGetInfoResult(key, getClassAndJson(null)[1], null, |
| CliStrings.GET__MSG__KEY_NOT_FOUND_REGION, false); |
| } |
| } |
| } |
| |
| @SuppressWarnings({"unchecked", "rawtypes"}) |
| public DataCommandResult locateEntry(String key, String keyClass, String valueClass, |
| String regionPath, boolean recursive, InternalCache cache) { |
| |
| if (StringUtils.isEmpty(regionPath)) { |
| return DataCommandResult.createLocateEntryResult(key, null, null, |
| CliStrings.LOCATE_ENTRY__MSG__REGIONNAME_EMPTY, false); |
| } |
| |
| if (StringUtils.isEmpty(key)) { |
| return DataCommandResult.createLocateEntryResult(key, null, null, |
| CliStrings.LOCATE_ENTRY__MSG__KEY_EMPTY, false); |
| } |
| List<Region> listOfRegionsStartingWithRegionPath = new ArrayList<>(); |
| |
| if (recursive) { |
| // Recursively find the keys starting from the specified region path. |
| List<String> regionPaths = getAllRegionPaths(cache, true); |
| for (String path : regionPaths) { |
| if (path.startsWith(regionPath) || path.startsWith(Region.SEPARATOR + regionPath)) { |
| Region targetRegion = cache.getRegion(path); |
| listOfRegionsStartingWithRegionPath.add(targetRegion); |
| } |
| } |
| if (listOfRegionsStartingWithRegionPath.size() == 0) { |
| if (logger.isDebugEnabled()) { |
| logger.debug("Region Not Found - {}", regionPath); |
| } |
| return DataCommandResult.createLocateEntryResult(key, null, null, |
| CliStrings.format(CliStrings.REMOVE__MSG__REGION_NOT_FOUND, regionPath), false); |
| } |
| } else { |
| Region region = cache.getRegion(regionPath); |
| if (region == null) { |
| if (logger.isDebugEnabled()) { |
| logger.debug("Region Not Found - {}", regionPath); |
| } |
| return DataCommandResult.createLocateEntryResult(key, null, null, |
| CliStrings.format(CliStrings.REMOVE__MSG__REGION_NOT_FOUND, regionPath), false); |
| } else { |
| listOfRegionsStartingWithRegionPath.add(region); |
| } |
| } |
| |
| Object keyObject; |
| try { |
| keyObject = getClassObject(key, keyClass); |
| } catch (ClassNotFoundException e) { |
| logger.error(e.getMessage(), e); |
| return DataCommandResult.createLocateEntryResult(key, null, null, |
| "ClassNotFoundException " + keyClass, false); |
| } catch (IllegalArgumentException e) { |
| logger.error(e.getMessage(), e); |
| return DataCommandResult.createLocateEntryResult(key, null, null, |
| "Error in converting JSON " + e.getMessage(), false); |
| } |
| |
| Object value; |
| DataCommandResult.KeyInfo keyInfo; |
| keyInfo = new DataCommandResult.KeyInfo(); |
| DistributedMember member = cache.getDistributedSystem().getDistributedMember(); |
| keyInfo.setHost(member.getHost()); |
| keyInfo.setMemberId(member.getId()); |
| keyInfo.setMemberName(member.getName()); |
| |
| for (Region region : listOfRegionsStartingWithRegionPath) { |
| if (region instanceof PartitionedRegion) { |
| // Following code is adaptation of which.java of old Gfsh |
| PartitionedRegion pr = (PartitionedRegion) region; |
| Region localRegion = PartitionRegionHelper.getLocalData(region); |
| value = localRegion.get(keyObject); |
| if (value != null) { |
| DistributedMember primaryMember = |
| PartitionRegionHelper.getPrimaryMemberForKey(region, keyObject); |
| int bucketId = pr.getKeyInfo(keyObject).getBucketId(); |
| boolean isPrimary = member == primaryMember; |
| keyInfo.addLocation(new Object[] {region.getFullPath(), true, getClassAndJson(value)[1], |
| isPrimary, "" + bucketId}); |
| } else { |
| if (logger.isDebugEnabled()) { |
| logger.debug("Key is not present in the region {}", regionPath); |
| } |
| return DataCommandResult.createLocateEntryInfoResult(key, null, null, |
| CliStrings.LOCATE_ENTRY__MSG__KEY_NOT_FOUND_REGION, false); |
| } |
| } else { |
| if (region.containsKey(keyObject)) { |
| value = region.get(keyObject); |
| if (logger.isDebugEnabled()) { |
| logger.debug("Get for key {} value {} in region {}", key, value, region.getFullPath()); |
| } |
| if (value != null) { |
| keyInfo.addLocation( |
| new Object[] {region.getFullPath(), true, getClassAndJson(value)[1], false, null}); |
| } else { |
| keyInfo.addLocation(new Object[] {region.getFullPath(), false, null, false, null}); |
| } |
| } else { |
| if (logger.isDebugEnabled()) { |
| logger.debug("Key is not present in the region {}", regionPath); |
| } |
| keyInfo.addLocation(new Object[] {region.getFullPath(), false, null, false, null}); |
| } |
| } |
| } |
| |
| if (keyInfo.hasLocation()) { |
| return DataCommandResult.createLocateEntryResult(key, keyInfo, null, null, true); |
| } else { |
| return DataCommandResult.createLocateEntryInfoResult(key, null, null, |
| CliStrings.LOCATE_ENTRY__MSG__KEY_NOT_FOUND_REGION, false); |
| } |
| } |
| |
| @SuppressWarnings({"rawtypes"}) |
| public DataCommandResult put(String key, String value, boolean putIfAbsent, String keyClass, |
| String valueClass, String regionName, InternalCache cache) { |
| |
| if (StringUtils.isEmpty(regionName)) { |
| return DataCommandResult.createPutResult(key, null, null, |
| CliStrings.PUT__MSG__REGIONNAME_EMPTY, false); |
| } |
| |
| if (StringUtils.isEmpty(key)) { |
| return DataCommandResult.createPutResult(key, null, null, CliStrings.PUT__MSG__KEY_EMPTY, |
| false); |
| } |
| |
| if (StringUtils.isEmpty(value)) { |
| return DataCommandResult.createPutResult(key, null, null, CliStrings.PUT__MSG__VALUE_EMPTY, |
| false); |
| } |
| |
| Region region = cache.getRegion(regionName); |
| if (region == null) { |
| return DataCommandResult.createPutResult(key, null, null, |
| CliStrings.format(CliStrings.PUT__MSG__REGION_NOT_FOUND, regionName), false); |
| } else { |
| Object keyObject; |
| Object valueObject; |
| try { |
| keyObject = getClassObject(key, keyClass); |
| } catch (ClassNotFoundException e) { |
| return DataCommandResult.createPutResult(key, null, null, |
| "ClassNotFoundException " + keyClass, false); |
| } catch (IllegalArgumentException e) { |
| return DataCommandResult.createPutResult(key, null, null, |
| "Error in converting JSON " + e.getMessage(), false); |
| } |
| |
| try { |
| valueObject = getClassObject(value, valueClass); |
| } catch (ClassNotFoundException e) { |
| return DataCommandResult.createPutResult(key, null, null, |
| "ClassNotFoundException " + valueClass, false); |
| } |
| Object returnValue; |
| if (putIfAbsent && region.containsKey(keyObject)) { |
| returnValue = region.get(keyObject); |
| } else { |
| returnValue = region.put(keyObject, valueObject); |
| } |
| Object array[] = getClassAndJson(returnValue); |
| DataCommandResult result = DataCommandResult.createPutResult(key, array[1], null, null, true); |
| if (array[0] != null) { |
| result.setValueClass((String) array[0]); |
| } |
| return result; |
| } |
| } |
| |
| @SuppressWarnings({"rawtypes", "unchecked"}) |
| private Object getClassObject(String string, String klassString) |
| throws ClassNotFoundException, IllegalArgumentException { |
| if (StringUtils.isEmpty(klassString)) { |
| return string; |
| } |
| Class klass = ClassPathLoader.getLatest().forName(klassString); |
| |
| if (klass.equals(String.class)) { |
| return string; |
| } |
| |
| Object resultObject; |
| try { |
| ObjectMapper mapper = GeodeJsonMapper.getMapper(); |
| resultObject = mapper.readValue(string, klass); |
| } catch (IOException e) { |
| throw new IllegalArgumentException( |
| "Failed to convert input key to " + klassString + " Msg : " + e.getMessage()); |
| } |
| |
| return resultObject; |
| } |
| |
| private Object[] getClassAndJson(Object obj) { |
| Object[] array = new Object[2]; |
| |
| if (obj == null) { |
| array[0] = null; |
| array[1] = null; |
| return array; |
| } |
| |
| array[0] = obj.getClass().getCanonicalName(); |
| |
| if (obj instanceof PdxInstance) { |
| array[1] = JSONFormatter.toJSON((PdxInstance) obj); |
| return array; |
| } |
| |
| ObjectMapper mapper = new ObjectMapper(); |
| try { |
| array[1] = mapper.writeValueAsString(obj); |
| } catch (JsonProcessingException e) { |
| array[1] = e.getMessage(); |
| } |
| |
| return array; |
| } |
| |
| /** |
| * Returns a sorted list of all region full paths found in the specified cache. |
| * |
| * @param cache The cache to search. |
| * @param recursive recursive search for sub-regions |
| * @return Returns a sorted list of all region paths defined in the distributed system. |
| */ |
| @SuppressWarnings({"rawtypes", "unchecked"}) |
| public static List getAllRegionPaths(InternalCache cache, boolean recursive) { |
| ArrayList list = new ArrayList(); |
| if (cache == null) { |
| return list; |
| } |
| |
| // get a list of all root regions |
| Set<Region<?, ?>> regions = cache.rootRegions(); |
| |
| for (Region rootRegion : regions) { |
| String regionPath = rootRegion.getFullPath(); |
| |
| Region region = cache.getRegion(regionPath); |
| list.add(regionPath); |
| Set<Region> subregionSet = region.subregions(true); |
| if (recursive) { |
| for (Region aSubregionSet : subregionSet) { |
| list.add(aSubregionSet.getFullPath()); |
| } |
| } |
| } |
| Collections.sort(list); |
| return list; |
| } |
| |
| public static String getLogMessage(QueryObserver observer, long startTime, String query) { |
| String usedIndexesString = null; |
| float time = 0.0f; |
| |
| if (startTime > 0L) { |
| time = (NanoTimer.getTime() - startTime) / 1.0e6f; |
| } |
| |
| if (observer != null && observer instanceof IndexTrackingQueryObserver) { |
| IndexTrackingQueryObserver indexObserver = (IndexTrackingQueryObserver) observer; |
| Map usedIndexes = indexObserver.getUsedIndexes(); |
| indexObserver.reset(); |
| StringBuffer buf = new StringBuffer(); |
| buf.append(" indexesUsed("); |
| buf.append(usedIndexes.size()); |
| buf.append(")"); |
| if (usedIndexes.size() > 0) { |
| buf.append(":"); |
| for (Iterator itr = usedIndexes.entrySet().iterator(); itr.hasNext();) { |
| Map.Entry entry = (Map.Entry) itr.next(); |
| buf.append(entry.getKey().toString()).append(entry.getValue()); |
| if (itr.hasNext()) { |
| buf.append(","); |
| } |
| } |
| } |
| usedIndexesString = buf.toString(); |
| } else if (DefaultQuery.QUERY_VERBOSE) { |
| usedIndexesString = " indexesUsed(NA due to other observer in the way: " |
| + observer.getClass().getName() + ")"; |
| } |
| |
| return String.format("Query Executed%s%s", startTime > 0L ? " in " + time + " ms;" : ";", |
| usedIndexesString != null ? usedIndexesString : ""); |
| } |
| |
| } |