blob: 7670961cd46dbc6254da8cbe66664a2e8e61b6d3 [file] [log] [blame]
/*
* 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.File;
import java.util.Properties;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.Logger;
import org.apache.geode.cache.Cache;
import org.apache.geode.cache.DiskStore;
import org.apache.geode.cache.EvictionAction;
import org.apache.geode.cache.Region;
import org.apache.geode.cache.asyncqueue.AsyncEventQueue;
import org.apache.geode.cache.execute.FunctionContext;
import org.apache.geode.cache.server.CacheServer;
import org.apache.geode.cache.wan.GatewaySender;
import org.apache.geode.distributed.DistributedMember;
import org.apache.geode.internal.cache.InternalCache;
import org.apache.geode.internal.cache.execute.InternalFunction;
import org.apache.geode.internal.lang.ObjectUtils;
import org.apache.geode.internal.logging.LogService;
import org.apache.geode.internal.util.ArrayUtils;
import org.apache.geode.management.internal.cli.domain.DiskStoreDetails;
import org.apache.geode.management.internal.exceptions.EntityNotFoundException;
/**
* The DescribeDiskStoreFunction class is an implementation of a GemFire Function used to collect
* information and details about a particular disk store for a particular GemFire distributed system
* member.
*
* @see org.apache.geode.cache.DiskStore
* @see org.apache.geode.cache.execute.Function
* @see org.apache.geode.cache.execute.FunctionAdapter
* @see org.apache.geode.cache.execute.FunctionContext
* @see org.apache.geode.internal.InternalEntity
* @see org.apache.geode.management.internal.cli.domain.DiskStoreDetails
* @since GemFire 7.0
*/
public class DescribeDiskStoreFunction implements InternalFunction {
private static final Logger logger = LogService.getLogger();
protected static void assertState(final boolean condition, final String message,
final Object... args) {
if (!condition) {
throw new IllegalStateException(String.format(message, args));
}
}
@Override
public String getId() {
return getClass().getName();
}
@SuppressWarnings("unused")
public void init(final Properties props) {}
@Override
public void execute(final FunctionContext context) {
Cache cache = context.getCache();
try {
if (cache instanceof InternalCache) {
InternalCache gemfireCache = (InternalCache) cache;
DistributedMember member = gemfireCache.getMyId();
String diskStoreName = (String) context.getArguments();
String memberId = member.getId();
String memberName = member.getName();
DiskStore diskStore = gemfireCache.findDiskStore(diskStoreName);
if (diskStore != null) {
DiskStoreDetails diskStoreDetails = new DiskStoreDetails(diskStore.getDiskStoreUUID(),
diskStore.getName(), memberId, memberName);
diskStoreDetails.setAllowForceCompaction(diskStore.getAllowForceCompaction());
diskStoreDetails.setAutoCompact(diskStore.getAutoCompact());
diskStoreDetails.setCompactionThreshold(diskStore.getCompactionThreshold());
diskStoreDetails.setMaxOplogSize(diskStore.getMaxOplogSize());
diskStoreDetails.setQueueSize(diskStore.getQueueSize());
diskStoreDetails.setTimeInterval(diskStore.getTimeInterval());
diskStoreDetails.setWriteBufferSize(diskStore.getWriteBufferSize());
diskStoreDetails.setDiskUsageWarningPercentage(diskStore.getDiskUsageWarningPercentage());
diskStoreDetails
.setDiskUsageCriticalPercentage(diskStore.getDiskUsageCriticalPercentage());
setDiskDirDetails(diskStore, diskStoreDetails);
setRegionDetails(gemfireCache, diskStore, diskStoreDetails);
setCacheServerDetails(gemfireCache, diskStore, diskStoreDetails);
setGatewayDetails(gemfireCache, diskStore, diskStoreDetails);
setPdxSerializationDetails(gemfireCache, diskStore, diskStoreDetails);
setAsyncEventQueueDetails(gemfireCache, diskStore, diskStoreDetails);
context.getResultSender().lastResult(diskStoreDetails);
} else {
context.getResultSender()
.sendException(new EntityNotFoundException(
String.format("A disk store with name '%1$s' was not found on member '%2$s'.",
diskStoreName, memberName)));
}
}
} catch (Exception e) {
logger.error("Error occurred while executing 'describe disk-store': {}!", e.getMessage(), e);
context.getResultSender().sendException(e);
}
}
private void setDiskDirDetails(final DiskStore diskStore,
final DiskStoreDetails diskStoreDetails) {
File[] diskDirs = diskStore.getDiskDirs();
Integer[] diskDirSizes = ArrayUtils.toIntegerArray(diskStore.getDiskDirSizes());
assertState(diskDirs.length == diskDirSizes.length,
"The number of disk directories with a specified size (%1$d) does not match the number of disk directories (%2$d)!",
diskDirSizes.length, diskDirs.length);
for (int index = 0; index < diskDirs.length; index++) {
diskStoreDetails.add(new DiskStoreDetails.DiskDirDetails(diskDirs[index].getAbsolutePath(),
ArrayUtils.getElementAtIndex(diskDirSizes, index, 0)));
}
}
protected String getDiskStoreName(final Region region) {
return StringUtils.defaultIfBlank(region.getAttributes().getDiskStoreName(),
DiskStoreDetails.DEFAULT_DISK_STORE_NAME);
}
protected boolean isOverflowToDisk(final Region region) {
return (region.getAttributes().getEvictionAttributes() != null
&& EvictionAction.OVERFLOW_TO_DISK
.equals(region.getAttributes().getEvictionAttributes().getAction()));
}
protected boolean isPersistent(final Region region) {
return region.getAttributes().getDataPolicy().withPersistence();
}
protected boolean isUsingDiskStore(final Region region, final DiskStore diskStore) {
return ((isPersistent(region) || isOverflowToDisk(region))
&& ObjectUtils.equals(getDiskStoreName(region), diskStore.getName()));
}
protected void setRegionDetails(final InternalCache cache, final DiskStore diskStore,
final DiskStoreDetails diskStoreDetails) {
for (Region<?, ?> region : cache.rootRegions()) {
setRegionDetails(region, diskStore, diskStoreDetails);
}
}
private void setRegionDetails(final Region<?, ?> region, final DiskStore diskStore,
final DiskStoreDetails diskStoreDetails) {
if (isUsingDiskStore(region, diskStore)) {
String regionFullPath = region.getFullPath();
DiskStoreDetails.RegionDetails regionDetails = new DiskStoreDetails.RegionDetails(
regionFullPath, StringUtils.defaultIfBlank(region.getName(), regionFullPath));
regionDetails.setOverflowToDisk(isOverflowToDisk(region));
regionDetails.setPersistent(isPersistent(region));
diskStoreDetails.add(regionDetails);
}
for (Region<?, ?> subregion : region.subregions(false)) {
setRegionDetails(subregion, diskStore, diskStoreDetails); // depth-first, recursive strategy
}
}
protected String getDiskStoreName(final CacheServer cacheServer) {
return (cacheServer.getClientSubscriptionConfig() == null ? null
: StringUtils.defaultIfBlank(cacheServer.getClientSubscriptionConfig().getDiskStoreName(),
DiskStoreDetails.DEFAULT_DISK_STORE_NAME));
}
protected boolean isUsingDiskStore(final CacheServer cacheServer, final DiskStore diskStore) {
return ObjectUtils.equals(getDiskStoreName(cacheServer), diskStore.getName());
}
protected void setCacheServerDetails(final InternalCache cache, final DiskStore diskStore,
final DiskStoreDetails diskStoreDetails) {
for (CacheServer cacheServer : cache.getCacheServers()) {
if (isUsingDiskStore(cacheServer, diskStore)) {
DiskStoreDetails.CacheServerDetails cacheServerDetails =
new DiskStoreDetails.CacheServerDetails(cacheServer.getBindAddress(),
cacheServer.getPort());
cacheServerDetails.setHostName(cacheServer.getHostnameForClients());
diskStoreDetails.add(cacheServerDetails);
}
}
}
protected String getDiskStoreName(final GatewaySender gateway) {
return StringUtils.defaultIfBlank(gateway.getDiskStoreName(),
DiskStoreDetails.DEFAULT_DISK_STORE_NAME);
}
protected boolean isPersistent(final GatewaySender gateway) {
return gateway.isPersistenceEnabled();
}
protected boolean isUsingDiskStore(final GatewaySender gateway, final DiskStore diskStore) {
return ObjectUtils.equals(getDiskStoreName(gateway), diskStore.getName());
}
protected void setGatewayDetails(final InternalCache cache, final DiskStore diskStore,
final DiskStoreDetails diskStoreDetails) {
for (GatewaySender gatewaySender : cache.getGatewaySenders()) {
if (isUsingDiskStore(gatewaySender, diskStore)) {
DiskStoreDetails.GatewayDetails gatewayDetails =
new DiskStoreDetails.GatewayDetails(gatewaySender.getId());
gatewayDetails.setPersistent(isPersistent(gatewaySender));
diskStoreDetails.add(gatewayDetails);
}
}
}
protected void setPdxSerializationDetails(final InternalCache cache, final DiskStore diskStore,
final DiskStoreDetails diskStoreDetails) {
if (cache.getPdxPersistent()) {
String diskStoreName = StringUtils.defaultIfBlank(cache.getPdxDiskStore(),
DiskStoreDetails.DEFAULT_DISK_STORE_NAME);
diskStoreDetails.setPdxSerializationMetaDataStored(
ObjectUtils.equals(diskStoreName, diskStore.getName()));
}
}
protected String getDiskStoreName(final AsyncEventQueue queue) {
return StringUtils.defaultIfBlank(queue.getDiskStoreName(),
DiskStoreDetails.DEFAULT_DISK_STORE_NAME);
}
protected boolean isUsingDiskStore(final AsyncEventQueue queue, final DiskStore diskStore) {
return (queue.isPersistent()
&& ObjectUtils.equals(getDiskStoreName(queue), diskStore.getName()));
}
protected void setAsyncEventQueueDetails(final InternalCache cache, final DiskStore diskStore,
final DiskStoreDetails diskStoreDetails) {
for (AsyncEventQueue queue : cache.getAsyncEventQueues()) {
if (isUsingDiskStore(queue, diskStore)) {
diskStoreDetails.add(new DiskStoreDetails.AsyncEventQueueDetails(queue.getId()));
}
}
}
}