You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by kh...@apache.org on 2017/03/17 20:11:23 UTC
[48/49] geode git commit: refactor for testability
refactor for testability
Extract inner Interceptor class from ExportLogsCommand
Project: http://git-wip-us.apache.org/repos/asf/geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/geode/commit/2bcba1da
Tree: http://git-wip-us.apache.org/repos/asf/geode/tree/2bcba1da
Diff: http://git-wip-us.apache.org/repos/asf/geode/diff/2bcba1da
Branch: refs/heads/feature/GEODE-2420
Commit: 2bcba1daae43247ee6dde673c36adba4f7142932
Parents: 26700b5
Author: Ken Howe <kh...@pivotal.io>
Authored: Fri Mar 17 12:59:59 2017 -0700
Committer: Ken Howe <kh...@pivotal.io>
Committed: Fri Mar 17 13:09:46 2017 -0700
----------------------------------------------------------------------
.../internal/cli/commands/ExportLogCommand.java | 251 -------------------
.../cli/commands/ExportLogsCommand.java | 192 ++++++++++++++
.../cli/commands/ExportLogsInterceptor.java | 108 ++++++++
.../cli/functions/ExportLogsFunction.java | 6 +-
.../cli/commands/ExportLogsCommandTest.java | 47 ++++
.../cli/commands/ExportLogsDUnitTest.java | 4 +-
.../ExportLogsInterceptorJUnitTest.java | 4 +-
.../cli/commands/ExportLogsStatsDUnitTest.java | 2 +-
8 files changed, 355 insertions(+), 259 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/geode/blob/2bcba1da/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ExportLogCommand.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ExportLogCommand.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ExportLogCommand.java
deleted file mode 100644
index 7dfc63d..0000000
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ExportLogCommand.java
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * 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 org.apache.commons.io.FileUtils;
-import org.apache.commons.lang.StringUtils;
-import org.apache.geode.cache.Region;
-import org.apache.geode.distributed.DistributedMember;
-import org.apache.geode.internal.cache.GemFireCacheImpl;
-import org.apache.geode.internal.logging.LogService;
-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.ExportLogsFunction;
-import org.apache.geode.management.internal.cli.i18n.CliStrings;
-import org.apache.geode.management.internal.cli.result.ResultBuilder;
-import org.apache.geode.management.internal.cli.shell.Gfsh;
-import org.apache.geode.management.internal.cli.util.ExportLogsCacheWriter;
-import org.apache.geode.management.internal.configuration.utils.ZipUtils;
-import org.apache.geode.management.internal.security.ResourceOperation;
-import org.apache.geode.security.ResourcePermission;
-import org.apache.logging.log4j.Level;
-import org.apache.logging.log4j.Logger;
-import org.springframework.shell.core.CommandMarker;
-import org.springframework.shell.core.annotation.CliCommand;
-import org.springframework.shell.core.annotation.CliOption;
-
-import java.io.File;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.time.LocalDateTime;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-
-public class ExportLogCommand implements CommandMarker {
- private static final Logger logger = LogService.getLogger();
- public static final String FORMAT = "yyyy/MM/dd/HH/mm/ss/SSS/z";
- public static final String ONLY_DATE_FORMAT = "yyyy/MM/dd";
-
- @CliCommand(value = CliStrings.EXPORT_LOGS, help = CliStrings.EXPORT_LOGS__HELP)
- @CliMetaData(shellOnly = false, isFileDownloadOverHttp = true,
- interceptor = "org.apache.geode.management.internal.cli.commands.ExportLogCommand$ExportLogsInterceptor",
- relatedTopic = {CliStrings.TOPIC_GEODE_SERVER, CliStrings.TOPIC_GEODE_DEBUG_UTIL})
- @ResourceOperation(resource = ResourcePermission.Resource.CLUSTER,
- operation = ResourcePermission.Operation.READ)
- public Result exportLogs(
- @CliOption(key = CliStrings.EXPORT_LOGS__DIR, help = CliStrings.EXPORT_LOGS__DIR__HELP,
- mandatory = false) String dirName,
- @CliOption(key = CliStrings.EXPORT_LOGS__GROUP,
- unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
- optionContext = ConverterHint.MEMBERGROUP,
- help = CliStrings.EXPORT_LOGS__GROUP__HELP) String[] groups,
- @CliOption(key = CliStrings.EXPORT_LOGS__MEMBER,
- unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
- optionContext = ConverterHint.ALL_MEMBER_IDNAME,
- help = CliStrings.EXPORT_LOGS__MEMBER__HELP) String[] memberIds,
- @CliOption(key = CliStrings.EXPORT_LOGS__LOGLEVEL,
- unspecifiedDefaultValue = LogService.DEFAULT_LOG_LEVEL,
- optionContext = ConverterHint.LOG_LEVEL,
- help = CliStrings.EXPORT_LOGS__LOGLEVEL__HELP) String logLevel,
- @CliOption(key = CliStrings.EXPORT_LOGS__UPTO_LOGLEVEL, unspecifiedDefaultValue = "false",
- help = CliStrings.EXPORT_LOGS__UPTO_LOGLEVEL__HELP) boolean onlyLogLevel,
- @CliOption(key = CliStrings.EXPORT_LOGS__MERGELOG, unspecifiedDefaultValue = "false",
- help = CliStrings.EXPORT_LOGS__MERGELOG__HELP) boolean mergeLog,
- @CliOption(key = CliStrings.EXPORT_LOGS__STARTTIME,
- unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
- help = CliStrings.EXPORT_LOGS__STARTTIME__HELP) String start,
- @CliOption(key = CliStrings.EXPORT_LOGS__ENDTIME,
- unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
- help = CliStrings.EXPORT_LOGS__ENDTIME__HELP) String end,
- @CliOption(key = CliStrings.EXPORT_LOGS__LOGSONLY, unspecifiedDefaultValue = "false",
- specifiedDefaultValue = "true",
- help = CliStrings.EXPORT_LOGS__LOGSONLY__HELP) boolean logsOnly,
- @CliOption(key = CliStrings.EXPORT_LOGS__STATSONLY, unspecifiedDefaultValue = "false",
- specifiedDefaultValue = "true",
- help = CliStrings.EXPORT_LOGS__STATSONLY__HELP) boolean statsOnly) {
- Result result = null;
- GemFireCacheImpl cache = GemFireCacheImpl.getInstance();
- try {
- Set<DistributedMember> targetMembers =
- CliUtil.findMembersIncludingLocators(groups, memberIds);
-
- if (targetMembers.isEmpty()) {
- return ResultBuilder.createUserErrorResult(CliStrings.NO_MEMBERS_FOUND_MESSAGE);
- }
-
- Map<String, Path> zipFilesFromMembers = new HashMap<>();
- for (DistributedMember server : targetMembers) {
- Region region = ExportLogsFunction.createOrGetExistingExportLogsRegion(true, cache);
-
- ExportLogsCacheWriter cacheWriter =
- (ExportLogsCacheWriter) region.getAttributes().getCacheWriter();
-
- cacheWriter.startFile(server.getName());
-
- CliUtil.executeFunction(new ExportLogsFunction(),
- new ExportLogsFunction.Args(start, end, logLevel, onlyLogLevel, logsOnly, statsOnly),
- server).getResult();
- Path zipFile = cacheWriter.endFile();
- ExportLogsFunction.destroyExportLogsRegion(cache);
-
- // only put the zipfile in the map if it is not null
- if (zipFile != null) {
- logger.info("Received zip file from member {}: {}", server.getId(), zipFile);
- zipFilesFromMembers.put(server.getId(), zipFile);
- }
- }
-
- if (zipFilesFromMembers.isEmpty()) {
- return ResultBuilder.createUserErrorResult("No files to be exported.");
- }
-
- Path tempDir = Files.createTempDirectory("exportedLogs");
- // make sure the directory is created, so that even if there is no files unzipped to this dir,
- // we can
- // still zip it and send an empty zip file back to the client
- Path exportedLogsDir = tempDir.resolve("exportedLogs");
- FileUtils.forceMkdir(exportedLogsDir.toFile());
-
- for (Path zipFile : zipFilesFromMembers.values()) {
- Path unzippedMemberDir =
- exportedLogsDir.resolve(zipFile.getFileName().toString().replace(".zip", ""));
- ZipUtils.unzip(zipFile.toAbsolutePath().toString(), unzippedMemberDir.toString());
- FileUtils.deleteQuietly(zipFile.toFile());
- }
-
- Path workingDir = Paths.get(System.getProperty("user.dir"));
- Path exportedLogsZipFile = workingDir
- .resolve("exportedLogs_" + System.currentTimeMillis() + ".zip").toAbsolutePath();
-
- logger.info("Zipping into: " + exportedLogsZipFile.toString());
- ZipUtils.zipDirectory(exportedLogsDir, exportedLogsZipFile);
- FileUtils.deleteDirectory(tempDir.toFile());
-
- // TODO:GEODE-2420: warn user if exportedLogsZipFile size > threshold
- if (isOverDiskSpaceThreshold()) {
- // append warning to exportedLogsZipFile.toString()??
- }
-
- result = ResultBuilder.createInfoResult(exportedLogsZipFile.toString());
- } catch (Exception ex) {
- logger.error(ex, ex);
- result = ResultBuilder.createGemFireErrorResult(ex.getMessage());
- } finally {
- ExportLogsFunction.destroyExportLogsRegion(cache);
- }
- logger.debug("Exporting logs returning = {}", result);
- return result;
- }
-
- protected static Gfsh getGfsh() {
- return Gfsh.getCurrentInstance();
- }
-
- boolean isOverDiskSpaceThreshold() {
- return false;
- }
-
- /**
- * after the export logs, will need to copy the tempFile to the desired location and delete the
- * temp file.
- */
- public static class ExportLogsInterceptor extends AbstractCliAroundInterceptor {
- @Override
- public Result preExecution(GfshParseResult parseResult) {
- // the arguments are in the order of it's being declared
- Map<String, String> arguments = parseResult.getParamValueStrings();
-
- // validates groupId and memberIds not both set
- if (arguments.get("group") != null && arguments.get("member") != null) {
- return ResultBuilder.createUserErrorResult("Can't specify both group and member.");
- }
-
- // validate log level
- String logLevel = arguments.get("log-level");
- if (StringUtils.isBlank(logLevel) || Level.getLevel(logLevel.toUpperCase()) == null) {
- return ResultBuilder.createUserErrorResult("Invalid log level: " + logLevel);
- }
-
- // validate start date and end date
- String start = arguments.get("start-time");
- String end = arguments.get("end-time");
- if (start != null && end != null) {
- // need to make sure end is later than start
- LocalDateTime startTime = ExportLogsFunction.parseTime(start);
- LocalDateTime endTime = ExportLogsFunction.parseTime(end);
- if (startTime.isAfter(endTime)) {
- return ResultBuilder.createUserErrorResult("start-time has to be earlier than end-time.");
- }
- }
-
- // validate onlyLogs and onlyStats
- boolean onlyLogs = Boolean.parseBoolean(arguments.get("logs-only"));
- boolean onlyStats = Boolean.parseBoolean(arguments.get("stats-only"));
- if (onlyLogs && onlyStats) {
- return ResultBuilder.createUserErrorResult("logs-only and stats-only can't both be true");
- }
-
- return ResultBuilder.createInfoResult("");
- }
-
- @Override
- public Result postExecution(GfshParseResult parseResult, Result commandResult, Path tempFile) {
- // in the command over http case, the command result is in the downloaded temp file
- if (tempFile != null) {
- Path dirPath;
- String dirName = parseResult.getParamValueStrings().get("dir");
- if (StringUtils.isBlank(dirName)) {
- dirPath = Paths.get(System.getProperty("user.dir"));
- } else {
- dirPath = Paths.get(dirName);
- }
- String fileName = "exportedLogs_" + System.currentTimeMillis() + ".zip";
- File exportedLogFile = dirPath.resolve(fileName).toFile();
- try {
- FileUtils.copyFile(tempFile.toFile(), exportedLogFile);
- FileUtils.deleteQuietly(tempFile.toFile());
- commandResult = ResultBuilder
- .createInfoResult("Logs exported to: " + exportedLogFile.getAbsolutePath());
- } catch (IOException e) {
- logger.error(e.getMessage(), e);
- commandResult = ResultBuilder.createGemFireErrorResult(e.getMessage());
- }
- } else if (commandResult.getStatus() == Result.Status.OK) {
- commandResult = ResultBuilder.createInfoResult(
- "Logs exported to the connected member's file system: " + commandResult.nextLine());
- }
- return commandResult;
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/geode/blob/2bcba1da/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ExportLogsCommand.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ExportLogsCommand.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ExportLogsCommand.java
new file mode 100644
index 0000000..9dd64d7
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ExportLogsCommand.java
@@ -0,0 +1,192 @@
+/*
+ * 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 org.apache.commons.io.FileUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.geode.cache.Region;
+import org.apache.geode.distributed.DistributedMember;
+import org.apache.geode.internal.cache.GemFireCacheImpl;
+import org.apache.geode.internal.logging.LogService;
+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.ExportLogsFunction;
+import org.apache.geode.management.internal.cli.i18n.CliStrings;
+import org.apache.geode.management.internal.cli.result.ResultBuilder;
+import org.apache.geode.management.internal.cli.shell.Gfsh;
+import org.apache.geode.management.internal.cli.util.ExportLogsCacheWriter;
+import org.apache.geode.management.internal.configuration.utils.ZipUtils;
+import org.apache.geode.management.internal.security.ResourceOperation;
+import org.apache.geode.security.ResourcePermission;
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.Logger;
+import org.springframework.shell.core.CommandMarker;
+import org.springframework.shell.core.annotation.CliCommand;
+import org.springframework.shell.core.annotation.CliOption;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.time.LocalDateTime;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+public class ExportLogsCommand implements CommandMarker {
+
+ private static final Logger logger = LogService.getLogger();
+
+ public static final String FORMAT = "yyyy/MM/dd/HH/mm/ss/SSS/z";
+ public static final String ONLY_DATE_FORMAT = "yyyy/MM/dd";
+
+ private GemFireCacheImpl cache;
+
+ public ExportLogsCommand() {
+ cache = GemFireCacheImpl.getInstance();
+ }
+
+ @CliCommand(value = CliStrings.EXPORT_LOGS, help = CliStrings.EXPORT_LOGS__HELP)
+ @CliMetaData(shellOnly = false, isFileDownloadOverHttp = true,
+ interceptor = "org.apache.geode.management.internal.cli.commands.ExportLogsInterceptor",
+ relatedTopic = {CliStrings.TOPIC_GEODE_SERVER, CliStrings.TOPIC_GEODE_DEBUG_UTIL})
+ @ResourceOperation(resource = ResourcePermission.Resource.CLUSTER,
+ operation = ResourcePermission.Operation.READ)
+ public Result exportLogs(
+ @CliOption(key = CliStrings.EXPORT_LOGS__DIR, help = CliStrings.EXPORT_LOGS__DIR__HELP,
+ mandatory = false) String dirName,
+ @CliOption(key = CliStrings.EXPORT_LOGS__GROUP,
+ unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
+ optionContext = ConverterHint.MEMBERGROUP,
+ help = CliStrings.EXPORT_LOGS__GROUP__HELP) String[] groups,
+ @CliOption(key = CliStrings.EXPORT_LOGS__MEMBER,
+ unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
+ optionContext = ConverterHint.ALL_MEMBER_IDNAME,
+ help = CliStrings.EXPORT_LOGS__MEMBER__HELP) String[] memberIds,
+ @CliOption(key = CliStrings.EXPORT_LOGS__LOGLEVEL,
+ unspecifiedDefaultValue = LogService.DEFAULT_LOG_LEVEL,
+ optionContext = ConverterHint.LOG_LEVEL,
+ help = CliStrings.EXPORT_LOGS__LOGLEVEL__HELP) String logLevel,
+ @CliOption(key = CliStrings.EXPORT_LOGS__UPTO_LOGLEVEL, unspecifiedDefaultValue = "false",
+ help = CliStrings.EXPORT_LOGS__UPTO_LOGLEVEL__HELP) boolean onlyLogLevel,
+ @CliOption(key = CliStrings.EXPORT_LOGS__MERGELOG, unspecifiedDefaultValue = "false",
+ help = CliStrings.EXPORT_LOGS__MERGELOG__HELP) boolean mergeLog,
+ @CliOption(key = CliStrings.EXPORT_LOGS__STARTTIME,
+ unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
+ help = CliStrings.EXPORT_LOGS__STARTTIME__HELP) String start,
+ @CliOption(key = CliStrings.EXPORT_LOGS__ENDTIME,
+ unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
+ help = CliStrings.EXPORT_LOGS__ENDTIME__HELP) String end,
+ @CliOption(key = CliStrings.EXPORT_LOGS__LOGSONLY, unspecifiedDefaultValue = "false",
+ specifiedDefaultValue = "true",
+ help = CliStrings.EXPORT_LOGS__LOGSONLY__HELP) boolean logsOnly,
+ @CliOption(key = CliStrings.EXPORT_LOGS__STATSONLY, unspecifiedDefaultValue = "false",
+ specifiedDefaultValue = "true",
+ help = CliStrings.EXPORT_LOGS__STATSONLY__HELP) boolean statsOnly) {
+ Result result = null;
+ GemFireCacheImpl cache = this.cache;
+ if (cache == null || cache.isClosed()) {
+ new Exception("KEN: cache is null").printStackTrace();
+ cache = GemFireCacheImpl.getInstance();
+ } else {
+ new Exception("KEN: cache has been created").printStackTrace();
+ }
+ try {
+ Set<DistributedMember> targetMembers =
+ CliUtil.findMembersIncludingLocators(groups, memberIds);
+
+ if (targetMembers.isEmpty()) {
+ return ResultBuilder.createUserErrorResult(CliStrings.NO_MEMBERS_FOUND_MESSAGE);
+ }
+
+ Map<String, Path> zipFilesFromMembers = new HashMap<>();
+ for (DistributedMember server : targetMembers) {
+ Region region = ExportLogsFunction.createOrGetExistingExportLogsRegion(true, cache);
+
+ ExportLogsCacheWriter cacheWriter =
+ (ExportLogsCacheWriter) region.getAttributes().getCacheWriter();
+
+ cacheWriter.startFile(server.getName());
+
+ CliUtil.executeFunction(new ExportLogsFunction(),
+ new ExportLogsFunction.Args(start, end, logLevel, onlyLogLevel, logsOnly, statsOnly),
+ server).getResult();
+ Path zipFile = cacheWriter.endFile();
+ ExportLogsFunction.destroyExportLogsRegion(cache);
+
+ // only put the zipfile in the map if it is not null
+ if (zipFile != null) {
+ logger.info("Received zip file from member {}: {}", server.getId(), zipFile);
+ zipFilesFromMembers.put(server.getId(), zipFile);
+ }
+ }
+
+ if (zipFilesFromMembers.isEmpty()) {
+ return ResultBuilder.createUserErrorResult("No files to be exported.");
+ }
+
+ Path tempDir = Files.createTempDirectory("exportedLogs");
+ // make sure the directory is created, so that even if there is no files unzipped to this dir,
+ // we can
+ // still zip it and send an empty zip file back to the client
+ Path exportedLogsDir = tempDir.resolve("exportedLogs");
+ FileUtils.forceMkdir(exportedLogsDir.toFile());
+
+ for (Path zipFile : zipFilesFromMembers.values()) {
+ Path unzippedMemberDir =
+ exportedLogsDir.resolve(zipFile.getFileName().toString().replace(".zip", ""));
+ ZipUtils.unzip(zipFile.toAbsolutePath().toString(), unzippedMemberDir.toString());
+ FileUtils.deleteQuietly(zipFile.toFile());
+ }
+
+ Path workingDir = Paths.get(System.getProperty("user.dir"));
+ Path exportedLogsZipFile = workingDir
+ .resolve("exportedLogs_" + System.currentTimeMillis() + ".zip").toAbsolutePath();
+
+ logger.info("Zipping into: " + exportedLogsZipFile.toString());
+ ZipUtils.zipDirectory(exportedLogsDir, exportedLogsZipFile);
+ FileUtils.deleteDirectory(tempDir.toFile());
+
+ // TODO:GEODE-2420: warn user if exportedLogsZipFile size > threshold
+ if (isOverDiskSpaceThreshold()) {
+ // append warning to exportedLogsZipFile.toString()??
+ }
+
+ result = ResultBuilder.createInfoResult(exportedLogsZipFile.toString());
+ } catch (Exception ex) {
+ logger.error(ex, ex);
+ result = ResultBuilder.createGemFireErrorResult(ex.getMessage());
+ } finally {
+ ExportLogsFunction.destroyExportLogsRegion(cache);
+ }
+ logger.debug("Exporting logs returning = {}", result);
+ return result;
+ }
+
+ protected static Gfsh getGfsh() {
+ return Gfsh.getCurrentInstance();
+ }
+
+ boolean isOverDiskSpaceThreshold() {
+ return false;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/geode/blob/2bcba1da/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ExportLogsInterceptor.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ExportLogsInterceptor.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ExportLogsInterceptor.java
new file mode 100644
index 0000000..8427c83
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ExportLogsInterceptor.java
@@ -0,0 +1,108 @@
+/*
+ * 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 org.apache.commons.io.FileUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.geode.internal.logging.LogService;
+import org.apache.geode.management.cli.Result;
+import org.apache.geode.management.internal.cli.AbstractCliAroundInterceptor;
+import org.apache.geode.management.internal.cli.GfshParseResult;
+import org.apache.geode.management.internal.cli.functions.ExportLogsFunction;
+import org.apache.geode.management.internal.cli.result.ResultBuilder;
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.Logger;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.time.LocalDateTime;
+import java.util.Map;
+
+/**
+ * after the export logs, will need to copy the tempFile to the desired location and delete the
+ * temp file.
+ */
+public class ExportLogsInterceptor extends AbstractCliAroundInterceptor {
+ private static final Logger logger = LogService.getLogger();
+
+ @Override
+ public Result preExecution(GfshParseResult parseResult) {
+ // the arguments are in the order of it's being declared
+ Map<String, String> arguments = parseResult.getParamValueStrings();
+
+ // validates groupId and memberIds not both set
+ if (arguments.get("group") != null && arguments.get("member") != null) {
+ return ResultBuilder.createUserErrorResult("Can't specify both group and member.");
+ }
+
+ // validate log level
+ String logLevel = arguments.get("log-level");
+ if (StringUtils.isBlank(logLevel) || Level.getLevel(logLevel.toUpperCase()) == null) {
+ return ResultBuilder.createUserErrorResult("Invalid log level: " + logLevel);
+ }
+
+ // validate start date and end date
+ String start = arguments.get("start-time");
+ String end = arguments.get("end-time");
+ if (start != null && end != null) {
+ // need to make sure end is later than start
+ LocalDateTime startTime = ExportLogsFunction.parseTime(start);
+ LocalDateTime endTime = ExportLogsFunction.parseTime(end);
+ if (startTime.isAfter(endTime)) {
+ return ResultBuilder.createUserErrorResult("start-time has to be earlier than end-time.");
+ }
+ }
+
+ // validate onlyLogs and onlyStats
+ boolean onlyLogs = Boolean.parseBoolean(arguments.get("logs-only"));
+ boolean onlyStats = Boolean.parseBoolean(arguments.get("stats-only"));
+ if (onlyLogs && onlyStats) {
+ return ResultBuilder.createUserErrorResult("logs-only and stats-only can't both be true");
+ }
+
+ return ResultBuilder.createInfoResult("");
+ }
+
+ @Override
+ public Result postExecution(GfshParseResult parseResult, Result commandResult, Path tempFile) {
+ // in the command over http case, the command result is in the downloaded temp file
+ if (tempFile != null) {
+ Path dirPath;
+ String dirName = parseResult.getParamValueStrings().get("dir");
+ if (StringUtils.isBlank(dirName)) {
+ dirPath = Paths.get(System.getProperty("user.dir"));
+ } else {
+ dirPath = Paths.get(dirName);
+ }
+ String fileName = "exportedLogs_" + System.currentTimeMillis() + ".zip";
+ File exportedLogFile = dirPath.resolve(fileName).toFile();
+ try {
+ FileUtils.copyFile(tempFile.toFile(), exportedLogFile);
+ FileUtils.deleteQuietly(tempFile.toFile());
+ commandResult = ResultBuilder
+ .createInfoResult("Logs exported to: " + exportedLogFile.getAbsolutePath());
+ } catch (IOException e) {
+ logger.error(e.getMessage(), e);
+ commandResult = ResultBuilder.createGemFireErrorResult(e.getMessage());
+ }
+ } else if (commandResult.getStatus() == Result.Status.OK) {
+ commandResult = ResultBuilder.createInfoResult(
+ "Logs exported to the connected member's file system: " + commandResult.nextLine());
+ }
+ return commandResult;
+ }
+}
http://git-wip-us.apache.org/repos/asf/geode/blob/2bcba1da/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/ExportLogsFunction.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/ExportLogsFunction.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/ExportLogsFunction.java
index 62026fb..516a9a7 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/ExportLogsFunction.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/ExportLogsFunction.java
@@ -28,7 +28,7 @@ import org.apache.geode.internal.InternalEntity;
import org.apache.geode.internal.cache.GemFireCacheImpl;
import org.apache.geode.internal.cache.InternalRegionArguments;
import org.apache.geode.internal.logging.LogService;
-import org.apache.geode.management.internal.cli.commands.ExportLogCommand;
+import org.apache.geode.management.internal.cli.commands.ExportLogsCommand;
import org.apache.geode.management.internal.cli.util.ExportLogsCacheWriter;
import org.apache.geode.management.internal.cli.util.LogExporter;
import org.apache.geode.management.internal.cli.util.LogFilter;
@@ -207,11 +207,11 @@ public class ExportLogsFunction implements Function, InternalEntity {
}
try {
- SimpleDateFormat df = new SimpleDateFormat(ExportLogCommand.FORMAT);
+ SimpleDateFormat df = new SimpleDateFormat(ExportLogsCommand.FORMAT);
return df.parse(dateString).toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
} catch (ParseException e) {
try {
- SimpleDateFormat df = new SimpleDateFormat(ExportLogCommand.ONLY_DATE_FORMAT);
+ SimpleDateFormat df = new SimpleDateFormat(ExportLogsCommand.ONLY_DATE_FORMAT);
return df.parse(dateString).toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
} catch (ParseException e1) {
return null;
http://git-wip-us.apache.org/repos/asf/geode/blob/2bcba1da/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/ExportLogsCommandTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/ExportLogsCommandTest.java b/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/ExportLogsCommandTest.java
new file mode 100644
index 0000000..21843f6
--- /dev/null
+++ b/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/ExportLogsCommandTest.java
@@ -0,0 +1,47 @@
+/*
+ * 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.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.*;
+
+import org.apache.geode.cache.Cache;
+import org.apache.geode.test.junit.categories.UnitTest;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+
+@Category(UnitTest.class)
+public class ExportLogsCommandTest {
+
+ @Mock
+ private Cache cache;
+
+ @Before
+ public void before() throws Exception {
+ // customize behavior
+ this.cache = mock(Cache.class);
+ }
+
+ @Test
+ public void noLogsIsNotOverThreshold() throws Exception {
+// ExportLogsCommand command = new ExportLogsCommand(this.cache);
+//
+// assertThat(command.isOverDiskSpaceThreshold()).isFalse();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/geode/blob/2bcba1da/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/ExportLogsDUnitTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/ExportLogsDUnitTest.java b/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/ExportLogsDUnitTest.java
index 95edd42..d0180d0 100644
--- a/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/ExportLogsDUnitTest.java
+++ b/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/ExportLogsDUnitTest.java
@@ -19,8 +19,8 @@ package org.apache.geode.management.internal.cli.commands;
import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.toList;
import static java.util.stream.Collectors.toSet;
-import static org.apache.geode.management.internal.cli.commands.ExportLogCommand.FORMAT;
-import static org.apache.geode.management.internal.cli.commands.ExportLogCommand.ONLY_DATE_FORMAT;
+import static org.apache.geode.management.internal.cli.commands.ExportLogsCommand.FORMAT;
+import static org.apache.geode.management.internal.cli.commands.ExportLogsCommand.ONLY_DATE_FORMAT;
import static org.assertj.core.api.Assertions.assertThat;
import org.apache.commons.io.FileUtils;
http://git-wip-us.apache.org/repos/asf/geode/blob/2bcba1da/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/ExportLogsInterceptorJUnitTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/ExportLogsInterceptorJUnitTest.java b/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/ExportLogsInterceptorJUnitTest.java
index 97ed686..9709aa6 100644
--- a/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/ExportLogsInterceptorJUnitTest.java
+++ b/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/ExportLogsInterceptorJUnitTest.java
@@ -31,14 +31,14 @@ import java.util.Map;
@Category(UnitTest.class)
public class ExportLogsInterceptorJUnitTest {
- private ExportLogCommand.ExportLogsInterceptor interceptor;
+ private ExportLogsInterceptor interceptor;
private GfshParseResult parseResult;
private Map<String, String> arguments;
private Result result;
@Before
public void before() {
- interceptor = new ExportLogCommand.ExportLogsInterceptor();
+ interceptor = new ExportLogsInterceptor();
parseResult = Mockito.mock(GfshParseResult.class);
arguments = new HashMap<>();
arguments.put("log-level", "info");
http://git-wip-us.apache.org/repos/asf/geode/blob/2bcba1da/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/ExportLogsStatsDUnitTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/ExportLogsStatsDUnitTest.java b/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/ExportLogsStatsDUnitTest.java
index de2ea64..92d0268 100644
--- a/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/ExportLogsStatsDUnitTest.java
+++ b/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/ExportLogsStatsDUnitTest.java
@@ -19,7 +19,7 @@ import static org.apache.geode.distributed.ConfigurationProperties.HTTP_SERVICE_
import static org.apache.geode.distributed.ConfigurationProperties.HTTP_SERVICE_PORT;
import static org.apache.geode.distributed.ConfigurationProperties.JMX_MANAGER_PORT;
import static org.apache.geode.distributed.ConfigurationProperties.STATISTIC_ARCHIVE_FILE;
-import static org.apache.geode.management.internal.cli.commands.ExportLogCommand.ONLY_DATE_FORMAT;
+import static org.apache.geode.management.internal.cli.commands.ExportLogsCommand.ONLY_DATE_FORMAT;
import static org.assertj.core.api.Assertions.assertThat;
import com.google.common.collect.Sets;