Java tutorial
/* * 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.commands; import static org.apache.geode.distributed.ConfigurationProperties.STATISTIC_SAMPLING_ENABLED; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; import java.util.TreeSet; import org.apache.commons.lang.StringUtils; import org.apache.logging.log4j.Logger; import org.springframework.shell.core.annotation.CliCommand; import org.springframework.shell.core.annotation.CliOption; import org.apache.geode.cache.execute.ResultCollector; import org.apache.geode.distributed.DistributedMember; import org.apache.geode.internal.cache.xmlcache.CacheXml; import org.apache.geode.internal.logging.LogService; import org.apache.geode.internal.logging.log4j.LogLevel; import org.apache.geode.management.cli.CliMetaData; import org.apache.geode.management.cli.ConverterHint; import org.apache.geode.management.cli.Result; import org.apache.geode.management.internal.cli.AbstractCliAroundInterceptor; import org.apache.geode.management.internal.cli.CliUtil; import org.apache.geode.management.internal.cli.GfshParseResult; import org.apache.geode.management.internal.cli.functions.AlterRuntimeConfigFunction; import org.apache.geode.management.internal.cli.functions.CliFunctionResult; import org.apache.geode.management.internal.cli.i18n.CliStrings; import org.apache.geode.management.internal.cli.result.ResultBuilder; import org.apache.geode.management.internal.configuration.domain.XmlEntity; import org.apache.geode.management.internal.security.ResourceOperation; import org.apache.geode.security.ResourcePermission; public class AlterRuntimeConfigCommand implements GfshCommand { private final AlterRuntimeConfigFunction alterRunTimeConfigFunction = new AlterRuntimeConfigFunction(); private static Logger logger = LogService.getLogger(); @CliCommand(value = { CliStrings.ALTER_RUNTIME_CONFIG }, help = CliStrings.ALTER_RUNTIME_CONFIG__HELP) @CliMetaData(relatedTopic = { CliStrings.TOPIC_GEODE_CONFIG }, interceptor = "org.apache.geode.management.internal.cli.commands.AlterRuntimeConfigCommand$AlterRuntimeInterceptor") @ResourceOperation(resource = ResourcePermission.Resource.CLUSTER, operation = ResourcePermission.Operation.MANAGE) public Result alterRuntimeConfig(@CliOption(key = { CliStrings.MEMBER, CliStrings.MEMBERS }, optionContext = ConverterHint.ALL_MEMBER_IDNAME, help = CliStrings.ALTER_RUNTIME_CONFIG__MEMBER__HELP) String[] memberNameOrId, @CliOption(key = { CliStrings.GROUP, CliStrings.GROUPS }, optionContext = ConverterHint.MEMBERGROUP, help = CliStrings.ALTER_RUNTIME_CONFIG__MEMBER__HELP) String[] group, @CliOption(key = { CliStrings.ALTER_RUNTIME_CONFIG__ARCHIVE__DISK__SPACE__LIMIT }, help = CliStrings.ALTER_RUNTIME_CONFIG__ARCHIVE__DISK__SPACE__LIMIT__HELP) Integer archiveDiskSpaceLimit, @CliOption(key = { CliStrings.ALTER_RUNTIME_CONFIG__ARCHIVE__FILE__SIZE__LIMIT }, help = CliStrings.ALTER_RUNTIME_CONFIG__ARCHIVE__FILE__SIZE__LIMIT__HELP) Integer archiveFileSizeLimit, @CliOption(key = { CliStrings.ALTER_RUNTIME_CONFIG__LOG__DISK__SPACE__LIMIT }, help = CliStrings.ALTER_RUNTIME_CONFIG__LOG__DISK__SPACE__LIMIT__HELP) Integer logDiskSpaceLimit, @CliOption(key = { CliStrings.ALTER_RUNTIME_CONFIG__LOG__FILE__SIZE__LIMIT }, help = CliStrings.ALTER_RUNTIME_CONFIG__LOG__FILE__SIZE__LIMIT__HELP) Integer logFileSizeLimit, @CliOption(key = { CliStrings.ALTER_RUNTIME_CONFIG__LOG__LEVEL }, optionContext = ConverterHint.LOG_LEVEL, help = CliStrings.ALTER_RUNTIME_CONFIG__LOG__LEVEL__HELP) String logLevel, @CliOption(key = { CliStrings.ALTER_RUNTIME_CONFIG__STATISTIC__ARCHIVE__FILE }, help = CliStrings.ALTER_RUNTIME_CONFIG__STATISTIC__ARCHIVE__FILE__HELP) String statisticArchiveFile, @CliOption(key = { CliStrings.ALTER_RUNTIME_CONFIG__STATISTIC__SAMPLE__RATE }, help = CliStrings.ALTER_RUNTIME_CONFIG__STATISTIC__SAMPLE__RATE__HELP) Integer statisticSampleRate, @CliOption(key = { CliStrings.ALTER_RUNTIME_CONFIG__STATISTIC__SAMPLING__ENABLED }, help = CliStrings.ALTER_RUNTIME_CONFIG__STATISTIC__SAMPLING__ENABLED__HELP) Boolean statisticSamplingEnabled, @CliOption(key = { CliStrings.ALTER_RUNTIME_CONFIG__COPY__ON__READ }, specifiedDefaultValue = "false", help = CliStrings.ALTER_RUNTIME_CONFIG__COPY__ON__READ__HELP) Boolean setCopyOnRead, @CliOption(key = { CliStrings.ALTER_RUNTIME_CONFIG__LOCK__LEASE }, help = CliStrings.ALTER_RUNTIME_CONFIG__LOCK__LEASE__HELP) Integer lockLease, @CliOption(key = { CliStrings.ALTER_RUNTIME_CONFIG__LOCK__TIMEOUT }, help = CliStrings.ALTER_RUNTIME_CONFIG__LOCK__TIMEOUT__HELP) Integer lockTimeout, @CliOption(key = { CliStrings.ALTER_RUNTIME_CONFIG__MESSAGE__SYNC__INTERVAL }, help = CliStrings.ALTER_RUNTIME_CONFIG__MESSAGE__SYNC__INTERVAL__HELP) Integer messageSyncInterval, @CliOption(key = { CliStrings.ALTER_RUNTIME_CONFIG__SEARCH__TIMEOUT }, help = CliStrings.ALTER_RUNTIME_CONFIG__SEARCH__TIMEOUT__HELP) Integer searchTimeout) { Map<String, String> runTimeDistributionConfigAttributes = new HashMap<>(); Map<String, String> rumTimeCacheAttributes = new HashMap<>(); Set<DistributedMember> targetMembers = CliUtil.findMembers(group, memberNameOrId); if (targetMembers.isEmpty()) { return ResultBuilder.createUserErrorResult(CliStrings.NO_MEMBERS_FOUND_MESSAGE); } if (archiveDiskSpaceLimit != null) { runTimeDistributionConfigAttributes.put(CliStrings.ALTER_RUNTIME_CONFIG__ARCHIVE__DISK__SPACE__LIMIT, archiveDiskSpaceLimit.toString()); } if (archiveFileSizeLimit != null) { runTimeDistributionConfigAttributes.put(CliStrings.ALTER_RUNTIME_CONFIG__ARCHIVE__FILE__SIZE__LIMIT, archiveFileSizeLimit.toString()); } if (logDiskSpaceLimit != null) { runTimeDistributionConfigAttributes.put(CliStrings.ALTER_RUNTIME_CONFIG__LOG__DISK__SPACE__LIMIT, logDiskSpaceLimit.toString()); } if (logFileSizeLimit != null) { runTimeDistributionConfigAttributes.put(CliStrings.ALTER_RUNTIME_CONFIG__LOG__FILE__SIZE__LIMIT, logFileSizeLimit.toString()); } if (logLevel != null && !logLevel.isEmpty()) { runTimeDistributionConfigAttributes.put(CliStrings.ALTER_RUNTIME_CONFIG__LOG__LEVEL, logLevel); } if (statisticArchiveFile != null && !statisticArchiveFile.isEmpty()) { runTimeDistributionConfigAttributes.put(CliStrings.ALTER_RUNTIME_CONFIG__STATISTIC__ARCHIVE__FILE, statisticArchiveFile); } if (statisticSampleRate != null) { runTimeDistributionConfigAttributes.put(CliStrings.ALTER_RUNTIME_CONFIG__STATISTIC__SAMPLE__RATE, statisticSampleRate.toString()); } if (statisticSamplingEnabled != null) { runTimeDistributionConfigAttributes.put(STATISTIC_SAMPLING_ENABLED, statisticSamplingEnabled.toString()); } // Attributes that are set on the cache. if (setCopyOnRead != null) { rumTimeCacheAttributes.put(CliStrings.ALTER_RUNTIME_CONFIG__COPY__ON__READ, setCopyOnRead.toString()); } if (lockLease != null && lockLease > 0 && lockLease < Integer.MAX_VALUE) { rumTimeCacheAttributes.put(CliStrings.ALTER_RUNTIME_CONFIG__LOCK__LEASE, lockLease.toString()); } if (lockTimeout != null && lockTimeout > 0 && lockTimeout < Integer.MAX_VALUE) { rumTimeCacheAttributes.put(CliStrings.ALTER_RUNTIME_CONFIG__LOCK__TIMEOUT, lockTimeout.toString()); } if (messageSyncInterval != null && messageSyncInterval > 0 && messageSyncInterval < Integer.MAX_VALUE) { rumTimeCacheAttributes.put(CliStrings.ALTER_RUNTIME_CONFIG__MESSAGE__SYNC__INTERVAL, messageSyncInterval.toString()); } if (searchTimeout != null && searchTimeout > 0 && searchTimeout < Integer.MAX_VALUE) { rumTimeCacheAttributes.put(CliStrings.ALTER_RUNTIME_CONFIG__SEARCH__TIMEOUT, searchTimeout.toString()); } if (runTimeDistributionConfigAttributes.isEmpty() && rumTimeCacheAttributes.isEmpty()) { return ResultBuilder.createUserErrorResult(CliStrings.ALTER_RUNTIME_CONFIG__RELEVANT__OPTION__MESSAGE); } Map<String, String> allRunTimeAttributes = new HashMap<>(); allRunTimeAttributes.putAll(runTimeDistributionConfigAttributes); allRunTimeAttributes.putAll(rumTimeCacheAttributes); ResultCollector<?, ?> rc = CliUtil.executeFunction(alterRunTimeConfigFunction, allRunTimeAttributes, targetMembers); List<CliFunctionResult> results = CliFunctionResult.cleanResults((List<?>) rc.getResult()); Set<String> successfulMembers = new TreeSet<>(); Set<String> errorMessages = new TreeSet<>(); for (CliFunctionResult result : results) { if (result.getThrowable() != null) { logger.info("Function failed: " + result.getThrowable()); errorMessages.add(result.getThrowable().getMessage()); } else { successfulMembers.add(result.getMemberIdOrName()); } } final String lineSeparator = System.getProperty("line.separator"); if (!successfulMembers.isEmpty()) { StringBuilder successMessageBuilder = new StringBuilder(); successMessageBuilder.append(CliStrings.ALTER_RUNTIME_CONFIG__SUCCESS__MESSAGE); successMessageBuilder.append(lineSeparator); for (String member : successfulMembers) { successMessageBuilder.append(member); successMessageBuilder.append(lineSeparator); } Properties properties = new Properties(); properties.putAll(runTimeDistributionConfigAttributes); Result result = ResultBuilder.createInfoResult(successMessageBuilder.toString()); // Set the Cache attributes to be modified final XmlEntity xmlEntity = XmlEntity.builder().withType(CacheXml.CACHE) .withAttributes(rumTimeCacheAttributes).build(); persistClusterConfiguration(result, () -> getSharedConfiguration().modifyXmlAndProperties(properties, xmlEntity, group)); return result; } else { StringBuilder errorMessageBuilder = new StringBuilder(); errorMessageBuilder.append("Following errors occurred while altering runtime config"); errorMessageBuilder.append(lineSeparator); for (String errorMessage : errorMessages) { errorMessageBuilder.append(errorMessage); errorMessageBuilder.append(lineSeparator); } return ResultBuilder.createUserErrorResult(errorMessageBuilder.toString()); } } public static class AlterRuntimeInterceptor extends AbstractCliAroundInterceptor { @Override public Result preExecution(GfshParseResult parseResult) { Map<String, String> arguments = parseResult.getParamValueStrings(); // validate log level String logLevel = arguments.get("log-level"); if (StringUtils.isNotBlank(logLevel) && (LogLevel.getLevel(logLevel) == null)) { return ResultBuilder.createUserErrorResult("Invalid log level: " + logLevel); } return ResultBuilder.createInfoResult(""); } } }