org.apache.geode.management.internal.cli.commands.AlterRuntimeConfigCommand.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.geode.management.internal.cli.commands.AlterRuntimeConfigCommand.java

Source

/*
 * 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("");
        }
    }
}