You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by sa...@apache.org on 2018/05/08 22:17:07 UTC

[geode] branch develop updated: GEODE-4858: Added CliFunction abstract class (#1932)

This is an automated email from the ASF dual-hosted git repository.

sai_boorlagadda pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/geode.git


The following commit(s) were added to refs/heads/develop by this push:
     new d0d624e  GEODE-4858: Added CliFunction abstract class (#1932)
d0d624e is described below

commit d0d624ec43f51ba3cca953feb47abb84d7338e9b
Author: Sai Boorlagadda <sa...@gmail.com>
AuthorDate: Tue May 8 15:17:00 2018 -0700

    GEODE-4858: Added CliFunction abstract class (#1932)
    
    Added a new CliFunction abstract class to define the
    return type for CLI functions to be CliFunctionResult.
---
 .../jdbc/internal/cli/AlterConnectionFunction.java | 14 ++---
 .../jdbc/internal/cli/AlterMappingFunction.java    | 13 ++---
 .../internal/cli/CreateConnectionFunction.java     | 25 +++-----
 .../jdbc/internal/cli/CreateMappingFunction.java   | 11 ++--
 .../internal/cli/DescribeConnectionCommand.java    | 11 ++--
 .../internal/cli/DescribeConnectionFunction.java   | 16 +++---
 .../jdbc/internal/cli/DescribeMappingCommand.java  | 11 ++--
 .../jdbc/internal/cli/DescribeMappingFunction.java | 18 +++---
 .../internal/cli/DestroyConnectionFunction.java    | 55 +++---------------
 .../jdbc/internal/cli/DestroyMappingFunction.java  | 56 +++---------------
 .../jdbc/internal/cli/ExceptionHandler.java        | 57 ------------------
 .../jdbc/internal/cli/JdbcCliFunction.java         | 67 ----------------------
 .../jdbc/internal/cli/ListConnectionCommand.java   | 10 ++--
 .../jdbc/internal/cli/ListConnectionFunction.java  | 18 ++----
 .../jdbc/internal/cli/ListMappingCommand.java      | 10 ++--
 .../jdbc/internal/cli/ListMappingFunction.java     | 18 ++----
 .../sanctioned-geode-connectors-serializables.txt  |  1 -
 .../internal/cli/AlterMappingFunctionTest.java     |  2 -
 .../cli/DescribeConnectionCommandTest.java         |  9 ++-
 .../cli/DescribeConnectionFunctionTest.java        | 14 ++---
 .../internal/cli/DescribeMappingCommandTest.java   |  9 ++-
 .../internal/cli/DescribeMappingFunctionTest.java  | 13 ++---
 .../cli/DestroyConnectionFunctionTest.java         |  6 +-
 .../cli/DestroyMappingCommandFunctionTest.java     |  7 ++-
 .../cli/JDBCConnectorFunctionsSecurityTest.java    |  9 ++-
 .../jdbc/internal/cli/JdbcCliFunctionTest.java     | 51 ----------------
 .../internal/cli/ListConnectionCommandTest.java    | 10 ++--
 .../internal/cli/ListConnectionFunctionTest.java   | 17 +++---
 .../jdbc/internal/cli/ListMappingCommandTest.java  | 12 ++--
 .../jdbc/internal/cli/ListMappingFunctionTest.java | 20 +++----
 .../apache/geode/management/cli/CliFunction.java   | 44 ++++++++++++++
 .../apache/geode/management/cli/GfshCommand.java   |  7 +++
 .../sanctioned-geode-core-serializables.txt        |  1 +
 33 files changed, 209 insertions(+), 433 deletions(-)

diff --git a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/AlterConnectionFunction.java b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/AlterConnectionFunction.java
index 1a92c4e..039ed69 100644
--- a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/AlterConnectionFunction.java
+++ b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/AlterConnectionFunction.java
@@ -19,19 +19,17 @@ import org.apache.geode.cache.execute.FunctionContext;
 import org.apache.geode.connectors.jdbc.internal.ConnectionConfigNotFoundException;
 import org.apache.geode.connectors.jdbc.internal.JdbcConnectorService;
 import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
+import org.apache.geode.management.cli.CliFunction;
 import org.apache.geode.management.internal.cli.functions.CliFunctionResult;
 
 
-public class AlterConnectionFunction
-    extends JdbcCliFunction<ConnectorService.Connection, CliFunctionResult> {
-
-  AlterConnectionFunction() {
-    super();
-  }
+public class AlterConnectionFunction extends CliFunction<ConnectorService.Connection> {
 
   @Override
-  CliFunctionResult getFunctionResult(JdbcConnectorService service,
-      FunctionContext<ConnectorService.Connection> context) throws Exception {
+  public CliFunctionResult executeFunction(FunctionContext<ConnectorService.Connection> context)
+      throws Exception {
+    JdbcConnectorService service = FunctionContextArgumentProvider.getJdbcConnectorService(context);
+
     ConnectorService.Connection connectionConfig = context.getArguments();
     ConnectorService.Connection existingConfig =
         service.getConnectionConfig(connectionConfig.getName());
diff --git a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/AlterMappingFunction.java b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/AlterMappingFunction.java
index 0798760..01c1800 100644
--- a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/AlterMappingFunction.java
+++ b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/AlterMappingFunction.java
@@ -20,19 +20,16 @@ import org.apache.geode.cache.execute.FunctionContext;
 import org.apache.geode.connectors.jdbc.internal.JdbcConnectorService;
 import org.apache.geode.connectors.jdbc.internal.RegionMappingNotFoundException;
 import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
+import org.apache.geode.management.cli.CliFunction;
 import org.apache.geode.management.internal.cli.functions.CliFunctionResult;
 
 
-public class AlterMappingFunction
-    extends JdbcCliFunction<ConnectorService.RegionMapping, CliFunctionResult> {
-
-  AlterMappingFunction() {
-    super();
-  }
+public class AlterMappingFunction extends CliFunction<ConnectorService.RegionMapping> {
 
   @Override
-  CliFunctionResult getFunctionResult(JdbcConnectorService service,
-      FunctionContext<ConnectorService.RegionMapping> context) throws Exception {
+  public CliFunctionResult executeFunction(FunctionContext<ConnectorService.RegionMapping> context)
+      throws Exception {
+    JdbcConnectorService service = FunctionContextArgumentProvider.getJdbcConnectorService(context);
     ConnectorService.RegionMapping mapping = context.getArguments();
     ConnectorService.RegionMapping existingMapping =
         service.getMappingForRegion(mapping.getRegionName());
diff --git a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/CreateConnectionFunction.java b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/CreateConnectionFunction.java
index 3b7a495..b217f74 100644
--- a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/CreateConnectionFunction.java
+++ b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/CreateConnectionFunction.java
@@ -18,25 +18,19 @@ import org.apache.geode.cache.execute.FunctionContext;
 import org.apache.geode.connectors.jdbc.internal.ConnectionConfigExistsException;
 import org.apache.geode.connectors.jdbc.internal.JdbcConnectorService;
 import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
+import org.apache.geode.management.cli.CliFunction;
 import org.apache.geode.management.internal.cli.functions.CliFunctionResult;
-import org.apache.geode.management.internal.configuration.domain.XmlEntity;
 
-
-public class CreateConnectionFunction
-    extends JdbcCliFunction<ConnectorService.Connection, CliFunctionResult> {
-
-  CreateConnectionFunction() {
-    super();
-  }
+public class CreateConnectionFunction extends CliFunction<ConnectorService.Connection> {
 
   @Override
-  CliFunctionResult getFunctionResult(JdbcConnectorService service,
-      FunctionContext<ConnectorService.Connection> context) throws Exception {
+  public CliFunctionResult executeFunction(FunctionContext<ConnectorService.Connection> context)
+      throws Exception {
+    JdbcConnectorService service = FunctionContextArgumentProvider.getJdbcConnectorService(context);
     ConnectorService.Connection connectionConfig = context.getArguments();
     createConnectionConfig(service, connectionConfig);
-    String member = getMember(context);
-    XmlEntity xmlEntity = createXmlEntity(context);
-    return createSuccessResult(connectionConfig.getName(), member, xmlEntity);
+    String member = context.getMemberName();
+    return createSuccessResult(connectionConfig.getName(), member);
   }
 
   /**
@@ -47,9 +41,8 @@ public class CreateConnectionFunction
     service.createConnectionConfig(connectionConfig);
   }
 
-  private CliFunctionResult createSuccessResult(String connectionName, String member,
-      XmlEntity xmlEntity) {
+  private CliFunctionResult createSuccessResult(String connectionName, String member) {
     String message = "Created JDBC connection " + connectionName + " on " + member;
-    return new CliFunctionResult(member, xmlEntity, message);
+    return new CliFunctionResult(member, message);
   }
 }
diff --git a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingFunction.java b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingFunction.java
index 3b955b7..d1650e6 100644
--- a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingFunction.java
+++ b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingFunction.java
@@ -18,18 +18,19 @@ import org.apache.geode.cache.execute.FunctionContext;
 import org.apache.geode.connectors.jdbc.internal.JdbcConnectorService;
 import org.apache.geode.connectors.jdbc.internal.RegionMappingExistsException;
 import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
+import org.apache.geode.management.cli.CliFunction;
 import org.apache.geode.management.internal.cli.functions.CliFunctionResult;
 
-public class CreateMappingFunction
-    extends JdbcCliFunction<ConnectorService.RegionMapping, CliFunctionResult> {
+public class CreateMappingFunction extends CliFunction<ConnectorService.RegionMapping> {
 
   CreateMappingFunction() {
     super();
   }
 
   @Override
-  CliFunctionResult getFunctionResult(JdbcConnectorService service,
-      FunctionContext<ConnectorService.RegionMapping> context) throws Exception {
+  public CliFunctionResult executeFunction(FunctionContext<ConnectorService.RegionMapping> context)
+      throws Exception {
+    JdbcConnectorService service = FunctionContextArgumentProvider.getJdbcConnectorService(context);
     // input
     ConnectorService.RegionMapping regionMapping = context.getArguments();
 
@@ -37,7 +38,7 @@ public class CreateMappingFunction
     createRegionMapping(service, regionMapping);
 
     // output
-    String member = getMember(context);
+    String member = context.getMemberName();
     String message =
         "Created JDBC mapping for region " + regionMapping.getRegionName() + " on " + member;
     return new CliFunctionResult(member, true, message);
diff --git a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeConnectionCommand.java b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeConnectionCommand.java
index 154b51b..d9361ed 100644
--- a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeConnectionCommand.java
+++ b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeConnectionCommand.java
@@ -20,7 +20,6 @@ import static org.apache.geode.connectors.jdbc.internal.cli.CreateConnectionComm
 import static org.apache.geode.connectors.jdbc.internal.cli.CreateConnectionCommand.CREATE_CONNECTION__URL;
 import static org.apache.geode.connectors.jdbc.internal.cli.CreateConnectionCommand.CREATE_CONNECTION__USER;
 
-import java.util.List;
 import java.util.Set;
 
 import org.apache.logging.log4j.Logger;
@@ -37,6 +36,7 @@ import org.apache.geode.management.cli.CliMetaData;
 import org.apache.geode.management.cli.GfshCommand;
 import org.apache.geode.management.cli.Result;
 import org.apache.geode.management.internal.cli.exceptions.EntityNotFoundException;
+import org.apache.geode.management.internal.cli.functions.CliFunctionResult;
 import org.apache.geode.management.internal.cli.i18n.CliStrings;
 import org.apache.geode.management.internal.cli.result.CompositeResultData;
 import org.apache.geode.management.internal.cli.result.ResultBuilder;
@@ -79,11 +79,10 @@ public class DescribeConnectionCommand extends GfshCommand {
       Set<DistributedMember> members = findMembers(null, null);
       if (members.size() > 0) {
         DistributedMember targetMember = members.iterator().next();
-        List<?> result =
-            (List<?>) executeFunction(new DescribeConnectionFunction(), name, targetMember)
-                .getResult();
-        if (!result.isEmpty()) {
-          connection = (ConnectorService.Connection) result.get(0);
+        CliFunctionResult result = executeFunctionAndGetFunctionResult(
+            new DescribeConnectionFunction(), name, targetMember);
+        if (result != null) {
+          connection = (ConnectorService.Connection) result.getResultObject();
         }
       }
     }
diff --git a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeConnectionFunction.java b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeConnectionFunction.java
index d8f9def..89833ea 100644
--- a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeConnectionFunction.java
+++ b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeConnectionFunction.java
@@ -17,17 +17,15 @@ package org.apache.geode.connectors.jdbc.internal.cli;
 import org.apache.geode.cache.execute.FunctionContext;
 import org.apache.geode.connectors.jdbc.internal.JdbcConnectorService;
 import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
+import org.apache.geode.management.cli.CliFunction;
+import org.apache.geode.management.internal.cli.functions.CliFunctionResult;
 
-public class DescribeConnectionFunction
-    extends JdbcCliFunction<String, ConnectorService.Connection> {
-
-  DescribeConnectionFunction() {
-    super();
-  }
+public class DescribeConnectionFunction extends CliFunction<String> {
 
   @Override
-  ConnectorService.Connection getFunctionResult(JdbcConnectorService service,
-      FunctionContext<String> context) {
-    return service.getConnectionConfig(context.getArguments());
+  public CliFunctionResult executeFunction(FunctionContext<String> context) {
+    JdbcConnectorService service = FunctionContextArgumentProvider.getJdbcConnectorService(context);
+    ConnectorService.Connection connection = service.getConnectionConfig(context.getArguments());
+    return new CliFunctionResult(context.getMemberName(), connection);
   }
 }
diff --git a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeMappingCommand.java b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeMappingCommand.java
index 2113b7b..487b3f9 100644
--- a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeMappingCommand.java
+++ b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeMappingCommand.java
@@ -20,7 +20,6 @@ import static org.apache.geode.connectors.jdbc.internal.cli.CreateMappingCommand
 import static org.apache.geode.connectors.jdbc.internal.cli.CreateMappingCommand.CREATE_MAPPING__TABLE_NAME;
 import static org.apache.geode.connectors.jdbc.internal.cli.CreateMappingCommand.CREATE_MAPPING__VALUE_CONTAINS_PRIMARY_KEY;
 
-import java.util.List;
 import java.util.Set;
 
 import org.springframework.shell.core.annotation.CliCommand;
@@ -35,6 +34,7 @@ import org.apache.geode.management.cli.CliMetaData;
 import org.apache.geode.management.cli.GfshCommand;
 import org.apache.geode.management.cli.Result;
 import org.apache.geode.management.internal.cli.exceptions.EntityNotFoundException;
+import org.apache.geode.management.internal.cli.functions.CliFunctionResult;
 import org.apache.geode.management.internal.cli.i18n.CliStrings;
 import org.apache.geode.management.internal.cli.result.CompositeResultData;
 import org.apache.geode.management.internal.cli.result.ResultBuilder;
@@ -76,11 +76,10 @@ public class DescribeMappingCommand extends GfshCommand {
       Set<DistributedMember> members = findMembers(null, null);
       if (members.size() > 0) {
         DistributedMember targetMember = members.iterator().next();
-        List<?> result =
-            (List<?>) executeFunction(new DescribeMappingFunction(), regionName, targetMember)
-                .getResult();
-        if (!result.isEmpty()) {
-          mapping = (ConnectorService.RegionMapping) result.get(0);
+        CliFunctionResult result = executeFunctionAndGetFunctionResult(
+            new DescribeMappingFunction(), regionName, targetMember);
+        if (result != null) {
+          mapping = (ConnectorService.RegionMapping) result.getResultObject();
         }
       }
     }
diff --git a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeMappingFunction.java b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeMappingFunction.java
index a35a9f2..3f7c634 100644
--- a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeMappingFunction.java
+++ b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeMappingFunction.java
@@ -16,18 +16,16 @@ package org.apache.geode.connectors.jdbc.internal.cli;
 
 import org.apache.geode.cache.execute.FunctionContext;
 import org.apache.geode.connectors.jdbc.internal.JdbcConnectorService;
-import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
+import org.apache.geode.management.cli.CliFunction;
+import org.apache.geode.management.internal.cli.functions.CliFunctionResult;
 
-public class DescribeMappingFunction
-    extends JdbcCliFunction<String, ConnectorService.RegionMapping> {
-
-  DescribeMappingFunction() {
-    super();
-  }
+public class DescribeMappingFunction extends CliFunction<String> {
 
   @Override
-  ConnectorService.RegionMapping getFunctionResult(JdbcConnectorService service,
-      FunctionContext<String> context) {
-    return service.getMappingForRegion(context.getArguments());
+  public CliFunctionResult executeFunction(FunctionContext<String> context) {
+    JdbcConnectorService service = FunctionContextArgumentProvider.getJdbcConnectorService(context);
+
+    return new CliFunctionResult(context.getMemberName(),
+        service.getMappingForRegion(context.getArguments()));
   }
 }
diff --git a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyConnectionFunction.java b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyConnectionFunction.java
index 003938d..412628f 100644
--- a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyConnectionFunction.java
+++ b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyConnectionFunction.java
@@ -17,62 +17,25 @@ package org.apache.geode.connectors.jdbc.internal.cli;
 import org.apache.geode.cache.execute.FunctionContext;
 import org.apache.geode.connectors.jdbc.internal.JdbcConnectorService;
 import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
+import org.apache.geode.management.cli.CliFunction;
 import org.apache.geode.management.internal.cli.functions.CliFunctionResult;
-import org.apache.geode.management.internal.configuration.domain.XmlEntity;
 
 
-public class DestroyConnectionFunction extends JdbcCliFunction<String, CliFunctionResult> {
-
-  DestroyConnectionFunction() {
-    super();
-  }
+public class DestroyConnectionFunction extends CliFunction<String> {
 
   @Override
-  CliFunctionResult getFunctionResult(JdbcConnectorService service,
-      FunctionContext<String> context) {
+  public CliFunctionResult executeFunction(FunctionContext<String> context) {
+    JdbcConnectorService service = FunctionContextArgumentProvider.getJdbcConnectorService(context);
     String connectionName = context.getArguments();
-    boolean success = destroyConnectionConfig(service, connectionName);
-
-    // output
-    String member = getMember(context);
-    return createResult(success, context, member, connectionName);
-  }
-
-  /**
-   * Destroys the named connection configuration
-   *
-   * @return true if the connection was found and destroyed
-   */
-  boolean destroyConnectionConfig(JdbcConnectorService service, String connectionName) {
     ConnectorService.Connection connectionConfig = service.getConnectionConfig(connectionName);
     if (connectionConfig != null) {
       service.destroyConnectionConfig(connectionName);
-      return true;
-    }
-    return false;
-  }
-
-  private CliFunctionResult createResult(boolean success, FunctionContext<String> context,
-      String member, String connectionName) {
-    CliFunctionResult result;
-    if (success) {
-      XmlEntity xmlEntity = createXmlEntity(context);
-      result = createSuccessResult(member, connectionName, xmlEntity);
-
+      String message =
+          "Destroyed JDBC connection \"" + connectionName + "\" on " + context.getMemberName();
+      return new CliFunctionResult(context.getMemberName(), true, message);
     } else {
-      result = createNotFoundResult(member, connectionName);
+      String message = "Connection named \"" + connectionName + "\" not found";
+      return new CliFunctionResult(context.getMemberName(), false, message);
     }
-    return result;
-  }
-
-  private CliFunctionResult createSuccessResult(String member, String connectionName,
-      XmlEntity xmlEntity) {
-    String message = "Destroyed JDBC connection \"" + connectionName + "\" on " + member;
-    return new CliFunctionResult(member, xmlEntity, message);
-  }
-
-  private CliFunctionResult createNotFoundResult(String member, String connectionName) {
-    String message = "Connection named \"" + connectionName + "\" not found";
-    return new CliFunctionResult(member, false, message);
   }
 }
diff --git a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyMappingFunction.java b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyMappingFunction.java
index 3dab02c..1d3fead 100644
--- a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyMappingFunction.java
+++ b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyMappingFunction.java
@@ -17,62 +17,24 @@ package org.apache.geode.connectors.jdbc.internal.cli;
 import org.apache.geode.cache.execute.FunctionContext;
 import org.apache.geode.connectors.jdbc.internal.JdbcConnectorService;
 import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
+import org.apache.geode.management.cli.CliFunction;
 import org.apache.geode.management.internal.cli.functions.CliFunctionResult;
-import org.apache.geode.management.internal.configuration.domain.XmlEntity;
 
-
-public class DestroyMappingFunction extends JdbcCliFunction<String, CliFunctionResult> {
-
-  DestroyMappingFunction() {
-    super();
-  }
+public class DestroyMappingFunction extends CliFunction<String> {
 
   @Override
-  CliFunctionResult getFunctionResult(JdbcConnectorService service, FunctionContext<String> context)
-      throws Exception {
-    // input
+  public CliFunctionResult executeFunction(FunctionContext<String> context) {
+    JdbcConnectorService service = FunctionContextArgumentProvider.getJdbcConnectorService(context);
     String regionName = context.getArguments();
-
-    // action
-    boolean success = destroyRegionMapping(service, regionName);
-
-    // output
-    String member = getMember(context);
-    return createResult(success, context, member, regionName);
-  }
-
-  /**
-   * Destroys the named region mapping
-   */
-  boolean destroyRegionMapping(JdbcConnectorService service, String regionName) {
+    String member = context.getMemberName();
     ConnectorService.RegionMapping mapping = service.getMappingForRegion(regionName);
     if (mapping != null) {
       service.destroyRegionMapping(regionName);
-      return true;
-    }
-    return false;
-  }
-
-  private CliFunctionResult createResult(boolean success, FunctionContext<String> context,
-      String member, String regionName) {
-    CliFunctionResult result;
-    if (success) {
-      XmlEntity xmlEntity = createXmlEntity(context);
-      result = createSuccessResult(member, regionName, xmlEntity);
+      String message = "Destroyed region mapping for region " + regionName + " on " + member;
+      return new CliFunctionResult(member, true, message);
     } else {
-      result = createNotFoundResult(member, regionName);
+      String message = "Region mapping for region \"" + regionName + "\" not found";
+      return new CliFunctionResult(member, false, message);
     }
-    return result;
-  }
-
-  private CliFunctionResult createSuccessResult(String member, String regionName,
-      XmlEntity xmlEntity) {
-    String message = "Destroyed region mapping for region " + regionName + " on " + member;
-    return new CliFunctionResult(member, xmlEntity, message);
-  }
-
-  private CliFunctionResult createNotFoundResult(String member, String regionName) {
-    String message = "Region mapping for region \"" + regionName + "\" not found";
-    return new CliFunctionResult(member, false, message);
   }
 }
diff --git a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/ExceptionHandler.java b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/ExceptionHandler.java
deleted file mode 100644
index 12721b9..0000000
--- a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/ExceptionHandler.java
+++ /dev/null
@@ -1,57 +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.connectors.jdbc.internal.cli;
-
-import org.apache.commons.lang.exception.ExceptionUtils;
-import org.apache.logging.log4j.Logger;
-
-import org.apache.geode.cache.Cache;
-import org.apache.geode.cache.execute.FunctionContext;
-import org.apache.geode.internal.logging.LogService;
-import org.apache.geode.management.internal.cli.CliUtil;
-import org.apache.geode.management.internal.cli.functions.CliFunctionResult;
-
-/**
- * Handles exceptions by returning an error result to GFSH
- */
-class ExceptionHandler {
-  private static final Logger logger = LogService.getLogger();
-
-  void handleException(final FunctionContext<?> context, final Exception exception) {
-    String message = getExceptionMessage(exception);
-    String member = getMember(context.getCache());
-    context.getResultSender().lastResult(handleException(member, message, exception));
-  }
-
-  private CliFunctionResult handleException(final String memberNameOrId, final String exceptionMsg,
-      final Exception exception) {
-    if (exception != null && logger.isDebugEnabled()) {
-      logger.debug(exception.getMessage(), exception);
-    }
-    return new CliFunctionResult(memberNameOrId, false, exceptionMsg);
-  }
-
-  private String getMember(final Cache cache) {
-    return CliUtil.getMemberNameOrId(cache.getDistributedSystem().getDistributedMember());
-  }
-
-  private String getExceptionMessage(final Exception exception) {
-    String message = exception.getMessage();
-    if (message == null) {
-      message = ExceptionUtils.getStackTrace(exception);
-    }
-    return message;
-  }
-}
diff --git a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/JdbcCliFunction.java b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/JdbcCliFunction.java
deleted file mode 100644
index 2114037..0000000
--- a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/JdbcCliFunction.java
+++ /dev/null
@@ -1,67 +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.connectors.jdbc.internal.cli;
-
-import org.apache.logging.log4j.Logger;
-
-import org.apache.geode.cache.execute.FunctionContext;
-import org.apache.geode.connectors.jdbc.internal.JdbcConnectorService;
-import org.apache.geode.internal.cache.execute.InternalFunction;
-import org.apache.geode.internal.logging.LogService;
-import org.apache.geode.management.internal.configuration.domain.XmlEntity;
-
-public abstract class JdbcCliFunction<T1, T2> implements InternalFunction<T1> {
-
-  private final transient ExceptionHandler exceptionHandler;
-  protected static Logger logger = LogService.getLogger();
-
-  JdbcCliFunction() {
-    this.exceptionHandler = new ExceptionHandler();
-  }
-
-  @Override
-  public boolean isHA() {
-    return false;
-  }
-
-  @Override
-  public String getId() {
-    return this.getClass().getName();
-  }
-
-  @Override
-  public void execute(FunctionContext<T1> context) {
-    try {
-      JdbcConnectorService service =
-          FunctionContextArgumentProvider.getJdbcConnectorService(context);
-      T2 result = getFunctionResult(service, context);
-      context.getResultSender().lastResult(result);
-    } catch (Exception e) {
-      logger.error(e.getMessage(), e);
-      exceptionHandler.handleException(context, e);
-    }
-  }
-
-  String getMember(FunctionContext<T1> context) {
-    return FunctionContextArgumentProvider.getMember(context);
-  }
-
-  XmlEntity createXmlEntity(FunctionContext<T1> context) {
-    return FunctionContextArgumentProvider.createXmlEntity(context);
-  }
-
-  abstract T2 getFunctionResult(JdbcConnectorService service, FunctionContext<T1> context)
-      throws Exception;
-}
diff --git a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/ListConnectionCommand.java b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/ListConnectionCommand.java
index 4b79a02..1fd2712 100644
--- a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/ListConnectionCommand.java
+++ b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/ListConnectionCommand.java
@@ -17,7 +17,6 @@ package org.apache.geode.connectors.jdbc.internal.cli;
 import static org.apache.geode.distributed.ConfigurationPersistenceService.CLUSTER_CONFIG;
 
 import java.util.Collection;
-import java.util.List;
 import java.util.Set;
 
 import org.springframework.shell.core.annotation.CliCommand;
@@ -29,6 +28,7 @@ import org.apache.geode.distributed.DistributedMember;
 import org.apache.geode.management.cli.CliMetaData;
 import org.apache.geode.management.cli.GfshCommand;
 import org.apache.geode.management.cli.Result;
+import org.apache.geode.management.internal.cli.functions.CliFunctionResult;
 import org.apache.geode.management.internal.cli.i18n.CliStrings;
 import org.apache.geode.management.internal.cli.result.ResultBuilder;
 import org.apache.geode.management.internal.cli.result.TabularResultData;
@@ -67,10 +67,10 @@ public class ListConnectionCommand extends GfshCommand {
       Set<DistributedMember> members = findMembers(null, null);
       if (members.size() > 0) {
         DistributedMember targetMember = members.iterator().next();
-        List<?> result =
-            (List<?>) executeFunction(new ListConnectionFunction(), null, targetMember).getResult();
-        if (!result.isEmpty()) {
-          connections = (Set<ConnectorService.Connection>) result.get(0);
+        CliFunctionResult result =
+            executeFunctionAndGetFunctionResult(new ListConnectionFunction(), null, targetMember);
+        if (result != null) {
+          connections = (Set<ConnectorService.Connection>) result.getResultObject();
         }
       }
     }
diff --git a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/ListConnectionFunction.java b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/ListConnectionFunction.java
index 9625ca1..85179ad 100644
--- a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/ListConnectionFunction.java
+++ b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/ListConnectionFunction.java
@@ -14,22 +14,16 @@
  */
 package org.apache.geode.connectors.jdbc.internal.cli;
 
-import java.util.Set;
-
 import org.apache.geode.cache.execute.FunctionContext;
 import org.apache.geode.connectors.jdbc.internal.JdbcConnectorService;
-import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
-
-public class ListConnectionFunction
-    extends JdbcCliFunction<Void, Set<ConnectorService.Connection>> {
+import org.apache.geode.management.cli.CliFunction;
+import org.apache.geode.management.internal.cli.functions.CliFunctionResult;
 
-  ListConnectionFunction() {
-    super();
-  }
+public class ListConnectionFunction extends CliFunction<Void> {
 
   @Override
-  Set<ConnectorService.Connection> getFunctionResult(JdbcConnectorService service,
-      FunctionContext<Void> context) {
-    return service.getConnectionConfigs();
+  public CliFunctionResult executeFunction(FunctionContext<Void> context) {
+    JdbcConnectorService service = FunctionContextArgumentProvider.getJdbcConnectorService(context);
+    return new CliFunctionResult(context.getMemberName(), service.getConnectionConfigs());
   }
 }
diff --git a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/ListMappingCommand.java b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/ListMappingCommand.java
index e31c6dc..5a79c08 100644
--- a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/ListMappingCommand.java
+++ b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/ListMappingCommand.java
@@ -17,7 +17,6 @@ package org.apache.geode.connectors.jdbc.internal.cli;
 import static org.apache.geode.distributed.ConfigurationPersistenceService.CLUSTER_CONFIG;
 
 import java.util.Collection;
-import java.util.List;
 import java.util.Set;
 
 import org.springframework.shell.core.annotation.CliCommand;
@@ -29,6 +28,7 @@ import org.apache.geode.distributed.DistributedMember;
 import org.apache.geode.management.cli.CliMetaData;
 import org.apache.geode.management.cli.GfshCommand;
 import org.apache.geode.management.cli.Result;
+import org.apache.geode.management.internal.cli.functions.CliFunctionResult;
 import org.apache.geode.management.internal.cli.i18n.CliStrings;
 import org.apache.geode.management.internal.cli.result.ResultBuilder;
 import org.apache.geode.management.internal.cli.result.TabularResultData;
@@ -68,10 +68,10 @@ public class ListMappingCommand extends GfshCommand {
       Set<DistributedMember> members = findMembers(null, null);
       if (members.size() > 0) {
         DistributedMember targetMember = members.iterator().next();
-        List<?> result =
-            (List<?>) executeFunction(new ListMappingFunction(), null, targetMember).getResult();
-        if (!result.isEmpty()) {
-          mappings = (Collection<ConnectorService.RegionMapping>) result.get(0);
+        CliFunctionResult result =
+            executeFunctionAndGetFunctionResult(new ListMappingFunction(), null, targetMember);
+        if (result != null) {
+          mappings = (Collection<ConnectorService.RegionMapping>) result.getResultObject();
         }
       }
     }
diff --git a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/ListMappingFunction.java b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/ListMappingFunction.java
index 8996307..5c39d9d 100644
--- a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/ListMappingFunction.java
+++ b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/ListMappingFunction.java
@@ -14,22 +14,16 @@
  */
 package org.apache.geode.connectors.jdbc.internal.cli;
 
-import java.util.Set;
-
 import org.apache.geode.cache.execute.FunctionContext;
 import org.apache.geode.connectors.jdbc.internal.JdbcConnectorService;
-import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
-
-public class ListMappingFunction
-    extends JdbcCliFunction<Void, Set<ConnectorService.RegionMapping>> {
+import org.apache.geode.management.cli.CliFunction;
+import org.apache.geode.management.internal.cli.functions.CliFunctionResult;
 
-  ListMappingFunction() {
-    super();
-  }
+public class ListMappingFunction extends CliFunction<Void> {
 
   @Override
-  Set<ConnectorService.RegionMapping> getFunctionResult(JdbcConnectorService service,
-      FunctionContext<Void> context) {
-    return service.getRegionMappings();
+  public CliFunctionResult executeFunction(FunctionContext<Void> context) {
+    JdbcConnectorService service = FunctionContextArgumentProvider.getJdbcConnectorService(context);
+    return new CliFunctionResult(context.getMemberName(), service.getRegionMappings());
   }
 }
diff --git a/geode-connectors/src/main/resources/org/apache/geode/internal/sanctioned-geode-connectors-serializables.txt b/geode-connectors/src/main/resources/org/apache/geode/internal/sanctioned-geode-connectors-serializables.txt
index 39512f3..bd81b4a 100755
--- a/geode-connectors/src/main/resources/org/apache/geode/internal/sanctioned-geode-connectors-serializables.txt
+++ b/geode-connectors/src/main/resources/org/apache/geode/internal/sanctioned-geode-connectors-serializables.txt
@@ -11,7 +11,6 @@ org/apache/geode/connectors/jdbc/internal/cli/DescribeConnectionFunction,false
 org/apache/geode/connectors/jdbc/internal/cli/DescribeMappingFunction,false
 org/apache/geode/connectors/jdbc/internal/cli/DestroyConnectionFunction,false
 org/apache/geode/connectors/jdbc/internal/cli/DestroyMappingFunction,false
-org/apache/geode/connectors/jdbc/internal/cli/JdbcCliFunction,false
 org/apache/geode/connectors/jdbc/internal/cli/ListConnectionFunction,false
 org/apache/geode/connectors/jdbc/internal/cli/ListMappingFunction,false
 org/apache/geode/connectors/jdbc/internal/configuration/ConnectorService,false,connection:java/util/List,name:java/lang/String,regionMapping:java/util/List
diff --git a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/AlterMappingFunctionTest.java b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/AlterMappingFunctionTest.java
index 977322e..9e57ffc 100644
--- a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/AlterMappingFunctionTest.java
+++ b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/AlterMappingFunctionTest.java
@@ -18,7 +18,6 @@ import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.doThrow;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
@@ -120,7 +119,6 @@ public class AlterMappingFunctionTest {
     when(service.getMappingForRegion(REGION_NAME)).thenReturn(existingMapping);
 
     AlterMappingFunction function = spy(new AlterMappingFunction());
-    doReturn(null).when(function).createXmlEntity(context);
     function.execute(context);
 
     verify(service, times(1)).replaceRegionMapping(any());
diff --git a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeConnectionCommandTest.java b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeConnectionCommandTest.java
index aa5b358..de9628c 100644
--- a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeConnectionCommandTest.java
+++ b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeConnectionCommandTest.java
@@ -23,6 +23,7 @@ import static org.mockito.Mockito.when;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import java.util.Set;
 
 import org.junit.Before;
 import org.junit.ClassRule;
@@ -35,6 +36,7 @@ import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
 import org.apache.geode.distributed.ConfigurationPersistenceService;
 import org.apache.geode.distributed.DistributedMember;
 import org.apache.geode.distributed.internal.InternalConfigurationPersistenceService;
+import org.apache.geode.management.internal.cli.functions.CliFunctionResult;
 import org.apache.geode.test.junit.categories.UnitTest;
 import org.apache.geode.test.junit.rules.GfshParserRule;
 
@@ -119,8 +121,9 @@ public class DescribeConnectionCommandTest {
     ConnectorService.Connection connection =
         new ConnectorService.Connection("name", "url1", "user1", "password1", "p1:v1,p2:v2");
     ResultCollector rc = mock(ResultCollector.class);
-    doReturn(rc).when(command).executeFunction(any(), any(), any(DistributedMember.class));
-    when(rc.getResult()).thenReturn(Collections.singletonList(connection));
+    doReturn(rc).when(command).executeFunction(any(), any(), any(Set.class));
+    when(rc.getResult()).thenReturn(
+        Collections.singletonList(new CliFunctionResult("server-1", connection, "success")));
 
     gfsh.executeAndAssertThat(command, COMMAND).statusIsSuccess().containsOutput("name", "name")
         .containsOutput("url", "url1").containsOutput("user", "user1")
@@ -135,7 +138,7 @@ public class DescribeConnectionCommandTest {
         null);
 
     ResultCollector rc = mock(ResultCollector.class);
-    doReturn(rc).when(command).executeFunction(any(), any(), any(DistributedMember.class));
+    doReturn(rc).when(command).executeFunction(any(), any(), any(Set.class));
     when(rc.getResult()).thenReturn(Collections.emptyList());
 
     gfsh.executeAndAssertThat(command, COMMAND).statusIsError()
diff --git a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeConnectionFunctionTest.java b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeConnectionFunctionTest.java
index 1bf804f..7fff9df 100644
--- a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeConnectionFunctionTest.java
+++ b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeConnectionFunctionTest.java
@@ -95,9 +95,9 @@ public class DescribeConnectionFunctionTest {
 
     function.execute(context);
 
-    ArgumentCaptor<Object> argument = ArgumentCaptor.forClass(Object.class);
+    ArgumentCaptor<CliFunctionResult> argument = ArgumentCaptor.forClass(CliFunctionResult.class);
     verify(resultSender, times(1)).lastResult(argument.capture());
-    assertThat(argument.getValue()).isSameAs(connectionConfig);
+    assertThat(argument.getValue().getResultObject()).isSameAs(connectionConfig);
   }
 
   @Test
@@ -106,10 +106,9 @@ public class DescribeConnectionFunctionTest {
 
     function.execute(context);
 
-    ArgumentCaptor<Object> argument = ArgumentCaptor.forClass(Object.class);
+    ArgumentCaptor<CliFunctionResult> argument = ArgumentCaptor.forClass(CliFunctionResult.class);
     verify(resultSender, times(1)).lastResult(argument.capture());
-    assertThat(argument.getValue()).isNull();
-
+    assertThat(argument.getValue().getResultObject()).isNull();
   }
 
   @Test
@@ -120,7 +119,7 @@ public class DescribeConnectionFunctionTest {
 
     ArgumentCaptor<CliFunctionResult> argument = ArgumentCaptor.forClass(CliFunctionResult.class);
     verify(resultSender, times(1)).lastResult(argument.capture());
-    assertThat(argument.getValue().getMessage()).contains(NullPointerException.class.getName());
+    assertThat(argument.getValue().getStatus()).contains(NullPointerException.class.getName());
   }
 
   @Test
@@ -132,7 +131,6 @@ public class DescribeConnectionFunctionTest {
 
     ArgumentCaptor<CliFunctionResult> argument = ArgumentCaptor.forClass(CliFunctionResult.class);
     verify(resultSender, times(1)).lastResult(argument.capture());
-    assertThat(argument.getValue().getMessage()).contains("some message")
-        .doesNotContain(IllegalArgumentException.class.getName());
+    assertThat(argument.getValue().getStatus()).contains("some message");
   }
 }
diff --git a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeMappingCommandTest.java b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeMappingCommandTest.java
index 74d9dfb..79c4dfa 100644
--- a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeMappingCommandTest.java
+++ b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeMappingCommandTest.java
@@ -23,6 +23,7 @@ import static org.mockito.Mockito.when;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import java.util.Set;
 
 import org.junit.Before;
 import org.junit.ClassRule;
@@ -35,6 +36,7 @@ import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
 import org.apache.geode.distributed.ConfigurationPersistenceService;
 import org.apache.geode.distributed.DistributedMember;
 import org.apache.geode.distributed.internal.InternalConfigurationPersistenceService;
+import org.apache.geode.management.internal.cli.functions.CliFunctionResult;
 import org.apache.geode.test.junit.categories.UnitTest;
 import org.apache.geode.test.junit.rules.GfshParserRule;
 
@@ -129,8 +131,9 @@ public class DescribeMappingCommandTest {
         .add(new ConnectorService.RegionMapping.FieldMapping("field2", "value2"));
 
     ResultCollector rc = mock(ResultCollector.class);
-    doReturn(rc).when(command).executeFunction(any(), any(), any(DistributedMember.class));
-    when(rc.getResult()).thenReturn(Collections.singletonList(mapping));
+    doReturn(rc).when(command).executeFunction(any(), any(), any(Set.class));
+    when(rc.getResult()).thenReturn(
+        Collections.singletonList(new CliFunctionResult("server-1", mapping, "success")));
 
     gfsh.executeAndAssertThat(command, COMMAND).statusIsSuccess().containsOutput("region", "region")
         .containsOutput("connection", "name1").containsOutput("table", "table1")
@@ -146,7 +149,7 @@ public class DescribeMappingCommandTest {
         null);
 
     ResultCollector rc = mock(ResultCollector.class);
-    doReturn(rc).when(command).executeFunction(any(), any(), any(DistributedMember.class));
+    doReturn(rc).when(command).executeFunction(any(), any(), any(Set.class));
     when(rc.getResult()).thenReturn(Collections.emptyList());
 
     gfsh.executeAndAssertThat(command, COMMAND).statusIsError()
diff --git a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeMappingFunctionTest.java b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeMappingFunctionTest.java
index 0487c7d..e5d49a6 100644
--- a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeMappingFunctionTest.java
+++ b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeMappingFunctionTest.java
@@ -95,9 +95,9 @@ public class DescribeMappingFunctionTest {
 
     function.execute(context);
 
-    ArgumentCaptor<Object> argument = ArgumentCaptor.forClass(Object.class);
+    ArgumentCaptor<CliFunctionResult> argument = ArgumentCaptor.forClass(CliFunctionResult.class);
     verify(resultSender, times(1)).lastResult(argument.capture());
-    assertThat(argument.getValue()).isSameAs(regionMapping);
+    assertThat(argument.getValue().getResultObject()).isSameAs(regionMapping);
   }
 
   @Test
@@ -106,9 +106,9 @@ public class DescribeMappingFunctionTest {
 
     function.execute(context);
 
-    ArgumentCaptor<Object> argument = ArgumentCaptor.forClass(Object.class);
+    ArgumentCaptor<CliFunctionResult> argument = ArgumentCaptor.forClass(CliFunctionResult.class);
     verify(resultSender, times(1)).lastResult(argument.capture());
-    assertThat(argument.getValue()).isNull();
+    assertThat(argument.getValue().getResultObject()).isNull();
 
   }
 
@@ -120,7 +120,7 @@ public class DescribeMappingFunctionTest {
 
     ArgumentCaptor<CliFunctionResult> argument = ArgumentCaptor.forClass(CliFunctionResult.class);
     verify(resultSender, times(1)).lastResult(argument.capture());
-    assertThat(argument.getValue().getMessage()).contains(NullPointerException.class.getName());
+    assertThat(argument.getValue().getStatus()).contains(NullPointerException.class.getName());
   }
 
   @Test
@@ -132,7 +132,6 @@ public class DescribeMappingFunctionTest {
 
     ArgumentCaptor<CliFunctionResult> argument = ArgumentCaptor.forClass(CliFunctionResult.class);
     verify(resultSender, times(1)).lastResult(argument.capture());
-    assertThat(argument.getValue().getMessage()).contains("some message")
-        .doesNotContain(IllegalArgumentException.class.getName());
+    assertThat(argument.getValue().getStatus()).contains("some message");
   }
 }
diff --git a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyConnectionFunctionTest.java b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyConnectionFunctionTest.java
index 8911c71..bf24a70 100644
--- a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyConnectionFunctionTest.java
+++ b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyConnectionFunctionTest.java
@@ -94,12 +94,14 @@ public class DestroyConnectionFunctionTest {
   public void destroyConnectionConfigReturnsTrueIfConnectionDestroyed() {
     when(service.getConnectionConfig(eq(connectionName))).thenReturn(configuration);
 
-    assertThat(function.destroyConnectionConfig(service, connectionName)).isTrue();
+    CliFunctionResult result = function.executeFunction(context);
+    assertThat(result.isSuccessful()).isTrue();
   }
 
   @Test
   public void destroyConnectionConfigReturnsFalseIfConnectionDoesNotExist() {
-    assertThat(function.destroyConnectionConfig(service, connectionName)).isFalse();
+    CliFunctionResult result = function.executeFunction(context);
+    assertThat(result.isSuccessful()).isFalse();
   }
 
   @Test
diff --git a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyMappingCommandFunctionTest.java b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyMappingCommandFunctionTest.java
index 5ee7360..ab3d3be 100644
--- a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyMappingCommandFunctionTest.java
+++ b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyMappingCommandFunctionTest.java
@@ -93,13 +93,14 @@ public class DestroyMappingCommandFunctionTest {
   @Test
   public void destroyRegionMappingReturnsTrueIfConnectionDestroyed() {
     when(service.getMappingForRegion(eq(regionName))).thenReturn(mapping);
-
-    assertThat(function.destroyRegionMapping(service, regionName)).isTrue();
+    CliFunctionResult result = function.executeFunction(context);
+    assertThat(result.isSuccessful()).isTrue();
   }
 
   @Test
   public void destroyRegionMappingReturnsFalseIfMappingDoesNotExist() {
-    assertThat(function.destroyRegionMapping(service, regionName)).isFalse();
+    CliFunctionResult result = function.executeFunction(context);
+    assertThat(result.isSuccessful()).isFalse();
   }
 
   @Test
diff --git a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/JDBCConnectorFunctionsSecurityTest.java b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/JDBCConnectorFunctionsSecurityTest.java
index a9a0c61..a4bfe6a 100644
--- a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/JDBCConnectorFunctionsSecurityTest.java
+++ b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/JDBCConnectorFunctionsSecurityTest.java
@@ -27,24 +27,23 @@ import org.junit.experimental.categories.Category;
 import org.apache.geode.cache.execute.Function;
 import org.apache.geode.cache.execute.FunctionContext;
 import org.apache.geode.cache.execute.FunctionService;
-import org.apache.geode.connectors.jdbc.internal.JdbcConnectorService;
 import org.apache.geode.examples.SimpleSecurityManager;
+import org.apache.geode.management.cli.CliFunction;
 import org.apache.geode.management.internal.cli.functions.CliFunctionResult;
 import org.apache.geode.test.junit.categories.IntegrationTest;
 import org.apache.geode.test.junit.rules.ConnectionConfiguration;
 import org.apache.geode.test.junit.rules.GfshCommandRule;
 import org.apache.geode.test.junit.rules.ServerStarterRule;
 
-class InheritsDefaultPermissionsJDBCFunction extends JdbcCliFunction<String, CliFunctionResult> {
+class InheritsDefaultPermissionsJDBCFunction extends CliFunction<String> {
 
   InheritsDefaultPermissionsJDBCFunction() {
     super();
   }
 
   @Override
-  CliFunctionResult getFunctionResult(JdbcConnectorService service,
-      FunctionContext<String> context) {
-    return new CliFunctionResult();
+  public CliFunctionResult executeFunction(FunctionContext<String> context) {
+    return new CliFunctionResult("some-member", true, "some-message");
   }
 }
 
diff --git a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/JdbcCliFunctionTest.java b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/JdbcCliFunctionTest.java
deleted file mode 100644
index 837620b..0000000
--- a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/JdbcCliFunctionTest.java
+++ /dev/null
@@ -1,51 +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.connectors.jdbc.internal.cli;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-
-import org.apache.geode.cache.execute.FunctionContext;
-import org.apache.geode.connectors.jdbc.internal.JdbcConnectorService;
-import org.apache.geode.test.junit.categories.UnitTest;
-
-@Category(UnitTest.class)
-public class JdbcCliFunctionTest {
-
-  private JdbcCliFunction<Void, Void> function;
-
-  @Before
-  public void setup() {
-    function = new JdbcCliFunction<Void, Void>() {
-      @Override
-      Void getFunctionResult(JdbcConnectorService service, FunctionContext<Void> context) {
-        return null;
-      }
-    };
-  }
-
-  @Test
-  public void isHAReturnsFalse() {
-    assertThat(function.isHA()).isFalse();
-  }
-
-  @Test
-  public void getIdReturnsNameOfClass() {
-    assertThat(function.getId()).isEqualTo(function.getClass().getName());
-  }
-}
diff --git a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/ListConnectionCommandTest.java b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/ListConnectionCommandTest.java
index 384aaa2..dd1e72c 100644
--- a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/ListConnectionCommandTest.java
+++ b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/ListConnectionCommandTest.java
@@ -22,6 +22,7 @@ import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.when;
 
 import java.util.Collections;
+import java.util.Set;
 import java.util.stream.Stream;
 
 import org.junit.Before;
@@ -35,6 +36,7 @@ import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
 import org.apache.geode.distributed.ConfigurationPersistenceService;
 import org.apache.geode.distributed.DistributedMember;
 import org.apache.geode.distributed.internal.InternalConfigurationPersistenceService;
+import org.apache.geode.management.internal.cli.functions.CliFunctionResult;
 import org.apache.geode.test.junit.categories.UnitTest;
 import org.apache.geode.test.junit.rules.GfshParserRule;
 
@@ -129,9 +131,9 @@ public class ListConnectionCommandTest {
         new ConnectorService.Connection("name3", "url3", "user3", "password3", "p5:v5,p6:v6");
 
     ResultCollector rc = mock(ResultCollector.class);
-    doReturn(rc).when(command).executeFunction(any(), any(), any(DistributedMember.class));
-    when(rc.getResult()).thenReturn(Collections
-        .singletonList(Stream.of(connection1, connection2, connection3).collect(toSet())));
+    doReturn(rc).when(command).executeFunction(any(), any(), any(Set.class));
+    when(rc.getResult()).thenReturn(Collections.singletonList(new CliFunctionResult("server-1",
+        Stream.of(connection1, connection2, connection3).collect(toSet()), "success")));
 
     gfsh.executeAndAssertThat(command, COMMAND + " --member=member1").statusIsSuccess()
         .containsOutput("name1", "name2", "name3");
@@ -144,7 +146,7 @@ public class ListConnectionCommandTest {
         null);
 
     ResultCollector rc = mock(ResultCollector.class);
-    doReturn(rc).when(command).executeFunction(any(), any(), any(DistributedMember.class));
+    doReturn(rc).when(command).executeFunction(any(), any(), any(Set.class));
     when(rc.getResult()).thenReturn(Collections.emptyList());
 
     gfsh.executeAndAssertThat(command, COMMAND).statusIsSuccess()
diff --git a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/ListConnectionFunctionTest.java b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/ListConnectionFunctionTest.java
index e8de75f..69c90e2 100644
--- a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/ListConnectionFunctionTest.java
+++ b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/ListConnectionFunctionTest.java
@@ -107,7 +107,7 @@ public class ListConnectionFunctionTest {
     expected.add(connectionConfig3);
 
     Set<ConnectorService.Connection> actual =
-        function.getFunctionResult(service, mock(FunctionContext.class));
+        (Set<ConnectorService.Connection>) function.executeFunction(context).getResultObject();
 
     assertThat(actual).containsExactlyInAnyOrder(connectionConfig1, connectionConfig2,
         connectionConfig3);
@@ -116,7 +116,7 @@ public class ListConnectionFunctionTest {
   @Test
   public void getConnectionConfigsReturnsEmpty() {
     Set<ConnectorService.Connection> actual =
-        function.getFunctionResult(service, mock(FunctionContext.class));
+        (Set<ConnectorService.Connection>) function.executeFunction(context).getResultObject();
 
     assertThat(actual).isEmpty();
   }
@@ -129,19 +129,19 @@ public class ListConnectionFunctionTest {
 
     function.execute(context);
 
-    ArgumentCaptor<Set<ConnectorService.Connection>> argument = ArgumentCaptor.forClass(Set.class);
+    ArgumentCaptor<CliFunctionResult> argument = ArgumentCaptor.forClass(CliFunctionResult.class);
     verify(resultSender, times(1)).lastResult(argument.capture());
-    assertThat(argument.getValue()).containsExactlyInAnyOrder(connectionConfig1, connectionConfig2,
-        connectionConfig3);
+    assertThat((Set) argument.getValue().getResultObject())
+        .containsExactlyInAnyOrder(connectionConfig1, connectionConfig2, connectionConfig3);
   }
 
   @Test
   public void executeReturnsEmptyResultForNoConfigs() {
     function.execute(context);
 
-    ArgumentCaptor<Set<ConnectorService.Connection>> argument = ArgumentCaptor.forClass(Set.class);
+    ArgumentCaptor<CliFunctionResult> argument = ArgumentCaptor.forClass(CliFunctionResult.class);
     verify(resultSender, times(1)).lastResult(argument.capture());
-    assertThat(argument.getValue()).isEmpty();
+    assertThat((Set) argument.getValue().getResultObject()).isEmpty();
   }
 
   @Test
@@ -163,7 +163,6 @@ public class ListConnectionFunctionTest {
 
     ArgumentCaptor<CliFunctionResult> argument = ArgumentCaptor.forClass(CliFunctionResult.class);
     verify(resultSender, times(1)).lastResult(argument.capture());
-    assertThat(argument.getValue().getStatus()).contains("some message")
-        .doesNotContain(IllegalArgumentException.class.getName());
+    assertThat(argument.getValue().getStatus()).contains("some message");
   }
 }
diff --git a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/ListMappingCommandTest.java b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/ListMappingCommandTest.java
index f644ec3..dfb78e3 100644
--- a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/ListMappingCommandTest.java
+++ b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/ListMappingCommandTest.java
@@ -22,6 +22,7 @@ import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.when;
 
 import java.util.Collections;
+import java.util.Set;
 import java.util.stream.Stream;
 
 import org.junit.Before;
@@ -35,6 +36,7 @@ import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
 import org.apache.geode.distributed.ConfigurationPersistenceService;
 import org.apache.geode.distributed.DistributedMember;
 import org.apache.geode.distributed.internal.InternalConfigurationPersistenceService;
+import org.apache.geode.management.internal.cli.functions.CliFunctionResult;
 import org.apache.geode.test.junit.categories.UnitTest;
 import org.apache.geode.test.junit.rules.GfshParserRule;
 
@@ -117,7 +119,7 @@ public class ListMappingCommandTest {
   }
 
   @Test
-  public void whenExistingMemberIsSpecified() {
+  public void whenCCIsNotAvailableAndMemberExists() {
     doReturn(null).when(command).getConfigurationPersistenceService();
     doReturn(Collections.singleton(mock(DistributedMember.class))).when(command).findMembers(null,
         null);
@@ -137,9 +139,9 @@ public class ListMappingCommandTest {
         .add(new ConnectorService.RegionMapping.FieldMapping("field4", "value4"));
 
     ResultCollector rc = mock(ResultCollector.class);
-    doReturn(rc).when(command).executeFunction(any(), any(), any(DistributedMember.class));
-    when(rc.getResult())
-        .thenReturn(Collections.singletonList(Stream.of(mapping1, mapping2).collect(toSet())));
+    doReturn(rc).when(command).executeFunction(any(), any(), any(Set.class));
+    when(rc.getResult()).thenReturn(Collections.singletonList(new CliFunctionResult("server-1",
+        Stream.of(mapping1, mapping2).collect(toSet()), "success")));
 
     gfsh.executeAndAssertThat(command, COMMAND).statusIsSuccess().containsOutput("region1",
         "region2");
@@ -153,7 +155,7 @@ public class ListMappingCommandTest {
         null);
 
     ResultCollector rc = mock(ResultCollector.class);
-    doReturn(rc).when(command).executeFunction(any(), any(), any(DistributedMember.class));
+    doReturn(rc).when(command).executeFunction(any(), any(), any(Set.class));
     when(rc.getResult()).thenReturn(Collections.emptyList());
 
     gfsh.executeAndAssertThat(command, COMMAND).statusIsSuccess()
diff --git a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/ListMappingFunctionTest.java b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/ListMappingFunctionTest.java
index aef645e..24ddbb0 100644
--- a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/ListMappingFunctionTest.java
+++ b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/ListMappingFunctionTest.java
@@ -107,7 +107,7 @@ public class ListMappingFunctionTest {
     expected.add(regionMapping3);
 
     Set<ConnectorService.RegionMapping> actual =
-        function.getFunctionResult(service, mock(FunctionContext.class));
+        (Set<ConnectorService.RegionMapping>) function.executeFunction(context).getResultObject();
 
     assertThat(actual).containsExactlyInAnyOrder(regionMapping1, regionMapping2, regionMapping3);
   }
@@ -115,7 +115,7 @@ public class ListMappingFunctionTest {
   @Test
   public void getRegionMappingsReturnsEmpty() {
     Set<ConnectorService.RegionMapping> actual =
-        function.getFunctionResult(service, mock(FunctionContext.class));
+        (Set<ConnectorService.RegionMapping>) function.executeFunction(context).getResultObject();
 
     assertThat(actual).isEmpty();
   }
@@ -128,21 +128,20 @@ public class ListMappingFunctionTest {
 
     function.execute(context);
 
-    ArgumentCaptor<Set<ConnectorService.RegionMapping>> argument =
-        ArgumentCaptor.forClass(Set.class);
+    ArgumentCaptor<CliFunctionResult> argument = ArgumentCaptor.forClass(CliFunctionResult.class);
     verify(resultSender, times(1)).lastResult(argument.capture());
-    assertThat(argument.getValue()).containsExactlyInAnyOrder(regionMapping1, regionMapping2,
-        regionMapping3);
+    Set<ConnectorService.RegionMapping> mappings =
+        (Set<ConnectorService.RegionMapping>) argument.getValue().getResultObject();
+    assertThat(mappings).containsExactlyInAnyOrder(regionMapping1, regionMapping2, regionMapping3);
   }
 
   @Test
   public void executeReturnsEmptyResultForNoRegionMappings() {
     function.execute(context);
 
-    ArgumentCaptor<Set<ConnectorService.RegionMapping>> argument =
-        ArgumentCaptor.forClass(Set.class);
+    ArgumentCaptor<CliFunctionResult> argument = ArgumentCaptor.forClass(CliFunctionResult.class);
     verify(resultSender, times(1)).lastResult(argument.capture());
-    assertThat(argument.getValue()).isEmpty();
+    assertThat((Set) argument.getValue().getResultObject()).isEmpty();
   }
 
   @Test
@@ -164,7 +163,6 @@ public class ListMappingFunctionTest {
 
     ArgumentCaptor<CliFunctionResult> argument = ArgumentCaptor.forClass(CliFunctionResult.class);
     verify(resultSender, times(1)).lastResult(argument.capture());
-    assertThat(argument.getValue().getStatus()).contains("some message")
-        .doesNotContain(IllegalArgumentException.class.getName());
+    assertThat(argument.getValue().getStatus()).contains("some message");
   }
 }
diff --git a/geode-core/src/main/java/org/apache/geode/management/cli/CliFunction.java b/geode-core/src/main/java/org/apache/geode/management/cli/CliFunction.java
new file mode 100644
index 0000000..28dcdca
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/management/cli/CliFunction.java
@@ -0,0 +1,44 @@
+/*
+ * 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.cli;
+
+import org.apache.geode.cache.execute.FunctionContext;
+import org.apache.geode.internal.cache.execute.InternalFunction;
+import org.apache.geode.management.internal.cli.functions.CliFunctionResult;
+
+/**
+ * An abstract function implementation to be extended by cli functions. Any cli function extending
+ * this class has to return a CliFunctionResult.
+ */
+public abstract class CliFunction<T> implements InternalFunction<T> {
+
+  @Override
+  public final void execute(FunctionContext<T> context) {
+    try {
+      context.getResultSender().lastResult(executeFunction(context));
+    } catch (Exception e) {
+      context.getResultSender().lastResult(new CliFunctionResult(context.getMemberName(), e));
+    }
+  }
+
+  @Override
+  public boolean isHA() {
+    return false;
+  }
+
+  public abstract CliFunctionResult executeFunction(FunctionContext<T> context) throws Exception;
+}
diff --git a/geode-core/src/main/java/org/apache/geode/management/cli/GfshCommand.java b/geode-core/src/main/java/org/apache/geode/management/cli/GfshCommand.java
index 1be3399..ab81ab2 100644
--- a/geode-core/src/main/java/org/apache/geode/management/cli/GfshCommand.java
+++ b/geode-core/src/main/java/org/apache/geode/management/cli/GfshCommand.java
@@ -182,6 +182,13 @@ public abstract class GfshCommand implements CommandMarker {
     return executeFunction(function, args, Collections.singleton(targetMember));
   }
 
+  public CliFunctionResult executeFunctionAndGetFunctionResult(Function function, Object args,
+      final DistributedMember targetMember) {
+    ResultCollector rc = executeFunction(function, args, Collections.singleton(targetMember));
+    List<CliFunctionResult> results = CliFunctionResult.cleanResults((List<?>) rc.getResult());
+    return results.size() > 0 ? results.get(0) : null;
+  }
+
   public List<CliFunctionResult> executeAndGetFunctionResult(Function function, Object args,
       Set<DistributedMember> targetMembers) {
     ResultCollector rc = executeFunction(function, args, targetMembers);
diff --git a/geode-core/src/main/resources/org/apache/geode/internal/sanctioned-geode-core-serializables.txt b/geode-core/src/main/resources/org/apache/geode/internal/sanctioned-geode-core-serializables.txt
index 75d2d1d..dde4c25 100644
--- a/geode-core/src/main/resources/org/apache/geode/internal/sanctioned-geode-core-serializables.txt
+++ b/geode-core/src/main/resources/org/apache/geode/internal/sanctioned-geode-core-serializables.txt
@@ -468,6 +468,7 @@ org/apache/geode/management/DependenciesNotFoundException,true,90823049292381598
 org/apache/geode/management/JVMMetrics,false,committedMemory:long,gcCount:long,gcTimeMillis:long,initMemory:long,maxMemory:long,totalThreads:int,usedMemory:long
 org/apache/geode/management/ManagementException,true,879398950879472121
 org/apache/geode/management/OSMetrics,false,arch:java/lang/String,availableProcessors:int,committedVirtualMemorySize:long,freePhysicalMemorySize:long,freeSwapSpaceSize:long,maxFileDescriptorCount:long,name:java/lang/String,openFileDescriptorCount:long,processCpuTime:long,systemLoadAverage:double,totalPhysicalMemorySize:long,totalSwapSpaceSize:long,version:java/lang/String
+org/apache/geode/management/cli/CliFunction,false
 org/apache/geode/management/cli/CommandProcessingException,true,-1398779521639575884,errorData:java/lang/Object,errorType:int
 org/apache/geode/management/cli/CommandServiceException,true,7316102209844678329
 org/apache/geode/management/cli/Result$Status,false,code:int

-- 
To stop receiving notification emails like this one, please contact
sai_boorlagadda@apache.org.