You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by bs...@apache.org on 2017/08/15 23:10:27 UTC

[16/50] [abbrv] geode git commit: GEODE-3436: revert recent refactoring of GFSH commands

http://git-wip-us.apache.org/repos/asf/geode/blob/645a32d0/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/DurableClientCommands.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/DurableClientCommands.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/DurableClientCommands.java
new file mode 100644
index 0000000..c5d859e
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/DurableClientCommands.java
@@ -0,0 +1,420 @@
+/*
+ * 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 java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+
+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.management.cli.CliMetaData;
+import org.apache.geode.management.cli.ConverterHint;
+import org.apache.geode.management.cli.Result;
+import org.apache.geode.management.internal.cli.CliUtil;
+import org.apache.geode.management.internal.cli.domain.DurableCqNamesResult;
+import org.apache.geode.management.internal.cli.domain.MemberResult;
+import org.apache.geode.management.internal.cli.domain.SubscriptionQueueSizeResult;
+import org.apache.geode.management.internal.cli.functions.CloseDurableClientFunction;
+import org.apache.geode.management.internal.cli.functions.CloseDurableCqFunction;
+import org.apache.geode.management.internal.cli.functions.GetSubscriptionQueueSizeFunction;
+import org.apache.geode.management.internal.cli.functions.ListDurableCqNamesFunction;
+import org.apache.geode.management.internal.cli.i18n.CliStrings;
+import org.apache.geode.management.internal.cli.result.ErrorResultData;
+import org.apache.geode.management.internal.cli.result.InfoResultData;
+import org.apache.geode.management.internal.cli.result.ResultBuilder;
+import org.apache.geode.management.internal.cli.result.TabularResultData;
+import org.apache.geode.management.internal.security.ResourceOperation;
+import org.apache.geode.security.ResourcePermission.Operation;
+import org.apache.geode.security.ResourcePermission.Resource;
+import org.apache.geode.security.ResourcePermission.Target;
+
+/**
+ * The DurableClientCommands class encapsulates all GemFire shell (Gfsh) commands related to durable
+ * clients and cqs defined in GemFire.
+ * </p>
+ */
+@SuppressWarnings("unused")
+public class DurableClientCommands implements GfshCommand {
+
+  private static final ListDurableCqNamesFunction listDurableCqNamesFunction =
+      new ListDurableCqNamesFunction();
+  private static final CloseDurableClientFunction closeDurableClientFunction =
+      new CloseDurableClientFunction();
+  private static final CloseDurableCqFunction closeDurableCqFunction = new CloseDurableCqFunction();
+  private static final GetSubscriptionQueueSizeFunction countDurableCqEvents =
+      new GetSubscriptionQueueSizeFunction();
+
+  @CliCommand(value = CliStrings.LIST_DURABLE_CQS, help = CliStrings.LIST_DURABLE_CQS__HELP)
+  @CliMetaData()
+  @ResourceOperation(resource = Resource.CLUSTER, operation = Operation.READ)
+  public Result listDurableClientCqs(
+      @CliOption(key = CliStrings.LIST_DURABLE_CQS__DURABLECLIENTID, mandatory = true,
+          help = CliStrings.LIST_DURABLE_CQS__DURABLECLIENTID__HELP) final String durableClientId,
+
+      @CliOption(key = {CliStrings.MEMBER, CliStrings.MEMBERS},
+          help = CliStrings.LIST_DURABLE_CQS__MEMBER__HELP,
+          optionContext = ConverterHint.MEMBERIDNAME) final String[] memberNameOrId,
+
+      @CliOption(key = {CliStrings.GROUP, CliStrings.GROUPS},
+          help = CliStrings.LIST_DURABLE_CQS__GROUP__HELP,
+          optionContext = ConverterHint.MEMBERGROUP) final String[] group) {
+    Result result;
+    try {
+
+      boolean noResults = true;
+      Set<DistributedMember> targetMembers = CliUtil.findMembers(group, memberNameOrId);
+
+      if (targetMembers.isEmpty()) {
+        return ResultBuilder.createUserErrorResult(CliStrings.NO_MEMBERS_FOUND_MESSAGE);
+      }
+
+      final ResultCollector<?, ?> rc =
+          CliUtil.executeFunction(new ListDurableCqNamesFunction(), durableClientId, targetMembers);
+      final List<DurableCqNamesResult> results = (List<DurableCqNamesResult>) rc.getResult();
+      Map<String, List<String>> memberCqNamesMap = new TreeMap<>();
+      Map<String, List<String>> errorMessageNodes = new HashMap<>();
+      Map<String, List<String>> exceptionMessageNodes = new HashMap<>();
+
+      for (DurableCqNamesResult memberResult : results) {
+        if (memberResult != null) {
+          if (memberResult.isSuccessful()) {
+            memberCqNamesMap.put(memberResult.getMemberNameOrId(), memberResult.getCqNamesList());
+          } else {
+            if (memberResult.isOpPossible()) {
+              groupByMessage(memberResult.getExceptionMessage(), memberResult.getMemberNameOrId(),
+                  exceptionMessageNodes);
+            } else {
+              groupByMessage(memberResult.getErrorMessage(), memberResult.getMemberNameOrId(),
+                  errorMessageNodes);
+            }
+          }
+        }
+      }
+
+      if (!memberCqNamesMap.isEmpty()) {
+        TabularResultData table = ResultBuilder.createTabularResultData();
+        Set<String> members = memberCqNamesMap.keySet();
+
+        for (String member : members) {
+          boolean isFirst = true;
+          List<String> cqNames = memberCqNamesMap.get(member);
+          for (String cqName : cqNames) {
+            if (isFirst) {
+              isFirst = false;
+              table.accumulate(CliStrings.MEMBER, member);
+            } else {
+              table.accumulate(CliStrings.MEMBER, "");
+            }
+            table.accumulate(CliStrings.LIST_DURABLE_CQS__NAME, cqName);
+          }
+        }
+        result = ResultBuilder.buildResult(table);
+      } else {
+        String errorHeader =
+            CliStrings.format(CliStrings.LIST_DURABLE_CQS__FAILURE__HEADER, durableClientId);
+        result = ResultBuilder.buildResult(
+            buildFailureData(null, exceptionMessageNodes, errorMessageNodes, errorHeader));
+      }
+    } catch (Exception e) {
+      result = ResultBuilder.createGemFireErrorResult(e.getMessage());
+    }
+
+    return result;
+  }
+
+  @CliCommand(value = CliStrings.COUNT_DURABLE_CQ_EVENTS,
+      help = CliStrings.COUNT_DURABLE_CQ_EVENTS__HELP)
+  @CliMetaData()
+  @ResourceOperation(resource = Resource.CLUSTER, operation = Operation.READ)
+  public Result countDurableCqEvents(
+      @CliOption(key = CliStrings.COUNT_DURABLE_CQ_EVENTS__DURABLE__CLIENT__ID, mandatory = true,
+          help = CliStrings.COUNT_DURABLE_CQ_EVENTS__DURABLE__CLIENT__ID__HELP) final String durableClientId,
+      @CliOption(key = CliStrings.COUNT_DURABLE_CQ_EVENTS__DURABLE__CQ__NAME,
+          help = CliStrings.COUNT_DURABLE_CQ_EVENTS__DURABLE__CQ__NAME__HELP) final String cqName,
+      @CliOption(key = {CliStrings.MEMBER, CliStrings.MEMBERS},
+          help = CliStrings.COUNT_DURABLE_CQ_EVENTS__MEMBER__HELP,
+          optionContext = ConverterHint.MEMBERIDNAME) final String[] memberNameOrId,
+      @CliOption(key = {CliStrings.GROUP, CliStrings.GROUPS},
+          help = CliStrings.COUNT_DURABLE_CQ_EVENTS__GROUP__HELP,
+          optionContext = ConverterHint.MEMBERGROUP) final String[] group) {
+
+    Result result;
+    try {
+      Set<DistributedMember> targetMembers = CliUtil.findMembers(group, memberNameOrId);
+
+      if (targetMembers.isEmpty()) {
+        return ResultBuilder.createUserErrorResult(CliStrings.NO_MEMBERS_FOUND_MESSAGE);
+      }
+
+      String[] params = new String[2];
+      params[0] = durableClientId;
+      params[1] = cqName;
+      final ResultCollector<?, ?> rc =
+          CliUtil.executeFunction(new GetSubscriptionQueueSizeFunction(), params, targetMembers);
+      final List<SubscriptionQueueSizeResult> funcResults =
+          (List<SubscriptionQueueSizeResult>) rc.getResult();
+
+      String queueSizeColumnName;
+
+      if (cqName != null && !cqName.isEmpty()) {
+        queueSizeColumnName = CliStrings
+            .format(CliStrings.COUNT_DURABLE_CQ_EVENTS__SUBSCRIPTION__QUEUE__SIZE__CLIENT, cqName);
+      } else {
+        queueSizeColumnName = CliStrings.format(
+            CliStrings.COUNT_DURABLE_CQ_EVENTS__SUBSCRIPTION__QUEUE__SIZE__CLIENT, durableClientId);
+      }
+      result = buildTableResultForQueueSize(funcResults, queueSizeColumnName);
+    } catch (Exception e) {
+      result = ResultBuilder.createGemFireErrorResult(e.getMessage());
+    }
+
+    return result;
+  }
+
+  @CliCommand(value = CliStrings.CLOSE_DURABLE_CLIENTS,
+      help = CliStrings.CLOSE_DURABLE_CLIENTS__HELP)
+  @CliMetaData()
+  @ResourceOperation(resource = Resource.CLUSTER, operation = Operation.MANAGE,
+      target = Target.QUERY)
+  public Result closeDurableClient(
+      @CliOption(key = CliStrings.CLOSE_DURABLE_CLIENTS__CLIENT__ID, mandatory = true,
+          help = CliStrings.CLOSE_DURABLE_CLIENTS__CLIENT__ID__HELP) final String durableClientId,
+      @CliOption(key = {CliStrings.MEMBER, CliStrings.MEMBERS},
+          help = CliStrings.CLOSE_DURABLE_CLIENTS__MEMBER__HELP,
+          optionContext = ConverterHint.MEMBERIDNAME) final String[] memberNameOrId,
+      @CliOption(key = {CliStrings.GROUP, CliStrings.GROUPS},
+          help = CliStrings.COUNT_DURABLE_CQ_EVENTS__GROUP__HELP,
+          optionContext = ConverterHint.MEMBERGROUP) final String[] group) {
+
+    Result result;
+    try {
+
+      Set<DistributedMember> targetMembers = CliUtil.findMembers(group, memberNameOrId);
+
+      if (targetMembers.isEmpty()) {
+        return ResultBuilder.createUserErrorResult(CliStrings.NO_MEMBERS_FOUND_MESSAGE);
+      }
+
+      final ResultCollector<?, ?> rc =
+          CliUtil.executeFunction(new CloseDurableClientFunction(), durableClientId, targetMembers);
+      final List<MemberResult> results = (List<MemberResult>) rc.getResult();
+      String failureHeader =
+          CliStrings.format(CliStrings.CLOSE_DURABLE_CLIENTS__FAILURE__HEADER, durableClientId);
+      String successHeader =
+          CliStrings.format(CliStrings.CLOSE_DURABLE_CLIENTS__SUCCESS, durableClientId);
+      result = buildResult(results, successHeader, failureHeader);
+    } catch (Exception e) {
+      result = ResultBuilder.createGemFireErrorResult(e.getMessage());
+    }
+    return result;
+  }
+
+
+  @CliCommand(value = CliStrings.CLOSE_DURABLE_CQS, help = CliStrings.CLOSE_DURABLE_CQS__HELP)
+  @CliMetaData()
+  @ResourceOperation(resource = Resource.CLUSTER, operation = Operation.MANAGE,
+      target = Target.QUERY)
+  public Result closeDurableCqs(@CliOption(key = CliStrings.CLOSE_DURABLE_CQS__DURABLE__CLIENT__ID,
+      mandatory = true,
+      help = CliStrings.CLOSE_DURABLE_CQS__DURABLE__CLIENT__ID__HELP) final String durableClientId,
+
+      @CliOption(key = CliStrings.CLOSE_DURABLE_CQS__NAME, mandatory = true,
+          help = CliStrings.CLOSE_DURABLE_CQS__NAME__HELP) final String cqName,
+
+      @CliOption(key = {CliStrings.MEMBER, CliStrings.MEMBERS},
+          help = CliStrings.CLOSE_DURABLE_CQS__MEMBER__HELP,
+          optionContext = ConverterHint.MEMBERIDNAME) final String[] memberNameOrId,
+
+      @CliOption(key = {CliStrings.GROUP, CliStrings.GROUPS},
+          help = CliStrings.CLOSE_DURABLE_CQS__GROUP__HELP,
+          optionContext = ConverterHint.MEMBERGROUP) final String[] group) {
+    Result result;
+    try {
+      Set<DistributedMember> targetMembers = CliUtil.findMembers(group, memberNameOrId);
+
+      if (targetMembers.isEmpty()) {
+        return ResultBuilder.createUserErrorResult(CliStrings.NO_MEMBERS_FOUND_MESSAGE);
+      }
+
+      String[] params = new String[2];
+      params[0] = durableClientId;
+      params[1] = cqName;
+
+      final ResultCollector<?, ?> rc =
+          CliUtil.executeFunction(new CloseDurableCqFunction(), params, targetMembers);
+      final List<MemberResult> results = (List<MemberResult>) rc.getResult();
+      String failureHeader =
+          CliStrings.format(CliStrings.CLOSE_DURABLE_CQS__FAILURE__HEADER, cqName, durableClientId);
+      String successHeader =
+          CliStrings.format(CliStrings.CLOSE_DURABLE_CQS__SUCCESS, cqName, durableClientId);
+      result = buildResult(results, successHeader, failureHeader);
+    } catch (Exception e) {
+      result = ResultBuilder.createGemFireErrorResult(e.getMessage());
+    }
+    return result;
+  }
+
+
+  private Result buildResult(List<MemberResult> results, String successHeader,
+      String failureHeader) {
+    Result result;
+    boolean failure = true;
+    boolean partialFailure = false;
+    Map<String, List<String>> errorMap = new HashMap<>();
+    Map<String, List<String>> successMap = new HashMap<>();
+    Map<String, List<String>> exceptionMap = new HashMap<>();
+
+    /*
+     * Aggregate the results from the members
+     */
+    for (MemberResult memberResult : results) {
+
+      if (memberResult.isSuccessful()) {
+        failure = false;
+        groupByMessage(memberResult.getSuccessMessage(), memberResult.getMemberNameOrId(),
+            successMap);
+      } else {
+
+        if (memberResult.isOpPossible()) {
+          partialFailure = true;
+          groupByMessage(memberResult.getExceptionMessage(), memberResult.getMemberNameOrId(),
+              exceptionMap);
+
+        } else {
+          groupByMessage(memberResult.getErrorMessage(), memberResult.getMemberNameOrId(),
+              errorMap);
+        }
+      }
+    }
+
+    if (!failure && !partialFailure) {
+      result = ResultBuilder.buildResult(buildSuccessData(successMap));
+    } else {
+      result = ResultBuilder
+          .buildResult(buildFailureData(successMap, exceptionMap, errorMap, failureHeader));
+    }
+    return result;
+  }
+
+  private Result buildTableResultForQueueSize(List<SubscriptionQueueSizeResult> results,
+      String queueSizeColumnName) {
+    Result result;
+    boolean failure = true;
+
+    Map<String, List<String>> failureMap = new HashMap<>();
+    Map<String, Long> memberQueueSizeTable = new TreeMap<>();
+
+    /*
+     * Aggregate the results from the members
+     */
+    for (SubscriptionQueueSizeResult memberResult : results) {
+
+      if (memberResult.isSuccessful()) {
+        failure = false;
+        memberQueueSizeTable.put(memberResult.getMemberNameOrId(),
+            memberResult.getSubscriptionQueueSize());
+      } else {
+        groupByMessage(memberResult.getErrorMessage(), memberResult.getMemberNameOrId(),
+            failureMap);
+      }
+    }
+
+    if (!failure) {
+      TabularResultData table = ResultBuilder.createTabularResultData();
+
+      Set<String> members = memberQueueSizeTable.keySet();
+
+      for (String member : members) {
+        long queueSize = memberQueueSizeTable.get(member);
+        table.accumulate(CliStrings.MEMBER, member);
+        table.accumulate(queueSizeColumnName, queueSize);
+      }
+      result = ResultBuilder.buildResult(table);
+
+    } else {
+      ErrorResultData erd = ResultBuilder.createErrorResultData();
+      buildErrorResult(erd, failureMap);
+      result = ResultBuilder.buildResult(erd);
+    }
+    return result;
+  }
+
+  private void groupByMessage(String message, String memberNameOrId,
+      Map<String, List<String>> map) {
+    List<String> members = map.get(message);
+
+    if (members == null) {
+      members = new LinkedList<>();
+    }
+    members.add(memberNameOrId);
+    map.put(message, members);
+  }
+
+
+  private InfoResultData buildSuccessData(Map<String, List<String>> successMap) {
+    InfoResultData ird = ResultBuilder.createInfoResultData();
+    Set<String> successMessages = successMap.keySet();
+
+    for (String successMessage : successMessages) {
+      ird.addLine(CliStrings.format(CliStrings.ACTION_SUCCEEDED_ON_MEMBER, successMessage));
+
+      List<String> successfulMembers = successMap.get(successMessage);
+      int num = 0;
+      for (String member : successfulMembers) {
+        ird.addLine("" + ++num + "." + member);
+      }
+      ird.addLine("\n");
+    }
+    return ird;
+  }
+
+  private ErrorResultData buildFailureData(Map<String, List<String>> successMap,
+      Map<String, List<String>> exceptionMap, Map<String, List<String>> errorMap,
+      String errorHeader) {
+    ErrorResultData erd = ResultBuilder.createErrorResultData();
+    buildErrorResult(erd, successMap);
+    erd.addLine("\n");
+    erd.addLine(errorHeader);
+    buildErrorResult(erd, exceptionMap);
+    buildErrorResult(erd, errorMap);
+    return erd;
+  }
+
+  private void buildErrorResult(ErrorResultData erd, Map<String, List<String>> resultMap) {
+    if (resultMap != null && !resultMap.isEmpty()) {
+      Set<String> messages = resultMap.keySet();
+
+      for (String message : messages) {
+        erd.addLine("\n");
+        erd.addLine(message);
+        erd.addLine(CliStrings.OCCURRED_ON_MEMBERS);
+        List<String> members = resultMap.get(message);
+        int num = 0;
+        for (String member : members) {
+          ++num;
+          erd.addLine("" + num + "." + member);
+        }
+      }
+    }
+  }
+}
+

http://git-wip-us.apache.org/repos/asf/geode/blob/645a32d0/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/DurableClientCommandsResultBuilder.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/DurableClientCommandsResultBuilder.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/DurableClientCommandsResultBuilder.java
deleted file mode 100644
index 743602a..0000000
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/DurableClientCommandsResultBuilder.java
+++ /dev/null
@@ -1,164 +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 java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
-
-import org.apache.geode.management.cli.Result;
-import org.apache.geode.management.internal.cli.domain.MemberResult;
-import org.apache.geode.management.internal.cli.domain.SubscriptionQueueSizeResult;
-import org.apache.geode.management.internal.cli.i18n.CliStrings;
-import org.apache.geode.management.internal.cli.result.ErrorResultData;
-import org.apache.geode.management.internal.cli.result.InfoResultData;
-import org.apache.geode.management.internal.cli.result.ResultBuilder;
-import org.apache.geode.management.internal.cli.result.TabularResultData;
-
-public class DurableClientCommandsResultBuilder {
-  public Result buildResult(List<MemberResult> results, String successHeader,
-      String failureHeader) {
-    Result result;
-    boolean failure = true;
-    boolean partialFailure = false;
-    Map<String, List<String>> errorMap = new HashMap<>();
-    Map<String, List<String>> successMap = new HashMap<>();
-    Map<String, List<String>> exceptionMap = new HashMap<>();
-
-    // Aggregate the results from the members
-    for (MemberResult memberResult : results) {
-      if (memberResult.isSuccessful()) {
-        failure = false;
-        groupByMessage(memberResult.getSuccessMessage(), memberResult.getMemberNameOrId(),
-            successMap);
-      } else {
-        if (memberResult.isOpPossible()) {
-          partialFailure = true;
-          groupByMessage(memberResult.getExceptionMessage(), memberResult.getMemberNameOrId(),
-              exceptionMap);
-        } else {
-          groupByMessage(memberResult.getErrorMessage(), memberResult.getMemberNameOrId(),
-              errorMap);
-        }
-      }
-    }
-
-    if (!failure && !partialFailure) {
-      result = ResultBuilder.buildResult(buildSuccessData(successMap));
-    } else {
-      result = ResultBuilder
-          .buildResult(buildFailureData(successMap, exceptionMap, errorMap, failureHeader));
-    }
-    return result;
-  }
-
-  Result buildTableResultForQueueSize(List<SubscriptionQueueSizeResult> results,
-      String queueSizeColumnName) {
-    Result result;
-    boolean failure = true;
-
-    Map<String, List<String>> failureMap = new HashMap<>();
-    Map<String, Long> memberQueueSizeTable = new TreeMap<>();
-
-    // Aggregate the results from the members
-    for (SubscriptionQueueSizeResult memberResult : results) {
-      if (memberResult.isSuccessful()) {
-        failure = false;
-        memberQueueSizeTable.put(memberResult.getMemberNameOrId(),
-            memberResult.getSubscriptionQueueSize());
-      } else {
-        groupByMessage(memberResult.getErrorMessage(), memberResult.getMemberNameOrId(),
-            failureMap);
-      }
-    }
-
-    if (!failure) {
-      TabularResultData table = ResultBuilder.createTabularResultData();
-      Set<String> members = memberQueueSizeTable.keySet();
-
-      for (String member : members) {
-        long queueSize = memberQueueSizeTable.get(member);
-        table.accumulate(CliStrings.MEMBER, member);
-        table.accumulate(queueSizeColumnName, queueSize);
-      }
-      result = ResultBuilder.buildResult(table);
-    } else {
-      ErrorResultData erd = ResultBuilder.createErrorResultData();
-      buildErrorResult(erd, failureMap);
-      result = ResultBuilder.buildResult(erd);
-    }
-    return result;
-  }
-
-  void groupByMessage(String message, String memberNameOrId, Map<String, List<String>> map) {
-    List<String> members = map.get(message);
-    if (members == null) {
-      members = new LinkedList<>();
-    }
-    members.add(memberNameOrId);
-    map.put(message, members);
-  }
-
-
-  private InfoResultData buildSuccessData(Map<String, List<String>> successMap) {
-    InfoResultData ird = ResultBuilder.createInfoResultData();
-    Set<String> successMessages = successMap.keySet();
-
-    for (String successMessage : successMessages) {
-      ird.addLine(CliStrings.format(CliStrings.ACTION_SUCCEEDED_ON_MEMBER, successMessage));
-      List<String> successfulMembers = successMap.get(successMessage);
-      int num = 0;
-      for (String member : successfulMembers) {
-        ird.addLine("" + ++num + "." + member);
-      }
-      ird.addLine("\n");
-    }
-    return ird;
-  }
-
-  ErrorResultData buildFailureData(Map<String, List<String>> successMap,
-      Map<String, List<String>> exceptionMap, Map<String, List<String>> errorMap,
-      String errorHeader) {
-    ErrorResultData erd = ResultBuilder.createErrorResultData();
-    buildErrorResult(erd, successMap);
-    erd.addLine("\n");
-    erd.addLine(errorHeader);
-    buildErrorResult(erd, exceptionMap);
-    buildErrorResult(erd, errorMap);
-    return erd;
-  }
-
-  private void buildErrorResult(ErrorResultData erd, Map<String, List<String>> resultMap) {
-    if (resultMap != null && !resultMap.isEmpty()) {
-      Set<String> messages = resultMap.keySet();
-
-      for (String message : messages) {
-        erd.addLine("\n");
-        erd.addLine(message);
-        erd.addLine(CliStrings.OCCURRED_ON_MEMBERS);
-        List<String> members = resultMap.get(message);
-        int num = 0;
-        for (String member : members) {
-          ++num;
-          erd.addLine("" + num + "." + member);
-        }
-      }
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/geode/blob/645a32d0/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ExecuteFunctionCommand.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ExecuteFunctionCommand.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ExecuteFunctionCommand.java
deleted file mode 100644
index dad9742..0000000
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ExecuteFunctionCommand.java
+++ /dev/null
@@ -1,330 +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 java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-import java.util.stream.Stream;
-
-import org.apache.commons.lang.BooleanUtils;
-import org.springframework.shell.core.annotation.CliCommand;
-import org.springframework.shell.core.annotation.CliOption;
-
-import org.apache.geode.cache.Region;
-import org.apache.geode.cache.execute.Execution;
-import org.apache.geode.cache.execute.Function;
-import org.apache.geode.cache.execute.FunctionException;
-import org.apache.geode.cache.execute.FunctionService;
-import org.apache.geode.cache.execute.ResultCollector;
-import org.apache.geode.distributed.DistributedMember;
-import org.apache.geode.internal.ClassPathLoader;
-import org.apache.geode.internal.cache.InternalCache;
-import org.apache.geode.management.DistributedRegionMXBean;
-import org.apache.geode.management.ManagementService;
-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.MBeanJMXAdapter;
-import org.apache.geode.management.internal.cli.CliUtil;
-import org.apache.geode.management.internal.cli.LogWrapper;
-import org.apache.geode.management.internal.cli.functions.UserFunctionExecution;
-import org.apache.geode.management.internal.cli.i18n.CliStrings;
-import org.apache.geode.management.internal.cli.result.CompositeResultData;
-import org.apache.geode.management.internal.cli.result.ErrorResultData;
-import org.apache.geode.management.internal.cli.result.ResultBuilder;
-import org.apache.geode.management.internal.cli.result.TabularResultData;
-import org.apache.geode.management.internal.security.ResourceOperation;
-import org.apache.geode.security.ResourcePermission;
-
-public class ExecuteFunctionCommand implements GfshCommand {
-  @CliCommand(value = CliStrings.EXECUTE_FUNCTION, help = CliStrings.EXECUTE_FUNCTION__HELP)
-  @CliMetaData(relatedTopic = {CliStrings.TOPIC_GEODE_FUNCTION})
-  @ResourceOperation(resource = ResourcePermission.Resource.DATA,
-      operation = ResourcePermission.Operation.WRITE)
-  public Result executeFunction(
-      // TODO: Add optioncontext for functionID
-      @CliOption(key = CliStrings.EXECUTE_FUNCTION__ID, mandatory = true,
-          help = CliStrings.EXECUTE_FUNCTION__ID__HELP) String functionId,
-      @CliOption(key = {CliStrings.GROUP, CliStrings.GROUPS},
-          optionContext = ConverterHint.MEMBERGROUP,
-          help = CliStrings.EXECUTE_FUNCTION__ONGROUPS__HELP) String[] onGroups,
-      @CliOption(key = CliStrings.MEMBER, optionContext = ConverterHint.MEMBERIDNAME,
-          help = CliStrings.EXECUTE_FUNCTION__ONMEMBER__HELP) String onMember,
-      @CliOption(key = CliStrings.EXECUTE_FUNCTION__ONREGION,
-          optionContext = ConverterHint.REGION_PATH,
-          help = CliStrings.EXECUTE_FUNCTION__ONREGION__HELP) String onRegion,
-      @CliOption(key = CliStrings.EXECUTE_FUNCTION__ARGUMENTS,
-          help = CliStrings.EXECUTE_FUNCTION__ARGUMENTS__HELP) String[] arguments,
-      @CliOption(key = CliStrings.EXECUTE_FUNCTION__RESULTCOLLECTOR,
-          help = CliStrings.EXECUTE_FUNCTION__RESULTCOLLECTOR__HELP) String resultCollector,
-      @CliOption(key = CliStrings.EXECUTE_FUNCTION__FILTER,
-          help = CliStrings.EXECUTE_FUNCTION__FILTER__HELP) String filterString) {
-    CompositeResultData executeFunctionResultTable = ResultBuilder.createCompositeResultData();
-    TabularResultData resultTable = executeFunctionResultTable.addSection().addTable("Table1");
-    String headerText = "Execution summary";
-    resultTable.setHeader(headerText);
-    ResultCollector resultCollectorInstance = null;
-    Set<String> filters = new HashSet<>();
-    Execution execution;
-    if (functionId != null) {
-      functionId = functionId.trim();
-    }
-    if (onRegion != null) {
-      onRegion = onRegion.trim();
-    }
-    if (onMember != null) {
-      onMember = onMember.trim();
-    }
-    if (filterString != null) {
-      filterString = filterString.trim();
-    }
-
-    try {
-      // validate otherwise return right away. no need to process anything
-      if (functionId == null || functionId.length() == 0) {
-        ErrorResultData errorResultData =
-            ResultBuilder.createErrorResultData().setErrorCode(ResultBuilder.ERRORCODE_DEFAULT)
-                .addLine(CliStrings.EXECUTE_FUNCTION__MSG__MISSING_FUNCTIONID);
-        return ResultBuilder.buildResult(errorResultData);
-      }
-
-      if (moreThanOneIsTrue(onRegion != null, onMember != null, onGroups != null)) {
-        // Provide Only one of region/member/groups
-        ErrorResultData errorResultData =
-            ResultBuilder.createErrorResultData().setErrorCode(ResultBuilder.ERRORCODE_DEFAULT)
-                .addLine(CliStrings.EXECUTE_FUNCTION__MSG__OPTIONS);
-        return ResultBuilder.buildResult(errorResultData);
-      } else if ((onRegion == null || onRegion.length() == 0) && (filterString != null)) {
-        ErrorResultData errorResultData = ResultBuilder.createErrorResultData()
-            .setErrorCode(ResultBuilder.ERRORCODE_DEFAULT)
-            .addLine(CliStrings.EXECUTE_FUNCTION__MSG__MEMBER_SHOULD_NOT_HAVE_FILTER_FOR_EXECUTION);
-        return ResultBuilder.buildResult(errorResultData);
-      }
-
-      InternalCache cache = getCache();
-
-      if (resultCollector != null) {
-        resultCollectorInstance =
-            (ResultCollector) ClassPathLoader.getLatest().forName(resultCollector).newInstance();
-      }
-
-      if (filterString != null && filterString.length() > 0) {
-        filters.add(filterString);
-      }
-
-      if (onRegion == null && onMember == null && onGroups == null) {
-        // run function on all the members excluding locators bug#46113
-        // if user wish to execute on locator then he can choose --member or --group option
-        Set<DistributedMember> dsMembers = CliUtil.getAllNormalMembers(cache);
-        if (dsMembers.size() > 0) {
-          new UserFunctionExecution();
-          LogWrapper.getInstance().info(CliStrings
-              .format(CliStrings.EXECUTE_FUNCTION__MSG__EXECUTING_0_ON_ENTIRE_DS, functionId));
-          for (DistributedMember member : dsMembers) {
-            executeAndGetResults(functionId, null, resultCollector, arguments, member, resultTable,
-                null);
-          }
-          return ResultBuilder.buildResult(resultTable);
-        } else {
-          return ResultBuilder
-              .createUserErrorResult(CliStrings.EXECUTE_FUNCTION__MSG__DS_HAS_NO_MEMBERS);
-        }
-      } else if (onRegion != null && onRegion.length() > 0) {
-        if (cache.getRegion(onRegion) == null) {
-          // find a member where region is present
-          DistributedRegionMXBean bean = ManagementService.getManagementService(getCache())
-              .getDistributedRegionMXBean(onRegion);
-          if (bean == null) {
-            bean = ManagementService.getManagementService(getCache())
-                .getDistributedRegionMXBean(Region.SEPARATOR + onRegion);
-
-            if (bean == null) {
-              return ResultBuilder.createGemFireErrorResult(CliStrings
-                  .format(CliStrings.EXECUTE_FUNCTION__MSG__MXBEAN_0_FOR_NOT_FOUND, onRegion));
-            }
-          }
-
-          DistributedMember member = null;
-          String[] membersName = bean.getMembers();
-          Set<DistributedMember> dsMembers = CliUtil.getAllMembers(cache);
-          Iterator it = dsMembers.iterator();
-          boolean matchFound = false;
-
-          if (membersName.length > 0) {
-            while (it.hasNext() && !matchFound) {
-              DistributedMember dsmember = (DistributedMember) it.next();
-              for (String memberName : membersName) {
-                if (MBeanJMXAdapter.getMemberNameOrId(dsmember).equals(memberName)) {
-                  member = dsmember;
-                  matchFound = true;
-                  break;
-                }
-              }
-            }
-          }
-          if (matchFound) {
-            executeAndGetResults(functionId, filterString, resultCollector, arguments, member,
-                resultTable, onRegion);
-            return ResultBuilder.buildResult(resultTable);
-          } else {
-            return ResultBuilder.createGemFireErrorResult(CliStrings.format(
-                CliStrings.EXECUTE_FUNCTION__MSG__NO_ASSOCIATED_MEMBER_REGION, " " + onRegion));
-          }
-        } else {
-          execution = FunctionService.onRegion(cache.getRegion(onRegion));
-          if (execution != null) {
-            if (resultCollectorInstance != null) {
-              execution = execution.withCollector(resultCollectorInstance);
-            }
-            if (filters.size() > 0) {
-              execution = execution.withFilter(filters);
-            }
-            if (arguments != null && arguments.length > 0) {
-              execution = execution.setArguments(arguments);
-            }
-
-            try {
-              List<Object> results = (List<Object>) execution.execute(functionId).getResult();
-              if (results.size() > 0) {
-                StringBuilder strResult = new StringBuilder();
-                for (Object obj : results) {
-                  strResult.append(obj);
-                }
-                toTabularResultData(resultTable,
-                    cache.getDistributedSystem().getDistributedMember().getId(),
-                    strResult.toString());
-              }
-              return ResultBuilder.buildResult(resultTable);
-            } catch (FunctionException e) {
-              return ResultBuilder.createGemFireErrorResult(CliStrings.format(
-                  CliStrings.EXECUTE_FUNCTION__MSG__ERROR_IN_EXECUTING_0_ON_REGION_1_DETAILS_2,
-                  functionId, onRegion, e.getMessage()));
-            }
-          } else {
-            return ResultBuilder.createGemFireErrorResult(CliStrings.format(
-                CliStrings.EXECUTE_FUNCTION__MSG__ERROR_IN_EXECUTING_0_ON_REGION_1_DETAILS_2,
-                functionId, onRegion,
-                CliStrings.EXECUTE_FUNCTION__MSG__ERROR_IN_RETRIEVING_EXECUTOR));
-          }
-        }
-      } else if (onGroups != null) {
-        // execute on group members
-        Set<DistributedMember> dsMembers = new HashSet<>();
-        for (String grp : onGroups) {
-          dsMembers.addAll(cache.getDistributedSystem().getGroupMembers(grp));
-        }
-
-        if (dsMembers.size() > 0) {
-          for (DistributedMember member : dsMembers) {
-            executeAndGetResults(functionId, filterString, resultCollector, arguments, member,
-                resultTable, onRegion);
-          }
-          return ResultBuilder.buildResult(resultTable);
-        } else {
-          StringBuilder grps = new StringBuilder();
-          for (String grp : onGroups) {
-            grps.append(grp);
-            grps.append(", ");
-          }
-          return ResultBuilder.createUserErrorResult(
-              CliStrings.format(CliStrings.EXECUTE_FUNCTION__MSG__GROUPS_0_HAS_NO_MEMBERS,
-                  grps.toString().substring(0, grps.toString().length() - 1)));
-        }
-      } else if (onMember != null && onMember.length() > 0) {
-        DistributedMember member = CliUtil.getDistributedMemberByNameOrId(onMember); // fix for bug
-        // 45658
-        if (member != null) {
-          executeAndGetResults(functionId, filterString, resultCollector, arguments, member,
-              resultTable, onRegion);
-        } else {
-          toTabularResultData(resultTable, onMember, CliStrings
-              .format(CliStrings.EXECUTE_FUNCTION__MSG__NO_ASSOCIATED_MEMBER + " " + onMember));
-        }
-        return ResultBuilder.buildResult(resultTable);
-      }
-    } catch (Exception e) {
-      ErrorResultData errorResultData = ResultBuilder.createErrorResultData()
-          .setErrorCode(ResultBuilder.ERRORCODE_DEFAULT).addLine(e.getMessage());
-      return ResultBuilder.buildResult(errorResultData);
-    }
-    return null;
-  }
-
-  private boolean moreThanOneIsTrue(Boolean... values) {
-    return Stream.of(values).mapToInt(BooleanUtils::toInteger).sum() > 1;
-  }
-
-  private void executeAndGetResults(String functionId, String filterString, String resultCollector,
-      String[] arguments, DistributedMember member, TabularResultData resultTable,
-      String onRegion) {
-    StringBuilder resultMessage = new StringBuilder();
-    try {
-      Function function = new UserFunctionExecution();
-      Object[] args = new Object[5];
-      args[0] = functionId;
-      if (filterString != null) {
-        args[1] = filterString;
-      }
-      if (resultCollector != null) {
-        args[2] = resultCollector;
-      }
-      if (arguments != null && arguments.length > 0) {
-        args[3] = "";
-        for (String str : arguments) {
-          // send via CSV separated value format
-          if (str != null) {
-            args[3] = args[3] + str + ",";
-          }
-        }
-      }
-      args[4] = onRegion;
-
-      Execution execution = FunctionService.onMember(member).setArguments(args);
-      if (execution != null) {
-        List<Object> results = (List<Object>) execution.execute(function).getResult();
-        if (results != null) {
-          for (Object resultObj : results) {
-            if (resultObj != null) {
-              if (resultObj instanceof String) {
-                resultMessage.append(((String) resultObj));
-              } else if (resultObj instanceof Exception) {
-                resultMessage.append(((Exception) resultObj).getMessage());
-              } else {
-                resultMessage.append(resultObj);
-              }
-            }
-          }
-        }
-        toTabularResultData(resultTable, member.getId(), resultMessage.toString());
-      } else {
-        toTabularResultData(resultTable, member.getId(),
-            CliStrings.EXECUTE_FUNCTION__MSG__ERROR_IN_RETRIEVING_EXECUTOR);
-      }
-    } catch (Exception e) {
-      resultMessage.append(CliStrings.format(
-          CliStrings.EXECUTE_FUNCTION__MSG__COULD_NOT_EXECUTE_FUNCTION_0_ON_MEMBER_1_ERROR_2,
-          functionId, member.getId(), e.getMessage()));
-      toTabularResultData(resultTable, member.getId(), resultMessage.toString());
-    }
-  }
-
-  private void toTabularResultData(TabularResultData table, String memberId, String memberResult) {
-    table.accumulate("Member ID/Name", memberId);
-    table.accumulate("Function Execution Result", memberResult);
-  }
-}

http://git-wip-us.apache.org/repos/asf/geode/blob/645a32d0/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ExportConfigCommand.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ExportConfigCommand.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ExportConfigCommand.java
deleted file mode 100644
index 672ec88..0000000
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ExportConfigCommand.java
+++ /dev/null
@@ -1,159 +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 java.io.File;
-import java.io.IOException;
-import java.nio.file.Path;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.springframework.shell.core.annotation.CliCommand;
-import org.springframework.shell.core.annotation.CliOption;
-
-import org.apache.geode.SystemFailure;
-import org.apache.geode.cache.execute.ResultCollector;
-import org.apache.geode.distributed.DistributedMember;
-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.CliFunctionResult;
-import org.apache.geode.management.internal.cli.functions.ExportConfigFunction;
-import org.apache.geode.management.internal.cli.i18n.CliStrings;
-import org.apache.geode.management.internal.cli.result.InfoResultData;
-import org.apache.geode.management.internal.cli.result.ResultBuilder;
-import org.apache.geode.management.internal.cli.shell.Gfsh;
-import org.apache.geode.management.internal.security.ResourceOperation;
-import org.apache.geode.security.ResourcePermission;
-
-public class ExportConfigCommand implements GfshCommand {
-  private final ExportConfigFunction exportConfigFunction = new ExportConfigFunction();
-
-  /**
-   * Export the cache configuration in XML format.
-   *
-   * @param member Member for which to write the configuration
-   * @param group Group or groups for which to write the configuration
-   * @return Results of the attempt to write the configuration
-   */
-  @CliCommand(value = {CliStrings.EXPORT_CONFIG}, help = CliStrings.EXPORT_CONFIG__HELP)
-  @CliMetaData(
-      interceptor = "org.apache.geode.management.internal.cli.commands.ExportConfigCommand$Interceptor",
-      relatedTopic = {CliStrings.TOPIC_GEODE_CONFIG})
-  @ResourceOperation(resource = ResourcePermission.Resource.CLUSTER,
-      operation = ResourcePermission.Operation.READ)
-  public Result exportConfig(
-      @CliOption(key = {CliStrings.MEMBER, CliStrings.MEMBERS},
-          optionContext = ConverterHint.ALL_MEMBER_IDNAME,
-          help = CliStrings.EXPORT_CONFIG__MEMBER__HELP) String[] member,
-      @CliOption(key = {CliStrings.GROUP, CliStrings.GROUPS},
-          optionContext = ConverterHint.MEMBERGROUP,
-          help = CliStrings.EXPORT_CONFIG__GROUP__HELP) String[] group,
-      @CliOption(key = {CliStrings.EXPORT_CONFIG__DIR},
-          help = CliStrings.EXPORT_CONFIG__DIR__HELP) String dir) {
-    InfoResultData infoData = ResultBuilder.createInfoResultData();
-
-    Set<DistributedMember> targetMembers = CliUtil.findMembers(group, member);
-    if (targetMembers.isEmpty()) {
-      return ResultBuilder.createUserErrorResult(CliStrings.NO_MEMBERS_FOUND_MESSAGE);
-    }
-
-    try {
-      ResultCollector<?, ?> rc =
-          CliUtil.executeFunction(this.exportConfigFunction, null, targetMembers);
-      List<CliFunctionResult> results = CliFunctionResult.cleanResults((List<?>) rc.getResult());
-
-      for (CliFunctionResult result : results) {
-        if (result.getThrowable() != null) {
-          infoData.addLine(CliStrings.format(CliStrings.EXPORT_CONFIG__MSG__EXCEPTION,
-              result.getMemberIdOrName(), result.getThrowable()));
-        } else if (result.isSuccessful()) {
-          String cacheFileName = result.getMemberIdOrName() + "-cache.xml";
-          String propsFileName = result.getMemberIdOrName() + "-gf.properties";
-          String[] fileContent = (String[]) result.getSerializables();
-          infoData.addAsFile(cacheFileName, fileContent[0], "Downloading Cache XML file: {0}",
-              false);
-          infoData.addAsFile(propsFileName, fileContent[1], "Downloading properties file: {0}",
-              false);
-        }
-      }
-      return ResultBuilder.buildResult(infoData);
-    } catch (VirtualMachineError e) {
-      SystemFailure.initiateFailure(e);
-      throw e;
-    } catch (Throwable th) {
-      SystemFailure.checkFailure();
-      th.printStackTrace(System.err);
-      return ResultBuilder
-          .createGemFireErrorResult(CliStrings.format(CliStrings.EXPORT_CONFIG__MSG__EXCEPTION,
-              th.getClass().getName() + ": " + th.getMessage()));
-    }
-  }
-
-  /**
-   * Interceptor used by gfsh to intercept execution of export config command at "shell".
-   */
-  public static class Interceptor extends AbstractCliAroundInterceptor {
-    private String saveDirString;
-
-    @Override
-    public Result preExecution(GfshParseResult parseResult) {
-      Map<String, String> paramValueMap = parseResult.getParamValueStrings();
-      String dir = paramValueMap.get("dir");
-      dir = (dir == null) ? null : dir.trim();
-
-      File saveDirFile = new File(".");
-      if (dir != null && !dir.isEmpty()) {
-        saveDirFile = new File(dir);
-        if (saveDirFile.exists()) {
-          if (!saveDirFile.isDirectory())
-            return ResultBuilder.createGemFireErrorResult(
-                CliStrings.format(CliStrings.EXPORT_CONFIG__MSG__NOT_A_DIRECTORY, dir));
-        } else if (!saveDirFile.mkdirs()) {
-          return ResultBuilder.createGemFireErrorResult(
-              CliStrings.format(CliStrings.EXPORT_CONFIG__MSG__CANNOT_CREATE_DIR, dir));
-        }
-      }
-      try {
-        if (!saveDirFile.canWrite()) {
-          return ResultBuilder.createGemFireErrorResult(CliStrings.format(
-              CliStrings.EXPORT_CONFIG__MSG__NOT_WRITEABLE, saveDirFile.getCanonicalPath()));
-        }
-      } catch (IOException ioex) {
-        return ResultBuilder.createGemFireErrorResult(
-            CliStrings.format(CliStrings.EXPORT_CONFIG__MSG__NOT_WRITEABLE, saveDirFile.getName()));
-      }
-
-      saveDirString = saveDirFile.getAbsolutePath();
-      return ResultBuilder.createInfoResult("OK");
-    }
-
-    @Override
-    public Result postExecution(GfshParseResult parseResult, Result commandResult, Path tempFile) {
-      if (commandResult.hasIncomingFiles()) {
-        try {
-          commandResult.saveIncomingFiles(saveDirString);
-        } catch (IOException ioex) {
-          Gfsh.getCurrentInstance().logSevere("Unable to export config", ioex);
-        }
-      }
-      return commandResult;
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/geode/blob/645a32d0/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ExportOfflineDiskStoreCommand.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ExportOfflineDiskStoreCommand.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ExportOfflineDiskStoreCommand.java
deleted file mode 100644
index c704364..0000000
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ExportOfflineDiskStoreCommand.java
+++ /dev/null
@@ -1,68 +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 java.io.File;
-
-import org.springframework.shell.core.annotation.CliCommand;
-import org.springframework.shell.core.annotation.CliOption;
-
-import org.apache.geode.SystemFailure;
-import org.apache.geode.internal.cache.DiskStoreImpl;
-import org.apache.geode.management.cli.CliMetaData;
-import org.apache.geode.management.cli.Result;
-import org.apache.geode.management.internal.cli.LogWrapper;
-import org.apache.geode.management.internal.cli.i18n.CliStrings;
-import org.apache.geode.management.internal.cli.result.ResultBuilder;
-
-public class ExportOfflineDiskStoreCommand implements GfshCommand {
-  @CliCommand(value = CliStrings.EXPORT_OFFLINE_DISK_STORE,
-      help = CliStrings.EXPORT_OFFLINE_DISK_STORE__HELP)
-  @CliMetaData(shellOnly = true, relatedTopic = {CliStrings.TOPIC_GEODE_DISKSTORE})
-  public Result exportOfflineDiskStore(
-      @CliOption(key = CliStrings.EXPORT_OFFLINE_DISK_STORE__DISKSTORENAME, mandatory = true,
-          help = CliStrings.EXPORT_OFFLINE_DISK_STORE__DISKSTORENAME__HELP) String diskStoreName,
-      @CliOption(key = CliStrings.EXPORT_OFFLINE_DISK_STORE__DISKDIRS, mandatory = true,
-          help = CliStrings.EXPORT_OFFLINE_DISK_STORE__DISKDIRS__HELP) String[] diskDirs,
-      @CliOption(key = CliStrings.EXPORT_OFFLINE_DISK_STORE__DIR, mandatory = true,
-          help = CliStrings.EXPORT_OFFLINE_DISK_STORE__DIR__HELP) String dir) {
-
-    try {
-      final File[] dirs = new File[diskDirs.length];
-      for (int i = 0; i < diskDirs.length; i++) {
-        dirs[i] = new File((diskDirs[i]));
-      }
-
-      File output = new File(dir);
-
-      // Note, this can consume a lot of memory, so this should
-      // not be moved to a separate process unless we provide a way for the user
-      // to configure the size of that process.
-      DiskStoreImpl.exportOfflineSnapshot(diskStoreName, dirs, output);
-      String resultString =
-          CliStrings.format(CliStrings.EXPORT_OFFLINE_DISK_STORE__SUCCESS, diskStoreName, dir);
-      return ResultBuilder.createInfoResult(resultString);
-    } catch (VirtualMachineError e) {
-      SystemFailure.initiateFailure(e);
-      throw e;
-    } catch (Throwable th) {
-      SystemFailure.checkFailure();
-      LogWrapper.getInstance().warning(th.getMessage(), th);
-      return ResultBuilder.createGemFireErrorResult(CliStrings
-          .format(CliStrings.EXPORT_OFFLINE_DISK_STORE__ERROR, diskStoreName, th.toString()));
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/geode/blob/645a32d0/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ExportStackTraceCommand.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ExportStackTraceCommand.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ExportStackTraceCommand.java
deleted file mode 100644
index 4f8693d..0000000
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ExportStackTraceCommand.java
+++ /dev/null
@@ -1,157 +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 java.io.BufferedInputStream;
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-import java.util.zip.GZIPInputStream;
-
-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.distributed.internal.InternalDistributedSystem;
-import org.apache.geode.internal.cache.InternalCache;
-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.CliUtil;
-import org.apache.geode.management.internal.cli.domain.StackTracesPerMember;
-import org.apache.geode.management.internal.cli.functions.GetStackTracesFunction;
-import org.apache.geode.management.internal.cli.i18n.CliStrings;
-import org.apache.geode.management.internal.cli.result.InfoResultData;
-import org.apache.geode.management.internal.cli.result.ResultBuilder;
-import org.apache.geode.management.internal.security.ResourceOperation;
-import org.apache.geode.security.ResourcePermission;
-
-public class ExportStackTraceCommand implements GfshCommand {
-  private final GetStackTracesFunction getStackTracesFunction = new GetStackTracesFunction();
-
-  /**
-   * Current implementation supports writing it to a file and returning the location of the file
-   */
-  @CliCommand(value = CliStrings.EXPORT_STACKTRACE, help = CliStrings.EXPORT_STACKTRACE__HELP)
-  @CliMetaData(relatedTopic = {CliStrings.TOPIC_GEODE_DEBUG_UTIL})
-  @ResourceOperation(resource = ResourcePermission.Resource.CLUSTER,
-      operation = ResourcePermission.Operation.READ)
-  public Result exportStackTrace(@CliOption(key = {CliStrings.MEMBER, CliStrings.MEMBERS},
-      optionContext = ConverterHint.ALL_MEMBER_IDNAME,
-      help = CliStrings.EXPORT_STACKTRACE__HELP) String[] memberNameOrId,
-
-      @CliOption(key = {CliStrings.GROUP, CliStrings.GROUPS},
-          optionContext = ConverterHint.ALL_MEMBER_IDNAME, help = CliStrings.GROUP) String[] group,
-
-      @CliOption(key = CliStrings.EXPORT_STACKTRACE__FILE,
-          help = CliStrings.EXPORT_STACKTRACE__FILE__HELP) String fileName,
-
-      @CliOption(key = CliStrings.EXPORT_STACKTRACE__FAIL__IF__FILE__PRESENT,
-          unspecifiedDefaultValue = "false",
-          help = CliStrings.EXPORT_STACKTRACE__FAIL__IF__FILE__PRESENT__HELP) boolean failIfFilePresent) {
-
-    Result result;
-    StringBuilder filePrefix = new StringBuilder("stacktrace");
-
-    if (fileName == null) {
-      fileName = filePrefix.append("_").append(System.currentTimeMillis()).toString();
-    }
-    final File outFile = new File(fileName);
-    try {
-      if (outFile.exists() && failIfFilePresent) {
-        return ResultBuilder.createShellClientErrorResult(CliStrings.format(
-            CliStrings.EXPORT_STACKTRACE__ERROR__FILE__PRESENT, outFile.getCanonicalPath()));
-      }
-
-
-      InternalCache cache = getCache();
-      InternalDistributedSystem ads = cache.getInternalDistributedSystem();
-
-      InfoResultData resultData = ResultBuilder.createInfoResultData();
-
-      Map<String, byte[]> dumps = new HashMap<>();
-      Set<DistributedMember> targetMembers = CliUtil.findMembers(group, memberNameOrId);
-      if (targetMembers.isEmpty()) {
-        return ResultBuilder.createUserErrorResult(CliStrings.NO_MEMBERS_FOUND_MESSAGE);
-      }
-
-      ResultCollector<?, ?> rc =
-          CliUtil.executeFunction(getStackTracesFunction, null, targetMembers);
-      ArrayList<Object> resultList = (ArrayList<Object>) rc.getResult();
-
-      for (Object resultObj : resultList) {
-        if (resultObj instanceof StackTracesPerMember) {
-          StackTracesPerMember stackTracePerMember = (StackTracesPerMember) resultObj;
-          dumps.put(stackTracePerMember.getMemberNameOrId(), stackTracePerMember.getStackTraces());
-        }
-      }
-
-      String filePath = writeStacksToFile(dumps, fileName);
-      resultData.addLine(CliStrings.format(CliStrings.EXPORT_STACKTRACE__SUCCESS, filePath));
-      resultData.addLine(CliStrings.EXPORT_STACKTRACE__HOST + ads.getDistributedMember().getHost());
-
-      result = ResultBuilder.buildResult(resultData);
-    } catch (IOException ex) {
-      result = ResultBuilder
-          .createGemFireErrorResult(CliStrings.EXPORT_STACKTRACE__ERROR + ex.getMessage());
-    }
-    return result;
-  }
-
-  /***
-   * Writes the Stack traces member-wise to a text file
-   *
-   * @param dumps - Map containing key : member , value : zipped stack traces
-   * @param fileName - Name of the file to which the stack-traces are written to
-   * @return Canonical path of the file which contains the stack-traces
-   * @throws IOException
-   */
-  private String writeStacksToFile(Map<String, byte[]> dumps, String fileName) throws IOException {
-    String filePath;
-    PrintWriter ps;
-    File outputFile;
-
-    outputFile = new File(fileName);
-    try (OutputStream os = new FileOutputStream(outputFile)) {
-      ps = new PrintWriter(os);
-
-      for (Map.Entry<String, byte[]> entry : dumps.entrySet()) {
-        ps.append("*** Stack-trace for member ").append(entry.getKey()).append(" ***");
-        ps.flush();
-        GZIPInputStream zipIn = new GZIPInputStream(new ByteArrayInputStream(entry.getValue()));
-        BufferedInputStream bin = new BufferedInputStream(zipIn);
-        byte[] buffer = new byte[10000];
-        int count;
-        while ((count = bin.read(buffer)) != -1) {
-          os.write(buffer, 0, count);
-        }
-        ps.append('\n');
-      }
-      ps.flush();
-      filePath = outputFile.getCanonicalPath();
-    }
-
-    return filePath;
-  }
-}

http://git-wip-us.apache.org/repos/asf/geode/blob/645a32d0/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/FunctionCommands.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/FunctionCommands.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/FunctionCommands.java
new file mode 100644
index 0000000..21d89c1
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/FunctionCommands.java
@@ -0,0 +1,537 @@
+/*
+ * 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 java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.stream.Stream;
+
+import org.apache.commons.lang.BooleanUtils;
+import org.springframework.shell.core.annotation.CliCommand;
+import org.springframework.shell.core.annotation.CliOption;
+
+import org.apache.geode.SystemFailure;
+import org.apache.geode.cache.Region;
+import org.apache.geode.cache.execute.Execution;
+import org.apache.geode.cache.execute.Function;
+import org.apache.geode.cache.execute.FunctionException;
+import org.apache.geode.cache.execute.FunctionService;
+import org.apache.geode.cache.execute.ResultCollector;
+import org.apache.geode.distributed.DistributedMember;
+import org.apache.geode.internal.ClassPathLoader;
+import org.apache.geode.internal.cache.InternalCache;
+import org.apache.geode.management.DistributedRegionMXBean;
+import org.apache.geode.management.ManagementService;
+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.cli.Result.Status;
+import org.apache.geode.management.internal.MBeanJMXAdapter;
+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.LogWrapper;
+import org.apache.geode.management.internal.cli.functions.CliFunctionResult;
+import org.apache.geode.management.internal.cli.functions.ListFunctionFunction;
+import org.apache.geode.management.internal.cli.functions.UnregisterFunction;
+import org.apache.geode.management.internal.cli.functions.UserFunctionExecution;
+import org.apache.geode.management.internal.cli.i18n.CliStrings;
+import org.apache.geode.management.internal.cli.result.CompositeResultData;
+import org.apache.geode.management.internal.cli.result.ErrorResultData;
+import org.apache.geode.management.internal.cli.result.ResultBuilder;
+import org.apache.geode.management.internal.cli.result.TabularResultData;
+import org.apache.geode.management.internal.security.ResourceOperation;
+import org.apache.geode.security.ResourcePermission.Operation;
+import org.apache.geode.security.ResourcePermission.Resource;
+import org.apache.geode.security.ResourcePermission.Target;
+
+/**
+ * @since GemFire 7.0
+ */
+@SuppressWarnings("unused")
+public class FunctionCommands implements GfshCommand {
+
+  private final ListFunctionFunction listFunctionFunction = new ListFunctionFunction();
+
+  @CliCommand(value = CliStrings.EXECUTE_FUNCTION, help = CliStrings.EXECUTE_FUNCTION__HELP)
+  @CliMetaData(relatedTopic = {CliStrings.TOPIC_GEODE_FUNCTION})
+  @ResourceOperation(resource = Resource.DATA, operation = Operation.WRITE)
+  public Result executeFunction(
+      // TODO: Add optioncontext for functionID
+      @CliOption(key = CliStrings.EXECUTE_FUNCTION__ID, mandatory = true,
+          help = CliStrings.EXECUTE_FUNCTION__ID__HELP) String functionId,
+      @CliOption(key = {CliStrings.GROUP, CliStrings.GROUPS},
+          optionContext = ConverterHint.MEMBERGROUP,
+          help = CliStrings.EXECUTE_FUNCTION__ONGROUPS__HELP) String[] onGroups,
+      @CliOption(key = CliStrings.MEMBER, optionContext = ConverterHint.MEMBERIDNAME,
+          help = CliStrings.EXECUTE_FUNCTION__ONMEMBER__HELP) String onMember,
+      @CliOption(key = CliStrings.EXECUTE_FUNCTION__ONREGION,
+          optionContext = ConverterHint.REGION_PATH,
+          help = CliStrings.EXECUTE_FUNCTION__ONREGION__HELP) String onRegion,
+      @CliOption(key = CliStrings.EXECUTE_FUNCTION__ARGUMENTS,
+          help = CliStrings.EXECUTE_FUNCTION__ARGUMENTS__HELP) String[] arguments,
+      @CliOption(key = CliStrings.EXECUTE_FUNCTION__RESULTCOLLECTOR,
+          help = CliStrings.EXECUTE_FUNCTION__RESULTCOLLECTOR__HELP) String resultCollector,
+      @CliOption(key = CliStrings.EXECUTE_FUNCTION__FILTER,
+          help = CliStrings.EXECUTE_FUNCTION__FILTER__HELP) String filterString) {
+
+    Result result = null;
+    CompositeResultData executeFunctionResultTable = ResultBuilder.createCompositeResultData();
+    TabularResultData resultTable = executeFunctionResultTable.addSection().addTable("Table1");
+    String headerText = "Execution summary";
+    resultTable.setHeader(headerText);
+    ResultCollector resultCollectorInstance = null;
+    Function function;
+    Set<String> filters = new HashSet<>();
+    Execution execution;
+    if (functionId != null) {
+      functionId = functionId.trim();
+    }
+    if (onRegion != null) {
+      onRegion = onRegion.trim();
+    }
+    if (onMember != null) {
+      onMember = onMember.trim();
+    }
+    if (filterString != null) {
+      filterString = filterString.trim();
+    }
+
+    try {
+      // validate otherwise return right away. no need to process anything
+      if (functionId == null || functionId.length() == 0) {
+        ErrorResultData errorResultData =
+            ResultBuilder.createErrorResultData().setErrorCode(ResultBuilder.ERRORCODE_DEFAULT)
+                .addLine(CliStrings.EXECUTE_FUNCTION__MSG__MISSING_FUNCTIONID);
+        result = ResultBuilder.buildResult(errorResultData);
+        return result;
+      }
+
+      if (isMoreThanOneIsTrue(onRegion != null, onMember != null, onGroups != null)) {
+        // Provide Only one of region/member/groups
+        ErrorResultData errorResultData =
+            ResultBuilder.createErrorResultData().setErrorCode(ResultBuilder.ERRORCODE_DEFAULT)
+                .addLine(CliStrings.EXECUTE_FUNCTION__MSG__OPTIONS);
+        result = ResultBuilder.buildResult(errorResultData);
+        return result;
+      } else if ((onRegion == null || onRegion.length() == 0) && (filterString != null)) {
+        ErrorResultData errorResultData = ResultBuilder.createErrorResultData()
+            .setErrorCode(ResultBuilder.ERRORCODE_DEFAULT)
+            .addLine(CliStrings.EXECUTE_FUNCTION__MSG__MEMBER_SHOULD_NOT_HAVE_FILTER_FOR_EXECUTION);
+        result = ResultBuilder.buildResult(errorResultData);
+        return result;
+      }
+
+      InternalCache cache = getCache();
+
+      if (resultCollector != null) {
+        resultCollectorInstance =
+            (ResultCollector) ClassPathLoader.getLatest().forName(resultCollector).newInstance();
+      }
+
+      if (filterString != null && filterString.length() > 0) {
+        filters.add(filterString);
+      }
+
+      if (onRegion == null && onMember == null && onGroups == null) {
+        // run function on all the members excluding locators bug#46113
+        // if user wish to execute on locator then he can choose --member or --group option
+        Set<DistributedMember> dsMembers = CliUtil.getAllNormalMembers(cache);
+        if (dsMembers.size() > 0) {
+          function = new UserFunctionExecution();
+          LogWrapper.getInstance().info(CliStrings
+              .format(CliStrings.EXECUTE_FUNCTION__MSG__EXECUTING_0_ON_ENTIRE_DS, functionId));
+          for (DistributedMember member : dsMembers) {
+            executeAndGetResults(functionId, filterString, resultCollector, arguments, cache,
+                member, resultTable, onRegion);
+          }
+          return ResultBuilder.buildResult(resultTable);
+        } else {
+          return ResultBuilder
+              .createUserErrorResult(CliStrings.EXECUTE_FUNCTION__MSG__DS_HAS_NO_MEMBERS);
+        }
+      } else if (onRegion != null && onRegion.length() > 0) {
+        if (cache.getRegion(onRegion) == null) {
+          // find a member where region is present
+          DistributedRegionMXBean bean = ManagementService.getManagementService(getCache())
+              .getDistributedRegionMXBean(onRegion);
+          if (bean == null) {
+            bean = ManagementService.getManagementService(getCache())
+                .getDistributedRegionMXBean(Region.SEPARATOR + onRegion);
+
+            if (bean == null) {
+              return ResultBuilder.createGemFireErrorResult(CliStrings
+                  .format(CliStrings.EXECUTE_FUNCTION__MSG__MXBEAN_0_FOR_NOT_FOUND, onRegion));
+            }
+          }
+
+          DistributedMember member = null;
+          String[] membersName = bean.getMembers();
+          Set<DistributedMember> dsMembers = CliUtil.getAllMembers(cache);
+          Iterator it = dsMembers.iterator();
+          boolean matchFound = false;
+
+          if (membersName.length > 0) {
+            while (it.hasNext() && !matchFound) {
+              DistributedMember dsmember = (DistributedMember) it.next();
+              for (String memberName : membersName) {
+                if (MBeanJMXAdapter.getMemberNameOrId(dsmember).equals(memberName)) {
+                  member = dsmember;
+                  matchFound = true;
+                  break;
+                }
+              }
+            }
+          }
+          if (matchFound) {
+            executeAndGetResults(functionId, filterString, resultCollector, arguments, cache,
+                member, resultTable, onRegion);
+            return ResultBuilder.buildResult(resultTable);
+          } else {
+            return ResultBuilder.createGemFireErrorResult(CliStrings.format(
+                CliStrings.EXECUTE_FUNCTION__MSG__NO_ASSOCIATED_MEMBER_REGION, " " + onRegion));
+          }
+        } else {
+          execution = FunctionService.onRegion(cache.getRegion(onRegion));
+          if (execution != null) {
+            if (resultCollectorInstance != null) {
+              execution = execution.withCollector(resultCollectorInstance);
+            }
+            if (filters != null && filters.size() > 0) {
+              execution = execution.withFilter(filters);
+            }
+            if (arguments != null && arguments.length > 0) {
+              execution = execution.setArguments(arguments);
+            }
+
+            try {
+              List<Object> results = (List<Object>) execution.execute(functionId).getResult();
+              if (results.size() > 0) {
+                StringBuilder strResult = new StringBuilder();
+                for (Object obj : results) {
+                  strResult.append(obj);
+                }
+                toTabularResultData(resultTable,
+                    cache.getDistributedSystem().getDistributedMember().getId(),
+                    strResult.toString());
+              }
+              return ResultBuilder.buildResult(resultTable);
+            } catch (FunctionException e) {
+              return ResultBuilder.createGemFireErrorResult(CliStrings.format(
+                  CliStrings.EXECUTE_FUNCTION__MSG__ERROR_IN_EXECUTING_0_ON_REGION_1_DETAILS_2,
+                  functionId, onRegion, e.getMessage()));
+            }
+          } else {
+            return ResultBuilder.createGemFireErrorResult(CliStrings.format(
+                CliStrings.EXECUTE_FUNCTION__MSG__ERROR_IN_EXECUTING_0_ON_REGION_1_DETAILS_2,
+                functionId, onRegion,
+                CliStrings.EXECUTE_FUNCTION__MSG__ERROR_IN_RETRIEVING_EXECUTOR));
+          }
+        }
+      } else if (onGroups != null) {
+        // execute on group members
+        Set<DistributedMember> dsMembers = new HashSet<>();
+        for (String grp : onGroups) {
+          dsMembers.addAll(cache.getDistributedSystem().getGroupMembers(grp));
+        }
+
+        StringBuilder successMessage = new StringBuilder();
+        if (dsMembers.size() > 0) {
+          for (DistributedMember member : dsMembers) {
+            executeAndGetResults(functionId, filterString, resultCollector, arguments, cache,
+                member, resultTable, onRegion);
+          }
+          return ResultBuilder.buildResult(resultTable);
+        } else {
+          StringBuilder grps = new StringBuilder();
+          for (String grp : onGroups) {
+            grps.append(grp);
+            grps.append(", ");
+          }
+          return ResultBuilder.createUserErrorResult(
+              CliStrings.format(CliStrings.EXECUTE_FUNCTION__MSG__GROUPS_0_HAS_NO_MEMBERS,
+                  grps.toString().substring(0, grps.toString().length() - 1)));
+        }
+      } else if (onMember != null && onMember.length() > 0) {
+        DistributedMember member = CliUtil.getDistributedMemberByNameOrId(onMember); // fix for bug
+        // 45658
+        if (member != null) {
+          executeAndGetResults(functionId, filterString, resultCollector, arguments, cache, member,
+              resultTable, onRegion);
+        } else {
+          toTabularResultData(resultTable, onMember, CliStrings
+              .format(CliStrings.EXECUTE_FUNCTION__MSG__NO_ASSOCIATED_MEMBER + " " + onMember));
+        }
+        return ResultBuilder.buildResult(resultTable);
+      }
+    } catch (Exception e) {
+      ErrorResultData errorResultData = ResultBuilder.createErrorResultData()
+          .setErrorCode(ResultBuilder.ERRORCODE_DEFAULT).addLine(e.getMessage());
+      result = ResultBuilder.buildResult(errorResultData);
+      return result;
+    }
+
+    return result;
+  }
+
+  private boolean isMoreThanOneIsTrue(Boolean... values) {
+    return Stream.of(values).mapToInt(BooleanUtils::toInteger).sum() > 1;
+  }
+
+  void executeAndGetResults(String functionId, String filterString, String resultCollector,
+      String[] arguments, InternalCache cache, DistributedMember member,
+      TabularResultData resultTable, String onRegion) {
+    StringBuilder resultMessage = new StringBuilder();
+    try {
+      Function function = new UserFunctionExecution();
+      Object[] args = new Object[5];
+      args[0] = functionId;
+      if (filterString != null) {
+        args[1] = filterString;
+      }
+      if (resultCollector != null) {
+        args[2] = resultCollector;
+      }
+      if (arguments != null && arguments.length > 0) {
+        args[3] = "";
+        for (String str : arguments) {
+          // send via CSV separated value format
+          if (str != null) {
+            args[3] = args[3] + str + ",";
+          }
+        }
+      }
+      args[4] = onRegion;
+
+      Execution execution = FunctionService.onMember(member).setArguments(args);
+      if (execution != null) {
+        List<Object> results = (List<Object>) execution.execute(function).getResult();
+        if (results != null) {
+          for (Object resultObj : results) {
+            if (resultObj != null) {
+              if (resultObj instanceof String) {
+                resultMessage.append(((String) resultObj));
+              } else if (resultObj instanceof Exception) {
+                resultMessage.append(((Exception) resultObj).getMessage());
+              } else {
+                resultMessage.append(resultObj);
+              }
+            }
+          }
+        }
+        toTabularResultData(resultTable, member.getId(), resultMessage.toString());
+      } else {
+        toTabularResultData(resultTable, member.getId(),
+            CliStrings.EXECUTE_FUNCTION__MSG__ERROR_IN_RETRIEVING_EXECUTOR);
+      }
+    } catch (Exception e) {
+      resultMessage.append(CliStrings.format(
+          CliStrings.EXECUTE_FUNCTION__MSG__COULD_NOT_EXECUTE_FUNCTION_0_ON_MEMBER_1_ERROR_2,
+          functionId, member.getId(), e.getMessage()));
+      toTabularResultData(resultTable, member.getId(), resultMessage.toString());
+    }
+  }
+
+  protected void toTabularResultData(TabularResultData table, String memberId,
+      String memberResult) {
+    String newLine = System.getProperty("line.separator");
+    table.accumulate("Member ID/Name", memberId);
+    table.accumulate("Function Execution Result", memberResult);
+  }
+
+  @CliCommand(value = CliStrings.DESTROY_FUNCTION, help = CliStrings.DESTROY_FUNCTION__HELP)
+  @CliMetaData(relatedTopic = {CliStrings.TOPIC_GEODE_FUNCTION},
+      interceptor = "org.apache.geode.management.internal.cli.commands.FunctionCommands$Interceptor")
+  @ResourceOperation(resource = Resource.CLUSTER, operation = Operation.MANAGE, target = Target.JAR)
+  // TODO: Add optioncontext for functionId
+  public Result destroyFunction(
+      @CliOption(key = CliStrings.DESTROY_FUNCTION__ID, mandatory = true,
+          help = CliStrings.DESTROY_FUNCTION__HELP) String functionId,
+      @CliOption(key = {CliStrings.GROUP, CliStrings.GROUPS},
+          optionContext = ConverterHint.MEMBERGROUP,
+          help = CliStrings.DESTROY_FUNCTION__ONGROUPS__HELP) String[] groups,
+      @CliOption(key = CliStrings.MEMBER, optionContext = ConverterHint.MEMBERIDNAME,
+          help = CliStrings.DESTROY_FUNCTION__ONMEMBER__HELP) String memberId) {
+    Result result;
+    try {
+      InternalCache cache = getCache();
+      Set<DistributedMember> dsMembers = new HashSet<>();
+      if (groups != null && memberId != null) {
+        return ResultBuilder
+            .createUserErrorResult(CliStrings.DESTROY_FUNCTION__MSG__PROVIDE_OPTION);
+      } else if (groups != null && groups.length > 0) {
+        // execute on group members
+        for (String grp : groups) {
+          dsMembers.addAll(cache.getDistributedSystem().getGroupMembers(grp));
+        }
+        @SuppressWarnings("unchecked")
+        Result results = executeFunction(cache, dsMembers, functionId);
+        return results;
+      } else if (memberId != null) {
+        // execute on member
+        dsMembers.add(getMember(cache, memberId));
+        @SuppressWarnings("unchecked")
+        Result results = executeFunction(cache, dsMembers, functionId);
+        return results;
+      } else {
+        // no option provided.
+        @SuppressWarnings("unchecked")
+        Result results = executeFunction(cache, cache.getMembers(), functionId);
+        return results;
+      }
+    } catch (Exception e) {
+      ErrorResultData errorResultData = ResultBuilder.createErrorResultData()
+          .setErrorCode(ResultBuilder.ERRORCODE_DEFAULT).addLine(e.getMessage());
+      result = ResultBuilder.buildResult(errorResultData);
+      return result;
+    }
+  }
+
+  /**
+   * Interceptor used by gfsh to intercept execution of destroy.
+   */
+  public static class Interceptor extends AbstractCliAroundInterceptor {
+    @Override
+    public Result preExecution(GfshParseResult parseResult) {
+      Map<String, String> paramValueMap = parseResult.getParamValueStrings();
+      Set<Entry<String, String>> setEnvMap = paramValueMap.entrySet();
+      String onGroup = paramValueMap.get(CliStrings.GROUP);
+      String onMember = paramValueMap.get(CliStrings.MEMBER);
+
+      if ((onGroup == null && onMember == null)) {
+        Response response = readYesNo("Do you really want to destroy "
+            + paramValueMap.get(CliStrings.DESTROY_FUNCTION__ID) + " on entire DS?", Response.NO);
+        if (response == Response.NO) {
+          return ResultBuilder.createShellClientAbortOperationResult(
+              "Aborted destroy of " + paramValueMap.get(CliStrings.DESTROY_FUNCTION__ID));
+        } else {
+          return ResultBuilder
+              .createInfoResult("Destroying " + paramValueMap.get(CliStrings.DESTROY_FUNCTION__ID));
+        }
+      } else {
+        return ResultBuilder
+            .createInfoResult("Destroying " + paramValueMap.get(CliStrings.DESTROY_FUNCTION__ID));
+      }
+    }
+  }
+
+  Result executeFunction(InternalCache cache, Set<DistributedMember> DsMembers, String functionId) {
+    // unregister on a set of of members
+    Function unregisterFunction = new UnregisterFunction();
+    FunctionService.registerFunction(unregisterFunction);
+    List resultList;
+
+    if (DsMembers.isEmpty()) {
+      return ResultBuilder.createInfoResult("No members for execution");
+    }
+    Object[] obj = new Object[1];
+    obj[0] = functionId;
+
+    Execution execution = FunctionService.onMembers(DsMembers).setArguments(obj);
+
+    if (execution == null) {
+      cache.getLogger().error("executeUnregister execution is null");
+      ErrorResultData errorResultData =
+          ResultBuilder.createErrorResultData().setErrorCode(ResultBuilder.ERRORCODE_DEFAULT)
+              .addLine(CliStrings.DESTROY_FUNCTION__MSG__CANNOT_EXECUTE);
+      return (ResultBuilder.buildResult(errorResultData));
+    }
+    try {
+      resultList = (ArrayList) execution.execute(unregisterFunction).getResult();
+    } catch (FunctionException ex) {
+      ErrorResultData errorResultData = ResultBuilder.createErrorResultData()
+          .setErrorCode(ResultBuilder.ERRORCODE_DEFAULT).addLine(ex.getMessage());
+      return (ResultBuilder.buildResult(errorResultData));
+    }
+    String resultStr = ((String) resultList.get(0));
+    if (resultStr.equals("Succeeded in unregistering")) {
+      StringBuilder members = new StringBuilder();
+      for (DistributedMember member : DsMembers) {
+        members.append(member.getId());
+        members.append(",");
+      }
+      return ResultBuilder.createInfoResult("Destroyed " + functionId + " Successfully on "
+          + members.toString().substring(0, members.toString().length() - 1));
+    } else {
+      return ResultBuilder.createInfoResult("Failed in unregistering");
+    }
+  }
+
+  @CliCommand(value = CliStrings.LIST_FUNCTION, help = CliStrings.LIST_FUNCTION__HELP)
+  @CliMetaData(relatedTopic = {CliStrings.TOPIC_GEODE_FUNCTION})
+  @ResourceOperation(resource = Resource.CLUSTER, operation = Operation.READ)
+  public Result listFunction(
+      @CliOption(key = CliStrings.LIST_FUNCTION__MATCHES,
+          help = CliStrings.LIST_FUNCTION__MATCHES__HELP) String matches,
+      @CliOption(key = {CliStrings.GROUP, CliStrings.GROUPS},
+          optionContext = ConverterHint.MEMBERGROUP,
+          help = CliStrings.LIST_FUNCTION__GROUP__HELP) String[] groups,
+      @CliOption(key = {CliStrings.MEMBER, CliStrings.MEMBERS},
+          optionContext = ConverterHint.MEMBERIDNAME,
+          help = CliStrings.LIST_FUNCTION__MEMBER__HELP) String[] members) {
+    TabularResultData tabularData = ResultBuilder.createTabularResultData();
+    boolean accumulatedData = false;
+
+    InternalCache cache = getCache();
+
+    Set<DistributedMember> targetMembers = CliUtil.findMembers(groups, members);
+
+    if (targetMembers.isEmpty()) {
+      return ResultBuilder.createUserErrorResult(CliStrings.NO_MEMBERS_FOUND_MESSAGE);
+    }
+
+    try {
+      ResultCollector<?, ?> rc =
+          CliUtil.executeFunction(this.listFunctionFunction, new Object[] {matches}, targetMembers);
+      List<CliFunctionResult> results = CliFunctionResult.cleanResults((List<?>) rc.getResult());
+
+      for (CliFunctionResult result : results) {
+        if (result.getThrowable() != null) {
+          tabularData.accumulate("Member", result.getMemberIdOrName());
+          tabularData.accumulate("Function", "<ERROR: " + result.getThrowable().getMessage() + ">");
+          accumulatedData = true;
+          tabularData.setStatus(Status.ERROR);
+        } else if (result.isSuccessful()) {
+          String[] strings = (String[]) result.getSerializables();
+          Arrays.sort(strings);
+          for (String string : strings) {
+            tabularData.accumulate("Member", result.getMemberIdOrName());
+            tabularData.accumulate("Function", string);
+            accumulatedData = true;
+          }
+        }
+      }
+
+      if (!accumulatedData) {
+        return ResultBuilder
+            .createInfoResult(CliStrings.LIST_FUNCTION__NO_FUNCTIONS_FOUND_ERROR_MESSAGE);
+      }
+      return ResultBuilder.buildResult(tabularData);
+    } catch (VirtualMachineError e) {
+      SystemFailure.initiateFailure(e);
+      throw e;
+    } catch (Throwable th) {
+      SystemFailure.checkFailure();
+      return ResultBuilder.createGemFireErrorResult(
+          "Exception while attempting to list functions: " + th.getMessage());
+    }
+  }
+}