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/04/13 18:30:57 UTC

[geode] branch develop updated: GEODE-4863: refactor jdbc commands to use this public cluster configuration api (#1776)

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 2ecb372  GEODE-4863: refactor jdbc commands to use this public cluster configuration api (#1776)
2ecb372 is described below

commit 2ecb3725a315bf1b85436dc4c56b32e53ce3237a
Author: Sai Boorlagadda <sa...@gmail.com>
AuthorDate: Fri Apr 13 11:30:52 2018 -0700

    GEODE-4863: refactor jdbc commands to use this public cluster configuration api (#1776)
    
       * refactored jdbc connector commands to use public cc service
       * removed JdbcConnectorServiceXmlGenerator
       * removed RegionMappingBuilder & ConnectionConfigBuilder
       * if cc service is running then user can only alter whats available in CC
       * describe & List commands now list entries from cc service
       * converted some integration tests to junits
       * removed unwanted functions, tests
    
    Signed-off-by: Jinmei Liao <ji...@pivotal.io>
---
 .../jdbc/internal/ConnectionConfigBuilder.java     |  82 --
 .../jdbc/internal/ConnectionConfiguration.java     | 110 ---
 .../jdbc/internal/DataSourceManager.java           |   4 +-
 .../jdbc/internal/HikariJdbcDataSource.java        |   4 +-
 .../jdbc/internal/HikariJdbcDataSourceFactory.java |   4 +-
 .../jdbc/internal/JdbcConnectorService.java        |  23 +-
 .../jdbc/internal/JdbcConnectorServiceImpl.java    |  74 +-
 .../jdbc/internal/JdbcDataSourceFactory.java       |   4 +-
 .../connectors/jdbc/internal/RegionMapping.java    | 291 -------
 .../jdbc/internal/RegionMappingBuilder.java        |  99 ---
 .../geode/connectors/jdbc/internal/SqlHandler.java |  24 +-
 .../jdbc/internal/SqlToPdxInstanceCreator.java     |   5 +-
 .../jdbc/internal/cli/AlterConnectionCommand.java  | 112 ++-
 .../jdbc/internal/cli/AlterConnectionFunction.java |  38 +-
 .../jdbc/internal/cli/AlterMappingCommand.java     | 113 ++-
 .../jdbc/internal/cli/AlterMappingFunction.java    |  47 +-
 .../jdbc/internal/cli/CreateConnectionCommand.java |  83 +-
 .../internal/cli/CreateConnectionFunction.java     |  10 +-
 .../jdbc/internal/cli/CreateMappingCommand.java    |  87 +--
 .../jdbc/internal/cli/CreateMappingFunction.java   |  25 +-
 .../internal/cli/DescribeConnectionCommand.java    |  61 +-
 .../internal/cli/DescribeConnectionFunction.java   |  34 -
 .../jdbc/internal/cli/DescribeMappingCommand.java  |  60 +-
 .../jdbc/internal/cli/DescribeMappingFunction.java |  33 -
 .../internal/cli/DestroyConnectionCommand.java     |  75 +-
 .../internal/cli/DestroyConnectionFunction.java    |   4 +-
 .../jdbc/internal/cli/DestroyMappingCommand.java   |  69 +-
 .../jdbc/internal/cli/DestroyMappingFunction.java  |   4 +-
 .../jdbc/internal/cli/ExceptionHandler.java        |   1 -
 .../cli/FunctionContextArgumentProvider.java       |   9 +-
 .../jdbc/internal/cli/JdbcCliFunction.java         |   5 +
 .../jdbc/internal/cli/ListConnectionCommand.java   |  51 +-
 .../jdbc/internal/cli/ListConnectionFunction.java  |  45 --
 .../jdbc/internal/cli/ListMappingCommand.java      |  51 +-
 .../jdbc/internal/cli/ListMappingFunction.java     |  44 --
 .../internal/configuration/ConnectorService.java   | 852 +++++++++++++++++++++
 .../jdbc/internal/configuration/package-info.java  |  24 +
 .../connectors/jdbc/internal/xml/ElementType.java  |  50 +-
 .../xml/JdbcConnectorServiceXmlGenerator.java      | 164 ----
 .../internal/xml/JdbcServiceConfiguration.java     |  18 +-
 .../geode.apache.org/schema/jdbc/jdbc-1.0.xsd      |   5 -
 .../sanctioned-geode-connectors-serializables.txt  |  10 +-
 .../jdbc/internal/ConnectionConfigBuilderTest.java |  90 ---
 .../jdbc/internal/ConnectionConfigurationTest.java |  96 ---
 .../jdbc/internal/DataSourceManagerUnitTest.java   |  11 +-
 .../jdbc/internal/JdbcConnectorServiceTest.java    |  24 +-
 .../jdbc/internal/RegionMappingBuilderTest.java    | 119 ---
 .../jdbc/internal/RegionMappingTest.java           | 234 +++---
 .../connectors/jdbc/internal/SqlHandlerTest.java   |  11 +-
 .../jdbc/internal/SqlToPdxInstanceCreatorTest.java |   5 +-
 .../jdbc/internal/TestConfigService.java           |  15 +-
 .../cli/AlterConnectionCommandDUnitTest.java       |   9 +-
 .../cli/AlterConnectionCommandIntegrationTest.java |   4 +-
 .../internal/cli/AlterConnectionCommandTest.java   | 147 ++++
 .../internal/cli/AlterConnectionFunctionTest.java  |  96 ++-
 .../internal/cli/AlterMappingCommandDUnitTest.java |  19 +-
 .../cli/AlterMappingCommandIntegrationTest.java    |   8 +-
 .../jdbc/internal/cli/AlterMappingCommandTest.java | 154 ++++
 .../internal/cli/AlterMappingFunctionTest.java     | 141 ++--
 .../cli/CreateConnectionCommandDUnitTest.java      |   4 +-
 .../CreateConnectionCommandIntegrationTest.java    |   8 +-
 .../internal/cli/CreateConnectionFunctionTest.java |  10 +-
 .../cli/CreateMappingCommandDUnitTest.java         |  24 +-
 .../cli/CreateMappingCommandIntegrationTest.java   |  11 +-
 .../internal/cli/CreateMappingFunctionTest.java    |   9 +-
 .../cli/DescribeConnectionCommandDUnitTest.java    |  45 +-
 .../DescribeConnectionCommandIntegrationTest.java  | 150 ----
 .../cli/DescribeConnectionCommandTest.java         |  92 +++
 .../cli/DescribeConnectionFunctionTest.java        | 138 ----
 .../cli/DescribeMappingCommandDUnitTest.java       |  45 +-
 .../cli/DescribeMappingCommandIntegrationTest.java | 145 ----
 .../internal/cli/DescribeMappingCommandTest.java   |  98 +++
 .../internal/cli/DescribeMappingFunctionTest.java  | 138 ----
 .../cli/DestroyConnectionCommandDUnitTest.java     |  32 +-
 .../DestroyConnectionCommandIntegrationTest.java   |   9 +-
 .../cli/DestroyConnectionFunctionTest.java         |   7 +-
 .../cli/DestroyMappingCommandDunitTest.java        |  35 +-
 .../cli/DestroyMappingCommandFunctionTest.java     |   7 +-
 .../cli/DestroyMappingCommandIntegrationTest.java  |   7 +-
 .../cli/JDBCConnectorFunctionsSecurityTest.java    |   4 -
 .../cli/JdbcClusterConfigDistributedTest.java      |   4 +-
 .../cli/ListConnectionCommandDUnitTest.java        |  49 +-
 .../cli/ListConnectionCommandIntegrationTest.java  | 110 ---
 .../internal/cli/ListConnectionCommandTest.java    |  92 +++
 .../internal/cli/ListConnectionFunctionTest.java   | 167 ----
 .../internal/cli/ListMappingCommandDUnitTest.java  |  55 +-
 .../cli/ListMappingCommandIntegrationTest.java     | 110 ---
 .../jdbc/internal/cli/ListMappingCommandTest.java  |  93 +++
 .../jdbc/internal/cli/ListMappingFunctionTest.java | 166 ----
 .../configuration/ConnectorServiceTest.java        | 102 +++
 .../jdbc/internal/xml/ElementTypeTest.java         |  40 +-
 ...onnectorServiceXmlGeneratorIntegrationTest.java | 334 --------
 .../xml/JdbcConnectorServiceXmlGeneratorTest.java  |  34 -
 .../JdbcConnectorServiceXmlIntegrationTest.java    | 127 ---
 .../internal/xml/JdbcServiceConfigurationTest.java |  68 +-
 .../distributed/ClusterConfigurationService.java   |   9 +
 .../apache/geode/management/cli/GfshCommand.java   |   1 +
 .../internal/cli/commands/InternalGfshCommand.java |   1 -
 .../internal/cli/functions/CliFunctionResult.java  |  60 +-
 .../internal/cli/result/ResultBuilder.java         |  15 +-
 .../codeAnalysis/sanctionedDataSerializables.txt   |   4 +-
 101 files changed, 2623 insertions(+), 4127 deletions(-)

diff --git a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/ConnectionConfigBuilder.java b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/ConnectionConfigBuilder.java
deleted file mode 100644
index 4ab2b7f..0000000
--- a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/ConnectionConfigBuilder.java
+++ /dev/null
@@ -1,82 +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;
-
-import static org.apache.geode.connectors.jdbc.internal.xml.JdbcConnectorServiceXmlParser.PARAMS_DELIMITER;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.geode.annotations.Experimental;
-
-@Experimental
-public class ConnectionConfigBuilder {
-
-  private String name;
-  private String url;
-  private String user;
-  private String password;
-  private Map<String, String> parameters;
-
-  public ConnectionConfigBuilder withName(String name) {
-    this.name = name;
-    return this;
-  }
-
-  public ConnectionConfigBuilder withUrl(String url) {
-    this.url = url;
-    return this;
-  }
-
-  public ConnectionConfigBuilder withUser(String user) {
-    this.user = user;
-    return this;
-  }
-
-  public ConnectionConfigBuilder withPassword(String password) {
-    this.password = password;
-    return this;
-  }
-
-  public ConnectionConfigBuilder withParameters(String[] params) {
-    if (params != null) {
-      parameters = new HashMap<>();
-      for (String param : params) {
-        if (param.isEmpty()) {
-          continue;
-        }
-        String[] keyValuePair = param.split(PARAMS_DELIMITER);
-        validateParam(keyValuePair, param);
-        parameters.put(keyValuePair[0], keyValuePair[1]);
-      }
-    } else {
-      parameters = null;
-    }
-    return this;
-  }
-
-  private void validateParam(String[] paramKeyValue, String param) {
-    // paramKeyValue is produced by split which will never give us
-    // an empty second element
-    if ((paramKeyValue.length != 2) || paramKeyValue[0].isEmpty()) {
-      throw new IllegalArgumentException("Parameter '" + param
-          + "' is not of the form 'parameterName" + PARAMS_DELIMITER + "value'");
-    }
-  }
-
-  public ConnectionConfiguration build() {
-    return new ConnectionConfiguration(name, url, user, password, parameters);
-  }
-}
diff --git a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/ConnectionConfiguration.java b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/ConnectionConfiguration.java
deleted file mode 100644
index c80e146..0000000
--- a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/ConnectionConfiguration.java
+++ /dev/null
@@ -1,110 +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;
-
-import java.io.Serializable;
-import java.util.Collections;
-import java.util.Map;
-import java.util.Properties;
-
-import org.apache.geode.annotations.Experimental;
-
-@Experimental
-public class ConnectionConfiguration implements Serializable {
-  private final String name;
-  private final String url;
-  private final String user;
-  private final String password;
-  private final Map<String, String> parameters;
-
-  public ConnectionConfiguration(String name, String url, String user, String password,
-      Map<String, String> parameters) {
-    this.name = name;
-    this.url = url;
-    this.user = user;
-    this.password = password;
-    this.parameters = parameters == null ? null : Collections.unmodifiableMap(parameters);
-  }
-
-  public String getName() {
-    return name;
-  }
-
-  public String getUrl() {
-    return url;
-  }
-
-  public String getUser() {
-    return user;
-  }
-
-  public String getPassword() {
-    return password;
-  }
-
-  public Map<String, String> getParameters() {
-    return parameters;
-  }
-
-  public Properties getConnectionProperties() {
-    Properties properties = new Properties();
-    if (parameters != null) {
-      properties.putAll(parameters);
-    }
-    return properties;
-  }
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) {
-      return true;
-    }
-    if (o == null || getClass() != o.getClass()) {
-      return false;
-    }
-
-    ConnectionConfiguration that = (ConnectionConfiguration) o;
-
-    if (name != null ? !name.equals(that.name) : that.name != null) {
-      return false;
-    }
-    if (url != null ? !url.equals(that.url) : that.url != null) {
-      return false;
-    }
-    if (user != null ? !user.equals(that.user) : that.user != null) {
-      return false;
-    }
-    if (password != null ? !password.equals(that.password) : that.password != null) {
-      return false;
-    }
-    return parameters != null ? parameters.equals(that.parameters) : that.parameters == null;
-  }
-
-  @Override
-  public int hashCode() {
-    int result = name != null ? name.hashCode() : 0;
-    result = 31 * result + (url != null ? url.hashCode() : 0);
-    result = 31 * result + (user != null ? user.hashCode() : 0);
-    result = 31 * result + (password != null ? password.hashCode() : 0);
-    result = 31 * result + (parameters != null ? parameters.hashCode() : 0);
-    return result;
-  }
-
-  @Override
-  public String toString() {
-    return "ConnectionConfiguration{" + "name='" + name + '\'' + ", url='" + url + '\'' + ", user='"
-        + user + '\'' + ", password='" + password + '\'' + ", parameters=" + parameters + '}';
-  }
-}
diff --git a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/DataSourceManager.java b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/DataSourceManager.java
index fb4e41c..e994585 100644
--- a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/DataSourceManager.java
+++ b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/DataSourceManager.java
@@ -17,6 +17,8 @@ package org.apache.geode.connectors.jdbc.internal;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 
+import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
+
 class DataSourceManager {
 
   private final JdbcDataSourceFactory jdbcDataSourceFactory;
@@ -26,7 +28,7 @@ class DataSourceManager {
     this.jdbcDataSourceFactory = jdbcDataSourceFactory;
   }
 
-  JdbcDataSource getOrCreateDataSource(ConnectionConfiguration config) {
+  JdbcDataSource getOrCreateDataSource(ConnectorService.Connection config) {
     return dataSourceMap.computeIfAbsent(config.getName(), k -> {
       return this.jdbcDataSourceFactory.create(config);
     });
diff --git a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/HikariJdbcDataSource.java b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/HikariJdbcDataSource.java
index 188d3d9..2aa3555 100644
--- a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/HikariJdbcDataSource.java
+++ b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/HikariJdbcDataSource.java
@@ -19,11 +19,13 @@ import java.sql.SQLException;
 
 import com.zaxxer.hikari.HikariDataSource;
 
+import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
+
 class HikariJdbcDataSource implements JdbcDataSource {
 
   private final HikariDataSource delegate;
 
-  HikariJdbcDataSource(ConnectionConfiguration config) {
+  HikariJdbcDataSource(ConnectorService.Connection config) {
     HikariDataSource ds = new HikariDataSource();
     ds.setJdbcUrl(config.getUrl());
     ds.setUsername(config.getUser());
diff --git a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/HikariJdbcDataSourceFactory.java b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/HikariJdbcDataSourceFactory.java
index a3e9a60..ad9a287 100644
--- a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/HikariJdbcDataSourceFactory.java
+++ b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/HikariJdbcDataSourceFactory.java
@@ -14,8 +14,10 @@
  */
 package org.apache.geode.connectors.jdbc.internal;
 
+import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
+
 class HikariJdbcDataSourceFactory implements JdbcDataSourceFactory {
-  public JdbcDataSource create(ConnectionConfiguration configuration) {
+  public JdbcDataSource create(ConnectorService.Connection configuration) {
     return new HikariJdbcDataSource(configuration);
   }
 }
diff --git a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/JdbcConnectorService.java b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/JdbcConnectorService.java
index 6cebfe8..2b8aacd 100644
--- a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/JdbcConnectorService.java
+++ b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/JdbcConnectorService.java
@@ -17,34 +17,35 @@ package org.apache.geode.connectors.jdbc.internal;
 import java.util.Set;
 
 import org.apache.geode.annotations.Experimental;
-import org.apache.geode.cache.Cache;
+import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
 import org.apache.geode.internal.cache.CacheService;
-import org.apache.geode.internal.cache.extension.Extension;
 
 @Experimental
-public interface JdbcConnectorService extends Extension<Cache>, CacheService {
+public interface JdbcConnectorService extends CacheService {
 
-  void createConnectionConfig(ConnectionConfiguration config)
+  void createConnectionConfig(ConnectorService.Connection config)
       throws ConnectionConfigExistsException;
 
-  void replaceConnectionConfig(ConnectionConfiguration config)
+  void replaceConnectionConfig(ConnectorService.Connection config)
       throws ConnectionConfigNotFoundException;
 
   void destroyConnectionConfig(String connectionName);
 
-  ConnectionConfiguration getConnectionConfig(String connectionName);
+  ConnectorService.Connection getConnectionConfig(String connectionName);
 
-  Set<ConnectionConfiguration> getConnectionConfigs();
+  Set<ConnectorService.Connection> getConnectionConfigs();
 
-  void createRegionMapping(RegionMapping mapping) throws RegionMappingExistsException;
+  void createRegionMapping(ConnectorService.RegionMapping mapping)
+      throws RegionMappingExistsException;
 
-  void replaceRegionMapping(RegionMapping mapping) throws RegionMappingNotFoundException;
+  void replaceRegionMapping(ConnectorService.RegionMapping mapping)
+      throws RegionMappingNotFoundException;
 
   void destroyRegionMapping(String regionName);
 
-  RegionMapping getMappingForRegion(String regionName);
+  ConnectorService.RegionMapping getMappingForRegion(String regionName);
 
-  Set<RegionMapping> getRegionMappings();
+  Set<ConnectorService.RegionMapping> getRegionMappings();
 
   DataSourceManager getDataSourceManager();
 }
diff --git a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/JdbcConnectorServiceImpl.java b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/JdbcConnectorServiceImpl.java
index 2c46455..72da9dc 100644
--- a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/JdbcConnectorServiceImpl.java
+++ b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/JdbcConnectorServiceImpl.java
@@ -21,42 +21,39 @@ import java.util.concurrent.ConcurrentHashMap;
 
 import org.apache.geode.annotations.Experimental;
 import org.apache.geode.cache.Cache;
-import org.apache.geode.connectors.jdbc.internal.xml.JdbcConnectorServiceXmlGenerator;
+import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
 import org.apache.geode.internal.cache.CacheService;
 import org.apache.geode.internal.cache.InternalCache;
-import org.apache.geode.internal.cache.extension.Extensible;
-import org.apache.geode.internal.cache.xmlcache.XmlGenerator;
 import org.apache.geode.management.internal.beans.CacheServiceMBeanBase;
 
 @Experimental
 public class JdbcConnectorServiceImpl implements JdbcConnectorService {
 
-  private final Map<String, ConnectionConfiguration> connectionsByName = new ConcurrentHashMap<>();
-  private final Map<String, RegionMapping> mappingsByRegion = new ConcurrentHashMap<>();
+  private final Map<String, ConnectorService.Connection> connectionsByName =
+      new ConcurrentHashMap<>();
+  private final Map<String, ConnectorService.RegionMapping> mappingsByRegion =
+      new ConcurrentHashMap<>();
   private final DataSourceManager manager =
       new DataSourceManager(new HikariJdbcDataSourceFactory());
   private volatile InternalCache cache;
   private boolean registered;
 
   @Override
-  public void createConnectionConfig(ConnectionConfiguration config)
+  public void createConnectionConfig(ConnectorService.Connection config)
       throws ConnectionConfigExistsException {
-    registerAsExtension();
-    ConnectionConfiguration existing = connectionsByName.putIfAbsent(config.getName(), config);
+    ConnectorService.Connection existing = connectionsByName.putIfAbsent(config.getName(), config);
     if (existing != null) {
-      throw new ConnectionConfigExistsException(
-          "ConnectionConfiguration " + config.getName() + " exists");
+      throw new ConnectionConfigExistsException("Connection " + config.getName() + " exists");
     }
   }
 
   @Override
-  public void replaceConnectionConfig(ConnectionConfiguration alteredConfig)
+  public void replaceConnectionConfig(ConnectorService.Connection alteredConfig)
       throws ConnectionConfigNotFoundException {
-    registerAsExtension();
-    ConnectionConfiguration existingConfig = connectionsByName.get(alteredConfig.getName());
+    ConnectorService.Connection existingConfig = connectionsByName.get(alteredConfig.getName());
     if (existingConfig == null) {
       throw new ConnectionConfigNotFoundException(
-          "ConnectionConfiguration " + alteredConfig.getName() + " was not found");
+          "Connection configuration " + alteredConfig.getName() + " was not found");
     }
 
     connectionsByName.put(existingConfig.getName(), alteredConfig);
@@ -64,25 +61,24 @@ public class JdbcConnectorServiceImpl implements JdbcConnectorService {
 
   @Override
   public void destroyConnectionConfig(String connectionName) {
-    registerAsExtension();
     connectionsByName.remove(connectionName);
   }
 
   @Override
-  public ConnectionConfiguration getConnectionConfig(String connectionName) {
+  public ConnectorService.Connection getConnectionConfig(String connectionName) {
     return connectionsByName.get(connectionName);
   }
 
   @Override
-  public Set<ConnectionConfiguration> getConnectionConfigs() {
-    Set<ConnectionConfiguration> connectionConfigs = new HashSet<>();
+  public Set<ConnectorService.Connection> getConnectionConfigs() {
+    Set<ConnectorService.Connection> connectionConfigs = new HashSet<>();
     connectionConfigs.addAll(connectionsByName.values());
     return connectionConfigs;
   }
 
   @Override
-  public Set<RegionMapping> getRegionMappings() {
-    Set<RegionMapping> regionMappings = new HashSet<>();
+  public Set<ConnectorService.RegionMapping> getRegionMappings() {
+    Set<ConnectorService.RegionMapping> regionMappings = new HashSet<>();
     regionMappings.addAll(mappingsByRegion.values());
     return regionMappings;
   }
@@ -93,9 +89,10 @@ public class JdbcConnectorServiceImpl implements JdbcConnectorService {
   }
 
   @Override
-  public void createRegionMapping(RegionMapping mapping) throws RegionMappingExistsException {
-    registerAsExtension();
-    RegionMapping existing = mappingsByRegion.putIfAbsent(mapping.getRegionName(), mapping);
+  public void createRegionMapping(ConnectorService.RegionMapping mapping)
+      throws RegionMappingExistsException {
+    ConnectorService.RegionMapping existing =
+        mappingsByRegion.putIfAbsent(mapping.getRegionName(), mapping);
     if (existing != null) {
       throw new RegionMappingExistsException(
           "RegionMapping for region " + mapping.getRegionName() + " exists");
@@ -103,10 +100,10 @@ public class JdbcConnectorServiceImpl implements JdbcConnectorService {
   }
 
   @Override
-  public void replaceRegionMapping(RegionMapping alteredMapping)
+  public void replaceRegionMapping(ConnectorService.RegionMapping alteredMapping)
       throws RegionMappingNotFoundException {
-    registerAsExtension();
-    RegionMapping existingMapping = mappingsByRegion.get(alteredMapping.getRegionName());
+    ConnectorService.RegionMapping existingMapping =
+        mappingsByRegion.get(alteredMapping.getRegionName());
     if (existingMapping == null) {
       throw new RegionMappingNotFoundException(
           "RegionMapping for region " + existingMapping.getRegionName() + " was not found");
@@ -116,13 +113,12 @@ public class JdbcConnectorServiceImpl implements JdbcConnectorService {
   }
 
   @Override
-  public RegionMapping getMappingForRegion(String regionName) {
+  public ConnectorService.RegionMapping getMappingForRegion(String regionName) {
     return mappingsByRegion.get(regionName);
   }
 
   @Override
   public void destroyRegionMapping(String regionName) {
-    registerAsExtension();
     mappingsByRegion.remove(regionName);
   }
 
@@ -131,12 +127,6 @@ public class JdbcConnectorServiceImpl implements JdbcConnectorService {
     this.cache = (InternalCache) cache;
   }
 
-  private synchronized void registerAsExtension() {
-    if (!registered) {
-      cache.getExtensionPoint().addExtension(this);
-      registered = true;
-    }
-  }
 
   @Override
   public Class<? extends CacheService> getInterface() {
@@ -147,20 +137,4 @@ public class JdbcConnectorServiceImpl implements JdbcConnectorService {
   public CacheServiceMBeanBase getMBean() {
     return null;
   }
-
-  @Override
-  public XmlGenerator<Cache> getXmlGenerator() {
-    return new JdbcConnectorServiceXmlGenerator(connectionsByName.values(),
-        mappingsByRegion.values());
-  }
-
-  @Override
-  public void beforeCreate(Extensible<Cache> source, Cache cache) {
-    // nothing
-  }
-
-  @Override
-  public void onCreate(Extensible<Cache> source, Extensible<Cache> target) {
-    // nothing
-  }
 }
diff --git a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/JdbcDataSourceFactory.java b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/JdbcDataSourceFactory.java
index 2dd5bbf..1588cc8 100644
--- a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/JdbcDataSourceFactory.java
+++ b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/JdbcDataSourceFactory.java
@@ -14,6 +14,8 @@
  */
 package org.apache.geode.connectors.jdbc.internal;
 
+import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
+
 /**
  * Given a ConnnectionConfiguration create a JdbcDataSource.
  */
@@ -21,5 +23,5 @@ interface JdbcDataSourceFactory {
   /**
    * Given a ConnnectionConfiguration create and return a JdbcDataSource
    */
-  JdbcDataSource create(ConnectionConfiguration configuration);
+  JdbcDataSource create(ConnectorService.Connection configuration);
 }
diff --git a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/RegionMapping.java b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/RegionMapping.java
deleted file mode 100644
index b466443..0000000
--- a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/RegionMapping.java
+++ /dev/null
@@ -1,291 +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;
-
-import java.io.Serializable;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-
-import org.apache.geode.annotations.Experimental;
-import org.apache.geode.connectors.jdbc.JdbcConnectorException;
-import org.apache.geode.pdx.internal.PdxType;
-import org.apache.geode.pdx.internal.TypeRegistry;
-
-@Experimental
-public class RegionMapping implements Serializable {
-  private final String regionName;
-  private final String pdxClassName;
-  private final String tableName;
-  private final String connectionConfigName;
-  private final Boolean primaryKeyInValue;
-  private final ConcurrentMap<String, String> fieldToColumnMap;
-  private final ConcurrentMap<String, String> columnToFieldMap;
-
-  private final Map<String, String> configuredFieldToColumnMap;
-  private final Map<String, String> configuredColumnToFieldMap;
-
-  public RegionMapping(String regionName, String pdxClassName, String tableName,
-      String connectionConfigName, Boolean primaryKeyInValue,
-      Map<String, String> configuredFieldToColumnMap) {
-    this.regionName = regionName;
-    this.pdxClassName = pdxClassName;
-    this.tableName = tableName;
-    this.connectionConfigName = connectionConfigName;
-    this.primaryKeyInValue = primaryKeyInValue;
-    this.fieldToColumnMap = new ConcurrentHashMap<>();
-    this.columnToFieldMap = new ConcurrentHashMap<>();
-    if (configuredFieldToColumnMap != null) {
-      this.configuredFieldToColumnMap =
-          Collections.unmodifiableMap(new HashMap<>(configuredFieldToColumnMap));
-      this.configuredColumnToFieldMap =
-          Collections.unmodifiableMap(createReverseMap(configuredFieldToColumnMap));
-    } else {
-      this.configuredFieldToColumnMap = null;
-      this.configuredColumnToFieldMap = null;
-    }
-  }
-
-  private static Map<String, String> createReverseMap(Map<String, String> input) {
-    Map<String, String> output = new HashMap<>();
-    for (Map.Entry<String, String> entry : input.entrySet()) {
-      String reverseMapKey = entry.getValue();
-      String reverseMapValue = entry.getKey();
-      if (output.containsKey(reverseMapKey)) {
-        throw new IllegalArgumentException(
-            "The field " + reverseMapValue + " can not be mapped to more than one column.");
-      }
-      output.put(reverseMapKey, reverseMapValue);
-    }
-    return output;
-  }
-
-  public String getConnectionConfigName() {
-    return connectionConfigName;
-  }
-
-  public String getRegionName() {
-    return regionName;
-  }
-
-  public String getPdxClassName() {
-    return pdxClassName;
-  }
-
-  public String getTableName() {
-    return tableName;
-  }
-
-  public Boolean isPrimaryKeyInValue() {
-    return primaryKeyInValue;
-  }
-
-  public String getRegionToTableName() {
-    if (tableName == null) {
-      return regionName;
-    }
-    return tableName;
-  }
-
-  private String getConfiguredColumnNameForField(String fieldName) {
-    String result = fieldName;
-    if (configuredFieldToColumnMap != null) {
-      String mapResult = configuredFieldToColumnMap.get(fieldName);
-      if (mapResult != null) {
-        result = mapResult;
-      }
-    }
-    return result;
-  }
-
-  public String getColumnNameForField(String fieldName, TableMetaDataView tableMetaDataView) {
-    String columnName = fieldToColumnMap.get(fieldName);
-    if (columnName == null) {
-      String configuredColumnName = getConfiguredColumnNameForField(fieldName);
-      Set<String> columnNames = tableMetaDataView.getColumnNames();
-      if (columnNames.contains(configuredColumnName)) {
-        // exact match
-        columnName = configuredColumnName;
-      } else {
-        for (String candidate : columnNames) {
-          if (candidate.equalsIgnoreCase(configuredColumnName)) {
-            if (columnName != null) {
-              throw new JdbcConnectorException(
-                  "The SQL table has at least two columns that match the PDX field: " + fieldName);
-            }
-            columnName = candidate;
-          }
-        }
-      }
-
-      if (columnName == null) {
-        columnName = configuredColumnName;
-      }
-      fieldToColumnMap.put(fieldName, columnName);
-      columnToFieldMap.put(columnName, fieldName);
-    }
-    return columnName;
-  }
-
-  private String getConfiguredFieldNameForColumn(String columnName) {
-    String result = columnName;
-    if (configuredColumnToFieldMap != null) {
-      String mapResult = configuredColumnToFieldMap.get(columnName);
-      if (mapResult != null) {
-        result = mapResult;
-      }
-    }
-    return result;
-  }
-
-  public String getFieldNameForColumn(String columnName, TypeRegistry typeRegistry) {
-    String fieldName = columnToFieldMap.get(columnName);
-    if (fieldName == null) {
-      String configuredFieldName = getConfiguredFieldNameForColumn(columnName);
-      if (getPdxClassName() == null) {
-        if (configuredFieldName.equals(configuredFieldName.toUpperCase())) {
-          fieldName = configuredFieldName.toLowerCase();
-        } else {
-          fieldName = configuredFieldName;
-        }
-      } else {
-        Set<PdxType> pdxTypes = getPdxTypesForClassName(typeRegistry);
-        fieldName = findExactMatch(configuredFieldName, pdxTypes);
-        if (fieldName == null) {
-          fieldName = findCaseInsensitiveMatch(columnName, configuredFieldName, pdxTypes);
-        }
-      }
-      assert fieldName != null;
-      fieldToColumnMap.put(fieldName, columnName);
-      columnToFieldMap.put(columnName, fieldName);
-    }
-    return fieldName;
-  }
-
-  private Set<PdxType> getPdxTypesForClassName(TypeRegistry typeRegistry) {
-    Set<PdxType> pdxTypes = typeRegistry.getPdxTypesForClassName(getPdxClassName());
-    if (pdxTypes.isEmpty()) {
-      throw new JdbcConnectorException(
-          "The class " + getPdxClassName() + " has not been pdx serialized.");
-    }
-    return pdxTypes;
-  }
-
-  /**
-   * Given a column name and a set of pdx types, find the field name in those types that match,
-   * ignoring case, the column name.
-   *
-   * @return the matching field name or null if no match
-   * @throws JdbcConnectorException if no fields match
-   * @throws JdbcConnectorException if more than one field matches
-   */
-  private String findCaseInsensitiveMatch(String columnName, String configuredFieldName,
-      Set<PdxType> pdxTypes) {
-    HashSet<String> matchingFieldNames = new HashSet<>();
-    for (PdxType pdxType : pdxTypes) {
-      for (String existingFieldName : pdxType.getFieldNames()) {
-        if (existingFieldName.equalsIgnoreCase(configuredFieldName)) {
-          matchingFieldNames.add(existingFieldName);
-        }
-      }
-    }
-    if (matchingFieldNames.isEmpty()) {
-      throw new JdbcConnectorException("The class " + getPdxClassName()
-          + " does not have a field that matches the column " + columnName);
-    } else if (matchingFieldNames.size() > 1) {
-      throw new JdbcConnectorException(
-          "Could not determine what pdx field to use for the column name " + columnName
-              + " because the pdx fields " + matchingFieldNames + " all match it.");
-    }
-    return matchingFieldNames.iterator().next();
-  }
-
-  /**
-   * Given a column name, search the given pdxTypes for a field whose name exactly matches the
-   * column name.
-   *
-   * @return the matching field name or null if no match
-   */
-  private String findExactMatch(String columnName, Set<PdxType> pdxTypes) {
-    for (PdxType pdxType : pdxTypes) {
-      if (pdxType.getPdxField(columnName) != null) {
-        return columnName;
-      }
-    }
-    return null;
-  }
-
-  public Map<String, String> getFieldToColumnMap() {
-    return configuredFieldToColumnMap;
-  }
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) {
-      return true;
-    }
-    if (o == null || getClass() != o.getClass()) {
-      return false;
-    }
-
-    RegionMapping that = (RegionMapping) o;
-
-    if (primaryKeyInValue != that.primaryKeyInValue) {
-      return false;
-    }
-    if (regionName != null ? !regionName.equals(that.regionName) : that.regionName != null) {
-      return false;
-    }
-    if (pdxClassName != null ? !pdxClassName.equals(that.pdxClassName)
-        : that.pdxClassName != null) {
-      return false;
-    }
-    if (tableName != null ? !tableName.equals(that.tableName) : that.tableName != null) {
-      return false;
-    }
-    if (connectionConfigName != null ? !connectionConfigName.equals(that.connectionConfigName)
-        : that.connectionConfigName != null) {
-      return false;
-    }
-
-    return (configuredFieldToColumnMap != null
-        ? configuredFieldToColumnMap.equals(that.configuredFieldToColumnMap)
-        : that.configuredFieldToColumnMap == null);
-  }
-
-  @Override
-  public int hashCode() {
-    int result = regionName != null ? regionName.hashCode() : 0;
-    result = 31 * result + (pdxClassName != null ? pdxClassName.hashCode() : 0);
-    result = 31 * result + (tableName != null ? tableName.hashCode() : 0);
-    result = 31 * result + (connectionConfigName != null ? connectionConfigName.hashCode() : 0);
-    result = 31 * result + (primaryKeyInValue ? 1 : 0);
-    result = 31 * result
-        + (configuredFieldToColumnMap != null ? configuredFieldToColumnMap.hashCode() : 0);
-    return result;
-  }
-
-  @Override
-  public String toString() {
-    return "RegionMapping{" + "regionName='" + regionName + '\'' + ", pdxClassName='" + pdxClassName
-        + '\'' + ", tableName='" + tableName + '\'' + ", connectionConfigName='"
-        + connectionConfigName + '\'' + ", primaryKeyInValue=" + primaryKeyInValue
-        + ", fieldToColumnMap=" + configuredFieldToColumnMap + '}';
-  }
-}
diff --git a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/RegionMappingBuilder.java b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/RegionMappingBuilder.java
deleted file mode 100644
index 0d989a4..0000000
--- a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/RegionMappingBuilder.java
+++ /dev/null
@@ -1,99 +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;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.geode.annotations.Experimental;
-
-@Experimental
-public class RegionMappingBuilder {
-
-  private static final String MAPPINGS_DELIMITER = ":";
-  private String regionName;
-  private String pdxClassName;
-  private String tableName;
-  private String connectionConfigName;
-  private Boolean primaryKeyInValue;
-  private Map<String, String> fieldToColumnMap = new HashMap<>();
-
-  public RegionMappingBuilder withRegionName(String regionName) {
-    this.regionName = regionName;
-    return this;
-  }
-
-  public RegionMappingBuilder withPdxClassName(String pdxClassName) {
-    this.pdxClassName = pdxClassName;
-    return this;
-  }
-
-  public RegionMappingBuilder withTableName(String tableName) {
-    this.tableName = tableName;
-    return this;
-  }
-
-  public RegionMappingBuilder withConnectionConfigName(String connectionConfigName) {
-    this.connectionConfigName = connectionConfigName;
-    return this;
-  }
-
-  public RegionMappingBuilder withPrimaryKeyInValue(String v) {
-    if (v != null) {
-      withPrimaryKeyInValue(Boolean.parseBoolean(v));
-    }
-    return this;
-  }
-
-  public RegionMappingBuilder withPrimaryKeyInValue(Boolean v) {
-    this.primaryKeyInValue = v;
-    return this;
-  }
-
-  public RegionMappingBuilder withFieldToColumnMapping(String fieldName, String columnMapping) {
-    this.fieldToColumnMap.put(fieldName, columnMapping);
-    return this;
-  }
-
-  public RegionMappingBuilder withFieldToColumnMappings(String[] mappings) {
-    if (mappings == null) {
-      fieldToColumnMap = null;
-    } else {
-      for (String mapping : mappings) {
-        if (mapping.isEmpty()) {
-          continue;
-        }
-        String[] keyValuePair = mapping.split(MAPPINGS_DELIMITER);
-        validateParam(keyValuePair, mapping);
-        fieldToColumnMap.put(keyValuePair[0], keyValuePair[1]);
-      }
-    }
-    return this;
-  }
-
-  private void validateParam(String[] paramKeyValue, String mapping) {
-    // paramKeyValue is produced by split which will never give us
-    // an empty second element
-    if (paramKeyValue.length != 2 || paramKeyValue[0].isEmpty()) {
-      throw new IllegalArgumentException("Field to column mapping '" + mapping
-          + "' is not of the form 'Field" + MAPPINGS_DELIMITER + "Column'");
-    }
-  }
-
-  public RegionMapping build() {
-    return new RegionMapping(regionName, pdxClassName, tableName, connectionConfigName,
-        primaryKeyInValue, fieldToColumnMap);
-  }
-}
diff --git a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/SqlHandler.java b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/SqlHandler.java
index 806b3d6..dbdf074 100644
--- a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/SqlHandler.java
+++ b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/SqlHandler.java
@@ -28,6 +28,7 @@ import org.apache.geode.annotations.Experimental;
 import org.apache.geode.cache.Operation;
 import org.apache.geode.cache.Region;
 import org.apache.geode.connectors.jdbc.JdbcConnectorException;
+import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
 import org.apache.geode.internal.cache.InternalCache;
 import org.apache.geode.pdx.PdxInstance;
 
@@ -48,7 +49,7 @@ public class SqlHandler {
     manager.close();
   }
 
-  Connection getConnection(ConnectionConfiguration config) throws SQLException {
+  Connection getConnection(ConnectorService.Connection config) throws SQLException {
     return manager.getOrCreateDataSource(config).getConnection();
   }
 
@@ -57,8 +58,8 @@ public class SqlHandler {
       throw new IllegalArgumentException("Key for query cannot be null");
     }
 
-    RegionMapping regionMapping = getMappingForRegion(region.getName());
-    ConnectionConfiguration connectionConfig =
+    ConnectorService.RegionMapping regionMapping = getMappingForRegion(region.getName());
+    ConnectorService.Connection connectionConfig =
         getConnectionConfig(regionMapping.getConnectionConfigName());
     PdxInstance result;
     try (Connection connection = getConnection(connectionConfig)) {
@@ -85,8 +86,9 @@ public class SqlHandler {
     return statement.executeQuery();
   }
 
-  private RegionMapping getMappingForRegion(String regionName) {
-    RegionMapping regionMapping = this.configService.getMappingForRegion(regionName);
+  private ConnectorService.RegionMapping getMappingForRegion(String regionName) {
+    ConnectorService.RegionMapping regionMapping =
+        this.configService.getMappingForRegion(regionName);
     if (regionMapping == null) {
       throw new JdbcConnectorException("JDBC mapping for region " + regionName
           + " not found. Create the mapping with the gfsh command 'create jdbc-mapping'.");
@@ -94,8 +96,8 @@ public class SqlHandler {
     return regionMapping;
   }
 
-  private ConnectionConfiguration getConnectionConfig(String connectionConfigName) {
-    ConnectionConfiguration connectionConfig =
+  private ConnectorService.Connection getConnectionConfig(String connectionConfigName) {
+    ConnectorService.Connection connectionConfig =
         this.configService.getConnectionConfig(connectionConfigName);
     if (connectionConfig == null) {
       throw new JdbcConnectorException("JDBC connection with name " + connectionConfigName
@@ -155,8 +157,8 @@ public class SqlHandler {
     if (value == null && operation != Operation.DESTROY) {
       throw new IllegalArgumentException("PdxInstance cannot be null for non-destroy operations");
     }
-    RegionMapping regionMapping = getMappingForRegion(region.getName());
-    ConnectionConfiguration connectionConfig =
+    ConnectorService.RegionMapping regionMapping = getMappingForRegion(region.getName());
+    ConnectorService.Connection connectionConfig =
         getConnectionConfig(regionMapping.getConnectionConfigName());
 
     try (Connection connection = getConnection(connectionConfig)) {
@@ -227,7 +229,7 @@ public class SqlHandler {
   }
 
   <K> EntryColumnData getEntryColumnData(TableMetaDataView tableMetaData,
-      RegionMapping regionMapping, K key, PdxInstance value, Operation operation) {
+      ConnectorService.RegionMapping regionMapping, K key, PdxInstance value, Operation operation) {
     String keyColumnName = tableMetaData.getKeyColumnName();
     ColumnData keyColumnData =
         new ColumnData(keyColumnName, key, tableMetaData.getColumnDataType(keyColumnName));
@@ -241,7 +243,7 @@ public class SqlHandler {
   }
 
   private List<ColumnData> createColumnDataList(TableMetaDataView tableMetaData,
-      RegionMapping regionMapping, PdxInstance value) {
+      ConnectorService.RegionMapping regionMapping, PdxInstance value) {
     List<ColumnData> result = new ArrayList<>();
     for (String fieldName : value.getFieldNames()) {
       String columnName = regionMapping.getColumnNameForField(fieldName, tableMetaData);
diff --git a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/SqlToPdxInstanceCreator.java b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/SqlToPdxInstanceCreator.java
index d4e1cf9..915db55 100644
--- a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/SqlToPdxInstanceCreator.java
+++ b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/SqlToPdxInstanceCreator.java
@@ -21,6 +21,7 @@ import java.sql.SQLException;
 import java.sql.Types;
 
 import org.apache.geode.connectors.jdbc.JdbcConnectorException;
+import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
 import org.apache.geode.internal.cache.InternalCache;
 import org.apache.geode.pdx.FieldType;
 import org.apache.geode.pdx.PdxInstance;
@@ -31,12 +32,12 @@ import org.apache.geode.pdx.internal.TypeRegistry;
 
 class SqlToPdxInstanceCreator {
   private final InternalCache cache;
-  private final RegionMapping regionMapping;
+  private final ConnectorService.RegionMapping regionMapping;
   private final ResultSet resultSet;
   private final TableMetaDataView tableMetaData;
   private final PdxInstanceFactory factory;
 
-  public SqlToPdxInstanceCreator(InternalCache cache, RegionMapping regionMapping,
+  public SqlToPdxInstanceCreator(InternalCache cache, ConnectorService.RegionMapping regionMapping,
       ResultSet resultSet, TableMetaDataView tableMetaData) {
     this.cache = cache;
     this.regionMapping = regionMapping;
diff --git a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/AlterConnectionCommand.java b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/AlterConnectionCommand.java
index 9a8655c..a8bc313 100644
--- a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/AlterConnectionCommand.java
+++ b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/AlterConnectionCommand.java
@@ -21,24 +21,22 @@ import org.springframework.shell.core.annotation.CliCommand;
 import org.springframework.shell.core.annotation.CliOption;
 
 import org.apache.geode.annotations.Experimental;
-import org.apache.geode.cache.execute.ResultCollector;
-import org.apache.geode.connectors.jdbc.internal.ConnectionConfigBuilder;
-import org.apache.geode.connectors.jdbc.internal.ConnectionConfiguration;
+import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
+import org.apache.geode.distributed.ClusterConfigurationService;
 import org.apache.geode.distributed.DistributedMember;
-import org.apache.geode.distributed.internal.InternalClusterConfigurationService;
 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.commands.InternalGfshCommand;
+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.CommandResult;
 import org.apache.geode.management.internal.cli.result.ResultBuilder;
-import org.apache.geode.management.internal.cli.result.TabularResultData;
-import org.apache.geode.management.internal.configuration.domain.XmlEntity;
 import org.apache.geode.management.internal.security.ResourceOperation;
 import org.apache.geode.security.ResourcePermission;
 
 @Experimental
-public class AlterConnectionCommand extends InternalGfshCommand {
+public class AlterConnectionCommand extends GfshCommand {
   static final String ALTER_JDBC_CONNECTION = "alter jdbc-connection";
   static final String ALTER_JDBC_CONNECTION__HELP =
       EXPERIMENTAL + "Alter properties for an existing jdbc connection.";
@@ -76,69 +74,49 @@ public class AlterConnectionCommand extends InternalGfshCommand {
           help = ALTER_CONNECTION__PARAMS__HELP) String[] params) {
     // input
     Set<DistributedMember> targetMembers = getMembers(null, null);
-    ConnectionConfiguration configuration = getArguments(name, url, user, password, params);
+    ConnectorService.Connection newConnection =
+        new ConnectorService.Connection(name, url, user, password, params);
+
+    ClusterConfigurationService ccService = getConfigurationService();
+
+    // if cc is running, you can only alter connection available in cc service.
+    if (ccService != null) {
+      // search for the connection that has this id to see if it exists
+      ConnectorService service =
+          ccService.getCustomCacheElement("cluster", "connector-service", ConnectorService.class);
+      if (service == null) {
+        throw new EntityNotFoundException("connection with name '" + name + "' does not exist.");
+      }
+      ConnectorService.Connection conn = ccService.findIdentifiable(service.getConnection(), name);
+      if (conn == null) {
+        throw new EntityNotFoundException("connection with name '" + name + "' does not exist.");
+      }
+    }
 
     // action
-    ResultCollector<CliFunctionResult, List<CliFunctionResult>> resultCollector =
-        execute(new AlterConnectionFunction(), configuration, targetMembers);
-
-    // output
-    TabularResultData tabularResultData = ResultBuilder.createTabularResultData();
-    XmlEntity xmlEntity = fillTabularResultData(resultCollector, tabularResultData);
-    tabularResultData.setHeader(EXPERIMENTAL);
-    Result result = ResultBuilder.buildResult(tabularResultData);
-    updateClusterConfiguration(result, xmlEntity);
-    return result;
-  }
-
-  ResultCollector<CliFunctionResult, List<CliFunctionResult>> execute(
-      AlterConnectionFunction function, ConnectionConfiguration configuration,
-      Set<DistributedMember> targetMembers) {
-    return (ResultCollector<CliFunctionResult, List<CliFunctionResult>>) executeFunction(function,
-        configuration, targetMembers);
-  }
-
-  private ConnectionConfiguration getArguments(String name, String url, String user,
-      String password, String[] params) {
-    ConnectionConfigBuilder builder = new ConnectionConfigBuilder().withName(name).withUrl(url)
-        .withUser(user).withPassword(password).withParameters(params);
-    return builder.build();
-  }
-
-  private XmlEntity fillTabularResultData(
-      ResultCollector<CliFunctionResult, List<CliFunctionResult>> resultCollector,
-      TabularResultData tabularResultData) {
-    XmlEntity xmlEntity = null;
-
-    for (CliFunctionResult oneResult : resultCollector.getResult()) {
-      if (oneResult.isSuccessful()) {
-        xmlEntity = addSuccessToResults(tabularResultData, oneResult);
-      } else {
-        addErrorToResults(tabularResultData, oneResult);
+    List<CliFunctionResult> results =
+        executeAndGetFunctionResult(new AlterConnectionFunction(), newConnection, targetMembers);
+
+    // update the cc with the merged connection returned from the server
+    boolean persisted = false;
+    if (ccService != null && results.stream().filter(CliFunctionResult::isSuccessful).count() > 0) {
+      ConnectorService service =
+          ccService.getCustomCacheElement("cluster", "connector-service", ConnectorService.class);
+      if (service == null) {
+        service = new ConnectorService();
       }
+      CliFunctionResult successResult =
+          results.stream().filter(CliFunctionResult::isSuccessful).findAny().get();
+      ConnectorService.Connection mergedConnection =
+          (ConnectorService.Connection) successResult.getResultObject();
+      ccService.removeFromList(service.getConnection(), name);
+      service.getConnection().add(mergedConnection);
+      ccService.saveCustomCacheElement("cluster", service);
+      persisted = true;
     }
 
-    return xmlEntity;
-  }
-
-  private XmlEntity addSuccessToResults(TabularResultData tabularResultData,
-      CliFunctionResult oneResult) {
-    tabularResultData.accumulate("Member", oneResult.getMemberIdOrName());
-    tabularResultData.accumulate("Status", oneResult.getMessage());
-    return oneResult.getXmlEntity();
-  }
-
-  private void addErrorToResults(TabularResultData tabularResultData, CliFunctionResult oneResult) {
-    tabularResultData.accumulate("Member", oneResult.getMemberIdOrName());
-    tabularResultData.accumulate("Status", ERROR_PREFIX + oneResult.getMessage());
-    tabularResultData.setStatus(Result.Status.ERROR);
-  }
-
-  private void updateClusterConfiguration(final Result result, final XmlEntity xmlEntity) {
-    if (xmlEntity != null) {
-      persistClusterConfiguration(result,
-          () -> ((InternalClusterConfigurationService) getConfigurationService())
-              .addXmlEntity(xmlEntity, null));
-    }
+    CommandResult commandResult = ResultBuilder.buildResult(results, EXPERIMENTAL, null);
+    commandResult.setCommandPersisted(persisted);
+    return commandResult;
   }
 }
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 14b231d..d5e2fac 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
@@ -14,19 +14,16 @@
  */
 package org.apache.geode.connectors.jdbc.internal.cli;
 
-import java.util.Map;
-
 import org.apache.geode.annotations.Experimental;
 import org.apache.geode.cache.execute.FunctionContext;
 import org.apache.geode.connectors.jdbc.internal.ConnectionConfigNotFoundException;
-import org.apache.geode.connectors.jdbc.internal.ConnectionConfiguration;
 import org.apache.geode.connectors.jdbc.internal.JdbcConnectorService;
+import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
 import org.apache.geode.management.internal.cli.functions.CliFunctionResult;
-import org.apache.geode.management.internal.configuration.domain.XmlEntity;
 
 @Experimental
 public class AlterConnectionFunction
-    extends JdbcCliFunction<ConnectionConfiguration, CliFunctionResult> {
+    extends JdbcCliFunction<ConnectorService.Connection, CliFunctionResult> {
 
   AlterConnectionFunction() {
     super();
@@ -34,9 +31,9 @@ public class AlterConnectionFunction
 
   @Override
   CliFunctionResult getFunctionResult(JdbcConnectorService service,
-      FunctionContext<ConnectionConfiguration> context) throws Exception {
-    ConnectionConfiguration connectionConfig = context.getArguments();
-    ConnectionConfiguration existingConfig =
+      FunctionContext<ConnectorService.Connection> context) throws Exception {
+    ConnectorService.Connection connectionConfig = context.getArguments();
+    ConnectorService.Connection existingConfig =
         service.getConnectionConfig(connectionConfig.getName());
     if (existingConfig == null) {
       throw new ConnectionConfigNotFoundException(
@@ -44,31 +41,28 @@ public class AlterConnectionFunction
     }
 
     // action
-    ConnectionConfiguration alteredConfig = alterConnectionConfig(connectionConfig, existingConfig);
+    ConnectorService.Connection alteredConfig =
+        alterConnectionConfig(connectionConfig, existingConfig);
     service.replaceConnectionConfig(alteredConfig);
 
-    // output
-    String member = getMember(context);
-    XmlEntity xmlEntity = createXmlEntity(context);
-    CliFunctionResult result = createSuccessResult(connectionConfig.getName(), member, xmlEntity);
-    return result;
+    return new CliFunctionResult(context.getMemberName(), alteredConfig, null);
   }
 
   /**
    * Creates the named connection configuration
    */
-  ConnectionConfiguration alterConnectionConfig(ConnectionConfiguration connectionConfig,
-      ConnectionConfiguration existingConfig) {
+  ConnectorService.Connection alterConnectionConfig(ConnectorService.Connection connectionConfig,
+      ConnectorService.Connection existingConfig) {
     String url = getValue(connectionConfig.getUrl(), existingConfig.getUrl());
     String user = getValue(connectionConfig.getUser(), existingConfig.getUser());
     String password = getValue(connectionConfig.getPassword(), existingConfig.getPassword());
 
-    Map<String, String> parameters = connectionConfig.getParameters();
+    String parameters = connectionConfig.getParameters();
     if (parameters == null) {
       parameters = existingConfig.getParameters();
     }
-    ConnectionConfiguration alteredConfig =
-        new ConnectionConfiguration(existingConfig.getName(), url, user, password, parameters);
+    ConnectorService.Connection alteredConfig =
+        new ConnectorService.Connection(existingConfig.getName(), url, user, password, parameters);
     return alteredConfig;
   }
 
@@ -80,10 +74,4 @@ public class AlterConnectionFunction
     }
     return newValue.isEmpty() ? null : newValue;
   }
-
-  private CliFunctionResult createSuccessResult(String connectionName, String member,
-      XmlEntity xmlEntity) {
-    String message = "Altered JDBC connection " + connectionName + " on " + member;
-    return new CliFunctionResult(member, xmlEntity, message);
-  }
 }
diff --git a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/AlterMappingCommand.java b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/AlterMappingCommand.java
index b2d21c5..a7bf949 100644
--- a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/AlterMappingCommand.java
+++ b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/AlterMappingCommand.java
@@ -21,19 +21,17 @@ import org.springframework.shell.core.annotation.CliCommand;
 import org.springframework.shell.core.annotation.CliOption;
 
 import org.apache.geode.annotations.Experimental;
-import org.apache.geode.cache.execute.ResultCollector;
-import org.apache.geode.connectors.jdbc.internal.RegionMapping;
-import org.apache.geode.connectors.jdbc.internal.RegionMappingBuilder;
+import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
+import org.apache.geode.distributed.ClusterConfigurationService;
 import org.apache.geode.distributed.DistributedMember;
-import org.apache.geode.distributed.internal.InternalClusterConfigurationService;
 import org.apache.geode.management.cli.CliMetaData;
 import org.apache.geode.management.cli.Result;
 import org.apache.geode.management.internal.cli.commands.InternalGfshCommand;
+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.CommandResult;
 import org.apache.geode.management.internal.cli.result.ResultBuilder;
-import org.apache.geode.management.internal.cli.result.TabularResultData;
-import org.apache.geode.management.internal.configuration.domain.XmlEntity;
 import org.apache.geode.management.internal.security.ResourceOperation;
 import org.apache.geode.security.ResourcePermission;
 
@@ -70,7 +68,7 @@ public class AlterMappingCommand extends InternalGfshCommand {
   public Result alterMapping(
       @CliOption(key = ALTER_MAPPING__REGION_NAME, mandatory = true,
           help = ALTER_MAPPING__REGION_NAME__HELP) String regionName,
-      @CliOption(key = ALTER_MAPPING__CONNECTION_NAME,
+      @CliOption(key = ALTER_MAPPING__CONNECTION_NAME, specifiedDefaultValue = "",
           help = ALTER_MAPPING__CONNECTION_NAME__HELP) String connectionName,
       @CliOption(key = ALTER_MAPPING__TABLE_NAME, help = ALTER_MAPPING__TABLE_NAME__HELP,
           specifiedDefaultValue = "") String table,
@@ -83,71 +81,50 @@ public class AlterMappingCommand extends InternalGfshCommand {
           specifiedDefaultValue = "") String[] fieldMappings) {
     // input
     Set<DistributedMember> targetMembers = getMembers(null, null);
-    RegionMapping mapping =
-        getArguments(regionName, connectionName, table, pdxClassName, keyInValue, fieldMappings);
+    ConnectorService.RegionMapping newMapping = new ConnectorService.RegionMapping(regionName,
+        pdxClassName, table, connectionName, keyInValue);
+    newMapping.setFieldMapping(fieldMappings);
+
+    ClusterConfigurationService ccService = getConfigurationService();
+    // if cc is running, you can only alter connection available in cc service.
+    if (ccService != null) {
+      // search for the connection that has this id to see if it exists
+      ConnectorService service =
+          ccService.getCustomCacheElement("cluster", "connector-service", ConnectorService.class);
+      if (service == null) {
+        throw new EntityNotFoundException("mapping with name '" + regionName + "' does not exist.");
+      }
+      ConnectorService.RegionMapping mapping =
+          ccService.findIdentifiable(service.getRegionMapping(), regionName);
+      if (mapping == null) {
+        throw new EntityNotFoundException("mapping with name '" + regionName + "' does not exist.");
+      }
+    }
 
     // action
-    ResultCollector<CliFunctionResult, List<CliFunctionResult>> resultCollector =
-        execute(new AlterMappingFunction(), mapping, targetMembers);
-
-    // output
-    TabularResultData tabularResultData = ResultBuilder.createTabularResultData();
-    XmlEntity xmlEntity = fillTabularResultData(resultCollector, tabularResultData);
-    tabularResultData.setHeader(EXPERIMENTAL);
-    Result result = ResultBuilder.buildResult(tabularResultData);
-    updateClusterConfiguration(result, xmlEntity);
-    return result;
-  }
-
-  ResultCollector<CliFunctionResult, List<CliFunctionResult>> execute(AlterMappingFunction function,
-      RegionMapping mapping, Set<DistributedMember> targetMembers) {
-    return (ResultCollector<CliFunctionResult, List<CliFunctionResult>>) executeFunction(function,
-        mapping, targetMembers);
-  }
-
-  private RegionMapping getArguments(String regionName, String connectionName, String table,
-      String pdxClassName, Boolean keyInValue, String[] fieldMappings) {
-    RegionMappingBuilder builder = new RegionMappingBuilder().withRegionName(regionName)
-        .withConnectionConfigName(connectionName).withTableName(table)
-        .withPdxClassName(pdxClassName).withPrimaryKeyInValue(keyInValue)
-        .withFieldToColumnMappings(fieldMappings);
-    return builder.build();
-  }
-
-  private XmlEntity fillTabularResultData(
-      ResultCollector<CliFunctionResult, List<CliFunctionResult>> resultCollector,
-      TabularResultData tabularResultData) {
-    XmlEntity xmlEntity = null;
-
-    for (CliFunctionResult oneResult : resultCollector.getResult()) {
-      if (oneResult.isSuccessful()) {
-        xmlEntity = addSuccessToResults(tabularResultData, oneResult);
-      } else {
-        addErrorToResults(tabularResultData, oneResult);
+    List<CliFunctionResult> results =
+        executeAndGetFunctionResult(new AlterMappingFunction(), newMapping, targetMembers);
+
+    boolean persisted = false;
+    // update the cc with the merged connection returned from the server
+    if (ccService != null && results.stream().filter(CliFunctionResult::isSuccessful).count() > 0) {
+      ConnectorService service =
+          ccService.getCustomCacheElement("cluster", "connector-service", ConnectorService.class);
+      if (service == null) {
+        service = new ConnectorService();
       }
+      CliFunctionResult successResult =
+          results.stream().filter(CliFunctionResult::isSuccessful).findAny().get();
+      ConnectorService.RegionMapping mergedMapping =
+          (ConnectorService.RegionMapping) successResult.getResultObject();
+      ccService.removeFromList(service.getRegionMapping(), connectionName);
+      service.getRegionMapping().add(mergedMapping);
+      ccService.saveCustomCacheElement("cluster", service);
+      persisted = true;
     }
 
-    return xmlEntity;
-  }
-
-  private XmlEntity addSuccessToResults(TabularResultData tabularResultData,
-      CliFunctionResult oneResult) {
-    tabularResultData.accumulate("Member", oneResult.getMemberIdOrName());
-    tabularResultData.accumulate("Status", oneResult.getMessage());
-    return oneResult.getXmlEntity();
-  }
-
-  private void addErrorToResults(TabularResultData tabularResultData, CliFunctionResult oneResult) {
-    tabularResultData.accumulate("Member", oneResult.getMemberIdOrName());
-    tabularResultData.accumulate("Status", ERROR_PREFIX + oneResult.getMessage());
-    tabularResultData.setStatus(Result.Status.ERROR);
-  }
-
-  private void updateClusterConfiguration(final Result result, final XmlEntity xmlEntity) {
-    if (xmlEntity != null) {
-      persistClusterConfiguration(result,
-          () -> ((InternalClusterConfigurationService) getConfigurationService())
-              .addXmlEntity(xmlEntity, null));
-    }
+    CommandResult commandResult = ResultBuilder.buildResult(results, EXPERIMENTAL, null);
+    commandResult.setCommandPersisted(persisted);
+    return commandResult;
   }
 }
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 55c2657..6e84ba3 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
@@ -14,18 +14,18 @@
  */
 package org.apache.geode.connectors.jdbc.internal.cli;
 
-import java.util.Map;
+import java.util.List;
 
 import org.apache.geode.annotations.Experimental;
 import org.apache.geode.cache.execute.FunctionContext;
 import org.apache.geode.connectors.jdbc.internal.JdbcConnectorService;
-import org.apache.geode.connectors.jdbc.internal.RegionMapping;
 import org.apache.geode.connectors.jdbc.internal.RegionMappingNotFoundException;
+import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
 import org.apache.geode.management.internal.cli.functions.CliFunctionResult;
-import org.apache.geode.management.internal.configuration.domain.XmlEntity;
 
 @Experimental
-public class AlterMappingFunction extends JdbcCliFunction<RegionMapping, CliFunctionResult> {
+public class AlterMappingFunction
+    extends JdbcCliFunction<ConnectorService.RegionMapping, CliFunctionResult> {
 
   AlterMappingFunction() {
     super();
@@ -33,40 +33,41 @@ public class AlterMappingFunction extends JdbcCliFunction<RegionMapping, CliFunc
 
   @Override
   CliFunctionResult getFunctionResult(JdbcConnectorService service,
-      FunctionContext<RegionMapping> context) throws Exception {
-    RegionMapping mapping = context.getArguments();
-    RegionMapping existingMapping = service.getMappingForRegion(mapping.getRegionName());
+      FunctionContext<ConnectorService.RegionMapping> context) throws Exception {
+    ConnectorService.RegionMapping mapping = context.getArguments();
+    ConnectorService.RegionMapping existingMapping =
+        service.getMappingForRegion(mapping.getRegionName());
     if (existingMapping == null) {
       throw new RegionMappingNotFoundException(
           "RegionMapping for region " + mapping.getRegionName() + " was not found");
     }
 
     // action
-    RegionMapping alteredMapping = alterRegionMapping(mapping, existingMapping);
+    ConnectorService.RegionMapping alteredMapping = alterRegionMapping(mapping, existingMapping);
     service.replaceRegionMapping(alteredMapping);
 
     // output
-    String member = getMember(context);
-    XmlEntity xmlEntity = createXmlEntity(context);
-    CliFunctionResult result = createSuccessResult(mapping.getRegionName(), member, xmlEntity);
-    return result;
+    return new CliFunctionResult(context.getMemberName(), alteredMapping, null);
   }
 
-  RegionMapping alterRegionMapping(RegionMapping regionMapping, RegionMapping existingMapping) {
-    String connectionName = regionMapping.getConnectionConfigName() == null
-        ? existingMapping.getConnectionConfigName() : regionMapping.getConnectionConfigName();
+  ConnectorService.RegionMapping alterRegionMapping(ConnectorService.RegionMapping regionMapping,
+      ConnectorService.RegionMapping existingMapping) {
+    String connectionName = getValue(regionMapping.getConnectionConfigName(),
+        existingMapping.getConnectionConfigName());
     String table = getValue(regionMapping.getTableName(), existingMapping.getTableName());
     String pdxClassName =
         getValue(regionMapping.getPdxClassName(), existingMapping.getPdxClassName());
     Boolean keyInValue = regionMapping.isPrimaryKeyInValue() == null
         ? existingMapping.isPrimaryKeyInValue() : regionMapping.isPrimaryKeyInValue();
 
-    Map<String, String> fieldMappings = regionMapping.getFieldToColumnMap();
-    if (fieldMappings == null) {
-      fieldMappings = existingMapping.getFieldToColumnMap();
+    List<ConnectorService.RegionMapping.FieldMapping> fieldMappings =
+        regionMapping.getFieldMapping();
+    if (!regionMapping.isFieldMappingModified()) {
+      fieldMappings = existingMapping.getFieldMapping();
     }
-    RegionMapping alteredMapping = new RegionMapping(existingMapping.getRegionName(), pdxClassName,
-        table, connectionName, keyInValue, fieldMappings);
+    ConnectorService.RegionMapping alteredMapping = new ConnectorService.RegionMapping(
+        existingMapping.getRegionName(), pdxClassName, table, connectionName, keyInValue);
+    alteredMapping.getFieldMapping().addAll(fieldMappings);
     return alteredMapping;
   }
 
@@ -78,10 +79,4 @@ public class AlterMappingFunction extends JdbcCliFunction<RegionMapping, CliFunc
     }
     return newValue.isEmpty() ? null : newValue;
   }
-
-  private CliFunctionResult createSuccessResult(String connectionName, String member,
-      XmlEntity xmlEntity) {
-    String message = "Altered JDBC connection " + connectionName + " on " + member;
-    return new CliFunctionResult(member, xmlEntity, message);
-  }
 }
diff --git a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/CreateConnectionCommand.java b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/CreateConnectionCommand.java
index af95486..ffe557c 100644
--- a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/CreateConnectionCommand.java
+++ b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/CreateConnectionCommand.java
@@ -23,11 +23,9 @@ import org.springframework.shell.core.annotation.CliCommand;
 import org.springframework.shell.core.annotation.CliOption;
 
 import org.apache.geode.annotations.Experimental;
-import org.apache.geode.cache.execute.ResultCollector;
-import org.apache.geode.connectors.jdbc.internal.ConnectionConfigBuilder;
-import org.apache.geode.connectors.jdbc.internal.ConnectionConfiguration;
+import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
+import org.apache.geode.distributed.ClusterConfigurationService;
 import org.apache.geode.distributed.DistributedMember;
-import org.apache.geode.distributed.internal.InternalClusterConfigurationService;
 import org.apache.geode.internal.logging.LogService;
 import org.apache.geode.management.cli.CliMetaData;
 import org.apache.geode.management.cli.Result;
@@ -36,9 +34,8 @@ import org.apache.geode.management.internal.cli.GfshParseResult;
 import org.apache.geode.management.internal.cli.commands.InternalGfshCommand;
 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.CommandResult;
 import org.apache.geode.management.internal.cli.result.ResultBuilder;
-import org.apache.geode.management.internal.cli.result.TabularResultData;
-import org.apache.geode.management.internal.configuration.domain.XmlEntity;
 import org.apache.geode.management.internal.security.ResourceOperation;
 import org.apache.geode.security.ResourcePermission;
 
@@ -83,70 +80,30 @@ public class CreateConnectionCommand extends InternalGfshCommand {
 
     // input
     Set<DistributedMember> targetMembers = getMembers(null, null);
-    ConnectionConfiguration configuration = getArguments(name, url, user, password, params);
+    ConnectorService.Connection connection =
+        new ConnectorService.Connection(name, url, user, password, params);
 
     // action
-    ResultCollector<CliFunctionResult, List<CliFunctionResult>> resultCollector =
-        execute(new CreateConnectionFunction(), configuration, targetMembers);
+    List<CliFunctionResult> results =
+        executeAndGetFunctionResult(new CreateConnectionFunction(), connection, targetMembers);
 
-    // output
-    TabularResultData tabularResultData = ResultBuilder.createTabularResultData();
-    XmlEntity xmlEntity = fillTabularResultData(resultCollector, tabularResultData);
-    tabularResultData.setHeader(EXPERIMENTAL);
-    Result result = ResultBuilder.buildResult(tabularResultData);
-    updateClusterConfiguration(result, xmlEntity);
-    return result;
-  }
-
-  ConnectionConfiguration getArguments(String name, String url, String user, String password,
-      String[] params) {
-    ConnectionConfigBuilder builder = new ConnectionConfigBuilder().withName(name).withUrl(url)
-        .withUser(user).withPassword(password).withParameters(params);
-    return builder.build();
-  }
+    boolean persisted = false;
+    ClusterConfigurationService ccService = getConfigurationService();
 
-  ResultCollector<CliFunctionResult, List<CliFunctionResult>> execute(
-      CreateConnectionFunction function, ConnectionConfiguration configuration,
-      Set<DistributedMember> targetMembers) {
-    return (ResultCollector<CliFunctionResult, List<CliFunctionResult>>) executeFunction(function,
-        configuration, targetMembers);
-  }
-
-  private XmlEntity fillTabularResultData(
-      ResultCollector<CliFunctionResult, List<CliFunctionResult>> resultCollector,
-      TabularResultData tabularResultData) {
-    XmlEntity xmlEntity = null;
-
-    for (CliFunctionResult oneResult : resultCollector.getResult()) {
-      if (oneResult.isSuccessful()) {
-        xmlEntity = addSuccessToResults(tabularResultData, oneResult);
-      } else {
-        addErrorToResults(tabularResultData, oneResult);
+    if (ccService != null && results.stream().filter(CliFunctionResult::isSuccessful).count() > 0) {
+      ConnectorService service =
+          ccService.getCustomCacheElement("cluster", "connector-service", ConnectorService.class);
+      if (service == null) {
+        service = new ConnectorService();
       }
+      service.getConnection().add(connection);
+      ccService.saveCustomCacheElement("cluster", service);
+      persisted = true;
     }
 
-    return xmlEntity;
-  }
-
-  private XmlEntity addSuccessToResults(TabularResultData tabularResultData,
-      CliFunctionResult oneResult) {
-    tabularResultData.accumulate("Member", oneResult.getMemberIdOrName());
-    tabularResultData.accumulate("Status", oneResult.getMessage());
-    return oneResult.getXmlEntity();
-  }
-
-  private void addErrorToResults(TabularResultData tabularResultData, CliFunctionResult oneResult) {
-    tabularResultData.accumulate("Member", oneResult.getMemberIdOrName());
-    tabularResultData.accumulate("Status", ERROR_PREFIX + oneResult.getMessage());
-    tabularResultData.setStatus(Result.Status.ERROR);
-  }
-
-  private void updateClusterConfiguration(final Result result, final XmlEntity xmlEntity) {
-    if (xmlEntity != null) {
-      persistClusterConfiguration(result,
-          () -> ((InternalClusterConfigurationService) getConfigurationService())
-              .addXmlEntity(xmlEntity, null));
-    }
+    CommandResult commandResult = ResultBuilder.buildResult(results, EXPERIMENTAL, null);
+    commandResult.setCommandPersisted(persisted);
+    return commandResult;
   }
 
   public static class Interceptor extends AbstractCliAroundInterceptor {
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 1fee150..010c24a 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
@@ -17,14 +17,14 @@ package org.apache.geode.connectors.jdbc.internal.cli;
 import org.apache.geode.annotations.Experimental;
 import org.apache.geode.cache.execute.FunctionContext;
 import org.apache.geode.connectors.jdbc.internal.ConnectionConfigExistsException;
-import org.apache.geode.connectors.jdbc.internal.ConnectionConfiguration;
 import org.apache.geode.connectors.jdbc.internal.JdbcConnectorService;
+import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
 import org.apache.geode.management.internal.cli.functions.CliFunctionResult;
 import org.apache.geode.management.internal.configuration.domain.XmlEntity;
 
 @Experimental
 public class CreateConnectionFunction
-    extends JdbcCliFunction<ConnectionConfiguration, CliFunctionResult> {
+    extends JdbcCliFunction<ConnectorService.Connection, CliFunctionResult> {
 
   CreateConnectionFunction() {
     super();
@@ -32,8 +32,8 @@ public class CreateConnectionFunction
 
   @Override
   CliFunctionResult getFunctionResult(JdbcConnectorService service,
-      FunctionContext<ConnectionConfiguration> context) throws Exception {
-    ConnectionConfiguration connectionConfig = context.getArguments();
+      FunctionContext<ConnectorService.Connection> context) throws Exception {
+    ConnectorService.Connection connectionConfig = context.getArguments();
     createConnectionConfig(service, connectionConfig);
     String member = getMember(context);
     XmlEntity xmlEntity = createXmlEntity(context);
@@ -44,7 +44,7 @@ public class CreateConnectionFunction
    * Creates the named connection configuration
    */
   void createConnectionConfig(JdbcConnectorService service,
-      ConnectionConfiguration connectionConfig) throws ConnectionConfigExistsException {
+      ConnectorService.Connection connectionConfig) throws ConnectionConfigExistsException {
     service.createConnectionConfig(connectionConfig);
   }
 
diff --git a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingCommand.java b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingCommand.java
index 570deaa..04123e3 100644
--- a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingCommand.java
+++ b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingCommand.java
@@ -21,19 +21,16 @@ import org.springframework.shell.core.annotation.CliCommand;
 import org.springframework.shell.core.annotation.CliOption;
 
 import org.apache.geode.annotations.Experimental;
-import org.apache.geode.cache.execute.ResultCollector;
-import org.apache.geode.connectors.jdbc.internal.RegionMapping;
-import org.apache.geode.connectors.jdbc.internal.RegionMappingBuilder;
+import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
+import org.apache.geode.distributed.ClusterConfigurationService;
 import org.apache.geode.distributed.DistributedMember;
-import org.apache.geode.distributed.internal.InternalClusterConfigurationService;
 import org.apache.geode.management.cli.CliMetaData;
 import org.apache.geode.management.cli.Result;
 import org.apache.geode.management.internal.cli.commands.InternalGfshCommand;
 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.CommandResult;
 import org.apache.geode.management.internal.cli.result.ResultBuilder;
-import org.apache.geode.management.internal.cli.result.TabularResultData;
-import org.apache.geode.management.internal.configuration.domain.XmlEntity;
 import org.apache.geode.management.internal.security.ResourceOperation;
 import org.apache.geode.security.ResourcePermission;
 
@@ -83,72 +80,30 @@ public class CreateMappingCommand extends InternalGfshCommand {
 
     // input
     Set<DistributedMember> targetMembers = getMembers(null, null);
-    RegionMapping mapping =
-        getArguments(regionName, connectionName, table, pdxClassName, keyInValue, fieldMappings);
+    ConnectorService.RegionMapping mapping = new ConnectorService.RegionMapping(regionName,
+        pdxClassName, table, connectionName, keyInValue);
+    mapping.setFieldMapping(fieldMappings);
 
     // action
-    ResultCollector<CliFunctionResult, List<CliFunctionResult>> resultCollector =
-        execute(new CreateMappingFunction(), mapping, targetMembers);
+    List<CliFunctionResult> results =
+        executeAndGetFunctionResult(new CreateMappingFunction(), mapping, targetMembers);
 
-    // output
-    TabularResultData tabularResultData = ResultBuilder.createTabularResultData();
-    XmlEntity xmlEntity = fillTabularResultData(resultCollector, tabularResultData);
-    tabularResultData.setHeader(EXPERIMENTAL);
-    Result result = ResultBuilder.buildResult(tabularResultData);
-    updateClusterConfiguration(result, xmlEntity);
-    return result;
-  }
-
-  RegionMapping getArguments(String regionName, String connectionName, String table,
-      String pdxClassName, boolean keyInValue, String[] fieldMappings) {
-    RegionMappingBuilder builder = new RegionMappingBuilder().withRegionName(regionName)
-        .withConnectionConfigName(connectionName).withTableName(table)
-        .withPdxClassName(pdxClassName).withPrimaryKeyInValue(keyInValue)
-        .withFieldToColumnMappings(fieldMappings);
-    return builder.build();
-  }
+    boolean persisted = false;
+    ClusterConfigurationService ccService = getConfigurationService();
 
-  ResultCollector<CliFunctionResult, List<CliFunctionResult>> execute(
-      CreateMappingFunction function, RegionMapping regionMapping,
-      Set<DistributedMember> targetMembers) {
-    return (ResultCollector<CliFunctionResult, List<CliFunctionResult>>) executeFunction(function,
-        regionMapping, targetMembers);
-  }
-
-  private XmlEntity fillTabularResultData(
-      ResultCollector<CliFunctionResult, List<CliFunctionResult>> resultCollector,
-      TabularResultData tabularResultData) {
-    XmlEntity xmlEntity = null;
-
-    for (CliFunctionResult oneResult : resultCollector.getResult()) {
-      if (oneResult.isSuccessful()) {
-        xmlEntity = addSuccessToResults(tabularResultData, oneResult);
-      } else {
-        addErrorToResults(tabularResultData, oneResult);
+    if (ccService != null && results.stream().filter(CliFunctionResult::isSuccessful).count() > 0) {
+      ConnectorService service =
+          ccService.getCustomCacheElement("cluster", "connector-service", ConnectorService.class);
+      if (service == null) {
+        service = new ConnectorService();
       }
+      service.getRegionMapping().add(mapping);
+      ccService.saveCustomCacheElement("cluster", service);
+      persisted = true;
     }
 
-    return xmlEntity;
-  }
-
-  private XmlEntity addSuccessToResults(TabularResultData tabularResultData,
-      CliFunctionResult oneResult) {
-    tabularResultData.accumulate("Member", oneResult.getMemberIdOrName());
-    tabularResultData.accumulate("Status", oneResult.getMessage());
-    return oneResult.getXmlEntity();
-  }
-
-  private void addErrorToResults(TabularResultData tabularResultData, CliFunctionResult oneResult) {
-    tabularResultData.accumulate("Member", oneResult.getMemberIdOrName());
-    tabularResultData.accumulate("Status", ERROR_PREFIX + oneResult.getMessage());
-    tabularResultData.setStatus(Result.Status.ERROR);
-  }
-
-  private void updateClusterConfiguration(final Result result, final XmlEntity xmlEntity) {
-    if (xmlEntity != null) {
-      persistClusterConfiguration(result,
-          () -> ((InternalClusterConfigurationService) getConfigurationService())
-              .addXmlEntity(xmlEntity, null));
-    }
+    CommandResult commandResult = ResultBuilder.buildResult(results, EXPERIMENTAL, null);
+    commandResult.setCommandPersisted(persisted);
+    return commandResult;
   }
 }
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 f6c4139..44f72ab 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
@@ -17,13 +17,13 @@ package org.apache.geode.connectors.jdbc.internal.cli;
 import org.apache.geode.annotations.Experimental;
 import org.apache.geode.cache.execute.FunctionContext;
 import org.apache.geode.connectors.jdbc.internal.JdbcConnectorService;
-import org.apache.geode.connectors.jdbc.internal.RegionMapping;
 import org.apache.geode.connectors.jdbc.internal.RegionMappingExistsException;
+import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
 import org.apache.geode.management.internal.cli.functions.CliFunctionResult;
-import org.apache.geode.management.internal.configuration.domain.XmlEntity;
 
 @Experimental
-public class CreateMappingFunction extends JdbcCliFunction<RegionMapping, CliFunctionResult> {
+public class CreateMappingFunction
+    extends JdbcCliFunction<ConnectorService.RegionMapping, CliFunctionResult> {
 
   CreateMappingFunction() {
     super();
@@ -31,30 +31,25 @@ public class CreateMappingFunction extends JdbcCliFunction<RegionMapping, CliFun
 
   @Override
   CliFunctionResult getFunctionResult(JdbcConnectorService service,
-      FunctionContext<RegionMapping> context) throws Exception {
+      FunctionContext<ConnectorService.RegionMapping> context) throws Exception {
     // input
-    RegionMapping regionMapping = context.getArguments();
+    ConnectorService.RegionMapping regionMapping = context.getArguments();
 
     // action
     createRegionMapping(service, regionMapping);
 
     // output
     String member = getMember(context);
-    XmlEntity xmlEntity = createXmlEntity(context);
-    return createSuccessResult(regionMapping.getRegionName(), member, xmlEntity);
+    String message =
+        "Created JDBC mapping for region " + regionMapping.getRegionName() + " on " + member;
+    return new CliFunctionResult(member, true, message);
   }
 
   /**
    * Creates the named connection configuration
    */
-  void createRegionMapping(JdbcConnectorService service, RegionMapping regionMapping)
-      throws RegionMappingExistsException {
+  void createRegionMapping(JdbcConnectorService service,
+      ConnectorService.RegionMapping regionMapping) throws RegionMappingExistsException {
     service.createRegionMapping(regionMapping);
   }
-
-  private CliFunctionResult createSuccessResult(String regionName, String member,
-      XmlEntity xmlEntity) {
-    String message = "Created JDBC mapping for region " + regionName + " on " + member;
-    return new CliFunctionResult(member, xmlEntity, 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 a99e35e..00be3c7 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,19 +20,16 @@ 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.springframework.shell.core.annotation.CliCommand;
 import org.springframework.shell.core.annotation.CliOption;
 
 import org.apache.geode.annotations.Experimental;
-import org.apache.geode.cache.execute.ResultCollector;
-import org.apache.geode.connectors.jdbc.internal.ConnectionConfiguration;
-import org.apache.geode.distributed.DistributedMember;
+import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
+import org.apache.geode.distributed.ClusterConfigurationService;
 import org.apache.geode.management.cli.CliMetaData;
 import org.apache.geode.management.cli.Result;
 import org.apache.geode.management.internal.cli.commands.InternalGfshCommand;
+import org.apache.geode.management.internal.cli.exceptions.EntityNotFoundException;
 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;
@@ -44,7 +41,7 @@ import org.apache.geode.security.ResourcePermission;
 public class DescribeConnectionCommand extends InternalGfshCommand {
   static final String DESCRIBE_CONNECTION = "describe jdbc-connection";
   static final String DESCRIBE_CONNECTION__HELP =
-      EXPERIMENTAL + "Describe the specified jdbc connection.";
+      EXPERIMENTAL + "Describe the specified jdbc connection found in cluster configuration.";
   static final String DESCRIBE_CONNECTION__NAME = "name";
   static final String DESCRIBE_CONNECTION__NAME__HELP =
       "Name of the jdbc connection to be described.";
@@ -59,37 +56,31 @@ public class DescribeConnectionCommand extends InternalGfshCommand {
   public Result describeConnection(@CliOption(key = DESCRIBE_CONNECTION__NAME, mandatory = true,
       help = DESCRIBE_CONNECTION__NAME__HELP) String name) {
 
-    // input
-    Set<DistributedMember> members = getMembers(null, null);
-    if (members.isEmpty()) {
-      return ResultBuilder.createUserErrorResult(CliStrings.NO_MEMBERS_FOUND_MESSAGE);
+    ClusterConfigurationService ccService = getConfigurationService();
+    if (ccService == null) {
+      return ResultBuilder.createInfoResult("cluster configuration service is not running");
     }
-    DistributedMember targetMember = members.iterator().next();
-
-    // action
-    ResultCollector<ConnectionConfiguration, List<ConnectionConfiguration>> resultCollector =
-        execute(new DescribeConnectionFunction(), name, targetMember);
-
-    // output
-    ConnectionConfiguration config = resultCollector.getResult().get(0);
-    if (config == null) {
-      return ResultBuilder.createInfoResult(
-          String.format(EXPERIMENTAL + "\n" + "Connection named '%s' not found", name));
+    // search for the connection that has this id to see if it exists
+    ConnectorService service =
+        ccService.getCustomCacheElement("cluster", "connector-service", ConnectorService.class);
+    if (service == null) {
+      throw new EntityNotFoundException(
+          EXPERIMENTAL + "\n" + "connection named '" + name + "' not found");
+    }
+    ConnectorService.Connection connection =
+        ccService.findIdentifiable(service.getConnection(), name);
+    if (connection == null) {
+      throw new EntityNotFoundException(
+          EXPERIMENTAL + "\n" + "connection named '" + name + "' not found");
     }
 
     CompositeResultData resultData = ResultBuilder.createCompositeResultData();
-    fillResultData(config, resultData);
+    fillResultData(connection, resultData);
     resultData.setHeader(EXPERIMENTAL);
     return ResultBuilder.buildResult(resultData);
   }
 
-  ResultCollector<ConnectionConfiguration, List<ConnectionConfiguration>> execute(
-      DescribeConnectionFunction function, String connectionName, DistributedMember targetMember) {
-    return (ResultCollector<ConnectionConfiguration, List<ConnectionConfiguration>>) executeFunction(
-        function, connectionName, targetMember);
-  }
-
-  private void fillResultData(ConnectionConfiguration config, CompositeResultData resultData) {
+  private void fillResultData(ConnectorService.Connection config, CompositeResultData resultData) {
     CompositeResultData.SectionResultData sectionResult =
         resultData.addSection(RESULT_SECTION_NAME);
     sectionResult.addSeparator('-');
@@ -103,11 +94,9 @@ public class DescribeConnectionCommand extends InternalGfshCommand {
     }
     TabularResultData tabularResultData = sectionResult.addTable(CREATE_CONNECTION__PARAMS);
     tabularResultData.setHeader("Additional connection parameters:");
-    if (config.getParameters() != null) {
-      config.getParameters().entrySet().forEach((entry) -> {
-        tabularResultData.accumulate("Param Name", entry.getKey());
-        tabularResultData.accumulate("Value", entry.getValue());
-      });
-    }
+    config.getParameterMap().entrySet().forEach((entry) -> {
+      tabularResultData.accumulate("Param Name", entry.getKey());
+      tabularResultData.accumulate("Value", entry.getValue());
+    });
   }
 }
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
deleted file mode 100644
index 054335f..0000000
--- a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeConnectionFunction.java
+++ /dev/null
@@ -1,34 +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.geode.annotations.Experimental;
-import org.apache.geode.cache.execute.FunctionContext;
-import org.apache.geode.connectors.jdbc.internal.ConnectionConfiguration;
-import org.apache.geode.connectors.jdbc.internal.JdbcConnectorService;
-
-@Experimental
-public class DescribeConnectionFunction extends JdbcCliFunction<String, ConnectionConfiguration> {
-
-  DescribeConnectionFunction() {
-    super();
-  }
-
-  @Override
-  ConnectionConfiguration getFunctionResult(JdbcConnectorService service,
-      FunctionContext<String> context) {
-    return service.getConnectionConfig(context.getArguments());
-  }
-}
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 7bb243a..b6a119d 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,19 +20,16 @@ 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;
 import org.springframework.shell.core.annotation.CliOption;
 
 import org.apache.geode.annotations.Experimental;
-import org.apache.geode.cache.execute.ResultCollector;
-import org.apache.geode.connectors.jdbc.internal.RegionMapping;
-import org.apache.geode.distributed.DistributedMember;
+import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
+import org.apache.geode.distributed.ClusterConfigurationService;
 import org.apache.geode.management.cli.CliMetaData;
 import org.apache.geode.management.cli.Result;
 import org.apache.geode.management.internal.cli.commands.InternalGfshCommand;
+import org.apache.geode.management.internal.cli.exceptions.EntityNotFoundException;
 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;
@@ -44,7 +41,7 @@ import org.apache.geode.security.ResourcePermission;
 public class DescribeMappingCommand extends InternalGfshCommand {
   static final String DESCRIBE_MAPPING = "describe jdbc-mapping";
   static final String DESCRIBE_MAPPING__HELP =
-      EXPERIMENTAL + "Describe the specified jdbc mapping.";
+      EXPERIMENTAL + "Describe the jdbc mapping in cluster configuration";
   static final String DESCRIBE_MAPPING__REGION_NAME = "region";
   static final String DESCRIBE_MAPPING__REGION_NAME__HELP =
       "Region name of the jdbc mapping to be described.";
@@ -59,37 +56,32 @@ public class DescribeMappingCommand extends InternalGfshCommand {
   public Result describeMapping(@CliOption(key = DESCRIBE_MAPPING__REGION_NAME, mandatory = true,
       help = DESCRIBE_MAPPING__REGION_NAME__HELP) String regionName) {
 
-    // input
-    Set<DistributedMember> members = getMembers(null, null);
-    if (members.isEmpty()) {
-      return ResultBuilder.createUserErrorResult(CliStrings.NO_MEMBERS_FOUND_MESSAGE);
+    ClusterConfigurationService ccService = getConfigurationService();
+    if (ccService == null) {
+      return ResultBuilder.createInfoResult("cluster configuration service is not running");
     }
-    DistributedMember targetMember = members.iterator().next();
-
-    // action
-    ResultCollector<RegionMapping, List<RegionMapping>> resultCollector =
-        execute(new DescribeMappingFunction(), regionName, targetMember);
-
-    // output
-    RegionMapping config = resultCollector.getResult().get(0);
-    if (config == null) {
-      return ResultBuilder.createInfoResult(
-          String.format(EXPERIMENTAL + "\n" + "Mapping for region '%s' not found", regionName));
+    // search for the connection that has this id to see if it exists
+    ConnectorService service =
+        ccService.getCustomCacheElement("cluster", "connector-service", ConnectorService.class);
+    if (service == null) {
+      throw new EntityNotFoundException(
+          EXPERIMENTAL + "\n" + "mapping for region '" + regionName + "' not found");
+    }
+    ConnectorService.RegionMapping mapping =
+        ccService.findIdentifiable(service.getRegionMapping(), regionName);
+    if (mapping == null) {
+      throw new EntityNotFoundException(
+          EXPERIMENTAL + "\n" + "mapping for region '" + regionName + "' not found");
     }
 
     CompositeResultData resultData = ResultBuilder.createCompositeResultData();
-    fillResultData(config, resultData);
+    fillResultData(mapping, resultData);
     resultData.setHeader(EXPERIMENTAL);
     return ResultBuilder.buildResult(resultData);
   }
 
-  ResultCollector<RegionMapping, List<RegionMapping>> execute(DescribeMappingFunction function,
-      String connectionName, DistributedMember targetMember) {
-    return (ResultCollector<RegionMapping, List<RegionMapping>>) executeFunction(function,
-        connectionName, targetMember);
-  }
-
-  private void fillResultData(RegionMapping mapping, CompositeResultData resultData) {
+  private void fillResultData(ConnectorService.RegionMapping mapping,
+      CompositeResultData resultData) {
     CompositeResultData.SectionResultData sectionResult =
         resultData.addSection(RESULT_SECTION_NAME);
     sectionResult.addSeparator('-');
@@ -102,10 +94,10 @@ public class DescribeMappingCommand extends InternalGfshCommand {
 
     TabularResultData tabularResultData = sectionResult.addTable(FIELD_TO_COLUMN_TABLE);
     tabularResultData.setHeader("Field to Column Mappings:");
-    if (mapping.getFieldToColumnMap() != null) {
-      mapping.getFieldToColumnMap().entrySet().forEach((entry) -> {
-        tabularResultData.accumulate("Field", entry.getKey());
-        tabularResultData.accumulate("Column", entry.getValue());
+    if (mapping.getFieldMapping() != null) {
+      mapping.getFieldMapping().forEach((entry) -> {
+        tabularResultData.accumulate("Field", entry.getFieldName());
+        tabularResultData.accumulate("Column", entry.getColumnName());
       });
     }
   }
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
deleted file mode 100644
index 76dcc64..0000000
--- a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeMappingFunction.java
+++ /dev/null
@@ -1,33 +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.geode.annotations.Experimental;
-import org.apache.geode.cache.execute.FunctionContext;
-import org.apache.geode.connectors.jdbc.internal.JdbcConnectorService;
-import org.apache.geode.connectors.jdbc.internal.RegionMapping;
-
-@Experimental
-public class DescribeMappingFunction extends JdbcCliFunction<String, RegionMapping> {
-
-  DescribeMappingFunction() {
-    super();
-  }
-
-  @Override
-  RegionMapping getFunctionResult(JdbcConnectorService service, FunctionContext<String> context) {
-    return service.getMappingForRegion(context.getArguments());
-  }
-}
diff --git a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyConnectionCommand.java b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyConnectionCommand.java
index 92e2401..88c13f9 100644
--- a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyConnectionCommand.java
+++ b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyConnectionCommand.java
@@ -21,17 +21,16 @@ import org.springframework.shell.core.annotation.CliCommand;
 import org.springframework.shell.core.annotation.CliOption;
 
 import org.apache.geode.annotations.Experimental;
-import org.apache.geode.cache.execute.ResultCollector;
+import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
+import org.apache.geode.distributed.ClusterConfigurationService;
 import org.apache.geode.distributed.DistributedMember;
-import org.apache.geode.distributed.internal.InternalClusterConfigurationService;
 import org.apache.geode.management.cli.CliMetaData;
 import org.apache.geode.management.cli.Result;
 import org.apache.geode.management.internal.cli.commands.InternalGfshCommand;
 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.CommandResult;
 import org.apache.geode.management.internal.cli.result.ResultBuilder;
-import org.apache.geode.management.internal.cli.result.TabularResultData;
-import org.apache.geode.management.internal.configuration.domain.XmlEntity;
 import org.apache.geode.management.internal.security.ResourceOperation;
 import org.apache.geode.security.ResourcePermission;
 
@@ -57,59 +56,27 @@ public class DestroyConnectionCommand extends InternalGfshCommand {
     Set<DistributedMember> targetMembers = getMembers(null, null);
 
     // action
-    ResultCollector<CliFunctionResult, List<CliFunctionResult>> resultCollector =
-        execute(new DestroyConnectionFunction(), name, targetMembers);
-
-    // output
-    TabularResultData tabularResultData = ResultBuilder.createTabularResultData();
-    XmlEntity xmlEntity = fillTabularResultData(resultCollector, tabularResultData);
-    tabularResultData.setHeader(EXPERIMENTAL);
-    Result result = ResultBuilder.buildResult(tabularResultData);
-    updateClusterConfiguration(result, xmlEntity);
-    return result;
-  }
-
-  ResultCollector<CliFunctionResult, List<CliFunctionResult>> execute(
-      DestroyConnectionFunction function, String connectionName,
-      Set<DistributedMember> targetMembers) {
-    return (ResultCollector<CliFunctionResult, List<CliFunctionResult>>) executeFunction(function,
-        connectionName, targetMembers);
-  }
-
-  private XmlEntity fillTabularResultData(
-      ResultCollector<CliFunctionResult, List<CliFunctionResult>> resultCollector,
-      TabularResultData tabularResultData) {
-    XmlEntity xmlEntity = null;
-
-    for (CliFunctionResult oneResult : resultCollector.getResult()) {
-      if (oneResult.isSuccessful()) {
-        xmlEntity = addSuccessToResults(tabularResultData, oneResult);
-      } else {
-        addErrorToResults(tabularResultData, oneResult);
+    List<CliFunctionResult> results =
+        executeAndGetFunctionResult(new DestroyConnectionFunction(), name, targetMembers);
+
+    boolean persisted = false;
+    ClusterConfigurationService ccService = getConfigurationService();
+
+    if (ccService != null && results.stream().filter(CliFunctionResult::isSuccessful).count() > 0) {
+      ConnectorService service =
+          ccService.getCustomCacheElement("cluster", "connector-service", ConnectorService.class);
+      if (service != null) {
+        ConnectorService.Connection conn =
+            ccService.findIdentifiable(service.getConnection(), name);
+        service.getConnection().remove(conn);
+        ccService.saveCustomCacheElement("cluster", service);
+        persisted = true;
       }
     }
 
-    return xmlEntity;
-  }
-
-  private XmlEntity addSuccessToResults(TabularResultData tabularResultData,
-      CliFunctionResult oneResult) {
-    tabularResultData.accumulate("Member", oneResult.getMemberIdOrName());
-    tabularResultData.accumulate("Status", oneResult.getMessage());
-    return oneResult.getXmlEntity();
-  }
+    CommandResult commandResult = ResultBuilder.buildResult(results, EXPERIMENTAL, null);
+    commandResult.setCommandPersisted(persisted);
 
-  private void addErrorToResults(TabularResultData tabularResultData, CliFunctionResult oneResult) {
-    tabularResultData.accumulate("Member", oneResult.getMemberIdOrName());
-    tabularResultData.accumulate("Status", ERROR_PREFIX + oneResult.getMessage());
-    tabularResultData.setStatus(Result.Status.ERROR);
-  }
-
-  private void updateClusterConfiguration(final Result result, final XmlEntity xmlEntity) {
-    if (xmlEntity != null) {
-      persistClusterConfiguration(result,
-          () -> ((InternalClusterConfigurationService) getConfigurationService())
-              .addXmlEntity(xmlEntity, null));
-    }
+    return commandResult;
   }
 }
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 85b7335..3383fa3 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
@@ -16,8 +16,8 @@ package org.apache.geode.connectors.jdbc.internal.cli;
 
 import org.apache.geode.annotations.Experimental;
 import org.apache.geode.cache.execute.FunctionContext;
-import org.apache.geode.connectors.jdbc.internal.ConnectionConfiguration;
 import org.apache.geode.connectors.jdbc.internal.JdbcConnectorService;
+import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
 import org.apache.geode.management.internal.cli.functions.CliFunctionResult;
 import org.apache.geode.management.internal.configuration.domain.XmlEntity;
 
@@ -45,7 +45,7 @@ public class DestroyConnectionFunction extends JdbcCliFunction<String, CliFuncti
    * @return true if the connection was found and destroyed
    */
   boolean destroyConnectionConfig(JdbcConnectorService service, String connectionName) {
-    ConnectionConfiguration connectionConfig = service.getConnectionConfig(connectionName);
+    ConnectorService.Connection connectionConfig = service.getConnectionConfig(connectionName);
     if (connectionConfig != null) {
       service.destroyConnectionConfig(connectionName);
       return true;
diff --git a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyMappingCommand.java b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyMappingCommand.java
index 6bcc970..0cc4e12 100644
--- a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyMappingCommand.java
+++ b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyMappingCommand.java
@@ -21,17 +21,16 @@ import org.springframework.shell.core.annotation.CliCommand;
 import org.springframework.shell.core.annotation.CliOption;
 
 import org.apache.geode.annotations.Experimental;
-import org.apache.geode.cache.execute.ResultCollector;
+import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
+import org.apache.geode.distributed.ClusterConfigurationService;
 import org.apache.geode.distributed.DistributedMember;
-import org.apache.geode.distributed.internal.InternalClusterConfigurationService;
 import org.apache.geode.management.cli.CliMetaData;
 import org.apache.geode.management.cli.Result;
 import org.apache.geode.management.internal.cli.commands.InternalGfshCommand;
 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.CommandResult;
 import org.apache.geode.management.internal.cli.result.ResultBuilder;
-import org.apache.geode.management.internal.cli.result.TabularResultData;
-import org.apache.geode.management.internal.configuration.domain.XmlEntity;
 import org.apache.geode.management.internal.security.ResourceOperation;
 import org.apache.geode.security.ResourcePermission;
 
@@ -55,58 +54,26 @@ public class DestroyMappingCommand extends InternalGfshCommand {
     Set<DistributedMember> targetMembers = getMembers(null, null);
 
     // action
-    ResultCollector<CliFunctionResult, List<CliFunctionResult>> resultCollector =
-        execute(new DestroyMappingFunction(), regionName, targetMembers);
+    List<CliFunctionResult> results =
+        executeAndGetFunctionResult(new DestroyMappingFunction(), regionName, targetMembers);
 
     // output
-    TabularResultData tabularResultData = ResultBuilder.createTabularResultData();
-    XmlEntity xmlEntity = fillTabularResultData(resultCollector, tabularResultData);
-    tabularResultData.setHeader(EXPERIMENTAL);
-    Result result = ResultBuilder.buildResult(tabularResultData);
-    updateClusterConfiguration(result, xmlEntity);
-    return result;
-  }
-
-  ResultCollector<CliFunctionResult, List<CliFunctionResult>> execute(
-      DestroyMappingFunction function, String regionName, Set<DistributedMember> targetMembers) {
-    return (ResultCollector<CliFunctionResult, List<CliFunctionResult>>) executeFunction(function,
-        regionName, targetMembers);
-  }
-
-  private XmlEntity fillTabularResultData(
-      ResultCollector<CliFunctionResult, List<CliFunctionResult>> resultCollector,
-      TabularResultData tabularResultData) {
-    XmlEntity xmlEntity = null;
-
-    for (CliFunctionResult oneResult : resultCollector.getResult()) {
-      if (oneResult.isSuccessful()) {
-        xmlEntity = addSuccessToResults(tabularResultData, oneResult);
-      } else {
-        addErrorToResults(tabularResultData, oneResult);
+    boolean persisted = false;
+    ClusterConfigurationService ccService = getConfigurationService();
+
+    if (ccService != null && results.stream().filter(CliFunctionResult::isSuccessful).count() > 0) {
+      ConnectorService service =
+          ccService.getCustomCacheElement("cluster", "connector-service", ConnectorService.class);
+      if (service != null) {
+        ccService.removeFromList(service.getRegionMapping(), regionName);
+        ccService.saveCustomCacheElement("cluster", service);
+        persisted = true;
       }
     }
 
-    return xmlEntity;
-  }
+    CommandResult commandResult = ResultBuilder.buildResult(results, EXPERIMENTAL, null);
+    commandResult.setCommandPersisted(persisted);
 
-  private XmlEntity addSuccessToResults(TabularResultData tabularResultData,
-      CliFunctionResult oneResult) {
-    tabularResultData.accumulate("Member", oneResult.getMemberIdOrName());
-    tabularResultData.accumulate("Status", oneResult.getMessage());
-    return oneResult.getXmlEntity();
-  }
-
-  private void addErrorToResults(TabularResultData tabularResultData, CliFunctionResult oneResult) {
-    tabularResultData.accumulate("Member", oneResult.getMemberIdOrName());
-    tabularResultData.accumulate("Status", ERROR_PREFIX + oneResult.getMessage());
-    tabularResultData.setStatus(Result.Status.ERROR);
-  }
-
-  private void updateClusterConfiguration(final Result result, final XmlEntity xmlEntity) {
-    if (xmlEntity != null) {
-      persistClusterConfiguration(result,
-          () -> ((InternalClusterConfigurationService) getConfigurationService())
-              .addXmlEntity(xmlEntity, null));
-    }
+    return commandResult;
   }
 }
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 9d3c0ef..c6bd0bb 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,7 +17,7 @@ package org.apache.geode.connectors.jdbc.internal.cli;
 import org.apache.geode.annotations.Experimental;
 import org.apache.geode.cache.execute.FunctionContext;
 import org.apache.geode.connectors.jdbc.internal.JdbcConnectorService;
-import org.apache.geode.connectors.jdbc.internal.RegionMapping;
+import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
 import org.apache.geode.management.internal.cli.functions.CliFunctionResult;
 import org.apache.geode.management.internal.configuration.domain.XmlEntity;
 
@@ -46,7 +46,7 @@ public class DestroyMappingFunction extends JdbcCliFunction<String, CliFunctionR
    * Destroys the named region mapping
    */
   boolean destroyRegionMapping(JdbcConnectorService service, String regionName) {
-    RegionMapping mapping = service.getMappingForRegion(regionName);
+    ConnectorService.RegionMapping mapping = service.getMappingForRegion(regionName);
     if (mapping != null) {
       service.destroyRegionMapping(regionName);
       return true;
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
index b1d3de9..12721b9 100644
--- 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
@@ -14,7 +14,6 @@
  */
 package org.apache.geode.connectors.jdbc.internal.cli;
 
-
 import org.apache.commons.lang.exception.ExceptionUtils;
 import org.apache.logging.log4j.Logger;
 
diff --git a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/FunctionContextArgumentProvider.java b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/FunctionContextArgumentProvider.java
index 3025096..2db2cc4 100644
--- a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/FunctionContextArgumentProvider.java
+++ b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/FunctionContextArgumentProvider.java
@@ -14,12 +14,6 @@
  */
 package org.apache.geode.connectors.jdbc.internal.cli;
 
-import static org.apache.geode.connectors.jdbc.internal.xml.ElementType.CONNECTION_SERVICE;
-import static org.apache.geode.connectors.jdbc.internal.xml.JdbcConnectorServiceXmlGenerator.PREFIX;
-import static org.apache.geode.connectors.jdbc.internal.xml.JdbcConnectorServiceXmlParser.NAME;
-import static org.apache.geode.connectors.jdbc.internal.xml.JdbcConnectorServiceXmlParser.NAMESPACE;
-import static org.apache.geode.internal.cache.xmlcache.CacheXml.CACHE;
-
 import org.apache.geode.cache.execute.FunctionContext;
 import org.apache.geode.connectors.jdbc.internal.JdbcConnectorService;
 import org.apache.geode.internal.cache.InternalCache;
@@ -58,8 +52,7 @@ class FunctionContextArgumentProvider {
    * Returns XmlEntity for JdbcConnectorServiceXmlGenerator snippet of cache xml
    */
   static XmlEntity createXmlEntity(FunctionContext<?> context) {
-    return new XmlEntity(createCacheProvider(context), CACHE, PREFIX, NAMESPACE,
-        CONNECTION_SERVICE.getTypeName(), NAME, CONNECTION_SERVICE.getTypeName());
+    return null;
   }
 
   private static XmlEntity.CacheProvider createCacheProvider(FunctionContext<?> context) {
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
index 2032fad..bbfe877 100644
--- 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
@@ -14,16 +14,20 @@
  */
 package org.apache.geode.connectors.jdbc.internal.cli;
 
+import org.apache.logging.log4j.Logger;
+
 import org.apache.geode.annotations.Experimental;
 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;
 
 @Experimental
 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();
@@ -47,6 +51,7 @@ public abstract class JdbcCliFunction<T1, T2> implements InternalFunction<T1> {
       T2 result = getFunctionResult(service, context);
       context.getResultSender().lastResult(result);
     } catch (Exception e) {
+      logger.error(e.getMessage(), e);
       exceptionHandler.handleException(context, e);
     }
   }
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 b71ee78..753d485 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
@@ -14,17 +14,13 @@
  */
 package org.apache.geode.connectors.jdbc.internal.cli;
 
-import java.util.Arrays;
-import java.util.HashSet;
 import java.util.List;
-import java.util.Set;
 
 import org.springframework.shell.core.annotation.CliCommand;
 
 import org.apache.geode.annotations.Experimental;
-import org.apache.geode.cache.execute.ResultCollector;
-import org.apache.geode.connectors.jdbc.internal.ConnectionConfiguration;
-import org.apache.geode.distributed.DistributedMember;
+import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
+import org.apache.geode.distributed.ClusterConfigurationService;
 import org.apache.geode.management.cli.CliMetaData;
 import org.apache.geode.management.cli.Result;
 import org.apache.geode.management.internal.cli.commands.InternalGfshCommand;
@@ -49,28 +45,23 @@ public class ListConnectionCommand extends InternalGfshCommand {
       operation = ResourcePermission.Operation.MANAGE)
   public Result listConnection() {
 
-    // input
-    Set<DistributedMember> targetMembers = getMembers(null, null);
-    if (targetMembers.isEmpty()) {
-      return ResultBuilder.createUserErrorResult(CliStrings.NO_MEMBERS_FOUND_MESSAGE);
+    ClusterConfigurationService ccService = getConfigurationService();
+    if (ccService == null) {
+      return ResultBuilder.createInfoResult("cluster configuration service is not running");
     }
 
-    // action
-    ResultCollector<ConnectionConfiguration, List<ConnectionConfiguration[]>> resultCollector =
-        execute(new ListConnectionFunction(), targetMembers.iterator().next());
+    ConnectorService service =
+        ccService.getCustomCacheElement("cluster", "connector-service", ConnectorService.class);
+    if (service == null) {
+      return ResultBuilder.createInfoResult(EXPERIMENTAL + "\n" + NO_CONNECTIONS_FOUND);
+    }
 
     // output
     TabularResultData tabularResultData = ResultBuilder.createTabularResultData();
-    boolean connectionsExist = fillTabularResultData(resultCollector, tabularResultData);
+    boolean connectionsExist = fillTabularResultData(service.getConnection(), tabularResultData);
     return createResult(tabularResultData, connectionsExist);
   }
 
-  ResultCollector<ConnectionConfiguration, List<ConnectionConfiguration[]>> execute(
-      ListConnectionFunction function, DistributedMember targetMember) {
-    return (ResultCollector<ConnectionConfiguration, List<ConnectionConfiguration[]>>) executeFunction(
-        function, null, targetMember);
-  }
-
   private Result createResult(TabularResultData tabularResultData, boolean connectionsExist) {
     if (connectionsExist) {
       tabularResultData.setHeader(EXPERIMENTAL);
@@ -83,25 +74,11 @@ public class ListConnectionCommand extends InternalGfshCommand {
   /**
    * Returns true if any connections exist
    */
-  private boolean fillTabularResultData(
-      ResultCollector<ConnectionConfiguration, List<ConnectionConfiguration[]>> resultCollector,
+  private boolean fillTabularResultData(List<ConnectorService.Connection> connections,
       TabularResultData tabularResultData) {
-    Set<ConnectionConfiguration> connectionConfigs = new HashSet<>();
-
-    for (Object resultObject : resultCollector.getResult()) {
-      if (resultObject instanceof ConnectionConfiguration[]) {
-        connectionConfigs.addAll(Arrays.asList((ConnectionConfiguration[]) resultObject));
-      } else if (resultObject instanceof Throwable) {
-        throw new IllegalStateException((Throwable) resultObject);
-      } else {
-        throw new IllegalStateException(resultObject.getClass().getName());
-      }
-    }
-
-    for (ConnectionConfiguration connectionConfig : connectionConfigs) {
+    for (ConnectorService.Connection connectionConfig : connections) {
       tabularResultData.accumulate(LIST_OF_CONNECTIONS, connectionConfig.getName());
     }
-
-    return !connectionConfigs.isEmpty();
+    return !connections.isEmpty();
   }
 }
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
deleted file mode 100644
index 50a1657..0000000
--- a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/ListConnectionFunction.java
+++ /dev/null
@@ -1,45 +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 java.util.Set;
-
-import org.apache.geode.annotations.Experimental;
-import org.apache.geode.cache.execute.FunctionContext;
-import org.apache.geode.connectors.jdbc.internal.ConnectionConfiguration;
-import org.apache.geode.connectors.jdbc.internal.JdbcConnectorService;
-
-@Experimental
-public class ListConnectionFunction extends JdbcCliFunction<Void, ConnectionConfiguration[]> {
-
-  ListConnectionFunction() {
-    super();
-  }
-
-  @Override
-  ConnectionConfiguration[] getFunctionResult(JdbcConnectorService service,
-      FunctionContext<Void> context) {
-    return getConnectionConfigAsArray(service);
-  }
-
-  ConnectionConfiguration[] getConnectionConfigAsArray(JdbcConnectorService service) {
-    Set<ConnectionConfiguration> connectionConfigs = getConnectionConfigs(service);
-    return connectionConfigs.toArray(new ConnectionConfiguration[connectionConfigs.size()]);
-  }
-
-  private Set<ConnectionConfiguration> getConnectionConfigs(JdbcConnectorService service) {
-    return 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 ad92ad8..217b676 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
@@ -14,17 +14,13 @@
  */
 package org.apache.geode.connectors.jdbc.internal.cli;
 
-import java.util.Arrays;
-import java.util.HashSet;
 import java.util.List;
-import java.util.Set;
 
 import org.springframework.shell.core.annotation.CliCommand;
 
 import org.apache.geode.annotations.Experimental;
-import org.apache.geode.cache.execute.ResultCollector;
-import org.apache.geode.connectors.jdbc.internal.RegionMapping;
-import org.apache.geode.distributed.DistributedMember;
+import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
+import org.apache.geode.distributed.ClusterConfigurationService;
 import org.apache.geode.management.cli.CliMetaData;
 import org.apache.geode.management.cli.Result;
 import org.apache.geode.management.internal.cli.commands.InternalGfshCommand;
@@ -48,28 +44,23 @@ public class ListMappingCommand extends InternalGfshCommand {
       operation = ResourcePermission.Operation.MANAGE)
   public Result listMapping() {
 
-    // input
-    Set<DistributedMember> targetMembers = getMembers(null, null);
-    if (targetMembers.isEmpty()) {
-      return ResultBuilder.createUserErrorResult(CliStrings.NO_MEMBERS_FOUND_MESSAGE);
+    ClusterConfigurationService ccService = getConfigurationService();
+    if (ccService == null) {
+      return ResultBuilder.createInfoResult("cluster configuration service is not running");
     }
 
-    // action
-    ResultCollector<RegionMapping, List<RegionMapping[]>> resultCollector =
-        execute(new ListMappingFunction(), targetMembers.iterator().next());
+    ConnectorService service =
+        ccService.getCustomCacheElement("cluster", "connector-service", ConnectorService.class);
+    if (service == null) {
+      return ResultBuilder.createInfoResult(EXPERIMENTAL + "\n" + NO_MAPPINGS_FOUND);
+    }
 
     // output
     TabularResultData tabularResultData = ResultBuilder.createTabularResultData();
-    boolean mappingsExist = fillTabularResultData(resultCollector, tabularResultData);
+    boolean mappingsExist = fillTabularResultData(service.getRegionMapping(), tabularResultData);
     return createResult(tabularResultData, mappingsExist);
   }
 
-  ResultCollector<RegionMapping, List<RegionMapping[]>> execute(ListMappingFunction function,
-      DistributedMember targetMember) {
-    return (ResultCollector<RegionMapping, List<RegionMapping[]>>) executeFunction(function, null,
-        targetMember);
-  }
-
   private Result createResult(TabularResultData tabularResultData, boolean mappingsExist) {
     if (mappingsExist) {
       tabularResultData.setHeader(EXPERIMENTAL);
@@ -82,25 +73,11 @@ public class ListMappingCommand extends InternalGfshCommand {
   /**
    * Returns true if any connections exist
    */
-  private boolean fillTabularResultData(
-      ResultCollector<RegionMapping, List<RegionMapping[]>> resultCollector,
+  private boolean fillTabularResultData(List<ConnectorService.RegionMapping> mappings,
       TabularResultData tabularResultData) {
-    Set<RegionMapping> regionMappings = new HashSet<>();
-
-    for (Object resultObject : resultCollector.getResult()) {
-      if (resultObject instanceof RegionMapping[]) {
-        regionMappings.addAll(Arrays.asList((RegionMapping[]) resultObject));
-      } else if (resultObject instanceof Throwable) {
-        throw new IllegalStateException((Throwable) resultObject);
-      } else {
-        throw new IllegalStateException(resultObject.getClass().getName());
-      }
-    }
-
-    for (RegionMapping mapping : regionMappings) {
+    for (ConnectorService.RegionMapping mapping : mappings) {
       tabularResultData.accumulate(LIST_OF_MAPPINGS, mapping.getRegionName());
     }
-
-    return !regionMappings.isEmpty();
+    return !mappings.isEmpty();
   }
 }
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
deleted file mode 100644
index 0d24bd0..0000000
--- a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/ListMappingFunction.java
+++ /dev/null
@@ -1,44 +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 java.util.Set;
-
-import org.apache.geode.annotations.Experimental;
-import org.apache.geode.cache.execute.FunctionContext;
-import org.apache.geode.connectors.jdbc.internal.JdbcConnectorService;
-import org.apache.geode.connectors.jdbc.internal.RegionMapping;
-
-@Experimental
-public class ListMappingFunction extends JdbcCliFunction<Void, RegionMapping[]> {
-
-  ListMappingFunction() {
-    super();
-  }
-
-  @Override
-  RegionMapping[] getFunctionResult(JdbcConnectorService service, FunctionContext<Void> context) {
-    return getRegionMappingsAsArray(service);
-  }
-
-  RegionMapping[] getRegionMappingsAsArray(JdbcConnectorService service) {
-    Set<RegionMapping> regionMappings = getRegionMappings(service);
-    return regionMappings.toArray(new RegionMapping[regionMappings.size()]);
-  }
-
-  private Set<RegionMapping> getRegionMappings(JdbcConnectorService service) {
-    return service.getRegionMappings();
-  }
-}
diff --git a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/configuration/ConnectorService.java b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/configuration/ConnectorService.java
new file mode 100644
index 0000000..423b4d3
--- /dev/null
+++ b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/configuration/ConnectorService.java
@@ -0,0 +1,852 @@
+/*
+ * 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.configuration;
+
+import static org.apache.geode.connectors.jdbc.internal.xml.JdbcConnectorServiceXmlParser.PARAMS_DELIMITER;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Properties;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlTransient;
+import javax.xml.bind.annotation.XmlType;
+
+import org.apache.geode.annotations.Experimental;
+import org.apache.geode.cache.configuration.CacheElement;
+import org.apache.geode.connectors.jdbc.JdbcConnectorException;
+import org.apache.geode.connectors.jdbc.internal.TableMetaDataView;
+import org.apache.geode.pdx.internal.PdxType;
+import org.apache.geode.pdx.internal.TypeRegistry;
+
+
+/**
+ * <p>
+ * Java class for anonymous complex type.
+ *
+ * <p>
+ * The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * &lt;complexType>
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;sequence>
+ *         &lt;element name="connection" maxOccurs="unbounded" minOccurs="0">
+ *           &lt;complexType>
+ *             &lt;simpleContent>
+ *               &lt;extension base="&lt;http://www.w3.org/2001/XMLSchema>string">
+ *                 &lt;attribute name="name" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *                 &lt;attribute name="url" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *                 &lt;attribute name="user" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *                 &lt;attribute name="password" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *                 &lt;attribute name="parameters" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *               &lt;/extension>
+ *             &lt;/simpleContent>
+ *           &lt;/complexType>
+ *         &lt;/element>
+ *         &lt;element name="region-mapping" maxOccurs="unbounded" minOccurs="0">
+ *           &lt;complexType>
+ *             &lt;complexContent>
+ *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *                 &lt;sequence>
+ *                   &lt;element name="field-mapping" maxOccurs="unbounded" minOccurs="0">
+ *                     &lt;complexType>
+ *                       &lt;simpleContent>
+ *                         &lt;extension base="&lt;http://www.w3.org/2001/XMLSchema>string">
+ *                           &lt;attribute name="field-name" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *                           &lt;attribute name="column-name" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *                         &lt;/extension>
+ *                       &lt;/simpleContent>
+ *                     &lt;/complexType>
+ *                   &lt;/element>
+ *                 &lt;/sequence>
+ *                 &lt;attribute name="connection-name" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *                 &lt;attribute name="region" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *                 &lt;attribute name="table" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *                 &lt;attribute name="pdx-class" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *                 &lt;attribute name="primary-key-in-value" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *               &lt;/restriction>
+ *             &lt;/complexContent>
+ *           &lt;/complexType>
+ *         &lt;/element>
+ *       &lt;/sequence>
+ *       &lt;attribute name="name" type="{http://www.w3.org/2001/XMLSchema}string" fixed="connector-service" />
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ *
+ *
+ */
+@Experimental
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "", propOrder = {"connection", "regionMapping"})
+@XmlRootElement(name = "connector-service", namespace = "http://geode.apache.org/schema/jdbc")
+public class ConnectorService implements CacheElement {
+  public static String SCHEMA =
+      "http://geode.apache.org/schema/jdbc http://geode.apache.org/schema/jdbc/jdbc-1.0.xsd";
+
+  @XmlElement(namespace = "http://geode.apache.org/schema/jdbc")
+  protected List<ConnectorService.Connection> connection;
+  @XmlElement(name = "region-mapping", namespace = "http://geode.apache.org/schema/jdbc")
+  protected List<ConnectorService.RegionMapping> regionMapping;
+  @XmlAttribute(name = "name")
+  protected String name;
+
+  /**
+   * Gets the value of the connection property.
+   *
+   * <p>
+   * This accessor method returns a reference to the live list,
+   * not a snapshot. Therefore any modification you make to the
+   * returned list will be present inside the JAXB object.
+   * This is why there is not a <CODE>set</CODE> method for the connection property.
+   *
+   * <p>
+   * For example, to add a new item, do as follows:
+   *
+   * <pre>
+   * getConnection().add(newItem);
+   * </pre>
+   *
+   *
+   * <p>
+   * Objects of the following type(s) are allowed in the list
+   * {@link ConnectorService.Connection }
+   *
+   *
+   */
+  public List<ConnectorService.Connection> getConnection() {
+    if (connection == null) {
+      connection = new ArrayList<ConnectorService.Connection>();
+    }
+    return this.connection;
+  }
+
+  /**
+   * Gets the value of the regionMapping property.
+   *
+   * <p>
+   * This accessor method returns a reference to the live list,
+   * not a snapshot. Therefore any modification you make to the
+   * returned list will be present inside the JAXB object.
+   * This is why there is not a <CODE>set</CODE> method for the regionMapping property.
+   *
+   * <p>
+   * For example, to add a new item, do as follows:
+   *
+   * <pre>
+   * getRegionMapping().add(newItem);
+   * </pre>
+   *
+   *
+   * <p>
+   * Objects of the following type(s) are allowed in the list
+   * {@link ConnectorService.RegionMapping }
+   *
+   *
+   */
+  public List<ConnectorService.RegionMapping> getRegionMapping() {
+    if (regionMapping == null) {
+      regionMapping = new ArrayList<ConnectorService.RegionMapping>();
+    }
+    return this.regionMapping;
+  }
+
+  /**
+   * Gets the value of the name property.
+   *
+   * @return
+   *         possible object is
+   *         {@link String }
+   *
+   */
+  public String getName() {
+    if (name == null) {
+      return "connector-service";
+    } else {
+      return name;
+    }
+  }
+
+  /**
+   * Sets the value of the name property.
+   *
+   * @param value
+   *        allowed object is
+   *        {@link String }
+   *
+   */
+  public void setName(String value) {
+    this.name = value;
+  }
+
+  @Override
+  public String getId() {
+    return getName();
+  }
+
+
+  /**
+   * <p>
+   * Java class for anonymous complex type.
+   *
+   * <p>
+   * The following schema fragment specifies the expected content contained within this class.
+   *
+   * <pre>
+   * &lt;complexType>
+   *   &lt;simpleContent>
+   *     &lt;extension base="&lt;http://www.w3.org/2001/XMLSchema>string">
+   *       &lt;attribute name="name" type="{http://www.w3.org/2001/XMLSchema}string" />
+   *       &lt;attribute name="url" type="{http://www.w3.org/2001/XMLSchema}string" />
+   *       &lt;attribute name="user" type="{http://www.w3.org/2001/XMLSchema}string" />
+   *       &lt;attribute name="password" type="{http://www.w3.org/2001/XMLSchema}string" />
+   *       &lt;attribute name="parameters" type="{http://www.w3.org/2001/XMLSchema}string" />
+   *     &lt;/extension>
+   *   &lt;/simpleContent>
+   * &lt;/complexType>
+   * </pre>
+   *
+   *
+   */
+  @XmlAccessorType(XmlAccessType.FIELD)
+  public static class Connection implements CacheElement {
+    @XmlAttribute(name = "name")
+    protected String name;
+    @XmlAttribute(name = "url")
+    protected String url;
+    @XmlAttribute(name = "user")
+    protected String user;
+    @XmlAttribute(name = "password")
+    protected String password;
+    @XmlAttribute(name = "parameters")
+    protected String parameters;
+
+    @XmlTransient
+    protected Map<String, String> parameterMap = new HashMap<>();
+
+    public Connection() {};
+
+    public Connection(String name, String url, String user, String password, String parameters) {
+      this.name = name;
+      this.url = url;
+      this.user = user;
+      this.password = password;
+      setParameters(parameters);
+    }
+
+    public Connection(String name, String url, String user, String password, String[] parameters) {
+      this.name = name;
+      this.url = url;
+      this.user = user;
+      this.password = password;
+      setParameters(parameters);
+    }
+
+    /**
+     * Gets the value of the name property.
+     *
+     * @return
+     *         possible object is
+     *         {@link String }
+     *
+     */
+    public String getName() {
+      return name;
+    }
+
+    /**
+     * Sets the value of the name property.
+     *
+     * @param value
+     *        allowed object is
+     *        {@link String }
+     *
+     */
+    public void setName(String value) {
+      this.name = value;
+    }
+
+    /**
+     * Gets the value of the url property.
+     *
+     * @return
+     *         possible object is
+     *         {@link String }
+     *
+     */
+    public String getUrl() {
+      return url;
+    }
+
+    /**
+     * Sets the value of the url property.
+     *
+     * @param value
+     *        allowed object is
+     *        {@link String }
+     *
+     */
+    public void setUrl(String value) {
+      this.url = value;
+    }
+
+    /**
+     * Gets the value of the user property.
+     *
+     * @return
+     *         possible object is
+     *         {@link String }
+     *
+     */
+    public String getUser() {
+      return user;
+    }
+
+    /**
+     * Sets the value of the user property.
+     *
+     * @param value
+     *        allowed object is
+     *        {@link String }
+     *
+     */
+    public void setUser(String value) {
+      this.user = value;
+    }
+
+    /**
+     * Gets the value of the password property.
+     *
+     * @return
+     *         possible object is
+     *         {@link String }
+     *
+     */
+    public String getPassword() {
+      return password;
+    }
+
+    /**
+     * Sets the value of the password property.
+     *
+     * @param value
+     *        allowed object is
+     *        {@link String }
+     *
+     */
+    public void setPassword(String value) {
+      this.password = value;
+    }
+
+    /**
+     * Gets the value of the parameters property.
+     *
+     * @return
+     *         possible object is
+     *         {@link String }
+     *
+     */
+    public String getParameters() {
+      return parameters;
+    }
+
+    /**
+     * Sets the value of the parameters property.
+     *
+     * @param value
+     *        allowed object is
+     *        {@link String }
+     *
+     */
+    public void setParameters(String value) {
+      if (value == null) {
+        return;
+      }
+      this.setParameters(value.split(","));
+    }
+
+    public void setParameters(String[] params) {
+      if (params == null) {
+        return;
+      }
+
+      Arrays.stream(params).forEach(s -> {
+        if (!s.isEmpty()) {
+          String[] keyValuePair = s.split(PARAMS_DELIMITER);
+          validateParam(keyValuePair, s);
+          parameterMap.put(keyValuePair[0], keyValuePair[1]);
+        }
+      });
+      this.parameters = Arrays.stream(params).collect(Collectors.joining(","));
+    }
+
+    public void setParameters(Map<String, String> parameterMap) {
+      if (parameterMap == null) {
+        return;
+      }
+
+      this.parameterMap = parameterMap;
+      this.parameters = parameterMap.keySet().stream().map(k -> k + ":" + parameterMap.get(k))
+          .collect(Collectors.joining(","));
+    }
+
+    public Map<String, String> getParameterMap() {
+      if (this.parameters != null && !this.parameters.isEmpty()) {
+        String[] params = this.parameters.split(",");
+        Arrays.stream(params).forEach(s -> {
+          String[] keyValuePair = s.split(PARAMS_DELIMITER);
+          parameterMap.put(keyValuePair[0], keyValuePair[1]);
+        });
+      }
+      return this.parameterMap;
+    }
+
+    private void validateParam(String[] paramKeyValue, String param) {
+      // paramKeyValue is produced by split which will never give us
+      // an empty second element
+      if ((paramKeyValue.length != 2) || paramKeyValue[0].isEmpty()) {
+        throw new IllegalArgumentException("Parameter '" + param
+            + "' is not of the form 'parameterName" + PARAMS_DELIMITER + "value'");
+      }
+    }
+
+    public Properties getConnectionProperties() {
+      Properties properties = new Properties();
+      if (parameterMap != null) {
+        properties.putAll(parameterMap);
+      }
+      return properties;
+    }
+
+    @Override
+    public String getId() {
+      return getName();
+    }
+  }
+
+
+  /**
+   * <p>
+   * Java class for anonymous complex type.
+   *
+   * <p>
+   * The following schema fragment specifies the expected content contained within this class.
+   *
+   * <pre>
+   * &lt;complexType>
+   *   &lt;complexContent>
+   *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+   *       &lt;sequence>
+   *         &lt;element name="field-mapping" maxOccurs="unbounded" minOccurs="0">
+   *           &lt;complexType>
+   *             &lt;simpleContent>
+   *               &lt;extension base="&lt;http://www.w3.org/2001/XMLSchema>string">
+   *                 &lt;attribute name="field-name" type="{http://www.w3.org/2001/XMLSchema}string" />
+   *                 &lt;attribute name="column-name" type="{http://www.w3.org/2001/XMLSchema}string" />
+   *               &lt;/extension>
+   *             &lt;/simpleContent>
+   *           &lt;/complexType>
+   *         &lt;/element>
+   *       &lt;/sequence>
+   *       &lt;attribute name="connection-name" type="{http://www.w3.org/2001/XMLSchema}string" />
+   *       &lt;attribute name="region" type="{http://www.w3.org/2001/XMLSchema}string" />
+   *       &lt;attribute name="table" type="{http://www.w3.org/2001/XMLSchema}string" />
+   *       &lt;attribute name="pdx-class" type="{http://www.w3.org/2001/XMLSchema}string" />
+   *       &lt;attribute name="primary-key-in-value" type="{http://www.w3.org/2001/XMLSchema}string" />
+   *     &lt;/restriction>
+   *   &lt;/complexContent>
+   * &lt;/complexType>
+   * </pre>
+   *
+   *
+   */
+  @XmlAccessorType(XmlAccessType.FIELD)
+  @XmlType(name = "", propOrder = {"fieldMapping"})
+  public static class RegionMapping implements CacheElement {
+    private static final String MAPPINGS_DELIMITER = ":";
+
+    @XmlElement(name = "field-mapping", namespace = "http://geode.apache.org/schema/jdbc")
+    protected List<ConnectorService.RegionMapping.FieldMapping> fieldMapping;
+    @XmlTransient
+    protected boolean fieldMappingModified = false;
+    @XmlAttribute(name = "connection-name")
+    protected String connectionConfigName;
+    @XmlAttribute(name = "region")
+    protected String regionName;
+    @XmlAttribute(name = "table")
+    protected String tableName;
+    @XmlAttribute(name = "pdx-class")
+    protected String pdxClassName;
+    @XmlAttribute(name = "primary-key-in-value")
+    protected Boolean primaryKeyInValue;
+
+
+    public RegionMapping() {}
+
+    public RegionMapping(String regionName, String pdxClassName, String tableName,
+        String connectionConfigName, Boolean primaryKeyInValue) {
+      this.regionName = regionName;
+      this.pdxClassName = pdxClassName;
+      this.tableName = tableName;
+      this.connectionConfigName = connectionConfigName;
+      this.primaryKeyInValue = primaryKeyInValue;
+    }
+
+    public void setFieldMapping(String[] mappings) {
+      if (mappings != null) {
+        this.fieldMapping =
+            Arrays.stream(mappings).filter(Objects::nonNull).filter(s -> !s.isEmpty()).map(s -> {
+              String[] keyValuePair = s.split(MAPPINGS_DELIMITER);
+              validateParam(keyValuePair, s);
+              return new ConnectorService.RegionMapping.FieldMapping(keyValuePair[0],
+                  keyValuePair[1]);
+            }).collect(Collectors.toList());
+        fieldMappingModified = true;
+      }
+    }
+
+    private void validateParam(String[] paramKeyValue, String mapping) {
+      // paramKeyValue is produced by split which will never give us
+      // an empty second element
+      if (paramKeyValue.length != 2 || paramKeyValue[0].isEmpty()) {
+        throw new IllegalArgumentException("Field to column mapping '" + mapping
+            + "' is not of the form 'Field" + MAPPINGS_DELIMITER + "Column'");
+      }
+    }
+
+    public void setConnectionConfigName(String connectionConfigName) {
+      this.connectionConfigName = connectionConfigName;
+    }
+
+    public void setRegionName(String regionName) {
+      this.regionName = regionName;
+    }
+
+    public void setTableName(String tableName) {
+      this.tableName = tableName;
+    }
+
+    public void setPdxClassName(String pdxClassName) {
+      this.pdxClassName = pdxClassName;
+    }
+
+    public void setPrimaryKeyInValue(Boolean primaryKeyInValue) {
+      this.primaryKeyInValue = primaryKeyInValue;
+    }
+
+    public boolean isFieldMappingModified() {
+      return fieldMappingModified;
+    }
+
+    public List<ConnectorService.RegionMapping.FieldMapping> getFieldMapping() {
+      if (fieldMapping == null) {
+        fieldMapping = new ArrayList<>();
+      }
+      return fieldMapping;
+    }
+
+    public String getConnectionConfigName() {
+      return connectionConfigName;
+    }
+
+    public String getRegionName() {
+      return regionName;
+    }
+
+    public String getPdxClassName() {
+      return pdxClassName;
+    }
+
+    public String getTableName() {
+      return tableName;
+    }
+
+    public Boolean getPrimaryKeyInValue() {
+      return primaryKeyInValue;
+    }
+
+    public Boolean isPrimaryKeyInValue() {
+      return primaryKeyInValue;
+    }
+
+    public String getRegionToTableName() {
+      if (tableName == null) {
+        return regionName;
+      }
+      return tableName;
+    }
+
+    public String getColumnNameForField(String fieldName, TableMetaDataView tableMetaDataView) {
+      FieldMapping configured = getFieldMapping().stream()
+          .filter(m -> m.getFieldName().equals(fieldName)).findAny().orElse(null);
+      if (configured != null) {
+        return configured.getColumnName();
+      }
+
+      Set<String> columnNames = tableMetaDataView.getColumnNames();
+      if (columnNames.contains(fieldName)) {
+        return fieldName;
+      }
+
+      List<String> ignoreCaseMatch = columnNames.stream().filter(c -> c.equalsIgnoreCase(fieldName))
+          .collect(Collectors.toList());
+      if (ignoreCaseMatch.size() > 1) {
+        throw new JdbcConnectorException(
+            "The SQL table has at least two columns that match the PDX field: " + fieldName);
+      }
+
+      if (ignoreCaseMatch.size() == 1) {
+        return ignoreCaseMatch.get(0);
+      }
+
+      // there is no match either in the configured mapping or the table columns
+      return fieldName;
+    }
+
+    public String getFieldNameForColumn(String columnName, TypeRegistry typeRegistry) {
+      String fieldName = null;
+
+      FieldMapping configured = getFieldMapping().stream()
+          .filter(m -> m.getColumnName().equals(columnName)).findAny().orElse(null);
+
+      if (configured != null) {
+        return configured.getFieldName();
+      }
+
+      if (getPdxClassName() == null) {
+        if (columnName.equals(columnName.toUpperCase())) {
+          fieldName = columnName.toLowerCase();
+        } else {
+          fieldName = columnName;
+        }
+      } else {
+        Set<PdxType> pdxTypes = getPdxTypesForClassName(typeRegistry);
+        fieldName = findExactMatch(columnName, pdxTypes);
+        if (fieldName == null) {
+          fieldName = findCaseInsensitiveMatch(columnName, pdxTypes);
+        }
+      }
+      assert fieldName != null;
+
+      return fieldName;
+    }
+
+    private Set<PdxType> getPdxTypesForClassName(TypeRegistry typeRegistry) {
+      Set<PdxType> pdxTypes = typeRegistry.getPdxTypesForClassName(getPdxClassName());
+      if (pdxTypes.isEmpty()) {
+        throw new JdbcConnectorException(
+            "The class " + getPdxClassName() + " has not been pdx serialized.");
+      }
+      return pdxTypes;
+    }
+
+    /**
+     * Given a column name and a set of pdx types, find the field name in those types that match,
+     * ignoring case, the column name.
+     *
+     * @return the matching field name or null if no match
+     * @throws JdbcConnectorException if no fields match
+     * @throws JdbcConnectorException if more than one field matches
+     */
+    private String findCaseInsensitiveMatch(String columnName, Set<PdxType> pdxTypes) {
+      HashSet<String> matchingFieldNames = new HashSet<>();
+      for (PdxType pdxType : pdxTypes) {
+        for (String existingFieldName : pdxType.getFieldNames()) {
+          if (existingFieldName.equalsIgnoreCase(columnName)) {
+            matchingFieldNames.add(existingFieldName);
+          }
+        }
+      }
+      if (matchingFieldNames.isEmpty()) {
+        throw new JdbcConnectorException("The class " + getPdxClassName()
+            + " does not have a field that matches the column " + columnName);
+      } else if (matchingFieldNames.size() > 1) {
+        throw new JdbcConnectorException(
+            "Could not determine what pdx field to use for the column name " + columnName
+                + " because the pdx fields " + matchingFieldNames + " all match it.");
+      }
+      return matchingFieldNames.iterator().next();
+    }
+
+    /**
+     * Given a column name, search the given pdxTypes for a field whose name exactly matches the
+     * column name.
+     *
+     * @return the matching field name or null if no match
+     */
+    private String findExactMatch(String columnName, Set<PdxType> pdxTypes) {
+      for (PdxType pdxType : pdxTypes) {
+        if (pdxType.getPdxField(columnName) != null) {
+          return columnName;
+        }
+      }
+      return null;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+      if (this == o) {
+        return true;
+      }
+      if (o == null || getClass() != o.getClass()) {
+        return false;
+      }
+
+      RegionMapping that = (RegionMapping) o;
+
+      if (primaryKeyInValue != that.primaryKeyInValue) {
+        return false;
+      }
+      if (regionName != null ? !regionName.equals(that.regionName) : that.regionName != null) {
+        return false;
+      }
+      if (pdxClassName != null ? !pdxClassName.equals(that.pdxClassName)
+          : that.pdxClassName != null) {
+        return false;
+      }
+      if (tableName != null ? !tableName.equals(that.tableName) : that.tableName != null) {
+        return false;
+      }
+      if (connectionConfigName != null ? !connectionConfigName.equals(that.connectionConfigName)
+          : that.connectionConfigName != null) {
+        return false;
+      }
+      if (fieldMapping != null ? !fieldMapping.equals(that.fieldMapping)
+          : that.fieldMapping != null) {
+        return false;
+      }
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      int result = regionName != null ? regionName.hashCode() : 0;
+      result = 31 * result + (pdxClassName != null ? pdxClassName.hashCode() : 0);
+      result = 31 * result + (tableName != null ? tableName.hashCode() : 0);
+      result = 31 * result + (connectionConfigName != null ? connectionConfigName.hashCode() : 0);
+      result = 31 * result + (primaryKeyInValue ? 1 : 0);
+      return result;
+    }
+
+    @Override
+    public String toString() {
+      return "RegionMapping{" + "regionName='" + regionName + '\'' + ", pdxClassName='"
+          + pdxClassName + '\'' + ", tableName='" + tableName + '\'' + ", connectionConfigName='"
+          + connectionConfigName + '\'' + ", primaryKeyInValue=" + primaryKeyInValue + '}';
+    }
+
+    @Override
+    public String getId() {
+      return getRegionName();
+    }
+
+    @XmlAccessorType(XmlAccessType.FIELD)
+    public static class FieldMapping implements Serializable {
+      @XmlAttribute(name = "field-name")
+      protected String fieldName;
+      @XmlAttribute(name = "column-name")
+      protected String columnName;
+
+      public FieldMapping() {}
+
+      public FieldMapping(String fieldName, String columnName) {
+        this.fieldName = fieldName;
+        this.columnName = columnName;
+      }
+
+      /**
+       * Gets the value of the fieldName property.
+       *
+       * @return
+       *         possible object is
+       *         {@link String }
+       *
+       */
+      public String getFieldName() {
+        return fieldName;
+      }
+
+      /**
+       * Sets the value of the fieldName property.
+       *
+       * @param value
+       *        allowed object is
+       *        {@link String }
+       *
+       */
+      public void setFieldName(String value) {
+        this.fieldName = value;
+      }
+
+      /**
+       * Gets the value of the columnName property.
+       *
+       * @return
+       *         possible object is
+       *         {@link String }
+       *
+       */
+      public String getColumnName() {
+        return columnName;
+      }
+
+      /**
+       * Sets the value of the columnName property.
+       *
+       * @param value
+       *        allowed object is
+       *        {@link String }
+       *
+       */
+      public void setColumnName(String value) {
+        this.columnName = value;
+      }
+
+      @Override
+      public boolean equals(Object o) {
+        if (this == o)
+          return true;
+        if (o == null || getClass() != o.getClass())
+          return false;
+        FieldMapping that = (FieldMapping) o;
+        return Objects.equals(fieldName, that.fieldName)
+            && Objects.equals(columnName, that.columnName);
+      }
+
+      @Override
+      public int hashCode() {
+        int result = fieldName != null ? fieldName.hashCode() : 0;
+        result = 31 * result + (columnName != null ? columnName.hashCode() : 0);
+
+        return result;
+      }
+    }
+  }
+}
diff --git a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/configuration/package-info.java b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/configuration/package-info.java
new file mode 100644
index 0000000..59e8d5f
--- /dev/null
+++ b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/configuration/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+@XmlSchema(namespace = "http://geode.apache.org/schema/jdbc",
+    xmlns = {@XmlNs(prefix = "jdbc", namespaceURI = "http://geode.apache.org/schema/jdbc")},
+    elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
+package org.apache.geode.connectors.jdbc.internal.configuration;
+
+import javax.xml.bind.annotation.XmlNs;
+import javax.xml.bind.annotation.XmlSchema;
diff --git a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/xml/ElementType.java b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/xml/ElementType.java
index 716e15f..df99ab1 100644
--- a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/xml/ElementType.java
+++ b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/xml/ElementType.java
@@ -19,10 +19,7 @@ import java.util.Stack;
 import org.xml.sax.Attributes;
 
 import org.apache.geode.cache.CacheXmlException;
-import org.apache.geode.connectors.jdbc.internal.ConnectionConfigBuilder;
-import org.apache.geode.connectors.jdbc.internal.ConnectionConfiguration;
-import org.apache.geode.connectors.jdbc.internal.RegionMapping;
-import org.apache.geode.connectors.jdbc.internal.RegionMappingBuilder;
+import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
 import org.apache.geode.internal.cache.xmlcache.CacheCreation;
 
 public enum ElementType {
@@ -51,13 +48,13 @@ public enum ElementType {
         throw new CacheXmlException(
             "jdbc <connection> elements must occur within <connector-service> elements");
       }
-      ConnectionConfigBuilder connectionConfigBuilder = new ConnectionConfigBuilder()
-          .withName(attributes.getValue(JdbcConnectorServiceXmlParser.NAME))
-          .withUrl(attributes.getValue(JdbcConnectorServiceXmlParser.URL))
-          .withUser(attributes.getValue(JdbcConnectorServiceXmlParser.USER))
-          .withPassword(attributes.getValue(JdbcConnectorServiceXmlParser.PASSWORD))
-          .withParameters(parseParameters(attributes));
-      stack.push(connectionConfigBuilder);
+      ConnectorService.Connection connection = new ConnectorService.Connection();
+      connection.setName(attributes.getValue(JdbcConnectorServiceXmlParser.NAME));
+      connection.setUrl(attributes.getValue(JdbcConnectorServiceXmlParser.URL));
+      connection.setUser(attributes.getValue(JdbcConnectorServiceXmlParser.USER));
+      connection.setPassword(attributes.getValue(JdbcConnectorServiceXmlParser.PASSWORD));
+      connection.setParameters(parseParameters(attributes));
+      stack.push(connection);
     }
 
     private String[] parseParameters(Attributes attributes) {
@@ -71,7 +68,7 @@ public enum ElementType {
 
     @Override
     void endElement(Stack<Object> stack) {
-      ConnectionConfiguration config = ((ConnectionConfigBuilder) stack.pop()).build();
+      ConnectorService.Connection config = (ConnectorService.Connection) stack.pop();
       JdbcServiceConfiguration connectorService = (JdbcServiceConfiguration) stack.peek();
       connectorService.addConnectionConfig(config);
     }
@@ -83,20 +80,20 @@ public enum ElementType {
         throw new CacheXmlException(
             "jdbc <region-mapping> elements must occur within <connector-service> elements");
       }
-      RegionMappingBuilder mapping = new RegionMappingBuilder()
-          .withRegionName(attributes.getValue(JdbcConnectorServiceXmlParser.REGION))
-          .withConnectionConfigName(
-              attributes.getValue(JdbcConnectorServiceXmlParser.CONNECTION_NAME))
-          .withTableName(attributes.getValue(JdbcConnectorServiceXmlParser.TABLE))
-          .withPdxClassName(attributes.getValue(JdbcConnectorServiceXmlParser.PDX_CLASS))
-          .withPrimaryKeyInValue(
-              attributes.getValue(JdbcConnectorServiceXmlParser.PRIMARY_KEY_IN_VALUE));
+      ConnectorService.RegionMapping mapping = new ConnectorService.RegionMapping();
+      mapping.setRegionName(attributes.getValue(JdbcConnectorServiceXmlParser.REGION));
+      mapping.setConnectionConfigName(
+          attributes.getValue(JdbcConnectorServiceXmlParser.CONNECTION_NAME));
+      mapping.setTableName(attributes.getValue(JdbcConnectorServiceXmlParser.TABLE));
+      mapping.setPdxClassName(attributes.getValue(JdbcConnectorServiceXmlParser.PDX_CLASS));
+      mapping.setPrimaryKeyInValue(
+          Boolean.valueOf(attributes.getValue(JdbcConnectorServiceXmlParser.PRIMARY_KEY_IN_VALUE)));
       stack.push(mapping);
     }
 
     @Override
     void endElement(Stack<Object> stack) {
-      RegionMapping mapping = ((RegionMappingBuilder) stack.pop()).build();
+      ConnectorService.RegionMapping mapping = (ConnectorService.RegionMapping) stack.pop();
       JdbcServiceConfiguration connectorService = (JdbcServiceConfiguration) stack.peek();
       connectorService.addRegionMapping(mapping);
     }
@@ -104,14 +101,15 @@ public enum ElementType {
   FIELD_MAPPING("field-mapping") {
     @Override
     void startElement(Stack<Object> stack, Attributes attributes) {
-      if (!(stack.peek() instanceof RegionMappingBuilder)) {
+      if (!(stack.peek() instanceof ConnectorService.RegionMapping)) {
         throw new CacheXmlException(
             "jdbc <field-mapping> elements must occur within <region-mapping> elements");
       }
-      RegionMappingBuilder mapping = (RegionMappingBuilder) stack.peek();
-      String fieldName = attributes.getValue(JdbcConnectorServiceXmlParser.FIELD_NAME);
-      String columnName = attributes.getValue(JdbcConnectorServiceXmlParser.COLUMN_NAME);
-      mapping.withFieldToColumnMapping(fieldName, columnName);
+      ConnectorService.RegionMapping mapping = (ConnectorService.RegionMapping) stack.peek();
+      mapping.getFieldMapping()
+          .add(new ConnectorService.RegionMapping.FieldMapping(
+              attributes.getValue(JdbcConnectorServiceXmlParser.FIELD_NAME),
+              attributes.getValue(JdbcConnectorServiceXmlParser.COLUMN_NAME)));
     }
 
     @Override
diff --git a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/xml/JdbcConnectorServiceXmlGenerator.java b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/xml/JdbcConnectorServiceXmlGenerator.java
deleted file mode 100644
index 6006733..0000000
--- a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/xml/JdbcConnectorServiceXmlGenerator.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.connectors.jdbc.internal.xml;
-
-import static org.apache.geode.connectors.jdbc.internal.xml.JdbcConnectorServiceXmlParser.COLUMN_NAME;
-import static org.apache.geode.connectors.jdbc.internal.xml.JdbcConnectorServiceXmlParser.CONNECTION_NAME;
-import static org.apache.geode.connectors.jdbc.internal.xml.JdbcConnectorServiceXmlParser.FIELD_NAME;
-import static org.apache.geode.connectors.jdbc.internal.xml.JdbcConnectorServiceXmlParser.NAME;
-import static org.apache.geode.connectors.jdbc.internal.xml.JdbcConnectorServiceXmlParser.NAMESPACE;
-import static org.apache.geode.connectors.jdbc.internal.xml.JdbcConnectorServiceXmlParser.PARAMETERS;
-import static org.apache.geode.connectors.jdbc.internal.xml.JdbcConnectorServiceXmlParser.PARAMS_DELIMITER;
-import static org.apache.geode.connectors.jdbc.internal.xml.JdbcConnectorServiceXmlParser.PASSWORD;
-import static org.apache.geode.connectors.jdbc.internal.xml.JdbcConnectorServiceXmlParser.PDX_CLASS;
-import static org.apache.geode.connectors.jdbc.internal.xml.JdbcConnectorServiceXmlParser.PRIMARY_KEY_IN_VALUE;
-import static org.apache.geode.connectors.jdbc.internal.xml.JdbcConnectorServiceXmlParser.REGION;
-import static org.apache.geode.connectors.jdbc.internal.xml.JdbcConnectorServiceXmlParser.TABLE;
-import static org.apache.geode.connectors.jdbc.internal.xml.JdbcConnectorServiceXmlParser.URL;
-import static org.apache.geode.connectors.jdbc.internal.xml.JdbcConnectorServiceXmlParser.USER;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Map;
-
-import org.xml.sax.ContentHandler;
-import org.xml.sax.SAXException;
-import org.xml.sax.helpers.AttributesImpl;
-
-import org.apache.geode.cache.Cache;
-import org.apache.geode.connectors.jdbc.internal.ConnectionConfiguration;
-import org.apache.geode.connectors.jdbc.internal.RegionMapping;
-import org.apache.geode.internal.cache.xmlcache.CacheXmlGenerator;
-import org.apache.geode.internal.cache.xmlcache.XmlGenerator;
-import org.apache.geode.internal.cache.xmlcache.XmlGeneratorUtils;
-
-public class JdbcConnectorServiceXmlGenerator implements XmlGenerator<Cache> {
-
-  public static final String PREFIX = "jdbc";
-
-  private static final AttributesImpl EMPTY = new AttributesImpl();
-
-  private final Collection<ConnectionConfiguration> connections;
-  private final Collection<RegionMapping> mappings;
-
-  public JdbcConnectorServiceXmlGenerator(Collection<ConnectionConfiguration> connections,
-      Collection<RegionMapping> mappings) {
-    this.connections = connections != null ? connections : Collections.emptyList();
-    this.mappings = mappings != null ? mappings : Collections.emptyList();
-  }
-
-  @Override
-  public String getNamespaceUri() {
-    return NAMESPACE;
-  }
-
-  @Override
-  public void generate(CacheXmlGenerator cacheXmlGenerator) throws SAXException {
-    final ContentHandler handler = cacheXmlGenerator.getContentHandler();
-
-    handler.startPrefixMapping(PREFIX, NAMESPACE);
-    AttributesImpl attributes = new AttributesImpl();
-    XmlGeneratorUtils.addAttribute(attributes, NAME, ElementType.CONNECTION_SERVICE.getTypeName());
-    XmlGeneratorUtils.startElement(handler, PREFIX, ElementType.CONNECTION_SERVICE.getTypeName(),
-        attributes);
-    for (ConnectionConfiguration connection : connections) {
-      outputConnectionConfiguration(handler, connection);
-    }
-    for (RegionMapping mapping : mappings) {
-      outputRegionMapping(handler, mapping);
-    }
-    XmlGeneratorUtils.endElement(handler, PREFIX, ElementType.CONNECTION_SERVICE.getTypeName());
-  }
-
-  /**
-   * For testing only
-   */
-  Collection<ConnectionConfiguration> getConnections() {
-    return connections;
-  }
-
-  /**
-   * For testing only
-   */
-  Collection<RegionMapping> getMappings() {
-    return mappings;
-  }
-
-  private void outputConnectionConfiguration(ContentHandler handler, ConnectionConfiguration config)
-      throws SAXException {
-    AttributesImpl attributes = new AttributesImpl();
-    XmlGeneratorUtils.addAttribute(attributes, NAME, config.getName());
-    XmlGeneratorUtils.addAttribute(attributes, URL, config.getUrl());
-    if (config.getUser() != null) {
-      XmlGeneratorUtils.addAttribute(attributes, USER, config.getUser());
-    }
-    if (config.getPassword() != null) {
-      XmlGeneratorUtils.addAttribute(attributes, PASSWORD, config.getPassword());
-    }
-    if (config.getParameters() != null) {
-      XmlGeneratorUtils.addAttribute(attributes, PARAMETERS, createParametersString(config));
-    }
-    XmlGeneratorUtils.emptyElement(handler, PREFIX, ElementType.CONNECTION.getTypeName(),
-        attributes);
-  }
-
-  private void outputRegionMapping(ContentHandler handler, RegionMapping mapping)
-      throws SAXException {
-    AttributesImpl attributes = new AttributesImpl();
-    XmlGeneratorUtils.addAttribute(attributes, CONNECTION_NAME, mapping.getConnectionConfigName());
-    XmlGeneratorUtils.addAttribute(attributes, REGION, mapping.getRegionName());
-    if (mapping.getTableName() != null) {
-      XmlGeneratorUtils.addAttribute(attributes, TABLE, mapping.getTableName());
-    }
-    if (mapping.getPdxClassName() != null) {
-      XmlGeneratorUtils.addAttribute(attributes, PDX_CLASS, mapping.getPdxClassName());
-    }
-    if (mapping.isPrimaryKeyInValue() != null) {
-      XmlGeneratorUtils.addAttribute(attributes, PRIMARY_KEY_IN_VALUE,
-          Boolean.toString(mapping.isPrimaryKeyInValue()));
-    }
-
-    XmlGeneratorUtils.startElement(handler, PREFIX, ElementType.REGION_MAPPING.getTypeName(),
-        attributes);
-    addFieldMappings(handler, mapping.getFieldToColumnMap());
-    XmlGeneratorUtils.endElement(handler, PREFIX, ElementType.REGION_MAPPING.getTypeName());
-  }
-
-  private void addFieldMappings(ContentHandler handler, Map<String, String> fieldMappings)
-      throws SAXException {
-    if (fieldMappings == null) {
-      return;
-    }
-    for (Map.Entry<String, String> fieldMapping : fieldMappings.entrySet()) {
-      AttributesImpl fieldAttributes = new AttributesImpl();
-      XmlGeneratorUtils.addAttribute(fieldAttributes, FIELD_NAME, fieldMapping.getKey());
-      XmlGeneratorUtils.addAttribute(fieldAttributes, COLUMN_NAME, fieldMapping.getValue());
-      XmlGeneratorUtils.emptyElement(handler, PREFIX, ElementType.FIELD_MAPPING.getTypeName(),
-          fieldAttributes);
-    }
-  }
-
-  private String createParametersString(ConnectionConfiguration config) {
-    assert config.getParameters() != null;
-    StringBuilder stringBuilder = new StringBuilder();
-    for (Map.Entry<String, String> entry : config.getParameters().entrySet()) {
-      if (stringBuilder.length() > 0) {
-        stringBuilder.append(",");
-      }
-      stringBuilder.append(entry.getKey()).append(PARAMS_DELIMITER).append(entry.getValue());
-    }
-    return stringBuilder.toString();
-  }
-}
diff --git a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/xml/JdbcServiceConfiguration.java b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/xml/JdbcServiceConfiguration.java
index 3426c81..7eb21fd 100644
--- a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/xml/JdbcServiceConfiguration.java
+++ b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/xml/JdbcServiceConfiguration.java
@@ -20,10 +20,9 @@ import java.util.List;
 import org.apache.geode.InternalGemFireException;
 import org.apache.geode.cache.Cache;
 import org.apache.geode.connectors.jdbc.internal.ConnectionConfigExistsException;
-import org.apache.geode.connectors.jdbc.internal.ConnectionConfiguration;
 import org.apache.geode.connectors.jdbc.internal.JdbcConnectorService;
-import org.apache.geode.connectors.jdbc.internal.RegionMapping;
 import org.apache.geode.connectors.jdbc.internal.RegionMappingExistsException;
+import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
 import org.apache.geode.internal.cache.InternalCache;
 import org.apache.geode.internal.cache.extension.Extensible;
 import org.apache.geode.internal.cache.extension.Extension;
@@ -31,20 +30,20 @@ import org.apache.geode.internal.cache.xmlcache.XmlGenerator;
 
 public class JdbcServiceConfiguration implements Extension<Cache> {
 
-  private final List<ConnectionConfiguration> connections = new ArrayList<>();
-  private final List<RegionMapping> mappings = new ArrayList<>();
+  private final List<ConnectorService.Connection> connections = new ArrayList<>();
+  private final List<ConnectorService.RegionMapping> mappings = new ArrayList<>();
 
-  void addConnectionConfig(ConnectionConfiguration config) {
+  void addConnectionConfig(ConnectorService.Connection config) {
     connections.add(config);
   }
 
-  void addRegionMapping(RegionMapping mapping) {
+  void addRegionMapping(ConnectorService.RegionMapping mapping) {
     mappings.add(mapping);
   }
 
   @Override
   public XmlGenerator<Cache> getXmlGenerator() {
-    return new JdbcConnectorServiceXmlGenerator(connections, mappings);
+    return null;
   }
 
   @Override
@@ -61,7 +60,7 @@ public class JdbcServiceConfiguration implements Extension<Cache> {
   }
 
   private void createConnectionConfig(JdbcConnectorService service,
-      ConnectionConfiguration connectionConfig) {
+      ConnectorService.Connection connectionConfig) {
     try {
       service.createConnectionConfig(connectionConfig);
     } catch (ConnectionConfigExistsException e) {
@@ -69,7 +68,8 @@ public class JdbcServiceConfiguration implements Extension<Cache> {
     }
   }
 
-  private void createRegionMapping(JdbcConnectorService service, RegionMapping regionMapping) {
+  private void createRegionMapping(JdbcConnectorService service,
+      ConnectorService.RegionMapping regionMapping) {
     try {
       service.createRegionMapping(regionMapping);
     } catch (RegionMappingExistsException e) {
diff --git a/geode-connectors/src/main/resources/META-INF/schemas/geode.apache.org/schema/jdbc/jdbc-1.0.xsd b/geode-connectors/src/main/resources/META-INF/schemas/geode.apache.org/schema/jdbc/jdbc-1.0.xsd
index 712ce44..31e05a8 100644
--- a/geode-connectors/src/main/resources/META-INF/schemas/geode.apache.org/schema/jdbc/jdbc-1.0.xsd
+++ b/geode-connectors/src/main/resources/META-INF/schemas/geode.apache.org/schema/jdbc/jdbc-1.0.xsd
@@ -17,16 +17,11 @@
   -->
 <xsd:schema
         targetNamespace="http://geode.apache.org/schema/jdbc"
-        xmlns:gf="http://geode.apache.org/schema/cache"
         xmlns:xsd="http://www.w3.org/2001/XMLSchema"
         elementFormDefault="qualified"
         attributeFormDefault="unqualified"
         version="1.0">
 
-    <xsd:import
-            namespace="http://geode.apache.org/schema/cache"
-            schemaLocation="http://geode.apache.org/schema/cache/cache-1.0.xsd"/>
-
     <xsd:annotation>
         <xsd:documentation><![CDATA[
 XML schema for JDBC Connector Service in Geode.
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 d35a3b7..dc3081c 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
@@ -1,18 +1,16 @@
 org/apache/geode/connectors/jdbc/JdbcConnectorException,true,1
 org/apache/geode/connectors/jdbc/internal/ConnectionConfigExistsException,false
 org/apache/geode/connectors/jdbc/internal/ConnectionConfigNotFoundException,false
-org/apache/geode/connectors/jdbc/internal/ConnectionConfiguration,false,name:java/lang/String,parameters:java/util/Map,password:java/lang/String,url:java/lang/String,user:java/lang/String
-org/apache/geode/connectors/jdbc/internal/RegionMapping,false,columnToFieldMap:java/util/concurrent/ConcurrentMap,configuredColumnToFieldMap:java/util/Map,configuredFieldToColumnMap:java/util/Map,connectionConfigName:java/lang/String,fieldToColumnMap:java/util/concurrent/ConcurrentMap,pdxClassName:java/lang/String,primaryKeyInValue:java/lang/Boolean,regionName:java/lang/String,tableName:java/lang/String
 org/apache/geode/connectors/jdbc/internal/RegionMappingExistsException,false
 org/apache/geode/connectors/jdbc/internal/RegionMappingNotFoundException,false
 org/apache/geode/connectors/jdbc/internal/cli/AlterConnectionFunction,false
 org/apache/geode/connectors/jdbc/internal/cli/AlterMappingFunction,false
 org/apache/geode/connectors/jdbc/internal/cli/CreateConnectionFunction,false
 org/apache/geode/connectors/jdbc/internal/cli/CreateMappingFunction,false
-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
+org/apache/geode/connectors/jdbc/internal/configuration/ConnectorService$Connection,false,name:java/lang/String,parameterMap:java/util/Map,parameters:java/lang/String,password:java/lang/String,url:java/lang/String,user:java/lang/String
+org/apache/geode/connectors/jdbc/internal/configuration/ConnectorService$RegionMapping,false,connectionConfigName:java/lang/String,fieldMapping:java/util/List,fieldMappingModified:boolean,pdxClassName:java/lang/String,primaryKeyInValue:java/lang/Boolean,regionName:java/lang/String,tableName:java/lang/String
+org/apache/geode/connectors/jdbc/internal/configuration/ConnectorService$RegionMapping$FieldMapping,false,columnName:java/lang/String,fieldName:java/lang/String
diff --git a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/ConnectionConfigBuilderTest.java b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/ConnectionConfigBuilderTest.java
deleted file mode 100644
index 5234dff..0000000
--- a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/ConnectionConfigBuilderTest.java
+++ /dev/null
@@ -1,90 +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;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
-
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-
-import org.apache.geode.test.junit.categories.UnitTest;
-
-@Category(UnitTest.class)
-public class ConnectionConfigBuilderTest {
-
-  @Test
-  public void createsAllNullObjectIfNothingSet() {
-    ConnectionConfiguration config = new ConnectionConfigBuilder().build();
-
-    assertThat(config.getName()).isNull();
-    assertThat(config.getUrl()).isNull();
-    assertThat(config.getUser()).isNull();
-    assertThat(config.getPassword()).isNull();
-  }
-
-  @Test
-  public void createsObjectWithCorrectValues() {
-    ConnectionConfiguration config = new ConnectionConfigBuilder().withName("name").withUrl("url")
-        .withUser("user").withPassword("password")
-        .withParameters(new String[] {"param1:value1", "param2:value2"}).build();
-
-    assertThat(config.getName()).isEqualTo("name");
-    assertThat(config.getUrl()).isEqualTo("url");
-    assertThat(config.getUser()).isEqualTo("user");
-    assertThat(config.getPassword()).isEqualTo("password");
-    assertThat(config.getConnectionProperties()).containsEntry("param1", "value1")
-        .containsEntry("param2", "value2");
-  }
-
-  @Test
-  public void createsObjectWithEmptyParameterElement() {
-    ConnectionConfiguration config = new ConnectionConfigBuilder().withName("name").withUrl("url")
-        .withUser("user").withPassword("password")
-        .withParameters(new String[] {"param1:value1", "", "param2:value2"}).build();
-
-    assertThat(config.getName()).isEqualTo("name");
-    assertThat(config.getUrl()).isEqualTo("url");
-    assertThat(config.getUser()).isEqualTo("user");
-    assertThat(config.getPassword()).isEqualTo("password");
-    assertThat(config.getConnectionProperties()).containsEntry("param1", "value1")
-        .containsEntry("param2", "value2");
-  }
-
-  @Test
-  public void createsObjectWithNullParameters() {
-    ConnectionConfiguration config =
-        new ConnectionConfigBuilder().withName("name").withUrl("url").withParameters(null).build();
-
-    assertThat(config.getName()).isEqualTo("name");
-    assertThat(config.getUrl()).isEqualTo("url");
-    assertThat(config.getParameters()).isNull();
-  }
-
-  @Test
-  public void throwsExceptionWithInvalidParams() {
-    ConnectionConfigBuilder config = new ConnectionConfigBuilder();
-    assertThatThrownBy(() -> config.withParameters(new String[] {"param1value1"}))
-        .isInstanceOf(IllegalArgumentException.class);
-    assertThatThrownBy(() -> config.withParameters(new String[] {":param1value1"}))
-        .isInstanceOf(IllegalArgumentException.class);
-    assertThatThrownBy(() -> config.withParameters(new String[] {"param1value1:"}))
-        .isInstanceOf(IllegalArgumentException.class);
-    assertThatThrownBy(() -> config.withParameters(new String[] {"1:2:3"}))
-        .isInstanceOf(IllegalArgumentException.class);
-    assertThatThrownBy(() -> config.withParameters(new String[] {":"}))
-        .isInstanceOf(IllegalArgumentException.class);
-  }
-}
diff --git a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/ConnectionConfigurationTest.java b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/ConnectionConfigurationTest.java
deleted file mode 100644
index 23ca0ae..0000000
--- a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/ConnectionConfigurationTest.java
+++ /dev/null
@@ -1,96 +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;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-
-import org.apache.geode.test.junit.categories.UnitTest;
-
-@Category(UnitTest.class)
-public class ConnectionConfigurationTest {
-
-  private String name;
-  private String url;
-  private String user;
-  private String password;
-  private Map<String, String> parameters;
-
-  private ConnectionConfiguration config;
-
-  @Before
-  public void setUp() {
-    name = "name";
-    url = "url";
-    user = "username";
-    password = "secret";
-
-    parameters = new HashMap<>();
-    parameters.put("param1", "value1");
-    parameters.put("param2", "value2");
-
-    config = new ConnectionConfiguration(null, null, null, null, null);
-  }
-
-  @Test
-  public void initiatedWithNullValues() {
-    assertThat(config.getName()).isNull();
-    assertThat(config.getUrl()).isNull();
-    assertThat(config.getUser()).isNull();
-    assertThat(config.getPassword()).isNull();
-  }
-
-  @Test
-  public void hasCorrectName() {
-    config = new ConnectionConfiguration(name, null, null, null, null);
-
-    assertThat(config.getName()).isEqualTo(name);
-  }
-
-  @Test
-  public void hasCorrectUrl() {
-    config = new ConnectionConfiguration(null, url, null, null, null);
-
-    assertThat(config.getUrl()).isEqualTo(url);
-  }
-
-  @Test
-  public void hasCorrectUser() {
-    config = new ConnectionConfiguration(null, null, user, null, null);
-
-    assertThat(config.getUser()).isEqualTo(user);
-  }
-
-  @Test
-  public void hasCorrectPassword() {
-    config = new ConnectionConfiguration(null, null, null, password, null);
-
-    assertThat(config.getPassword()).isEqualTo(password);
-  }
-
-  @Test
-  public void hasCorrectProperties() {
-    config = new ConnectionConfiguration(null, null, null, null, parameters);
-
-    assertThat(config.getConnectionProperties()).containsEntry("param1", "value1")
-        .containsEntry("param2", "value2");
-  }
-}
diff --git a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/DataSourceManagerUnitTest.java b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/DataSourceManagerUnitTest.java
index 05a422a..e93dd61 100644
--- a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/DataSourceManagerUnitTest.java
+++ b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/DataSourceManagerUnitTest.java
@@ -25,6 +25,7 @@ import org.junit.Before;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 
+import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
 import org.apache.geode.test.junit.categories.UnitTest;
 
 @Category(UnitTest.class)
@@ -35,8 +36,8 @@ public class DataSourceManagerUnitTest {
   private JdbcDataSource dataSource;
   private JdbcDataSource dataSource2;
 
-  private ConnectionConfiguration connectionConfig;
-  private ConnectionConfiguration connectionConfig2;
+  private ConnectorService.Connection connectionConfig;
+  private ConnectorService.Connection connectionConfig2;
 
   @Before
   public void setup() throws Exception {
@@ -44,8 +45,10 @@ public class DataSourceManagerUnitTest {
     JdbcDataSourceFactory dataSourceFactory = mock(JdbcDataSourceFactory.class);
     when(dataSourceFactory.create(any())).thenReturn(dataSource);
     manager = new DataSourceManager(dataSourceFactory);
-    connectionConfig = new ConnectionConfiguration("dataSource1", "url", null, null, null);
-    connectionConfig2 = new ConnectionConfiguration("dataSource2", "url", null, null, null);
+    connectionConfig =
+        new ConnectorService.Connection("dataSource1", "url", null, null, (String[]) null);
+    connectionConfig2 =
+        new ConnectorService.Connection("dataSource2", "url", null, null, (String[]) null);
 
     dataSource2 = mock(JdbcDataSource.class);
     doThrow(new Exception()).when(dataSource2).close();
diff --git a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/JdbcConnectorServiceTest.java b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/JdbcConnectorServiceTest.java
index 03e5d32..23e5a06 100644
--- a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/JdbcConnectorServiceTest.java
+++ b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/JdbcConnectorServiceTest.java
@@ -19,13 +19,11 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
-import java.util.HashMap;
-import java.util.Map;
-
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 
+import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
 import org.apache.geode.internal.cache.InternalCache;
 import org.apache.geode.internal.cache.extension.ExtensionPoint;
 import org.apache.geode.test.junit.categories.UnitTest;
@@ -36,23 +34,21 @@ public class JdbcConnectorServiceTest {
   private static final String TEST_CONFIG_NAME = "testConfig";
   private static final String TEST_REGION_NAME = "testRegion";
 
-  private ConnectionConfiguration config;
-  private ConnectionConfiguration config2;
-  private ConnectionConfiguration configToAlter;
-  private RegionMapping mapping;
+  private ConnectorService.Connection config;
+  private ConnectorService.Connection config2;
+  private ConnectorService.Connection configToAlter;
+  private ConnectorService.RegionMapping mapping;
 
   private JdbcConnectorServiceImpl service;
 
   @Before
   public void setUp() throws Exception {
     InternalCache cache = mock(InternalCache.class);
-    config = mock(ConnectionConfiguration.class);
-    mapping = mock(RegionMapping.class);
-    config2 = mock(ConnectionConfiguration.class);
-    Map<String, String> parameters = new HashMap<>();
-    parameters.put("key1", "value1");
-    parameters.put("key2", "value2");
-    configToAlter = new ConnectionConfiguration(TEST_CONFIG_NAME, "originalUrl", "originalUser",
+    config = mock(ConnectorService.Connection.class);
+    mapping = mock(ConnectorService.RegionMapping.class);
+    config2 = mock(ConnectorService.Connection.class);
+    String[] parameters = new String[] {"key1:value1", "key2:value2"};
+    configToAlter = new ConnectorService.Connection(TEST_CONFIG_NAME, "originalUrl", "originalUser",
         "originalPassword", parameters);
 
     when(cache.getExtensionPoint()).thenReturn(mock(ExtensionPoint.class));
diff --git a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/RegionMappingBuilderTest.java b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/RegionMappingBuilderTest.java
deleted file mode 100644
index 7861b7d..0000000
--- a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/RegionMappingBuilderTest.java
+++ /dev/null
@@ -1,119 +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;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
-import static org.mockito.Mockito.mock;
-
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-
-import org.apache.geode.test.junit.categories.UnitTest;
-
-@Category(UnitTest.class)
-public class RegionMappingBuilderTest {
-
-  @Test
-  public void createsMappingWithDefaultValuesIfNonAreSet() {
-    RegionMapping regionMapping = new RegionMappingBuilder().build();
-
-    assertThat(regionMapping.getRegionName()).isNull();
-    assertThat(regionMapping.getTableName()).isNull();
-    assertThat(regionMapping.getPdxClassName()).isNull();
-    assertThat(regionMapping.getConnectionConfigName()).isNull();
-    assertThat(regionMapping.isPrimaryKeyInValue()).isNull();
-  }
-
-  @Test
-  public void createsMappingWithSpecifiedValues() {
-    RegionMapping regionMapping = new RegionMappingBuilder().withTableName("tableName")
-        .withRegionName("regionName").withPrimaryKeyInValue("true").withPdxClassName("pdxClassName")
-        .withConnectionConfigName("configName").withFieldToColumnMapping("fieldName", "columnName")
-        .build();
-
-    assertThat(regionMapping.getRegionName()).isEqualTo("regionName");
-    assertThat(regionMapping.getTableName()).isEqualTo("tableName");
-    assertThat(regionMapping.getPdxClassName()).isEqualTo("pdxClassName");
-    assertThat(regionMapping.getConnectionConfigName()).isEqualTo("configName");
-    assertThat(regionMapping.isPrimaryKeyInValue()).isTrue();
-    assertThat(regionMapping.getColumnNameForField("fieldName", mock(TableMetaDataView.class)))
-        .isEqualTo("columnName");
-  }
-
-  @Test
-  public void createsMappingWithNullAsPrimaryKeyInValue() {
-    RegionMapping regionMapping = new RegionMappingBuilder().withRegionName("regionName")
-        .withConnectionConfigName("configName").withPrimaryKeyInValue((String) null).build();
-
-    assertThat(regionMapping.getRegionName()).isEqualTo("regionName");
-    assertThat(regionMapping.getConnectionConfigName()).isEqualTo("configName");
-    assertThat(regionMapping.isPrimaryKeyInValue()).isNull();
-  }
-
-  @Test
-  public void createsMappingWithNullFieldToColumnMappings() {
-    RegionMapping regionMapping = new RegionMappingBuilder().withRegionName("regionName")
-        .withConnectionConfigName("configName").withFieldToColumnMappings(null).build();
-
-    assertThat(regionMapping.getRegionName()).isEqualTo("regionName");
-    assertThat(regionMapping.getConnectionConfigName()).isEqualTo("configName");
-    assertThat(regionMapping.getFieldToColumnMap()).isNull();
-  }
-
-  @Test
-  public void createsFieldMappingsFromArray() {
-    String[] fieldMappings = new String[] {"field1:column1", "field2:column2"};
-    RegionMapping regionMapping =
-        new RegionMappingBuilder().withFieldToColumnMappings(fieldMappings).build();
-
-    assertThat(regionMapping.getColumnNameForField("field1", mock(TableMetaDataView.class)))
-        .isEqualTo("column1");
-    assertThat(regionMapping.getColumnNameForField("field2", mock(TableMetaDataView.class)))
-        .isEqualTo("column2");
-  }
-
-  @Test
-  public void createsFieldMappingsFromArrayWithEmptyElement() {
-    String[] fieldMappings = new String[] {"field1:column1", "", "field2:column2"};
-    RegionMapping regionMapping =
-        new RegionMappingBuilder().withFieldToColumnMappings(fieldMappings).build();
-
-    assertThat(regionMapping.getColumnNameForField("field1", mock(TableMetaDataView.class)))
-        .isEqualTo("column1");
-    assertThat(regionMapping.getColumnNameForField("field2", mock(TableMetaDataView.class)))
-        .isEqualTo("column2");
-  }
-
-  @Test
-  public void throwsExceptionForInvalidFieldMappings() {
-    RegionMappingBuilder regionMappingbuilder = new RegionMappingBuilder();
-
-    assertThatThrownBy(
-        () -> regionMappingbuilder.withFieldToColumnMappings(new String[] {"field1column1"}))
-            .isInstanceOf(IllegalArgumentException.class);
-    assertThatThrownBy(
-        () -> regionMappingbuilder.withFieldToColumnMappings(new String[] {":field1column1"}))
-            .isInstanceOf(IllegalArgumentException.class);
-    assertThatThrownBy(
-        () -> regionMappingbuilder.withFieldToColumnMappings(new String[] {"field1:column1:extra"}))
-            .isInstanceOf(IllegalArgumentException.class);
-    assertThatThrownBy(
-        () -> regionMappingbuilder.withFieldToColumnMappings(new String[] {"field1column1:"}))
-            .isInstanceOf(IllegalArgumentException.class);
-    assertThatThrownBy(() -> regionMappingbuilder.withFieldToColumnMappings(new String[] {":"}))
-        .isInstanceOf(IllegalArgumentException.class);
-  }
-}
diff --git a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/RegionMappingTest.java b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/RegionMappingTest.java
index 307fb08..e67893a 100644
--- a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/RegionMappingTest.java
+++ b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/RegionMappingTest.java
@@ -20,9 +20,7 @@ import static org.mockito.Mockito.when;
 
 import java.util.Arrays;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.HashSet;
-import java.util.Map;
 
 import org.junit.Before;
 import org.junit.Rule;
@@ -31,6 +29,7 @@ import org.junit.experimental.categories.Category;
 import org.junit.rules.ExpectedException;
 
 import org.apache.geode.connectors.jdbc.JdbcConnectorException;
+import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
 import org.apache.geode.pdx.internal.PdxField;
 import org.apache.geode.pdx.internal.PdxType;
 import org.apache.geode.pdx.internal.TypeRegistry;
@@ -48,9 +47,7 @@ public class RegionMappingTest {
   private String fieldName2;
   private String columnName2;
 
-  private Map<String, String> fieldMap;
-
-  private RegionMapping mapping;
+  private ConnectorService.RegionMapping mapping;
 
   @Before
   public void setUp() {
@@ -59,20 +56,24 @@ public class RegionMappingTest {
     columnName1 = "myColumn1";
     fieldName2 = "myField2";
     columnName2 = "myColumn2";
+  }
 
-    fieldMap = new HashMap<>();
-
+  @Test
+  public void emptyArrayFiledMapping() {
+    mapping = new ConnectorService.RegionMapping("region", "class", "table", "connection", false);
+    mapping.setFieldMapping(new String[0]);
+    assertThat(mapping.isFieldMappingModified()).isTrue();
+    assertThat(mapping.getFieldMapping()).isEmpty();
   }
 
   @Test
   public void initiatedWithNullValues() {
-    mapping = new RegionMapping(null, null, null, null, false, null);
+    mapping = new ConnectorService.RegionMapping(null, null, null, null, false);
 
     assertThat(mapping.getTableName()).isNull();
     assertThat(mapping.getRegionName()).isNull();
     assertThat(mapping.getConnectionConfigName()).isNull();
     assertThat(mapping.getPdxClassName()).isNull();
-    assertThat(mapping.getFieldToColumnMap()).isNull();
     assertThat(mapping.getRegionToTableName()).isNull();
     assertThat(mapping.getColumnNameForField("fieldName", mock(TableMetaDataView.class)))
         .isEqualTo("fieldName");
@@ -82,7 +83,7 @@ public class RegionMappingTest {
 
   @Test
   public void hasCorrectTableName() {
-    mapping = new RegionMapping(null, null, name, null, false, null);
+    mapping = new ConnectorService.RegionMapping(null, null, name, null, false);
 
     assertThat(mapping.getTableName()).isEqualTo(name);
     assertThat(mapping.getRegionToTableName()).isEqualTo(name);
@@ -90,7 +91,7 @@ public class RegionMappingTest {
 
   @Test
   public void hasCorrectTableNameWhenRegionNameIsSet() {
-    mapping = new RegionMapping("regionName", null, "tableName", null, false, null);
+    mapping = new ConnectorService.RegionMapping("regionName", null, "tableName", null, false);
 
     assertThat(mapping.getRegionName()).isEqualTo("regionName");
     assertThat(mapping.getTableName()).isEqualTo("tableName");
@@ -99,7 +100,7 @@ public class RegionMappingTest {
 
   @Test
   public void hasCorrectRegionName() {
-    mapping = new RegionMapping(name, null, null, null, false, null);
+    mapping = new ConnectorService.RegionMapping(name, null, null, null, false);
 
     assertThat(mapping.getRegionName()).isEqualTo(name);
     assertThat(mapping.getRegionToTableName()).isEqualTo(name);
@@ -107,34 +108,29 @@ public class RegionMappingTest {
 
   @Test
   public void hasCorrectConfigName() {
-    mapping = new RegionMapping(null, null, null, name, false, null);
+    mapping = new ConnectorService.RegionMapping(null, null, null, name, false);
 
     assertThat(mapping.getConnectionConfigName()).isEqualTo(name);
   }
 
   @Test
   public void hasCorrectPdxClassName() {
-    mapping = new RegionMapping(null, name, null, null, false, null);
+    mapping = new ConnectorService.RegionMapping(null, name, null, null, false);
 
     assertThat(mapping.getPdxClassName()).isEqualTo(name);
   }
 
   @Test
   public void primaryKeyInValueSetCorrectly() {
-    mapping = new RegionMapping(null, null, null, null, true, null);
+    mapping = new ConnectorService.RegionMapping(null, null, null, null, true);
 
     assertThat(mapping.isPrimaryKeyInValue()).isTrue();
   }
 
   @Test
   public void returnsColumnNameIfFieldNotMapped() {
-    fieldMap.put("otherField", "column");
-    mapping = new RegionMapping(null, null, null, null, true, fieldMap);
-    Map<String, String> expectedFieldMap = new HashMap<>(fieldMap);
-    expectedFieldMap.put(fieldName1, fieldName1);
-    Map<String, String> expectedColumnMap = new HashMap<>();
-    expectedColumnMap.put("column", "otherField");
-    expectedColumnMap.put(fieldName1, fieldName1);
+    mapping = new ConnectorService.RegionMapping(null, null, null, null, true);
+    mapping.setFieldMapping(new String[] {"otherField:column"});
 
     String columnName = mapping.getColumnNameForField(fieldName1, mock(TableMetaDataView.class));
 
@@ -143,9 +139,9 @@ public class RegionMappingTest {
 
   @Test
   public void returnsColumnNameFromTableMetaDataIfFieldNotMappedAndMetaDataMatchesWithCaseDiffering() {
-    fieldMap.put("otherField", "column");
     String metaDataColumnName = fieldName1.toUpperCase();
-    mapping = new RegionMapping(null, null, null, null, true, fieldMap);
+    mapping = new ConnectorService.RegionMapping(null, null, null, null, true);
+    mapping.setFieldMapping(new String[] {"otherField:column"});
     TableMetaDataView tableMetaDataView = mock(TableMetaDataView.class);
     when(tableMetaDataView.getColumnNames()).thenReturn(Collections.singleton(metaDataColumnName));
 
@@ -155,9 +151,9 @@ public class RegionMappingTest {
 
   @Test
   public void returnsColumnNameFromTableMetaDataIfFieldNotMappedAndMetaDataMatchesExactly() {
-    fieldMap.put("otherField", "column");
     String metaDataColumnName = fieldName1;
-    mapping = new RegionMapping(null, null, null, null, true, fieldMap);
+    mapping = new ConnectorService.RegionMapping(null, null, null, null, true);
+    mapping.setFieldMapping(new String[] {"otherField:column"});
     TableMetaDataView tableMetaDataView = mock(TableMetaDataView.class);
     when(tableMetaDataView.getColumnNames()).thenReturn(Collections.singleton(metaDataColumnName));
 
@@ -167,8 +163,8 @@ public class RegionMappingTest {
 
   @Test
   public void returnsColumnNameIfFieldNotMappedAndNotInMetaData() {
-    fieldMap.put("otherField", "column");
-    mapping = new RegionMapping(null, null, null, null, true, fieldMap);
+    mapping = new ConnectorService.RegionMapping(null, null, null, null, true);
+    mapping.setFieldMapping(new String[] {"otherField:column"});
     TableMetaDataView tableMetaDataView = mock(TableMetaDataView.class);
     when(tableMetaDataView.getColumnNames()).thenReturn(Collections.singleton("does not match"));
 
@@ -177,8 +173,9 @@ public class RegionMappingTest {
 
   @Test
   public void getColumnNameForFieldThrowsIfTwoColumnsMatchField() {
-    fieldMap.put("otherField", "column");
-    mapping = new RegionMapping(null, null, null, null, true, fieldMap);
+    mapping = new ConnectorService.RegionMapping(null, null, null, null, true);
+    mapping.setFieldMapping(new String[] {"otherField:column"});
+
     TableMetaDataView tableMetaDataView = mock(TableMetaDataView.class);
     HashSet<String> columnNames =
         new HashSet<>(Arrays.asList(fieldName1.toUpperCase(), fieldName1.toLowerCase()));
@@ -193,27 +190,24 @@ public class RegionMappingTest {
 
   @Test
   public void ifMixedCaseColumnNameNotMappedReturnsItAsFieldName() {
-    fieldMap.put("otherField", "column");
-
-    mapping = new RegionMapping(null, null, null, null, true, fieldMap);
+    mapping = new ConnectorService.RegionMapping(null, null, null, null, true);
+    mapping.setFieldMapping(new String[] {"otherField:column"});
 
     assertThat(mapping.getFieldNameForColumn("columnName", null)).isEqualTo("columnName");
   }
 
   @Test
   public void ifLowerCaseColumnNameNotMappedReturnsItAsFieldName() {
-    fieldMap.put("otherField", "column");
-
-    mapping = new RegionMapping(null, null, null, null, true, fieldMap);
+    mapping = new ConnectorService.RegionMapping(null, null, null, null, true);
+    mapping.setFieldMapping(new String[] {"otherField:column"});
 
     assertThat(mapping.getFieldNameForColumn("columnname", null)).isEqualTo("columnname");
   }
 
   @Test
   public void ifUpperCaseColumnNameNotMappedReturnsItLowerCasedAsFieldName() {
-    fieldMap.put("otherField", "column");
-
-    mapping = new RegionMapping(null, null, null, null, true, fieldMap);
+    mapping = new ConnectorService.RegionMapping(null, null, null, null, true);
+    mapping.setFieldMapping(new String[] {"otherField:column"});
 
     assertThat(mapping.getFieldNameForColumn("COLUMNNAME", null)).isEqualTo("columnname");
   }
@@ -221,7 +215,7 @@ public class RegionMappingTest {
 
   @Test
   public void throwsIfColumnNotMappedAndPdxClassNameDoesNotExist() {
-    mapping = new RegionMapping(null, "pdxClassName", null, null, true, null);
+    mapping = new ConnectorService.RegionMapping(null, "pdxClassName", null, null, true);
     TypeRegistry typeRegistry = mock(TypeRegistry.class);
     when(typeRegistry.getPdxTypesForClassName("pdxClassName")).thenReturn(Collections.emptySet());
     expectedException.expect(JdbcConnectorException.class);
@@ -234,7 +228,7 @@ public class RegionMappingTest {
   public void throwsIfColumnNotMappedAndPdxClassNameDoesExistButHasNoMatchingFields() {
     String pdxClassName = "pdxClassName";
     String columnName = "columnName";
-    mapping = new RegionMapping(null, pdxClassName, null, null, true, null);
+    mapping = new ConnectorService.RegionMapping(null, pdxClassName, null, null, true);
     TypeRegistry typeRegistry = mock(TypeRegistry.class);
     HashSet<PdxType> pdxTypes = new HashSet<>(Arrays.asList(mock(PdxType.class)));
     when(typeRegistry.getPdxTypesForClassName(pdxClassName)).thenReturn(pdxTypes);
@@ -249,7 +243,7 @@ public class RegionMappingTest {
   public void throwsIfColumnNotMappedAndPdxClassNameDoesExistButHasMoreThanOneMatchingFields() {
     String pdxClassName = "pdxClassName";
     String columnName = "columnName";
-    mapping = new RegionMapping(null, pdxClassName, null, null, true, null);
+    mapping = new ConnectorService.RegionMapping(null, pdxClassName, null, null, true);
     TypeRegistry typeRegistry = mock(TypeRegistry.class);
     PdxType pdxType = mock(PdxType.class);
     when(pdxType.getFieldNames())
@@ -267,7 +261,7 @@ public class RegionMappingTest {
   public void returnsIfColumnNotMappedAndPdxClassNameDoesExistAndHasOneFieldThatInexactlyMatches() {
     String pdxClassName = "pdxClassName";
     String columnName = "columnName";
-    mapping = new RegionMapping(null, pdxClassName, null, null, true, null);
+    mapping = new ConnectorService.RegionMapping(null, pdxClassName, null, null, true);
     TypeRegistry typeRegistry = mock(TypeRegistry.class);
     PdxType pdxType = mock(PdxType.class);
     when(pdxType.getFieldNames())
@@ -283,7 +277,7 @@ public class RegionMappingTest {
   public void returnsIfColumnNotMappedAndPdxClassNameDoesExistAndHasOneFieldThatExactlyMatches() {
     String pdxClassName = "pdxClassName";
     String columnName = "columnName";
-    mapping = new RegionMapping(null, pdxClassName, null, null, true, null);
+    mapping = new ConnectorService.RegionMapping(null, pdxClassName, null, null, true);
     TypeRegistry typeRegistry = mock(TypeRegistry.class);
     PdxType pdxType = mock(PdxType.class);
     when(pdxType.getPdxField(columnName)).thenReturn(mock(PdxField.class));
@@ -295,9 +289,8 @@ public class RegionMappingTest {
 
   @Test
   public void returnsMappedColumnNameForField() {
-    fieldMap.put(fieldName1, columnName1);
-
-    mapping = new RegionMapping(null, null, null, null, true, fieldMap);
+    mapping = new ConnectorService.RegionMapping(null, null, null, null, true);
+    mapping.setFieldMapping(new String[] {fieldName1 + ":" + columnName1});
 
     assertThat(mapping.getColumnNameForField(fieldName1, mock(TableMetaDataView.class)))
         .isEqualTo(columnName1);
@@ -305,8 +298,9 @@ public class RegionMappingTest {
 
   @Test
   public void returnsMappedColumnNameForFieldEvenIfMetaDataMatches() {
-    fieldMap.put(fieldName1, columnName1);
-    mapping = new RegionMapping(null, null, null, null, true, fieldMap);
+    mapping = new ConnectorService.RegionMapping(null, null, null, null, true);
+    mapping.setFieldMapping(new String[] {fieldName1 + ":" + columnName1});
+
     TableMetaDataView tableMetaDataView = mock(TableMetaDataView.class);
     when(tableMetaDataView.getColumnNames()).thenReturn(Collections.singleton(fieldName1));
 
@@ -315,17 +309,17 @@ public class RegionMappingTest {
 
   @Test
   public void returnsMappedFieldNameForColumn() {
-    fieldMap.put(fieldName1, columnName1);
-
-    mapping = new RegionMapping(null, null, null, null, true, fieldMap);
+    mapping = new ConnectorService.RegionMapping(null, null, null, null, true);
+    mapping.setFieldMapping(new String[] {fieldName1 + ":" + columnName1});
 
     assertThat(mapping.getFieldNameForColumn(columnName1, null)).isEqualTo(fieldName1);
   }
 
   @Test
   public void returnsCachedFieldNameForColumn() {
-    fieldMap.put(fieldName1, columnName1);
-    mapping = new RegionMapping(null, null, null, null, true, fieldMap);
+    mapping = new ConnectorService.RegionMapping(null, null, null, null, true);
+    mapping.setFieldMapping(new String[] {fieldName1 + ":" + columnName1});
+
     TableMetaDataView tableMetaDataView = mock(TableMetaDataView.class);
 
     mapping.getColumnNameForField(fieldName1, tableMetaDataView);
@@ -335,8 +329,9 @@ public class RegionMappingTest {
 
   @Test
   public void returnsCachedColumnNameForField() {
-    fieldMap.put(fieldName1, columnName1);
-    mapping = new RegionMapping(null, null, null, null, true, fieldMap);
+    mapping = new ConnectorService.RegionMapping(null, null, null, null, true);
+    mapping.setFieldMapping(new String[] {fieldName1 + ":" + columnName1});
+
     mapping.getFieldNameForColumn(columnName1, null);
 
     TableMetaDataView tableMetaDataView = mock(TableMetaDataView.class);
@@ -346,67 +341,60 @@ public class RegionMappingTest {
 
   @Test
   public void returnsAllMappings() {
-    fieldMap.put(fieldName1, columnName1);
-    fieldMap.put(fieldName2, columnName2);
-    mapping = new RegionMapping(null, null, null, null, true, fieldMap);
-
-    Map<String, String> actualFieldMap = mapping.getFieldToColumnMap();
+    mapping = new ConnectorService.RegionMapping(null, null, null, null, true);
+    mapping.setFieldMapping(
+        new String[] {fieldName1 + ":" + columnName1, fieldName2 + ":" + columnName2});
 
-    assertThat(actualFieldMap).isEqualTo(fieldMap);
-  }
-
-  @Test
-  public void regionMappingFailsForInvalidFieldToColumnMapping() {
-    fieldMap.put(fieldName1, columnName1);
-    fieldMap.put(fieldName2, columnName1);
-    expectedException.expect(IllegalArgumentException.class);
-    new RegionMapping(null, null, null, null, true, fieldMap);
+    assertThat(mapping.getFieldMapping()).hasSize(2);
+    assertThat(mapping.getFieldMapping().get(0).getFieldName()).isEqualTo("myField1");
+    assertThat(mapping.getFieldMapping().get(0).getColumnName()).isEqualTo("myColumn1");
+    assertThat(mapping.getFieldMapping().get(1).getFieldName()).isEqualTo("myField2");
+    assertThat(mapping.getFieldMapping().get(1).getColumnName()).isEqualTo("myColumn2");
   }
 
   @Test
   public void verifyTwoNonDefaultInstancesAreEqual() {
-    fieldMap.put(fieldName1, columnName1);
-    fieldMap.put(fieldName2, columnName2);
-    RegionMapping rm1 = new RegionMapping("regionName", "pdxClassName", "tableName",
-        "connectionName", true, fieldMap);
-    RegionMapping rm2 = new RegionMapping("regionName", "pdxClassName", "tableName",
-        "connectionName", true, fieldMap);
+    ConnectorService.RegionMapping rm1 = new ConnectorService.RegionMapping("regionName",
+        "pdxClassName", "tableName", "connectionName", true);
+    rm1.setFieldMapping(
+        new String[] {fieldName1 + ":" + columnName1, fieldName2 + ":" + columnName2});
+
+    ConnectorService.RegionMapping rm2 = new ConnectorService.RegionMapping("regionName",
+        "pdxClassName", "tableName", "connectionName", true);
+    rm2.setFieldMapping(
+        new String[] {fieldName1 + ":" + columnName1, fieldName2 + ":" + columnName2});
+
     assertThat(rm1).isEqualTo(rm2);
   }
 
   @Test
   public void verifyTwoDefaultInstancesAreEqual() {
-    RegionMapping rm1 = new RegionMapping("regionName", null, null, "connectionName", false, null);
-    RegionMapping rm2 = new RegionMapping("regionName", null, null, "connectionName", false, null);
+    ConnectorService.RegionMapping rm1 =
+        new ConnectorService.RegionMapping("regionName", null, null, "connectionName", false);
+    ConnectorService.RegionMapping rm2 =
+        new ConnectorService.RegionMapping("regionName", null, null, "connectionName", false);
     assertThat(rm1).isEqualTo(rm2);
   }
 
-  @Test
-  public void verifyTwoSimiliarInstancesAreNotEqual() {
-    fieldMap.put(fieldName1, columnName1);
-    fieldMap.put(fieldName2, columnName2);
-    RegionMapping rm1 = new RegionMapping("regionName", "pdxClassName", "tableName",
-        "connectionName", true, fieldMap);
-    RegionMapping rm2 =
-        new RegionMapping("regionName", "pdxClassName", "tableName", "connectionName", true, null);
-    assertThat(rm1).isNotEqualTo(rm2);
-  }
-
 
   @Test
   public void verifyTwoInstancesThatAreEqualHaveSameHashCode() {
-    fieldMap.put(fieldName1, columnName1);
-    fieldMap.put(fieldName2, columnName2);
-    RegionMapping rm1 = new RegionMapping("regionName", "pdxClassName", "tableName",
-        "connectionName", true, fieldMap);
-    RegionMapping rm2 = new RegionMapping("regionName", "pdxClassName", "tableName",
-        "connectionName", true, fieldMap);
+    ConnectorService.RegionMapping rm1 = new ConnectorService.RegionMapping("regionName",
+        "pdxClassName", "tableName", "connectionName", true);
+    rm1.setFieldMapping(
+        new String[] {fieldName1 + ":" + columnName1, fieldName2 + ":" + columnName2});
+
+    ConnectorService.RegionMapping rm2 = new ConnectorService.RegionMapping("regionName",
+        "pdxClassName", "tableName", "connectionName", true);
+    rm1.setFieldMapping(
+        new String[] {fieldName1 + ":" + columnName1, fieldName2 + ":" + columnName2});
+
     assertThat(rm1.hashCode()).isEqualTo(rm2.hashCode());
   }
 
   @Test
   public void verifyThatMappingIsEqualToItself() {
-    mapping = new RegionMapping(null, null, null, null, false, null);
+    mapping = new ConnectorService.RegionMapping(null, null, null, null, false);
     boolean result = mapping.equals(mapping);
     assertThat(mapping.hashCode()).isEqualTo(mapping.hashCode());
     assertThat(result).isTrue();
@@ -414,70 +402,36 @@ public class RegionMappingTest {
 
   @Test
   public void verifyThatNullIsNotEqual() {
-    mapping = new RegionMapping(null, null, null, null, false, null);
+    mapping = new ConnectorService.RegionMapping(null, null, null, null, false);
     boolean result = mapping.equals(null);
     assertThat(result).isFalse();
   }
 
   @Test
   public void verifyOtherClassIsNotEqual() {
-    mapping = new RegionMapping(null, null, null, null, false, null);
+    mapping = new ConnectorService.RegionMapping(null, null, null, null, false);
     boolean result = mapping.equals("not equal");
     assertThat(result).isFalse();
   }
 
   @Test
   public void verifyMappingWithDifferentRegionNamesAreNotEqual() {
-    RegionMapping rm1 = new RegionMapping(null, null, null, null, false, null);
-    RegionMapping rm2 = new RegionMapping("name", null, null, null, false, null);
+    ConnectorService.RegionMapping rm1 =
+        new ConnectorService.RegionMapping(null, null, null, null, false);
+    ConnectorService.RegionMapping rm2 =
+        new ConnectorService.RegionMapping("name", null, null, null, false);
     boolean result = rm1.equals(rm2);
     assertThat(result).isFalse();
   }
 
   @Test
   public void verifyMappingWithDifferentPdxClassNameAreNotEqual() {
-    RegionMapping rm1 = new RegionMapping(null, null, null, null, false, null);
-    RegionMapping rm2 = new RegionMapping(null, "pdxClass", null, null, false, null);
+    ConnectorService.RegionMapping rm1 =
+        new ConnectorService.RegionMapping(null, null, null, null, false);
+    ConnectorService.RegionMapping rm2 =
+        new ConnectorService.RegionMapping(null, "pdxClass", null, null, false);
     boolean result = rm1.equals(rm2);
     assertThat(result).isFalse();
   }
 
-  @Test
-  public void verifyMappingWithDifferentFieldMappingAreNotEqual() {
-    Map<String, String> fieldMap1 = new HashMap<>();
-    Map<String, String> fieldMap2 = new HashMap<>();
-    fieldMap1.put(fieldName1, columnName1);
-    fieldMap2.put(fieldName2, columnName2);
-
-    RegionMapping rm1 = new RegionMapping("name", "pdxClass", "tname", "cc", true, fieldMap1);
-    RegionMapping rm2 = new RegionMapping("name", "pdxClass", "tname", "cc", true, fieldMap2);
-    boolean result = rm1.equals(rm2);
-    assertThat(result).isFalse();
-  }
-
-  @Test
-  public void verifyMappingWithOneFieldMappingNullAreNotEqual() {
-    Map<String, String> fieldMap1 = new HashMap<>();
-
-    RegionMapping rm1 = new RegionMapping("name", "pdxClass", "tname", "cc", true, fieldMap1);
-    RegionMapping rm2 = new RegionMapping("name", "pdxClass", "tname", "cc", true, null);
-    boolean result = rm1.equals(rm2);
-    assertThat(result).isFalse();
-
-    rm1 = new RegionMapping("name", "pdxClass", "tname", "cc", true, null);
-    rm2 = new RegionMapping("name", "pdxClass", "tname", "cc", true, fieldMap1);
-    result = rm1.equals(rm2);
-    assertThat(result).isFalse();
-  }
-
-  @Test
-  public void verifyToStringForExpectedMessage() {
-    mapping = new RegionMapping("name", "pdxClass", "tname", "cc", true, null);
-
-    String result = mapping.toString();
-    System.out.println("DEBUG:" + result);
-
-    assertThat(result).contains("RegionMapping{regionName='");
-  }
-
 }
diff --git a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/SqlHandlerTest.java b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/SqlHandlerTest.java
index 7bc3301..23dcc75 100644
--- a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/SqlHandlerTest.java
+++ b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/SqlHandlerTest.java
@@ -47,6 +47,7 @@ import org.apache.geode.InternalGemFireException;
 import org.apache.geode.cache.Operation;
 import org.apache.geode.cache.Region;
 import org.apache.geode.connectors.jdbc.JdbcConnectorException;
+import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
 import org.apache.geode.internal.cache.InternalCache;
 import org.apache.geode.pdx.internal.PdxInstanceImpl;
 import org.apache.geode.pdx.internal.PdxType;
@@ -65,7 +66,7 @@ public class SqlHandlerTest {
 
   private DataSourceManager manager;
   private JdbcDataSource dataSource;
-  private ConnectionConfiguration connectionConfig;
+  private ConnectorService.Connection connectionConfig;
   private JdbcConnectorService connectorService;
   private TableMetaDataManager tableMetaDataManager;
   private TableMetaDataView tableMetaDataView;
@@ -74,7 +75,7 @@ public class SqlHandlerTest {
   private InternalCache cache;
   private SqlHandler handler;
   private PreparedStatement statement;
-  private RegionMapping regionMapping;
+  private ConnectorService.RegionMapping regionMapping;
   private PdxInstanceImpl value;
   private Object key;
 
@@ -83,7 +84,7 @@ public class SqlHandlerTest {
   public void setup() throws Exception {
     manager = mock(DataSourceManager.class);
     dataSource = mock(JdbcDataSource.class);
-    connectionConfig = mock(ConnectionConfiguration.class);
+    connectionConfig = mock(ConnectorService.Connection.class);
     when(connectionConfig.getName()).thenReturn(CONNECTION_CONFIG_NAME);
     when(connectionConfig.getUrl()).thenReturn("fake:url");
     region = mock(Region.class);
@@ -105,7 +106,7 @@ public class SqlHandlerTest {
 
     when(connectorService.getConnectionConfig(CONNECTION_CONFIG_NAME)).thenReturn(connectionConfig);
 
-    regionMapping = mock(RegionMapping.class);
+    regionMapping = mock(ConnectorService.RegionMapping.class);
     when(regionMapping.getConnectionConfigName()).thenReturn(CONNECTION_CONFIG_NAME);
     when(regionMapping.getRegionName()).thenReturn(REGION_NAME);
     when(regionMapping.getTableName()).thenReturn(TABLE_NAME);
@@ -145,7 +146,7 @@ public class SqlHandlerTest {
     @SuppressWarnings("unchecked")
     Region<Object, Object> region2 = mock(Region.class);
     when(region2.getName()).thenReturn("region2");
-    RegionMapping regionMapping2 = mock(RegionMapping.class);
+    ConnectorService.RegionMapping regionMapping2 = mock(ConnectorService.RegionMapping.class);
     when(regionMapping2.getConnectionConfigName()).thenReturn("bogus connection name");
     when(regionMapping2.getRegionName()).thenReturn("region2");
     when(connectorService.getMappingForRegion("region2")).thenReturn(regionMapping2);
diff --git a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/SqlToPdxInstanceCreatorTest.java b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/SqlToPdxInstanceCreatorTest.java
index d9b5250..655f4cb 100644
--- a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/SqlToPdxInstanceCreatorTest.java
+++ b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/SqlToPdxInstanceCreatorTest.java
@@ -43,6 +43,7 @@ import org.junit.rules.ExpectedException;
 import org.junit.runner.RunWith;
 
 import org.apache.geode.connectors.jdbc.JdbcConnectorException;
+import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
 import org.apache.geode.internal.cache.InternalCache;
 import org.apache.geode.pdx.FieldType;
 import org.apache.geode.pdx.PdxInstance;
@@ -65,7 +66,7 @@ public class SqlToPdxInstanceCreatorTest {
   private static final String PDX_FIELD_NAME_2 = COLUMN_NAME_2.toLowerCase();
 
   private InternalCache cache;
-  private RegionMapping regionMapping;
+  private ConnectorService.RegionMapping regionMapping;
   private ResultSet resultSet;
   private TableMetaDataView tableMetaDataView;
 
@@ -75,7 +76,7 @@ public class SqlToPdxInstanceCreatorTest {
   @Before
   public void setup() throws Exception {
     cache = mock(InternalCache.class);
-    regionMapping = mock(RegionMapping.class);
+    regionMapping = mock(ConnectorService.RegionMapping.class);
     resultSet = mock(ResultSet.class);
     tableMetaDataView = mock(TableMetaDataView.class);
     when(tableMetaDataView.getKeyColumnName()).thenReturn(KEY_COLUMN);
diff --git a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/TestConfigService.java b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/TestConfigService.java
index 4e2aacf..d9b47c2 100644
--- a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/TestConfigService.java
+++ b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/TestConfigService.java
@@ -17,8 +17,7 @@ package org.apache.geode.connectors.jdbc.internal;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
-import java.util.Collections;
-
+import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
 import org.apache.geode.internal.cache.InternalCache;
 import org.apache.geode.internal.cache.extension.ExtensionPoint;
 
@@ -52,12 +51,14 @@ public class TestConfigService {
     return cache;
   }
 
-  private static RegionMapping createRegionMapping(String pdxClassName, boolean primaryKeyInValue) {
-    return new RegionMapping(REGION_NAME, pdxClassName, REGION_TABLE_NAME, CONNECTION_CONFIG_NAME,
-        primaryKeyInValue, Collections.emptyMap());
+  private static ConnectorService.RegionMapping createRegionMapping(String pdxClassName,
+      boolean primaryKeyInValue) {
+    return new ConnectorService.RegionMapping(REGION_NAME, pdxClassName, REGION_TABLE_NAME,
+        CONNECTION_CONFIG_NAME, primaryKeyInValue);
   }
 
-  private static ConnectionConfiguration createConnectionConfig(String connectionUrl) {
-    return new ConnectionConfiguration(CONNECTION_CONFIG_NAME, connectionUrl, null, null, null);
+  private static ConnectorService.Connection createConnectionConfig(String connectionUrl) {
+    return new ConnectorService.Connection(CONNECTION_CONFIG_NAME, connectionUrl, null, null,
+        (String[]) null);
   }
 }
diff --git a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/AlterConnectionCommandDUnitTest.java b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/AlterConnectionCommandDUnitTest.java
index 1f1dbe2..fa43fba 100644
--- a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/AlterConnectionCommandDUnitTest.java
+++ b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/AlterConnectionCommandDUnitTest.java
@@ -33,8 +33,8 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 
-import org.apache.geode.connectors.jdbc.internal.ConnectionConfiguration;
 import org.apache.geode.connectors.jdbc.internal.JdbcConnectorService;
+import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
 import org.apache.geode.distributed.internal.InternalLocator;
 import org.apache.geode.internal.cache.InternalCache;
 import org.apache.geode.management.internal.cli.util.CommandStringBuilder;
@@ -86,7 +86,6 @@ public class AlterConnectionCommandDUnitTest {
     csb.addOption(ALTER_CONNECTION__PARAMS, "Key1:Value1,Key22:Value22");
     gfsh.executeAndAssertThat(csb.toString()).statusIsSuccess();
 
-
     locator.invoke(() -> {
       String xml = InternalLocator.getLocator().getSharedConfiguration().getConfiguration("cluster")
           .getCacheXmlContent();
@@ -95,7 +94,7 @@ public class AlterConnectionCommandDUnitTest {
 
     server.invoke(() -> {
       InternalCache cache = ClusterStartupRule.getCache();
-      ConnectionConfiguration config =
+      ConnectorService.Connection config =
           cache.getService(JdbcConnectorService.class).getConnectionConfig("name");
       assertThat(config.getUrl()).isEqualTo("newUrl");
       assertThat(config.getUser()).isEqualTo("newUsername");
@@ -124,12 +123,14 @@ public class AlterConnectionCommandDUnitTest {
 
     server.invoke(() -> {
       InternalCache cache = ClusterStartupRule.getCache();
-      ConnectionConfiguration config =
+      ConnectorService.Connection config =
           cache.getService(JdbcConnectorService.class).getConnectionConfig("name");
       assertThat(config.getUrl()).isNull();
       assertThat(config.getUser()).isNull();
       assertThat(config.getPassword()).isNull();
       assertThat(config.getConnectionProperties()).hasSize(0);
     });
+
+    startupRule.startServerVM(2, locator.getPort());
   }
 }
diff --git a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/AlterConnectionCommandIntegrationTest.java b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/AlterConnectionCommandIntegrationTest.java
index b0266e8..fa52781 100644
--- a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/AlterConnectionCommandIntegrationTest.java
+++ b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/AlterConnectionCommandIntegrationTest.java
@@ -23,8 +23,8 @@ import org.junit.Test;
 import org.junit.experimental.categories.Category;
 
 import org.apache.geode.cache.CacheFactory;
-import org.apache.geode.connectors.jdbc.internal.ConnectionConfiguration;
 import org.apache.geode.connectors.jdbc.internal.JdbcConnectorService;
+import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
 import org.apache.geode.internal.cache.InternalCache;
 import org.apache.geode.management.cli.Result;
 import org.apache.geode.test.junit.categories.IntegrationTest;
@@ -69,7 +69,7 @@ public class AlterConnectionCommandIntegrationTest {
     assertThat(result.getStatus()).isSameAs(Result.Status.OK);
 
     JdbcConnectorService service = cache.getService(JdbcConnectorService.class);
-    ConnectionConfiguration connectionConfig = service.getConnectionConfig(name);
+    ConnectorService.Connection connectionConfig = service.getConnectionConfig(name);
 
     assertThat(connectionConfig).isNotNull();
     assertThat(connectionConfig.getName()).isEqualTo(name);
diff --git a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/AlterConnectionCommandTest.java b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/AlterConnectionCommandTest.java
new file mode 100644
index 0000000..207e199
--- /dev/null
+++ b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/AlterConnectionCommandTest.java
@@ -0,0 +1,147 @@
+/*
+ * 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 static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
+import org.apache.geode.distributed.ClusterConfigurationService;
+import org.apache.geode.distributed.internal.InternalClusterConfigurationService;
+import org.apache.geode.management.internal.cli.GfshParseResult;
+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;
+
+@Category(UnitTest.class)
+public class AlterConnectionCommandTest {
+  public static final String COMMAND = "alter jdbc-connection --name=name ";
+  private AlterConnectionCommand command;
+  private List<CliFunctionResult> results;
+  private CliFunctionResult result;
+  private ClusterConfigurationService ccService;
+
+  @ClassRule
+  public static GfshParserRule gfsh = new GfshParserRule();
+
+  @Before
+  public void setUp() throws Exception {
+    results = new ArrayList<>();
+    command = spy(AlterConnectionCommand.class);
+    doReturn(Collections.EMPTY_SET).when(command).getMembers(any(), any());
+    doReturn(results).when(command).executeAndGetFunctionResult(any(), any(), any());
+    result = mock(CliFunctionResult.class);
+    when(result.isSuccessful()).thenReturn(true);
+    when(result.getMemberIdOrName()).thenReturn("memberName");
+    when(result.getStatus()).thenReturn("message");
+    ccService = mock(InternalClusterConfigurationService.class);
+    doReturn(ccService).when(command).getConfigurationService();
+  }
+
+  @Test
+  public void requiredParameter() {
+    gfsh.executeAndAssertThat(command, "alter jdbc-connection").statusIsError()
+        .containsOutput("Invalid command");
+  }
+
+  @Test
+  public void whenValuesNotSpecified() {
+    GfshParseResult result = gfsh.parse(COMMAND);
+    assertThat(result.getParamValue("url")).isNull();
+    assertThat(result.getParamValue("user")).isNull();
+    assertThat(result.getParamValue("password")).isNull();
+    assertThat(result.getParamValue("params")).isNull();
+  }
+
+  @Test
+  public void whenValuesSpecifiedAsEmptyString() {
+    GfshParseResult result = gfsh.parse(COMMAND + " --url='' --user='' --password='' --params=''");
+    assertThat(result.getParamValue("url")).isEqualTo("");
+    assertThat(result.getParamValue("user")).isEqualTo("");
+    assertThat(result.getParamValue("password")).isEqualTo("");
+    assertThat(result.getParamValue("params")).isEqualTo(new String[] {""});
+  }
+
+  @Test
+  public void whenCCServiceIsNotAvailable() {
+    doReturn(null).when(command).getConfigurationService();
+    results.add(result);
+    gfsh.executeAndAssertThat(command, COMMAND).statusIsSuccess();
+    verify(command).executeAndGetFunctionResult(any(), any(), any());
+  }
+
+  @Test
+  public void whenCCServiceIsRunningAndNoConnectorServiceFound() {
+    gfsh.executeAndAssertThat(command, COMMAND).statusIsError()
+        .containsOutput("connection with name 'name' does not exist.");
+    verify(command, times(0)).executeAndGetFunctionResult(any(), any(), any());
+  }
+
+  @Test
+  public void whenCCServiceIsRunningAndNoConnectionFound() {
+    ConnectorService connectorService = mock(ConnectorService.class);
+    when(ccService.getCustomCacheElement(any(), any(), any())).thenReturn(connectorService);
+    gfsh.executeAndAssertThat(command, COMMAND).statusIsError()
+        .containsOutput("connection with name 'name' does not exist.");
+    verify(command, times(0)).executeAndGetFunctionResult(any(), any(), any());
+  }
+
+  @Test
+  public void noSuccessfulResult() {
+    // connection found in CC
+    ConnectorService connectorService = mock(ConnectorService.class);
+    when(ccService.getCustomCacheElement(any(), any(), any())).thenReturn(connectorService);
+    when(ccService.findIdentifiable(any(), any()))
+        .thenReturn(mock(ConnectorService.Connection.class));
+
+    // result is not successful
+    when(result.isSuccessful()).thenReturn(false);
+    results.add(result);
+
+    gfsh.executeAndAssertThat(command, COMMAND).statusIsError();
+    verify(command).executeAndGetFunctionResult(any(), any(), any());
+  }
+
+  @Test
+  public void successfulResult() {
+    // connection found in CC
+    ConnectorService connectorService = mock(ConnectorService.class);
+    when(ccService.getCustomCacheElement(any(), any(), any())).thenReturn(connectorService);
+    when(ccService.findIdentifiable(any(), any()))
+        .thenReturn(mock(ConnectorService.Connection.class));
+
+    // result is not successful
+    when(result.isSuccessful()).thenReturn(true);
+    results.add(result);
+
+    gfsh.executeAndAssertThat(command, COMMAND).statusIsSuccess();
+    verify(command).executeAndGetFunctionResult(any(), any(), any());
+  }
+}
diff --git a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/AlterConnectionFunctionTest.java b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/AlterConnectionFunctionTest.java
index 7ca2a31..7a32ea2 100644
--- a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/AlterConnectionFunctionTest.java
+++ b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/AlterConnectionFunctionTest.java
@@ -26,7 +26,6 @@ import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import java.io.Serializable;
-import java.util.HashMap;
 import java.util.Map;
 
 import org.apache.commons.lang.SerializationUtils;
@@ -37,10 +36,9 @@ import org.mockito.ArgumentCaptor;
 
 import org.apache.geode.cache.execute.FunctionContext;
 import org.apache.geode.cache.execute.ResultSender;
-import org.apache.geode.connectors.jdbc.internal.ConnectionConfigBuilder;
 import org.apache.geode.connectors.jdbc.internal.ConnectionConfigNotFoundException;
-import org.apache.geode.connectors.jdbc.internal.ConnectionConfiguration;
 import org.apache.geode.connectors.jdbc.internal.JdbcConnectorService;
+import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
 import org.apache.geode.distributed.DistributedMember;
 import org.apache.geode.distributed.DistributedSystem;
 import org.apache.geode.internal.cache.InternalCache;
@@ -52,10 +50,10 @@ public class AlterConnectionFunctionTest {
 
   private static final String CONNECTION_NAME = "theConnection";
 
-  private ConnectionConfiguration connectionConfig;
-  private ConnectionConfiguration existingConfig;
-  private ConnectionConfiguration configToAlter;
-  private FunctionContext<ConnectionConfiguration> context;
+  private ConnectorService.Connection connectionConfig;
+  private ConnectorService.Connection existingConfig;
+  private ConnectorService.Connection configToAlter;
+  private FunctionContext<ConnectorService.Connection> context;
   private ResultSender<Object> resultSender;
   private JdbcConnectorService service;
 
@@ -70,12 +68,12 @@ public class AlterConnectionFunctionTest {
     DistributedMember distributedMember = mock(DistributedMember.class);
     service = mock(JdbcConnectorService.class);
 
-    connectionConfig = new ConnectionConfigBuilder().withName(CONNECTION_NAME).build();
-    existingConfig = new ConnectionConfigBuilder().withName(CONNECTION_NAME).build();
-    Map<String, String> parameters = new HashMap<>();
-    parameters.put("key1", "value1");
-    parameters.put("key2", "value2");
-    configToAlter = new ConnectionConfiguration(CONNECTION_NAME, "originalUrl", "originalUser",
+    connectionConfig =
+        new ConnectorService.Connection(CONNECTION_NAME, null, null, null, (String) null);
+    existingConfig =
+        new ConnectorService.Connection(CONNECTION_NAME, null, null, null, (String) null);
+    String[] parameters = {"key1:value1", "key2:value2"};
+    configToAlter = new ConnectorService.Connection(CONNECTION_NAME, "originalUrl", "originalUser",
         "originalPassword", parameters);
 
     when(context.getResultSender()).thenReturn(resultSender);
@@ -139,84 +137,110 @@ public class AlterConnectionFunctionTest {
 
   @Test
   public void alterConnectionConfigUrl() {
-    ConnectionConfiguration newConfigValues =
-        new ConnectionConfiguration(CONNECTION_NAME, "newUrl", null, null, null);
+    ConnectorService.Connection newConfigValues =
+        new ConnectorService.Connection(CONNECTION_NAME, "newUrl", null, null, (String[]) null);
 
-    ConnectionConfiguration alteredConfig =
+    ConnectorService.Connection alteredConfig =
         function.alterConnectionConfig(newConfigValues, configToAlter);
 
     assertThat(alteredConfig.getName()).isEqualTo(CONNECTION_NAME);
     assertThat(alteredConfig.getUrl()).isEqualTo("newUrl");
     assertThat(alteredConfig.getUser()).isEqualTo("originalUser");
     assertThat(alteredConfig.getPassword()).isEqualTo("originalPassword");
-    Map<String, String> parameters = alteredConfig.getParameters();
+    Map<String, String> parameters = alteredConfig.getParameterMap();
     assertThat(parameters).containsOnly(entry("key1", "value1"), entry("key2", "value2"));
   }
 
   @Test
   public void alterConnectionConfigUser() {
-    ConnectionConfiguration newConfigValues =
-        new ConnectionConfiguration(CONNECTION_NAME, null, "newUser", null, null);
+    ConnectorService.Connection newConfigValues =
+        new ConnectorService.Connection(CONNECTION_NAME, null, "newUser", null, (String[]) null);
 
-    ConnectionConfiguration alteredConfig =
+    ConnectorService.Connection alteredConfig =
         function.alterConnectionConfig(newConfigValues, configToAlter);
 
     assertThat(alteredConfig.getName()).isEqualTo(CONNECTION_NAME);
     assertThat(alteredConfig.getUrl()).isEqualTo("originalUrl");
     assertThat(alteredConfig.getUser()).isEqualTo("newUser");
     assertThat(alteredConfig.getPassword()).isEqualTo("originalPassword");
-    assertThat(alteredConfig.getParameters()).containsOnly(entry("key1", "value1"),
+    assertThat(alteredConfig.getParameterMap()).containsOnly(entry("key1", "value1"),
         entry("key2", "value2"));
   }
 
   @Test
   public void alterConnectionConfigPassword() {
-    ConnectionConfiguration newConfigValues =
-        new ConnectionConfiguration(CONNECTION_NAME, null, null, "newPassword", null);
+    ConnectorService.Connection newConfigValues = new ConnectorService.Connection(CONNECTION_NAME,
+        null, null, "newPassword", (String[]) null);
 
-    ConnectionConfiguration alteredConfig =
+    ConnectorService.Connection alteredConfig =
         function.alterConnectionConfig(newConfigValues, configToAlter);
 
     assertThat(alteredConfig.getName()).isEqualTo(CONNECTION_NAME);
     assertThat(alteredConfig.getUrl()).isEqualTo("originalUrl");
     assertThat(alteredConfig.getUser()).isEqualTo("originalUser");
     assertThat(alteredConfig.getPassword()).isEqualTo("newPassword");
-    assertThat(alteredConfig.getParameters()).containsOnly(entry("key1", "value1"),
+    assertThat(alteredConfig.getParameterMap()).containsOnly(entry("key1", "value1"),
         entry("key2", "value2"));
   }
 
   @Test
   public void alterConnectionConfigParameters() {
-    Map<String, String> newParameters = new HashMap<>();
-    newParameters.put("key1", "anotherValue1");
-    newParameters.put("key8", "value8");
-    ConnectionConfiguration newConfigValues =
-        new ConnectionConfiguration(CONNECTION_NAME, null, null, null, newParameters);
+    String[] newParameters = new String[] {"key1:anotherValue1", "key8:value8"};
+    ConnectorService.Connection newConfigValues =
+        new ConnectorService.Connection(CONNECTION_NAME, null, null, null, newParameters);
 
-    ConnectionConfiguration alteredConfig =
+    ConnectorService.Connection alteredConfig =
         function.alterConnectionConfig(newConfigValues, configToAlter);
 
     assertThat(alteredConfig.getName()).isEqualTo(CONNECTION_NAME);
     assertThat(alteredConfig.getUrl()).isEqualTo("originalUrl");
     assertThat(alteredConfig.getUser()).isEqualTo("originalUser");
     assertThat(alteredConfig.getPassword()).isEqualTo("originalPassword");
-    assertThat(alteredConfig.getParameters()).containsOnly(entry("key1", "anotherValue1"),
+    assertThat(alteredConfig.getParameterMap()).containsOnly(entry("key1", "anotherValue1"),
         entry("key8", "value8"));
   }
 
   @Test
   public void alterConnectionConfigWithNothingToAlter() {
-    ConnectionConfiguration newConfigValues =
-        new ConnectionConfiguration(CONNECTION_NAME, null, null, null, null);
+    ConnectorService.Connection newConfigValues =
+        new ConnectorService.Connection(CONNECTION_NAME, null, null, null, (String[]) null);
 
-    ConnectionConfiguration alteredConfig =
+    ConnectorService.Connection alteredConfig =
         function.alterConnectionConfig(newConfigValues, configToAlter);
 
     assertThat(alteredConfig.getName()).isEqualTo(CONNECTION_NAME);
     assertThat(alteredConfig.getUrl()).isEqualTo("originalUrl");
     assertThat(alteredConfig.getUser()).isEqualTo("originalUser");
     assertThat(alteredConfig.getPassword()).isEqualTo("originalPassword");
-    assertThat(alteredConfig.getParameters()).containsOnly(entry("key1", "value1"),
+    assertThat(alteredConfig.getParameterMap()).containsOnly(entry("key1", "value1"),
         entry("key2", "value2"));
   }
+
+  @Test
+  public void alterConnectionRemoveParameters() {
+    ConnectorService.Connection newConfigValues =
+        new ConnectorService.Connection(CONNECTION_NAME, null, null, null, new String[0]);
+
+    ConnectorService.Connection alteredConfig =
+        function.alterConnectionConfig(newConfigValues, configToAlter);
+    assertThat(alteredConfig.getName()).isEqualTo(CONNECTION_NAME);
+    assertThat(alteredConfig.getUrl()).isEqualTo("originalUrl");
+    assertThat(alteredConfig.getUser()).isEqualTo("originalUser");
+    assertThat(alteredConfig.getPassword()).isEqualTo("originalPassword");
+    assertThat(alteredConfig.getParameterMap()).isEmpty();
+  }
+
+  @Test
+  public void alterConnectionRemoveParametersWithEmptyString() {
+    ConnectorService.Connection newConfigValues =
+        new ConnectorService.Connection(CONNECTION_NAME, null, null, null, new String[] {""});
+
+    ConnectorService.Connection alteredConfig =
+        function.alterConnectionConfig(newConfigValues, configToAlter);
+    assertThat(alteredConfig.getName()).isEqualTo(CONNECTION_NAME);
+    assertThat(alteredConfig.getUrl()).isEqualTo("originalUrl");
+    assertThat(alteredConfig.getUser()).isEqualTo("originalUser");
+    assertThat(alteredConfig.getPassword()).isEqualTo("originalPassword");
+    assertThat(alteredConfig.getParameterMap()).isEmpty();
+  }
 }
diff --git a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/AlterMappingCommandDUnitTest.java b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/AlterMappingCommandDUnitTest.java
index 4c7d52c..9a5c65f 100644
--- a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/AlterMappingCommandDUnitTest.java
+++ b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/AlterMappingCommandDUnitTest.java
@@ -29,7 +29,8 @@ 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 static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.entry;
+
+import java.util.List;
 
 import org.junit.Before;
 import org.junit.Rule;
@@ -37,7 +38,7 @@ import org.junit.Test;
 import org.junit.experimental.categories.Category;
 
 import org.apache.geode.connectors.jdbc.internal.JdbcConnectorService;
-import org.apache.geode.connectors.jdbc.internal.RegionMapping;
+import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
 import org.apache.geode.distributed.internal.InternalLocator;
 import org.apache.geode.internal.cache.InternalCache;
 import org.apache.geode.management.internal.cli.util.CommandStringBuilder;
@@ -99,14 +100,18 @@ public class AlterMappingCommandDUnitTest {
 
     server.invoke(() -> {
       InternalCache cache = ClusterStartupRule.getCache();
-      RegionMapping mapping =
+      ConnectorService.RegionMapping mapping =
           cache.getService(JdbcConnectorService.class).getMappingForRegion("testRegion");
       assertThat(mapping.getConnectionConfigName()).isEqualTo("newConnection");
       assertThat(mapping.getTableName()).isEqualTo("newTable");
       assertThat(mapping.getPdxClassName()).isEqualTo("newPdxClass");
       assertThat(mapping.isPrimaryKeyInValue()).isEqualTo(false);
-      assertThat(mapping.getFieldToColumnMap()).containsExactly(entry("field3", "column3"),
-          entry("field4", "column4"));
+      List<ConnectorService.RegionMapping.FieldMapping> fieldMappings = mapping.getFieldMapping();
+      assertThat(fieldMappings).hasSize(2);
+      assertThat(fieldMappings.get(0).getFieldName()).isEqualTo("field3");
+      assertThat(fieldMappings.get(0).getColumnName()).isEqualTo("column3");
+      assertThat(fieldMappings.get(1).getFieldName()).isEqualTo("field4");
+      assertThat(fieldMappings.get(1).getColumnName()).isEqualTo("column4");
     });
   }
 
@@ -128,12 +133,12 @@ public class AlterMappingCommandDUnitTest {
 
     server.invoke(() -> {
       InternalCache cache = ClusterStartupRule.getCache();
-      RegionMapping mapping =
+      ConnectorService.RegionMapping mapping =
           cache.getService(JdbcConnectorService.class).getMappingForRegion("testRegion");
       assertThat(mapping.getConnectionConfigName()).isEqualTo("connection");
       assertThat(mapping.getTableName()).isNull();
       assertThat(mapping.getPdxClassName()).isNull();
-      assertThat(mapping.getFieldToColumnMap()).isEmpty();
+      assertThat(mapping.getFieldMapping()).isEmpty();
     });
   }
 }
diff --git a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/AlterMappingCommandIntegrationTest.java b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/AlterMappingCommandIntegrationTest.java
index 9be6d84..86143fd 100644
--- a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/AlterMappingCommandIntegrationTest.java
+++ b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/AlterMappingCommandIntegrationTest.java
@@ -24,7 +24,7 @@ import org.junit.experimental.categories.Category;
 
 import org.apache.geode.cache.CacheFactory;
 import org.apache.geode.connectors.jdbc.internal.JdbcConnectorService;
-import org.apache.geode.connectors.jdbc.internal.RegionMapping;
+import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
 import org.apache.geode.internal.cache.InternalCache;
 import org.apache.geode.management.cli.Result;
 import org.apache.geode.test.junit.categories.IntegrationTest;
@@ -71,15 +71,15 @@ public class AlterMappingCommandIntegrationTest {
     assertThat(result.getStatus()).isSameAs(Result.Status.OK);
 
     JdbcConnectorService service = cache.getService(JdbcConnectorService.class);
-    RegionMapping regionMapping = service.getMappingForRegion(regionName);
+    ConnectorService.RegionMapping regionMapping = service.getMappingForRegion(regionName);
 
     assertThat(regionMapping).isNotNull();
     assertThat(regionMapping.getConnectionConfigName()).isEqualTo("newConnection");
     assertThat(regionMapping.getTableName()).isEqualTo("newTable");
     assertThat(regionMapping.getPdxClassName()).isEqualTo("newPdxClass");
     assertThat(regionMapping.isPrimaryKeyInValue()).isFalse();
-    assertThat(regionMapping.getFieldToColumnMap()).containsEntry("field3", "column3")
-        .containsEntry("field4", "column4");
+    // assertThat(regionMapping.getFieldToColumnMap()).containsEntry("field3", "column3")
+    // .containsEntry("field4", "column4");
   }
 
 }
diff --git a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/AlterMappingCommandTest.java b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/AlterMappingCommandTest.java
new file mode 100644
index 0000000..9df6885
--- /dev/null
+++ b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/AlterMappingCommandTest.java
@@ -0,0 +1,154 @@
+/*
+ * 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 static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
+import org.apache.geode.distributed.ClusterConfigurationService;
+import org.apache.geode.distributed.internal.InternalClusterConfigurationService;
+import org.apache.geode.management.internal.cli.GfshParseResult;
+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;
+
+@Category(UnitTest.class)
+public class AlterMappingCommandTest {
+  public static final String COMMAND = "alter jdbc-mapping --region='region' ";
+  private AlterMappingCommand command;
+  private List<CliFunctionResult> results;
+  private CliFunctionResult result;
+  private ClusterConfigurationService ccService;
+
+  @ClassRule
+  public static GfshParserRule gfsh = new GfshParserRule();
+
+  @Before
+  public void setUp() throws Exception {
+    command = spy(AlterMappingCommand.class);
+    results = new ArrayList<>();
+    doReturn(Collections.EMPTY_SET).when(command).getMembers(any(), any());
+    doReturn(results).when(command).executeAndGetFunctionResult(any(), any(), any());
+    result = mock(CliFunctionResult.class);
+    when(result.isSuccessful()).thenReturn(true);
+    when(result.getMemberIdOrName()).thenReturn("memberName");
+    when(result.getStatus()).thenReturn("message");
+    ccService = mock(InternalClusterConfigurationService.class);
+    doReturn(ccService).when(command).getConfigurationService();
+  }
+
+  @Test
+  public void requiredParameter() {
+    gfsh.executeAndAssertThat(command, "alter jdbc-mapping").statusIsError()
+        .containsOutput("Invalid command");
+  }
+
+  @Test
+  public void valuesAreParsedAsExpected() {
+    GfshParseResult parseResult = gfsh.parse("alter jdbc-mapping --region='region' --connection='' "
+        + "--table='' --pdx-class-name='' " + "--field-mapping=''");
+
+    String[] mappings = (String[]) parseResult.getParamValue("field-mapping");
+    assertThat(mappings).hasSize(1);
+    assertThat(mappings[0]).isEqualTo("");
+    assertThat(parseResult.getParamValue("region")).isEqualTo("region");
+    assertThat(parseResult.getParamValue("connection")).isEqualTo("");
+    assertThat(parseResult.getParamValue("table")).isEqualTo("");
+    assertThat(parseResult.getParamValue("pdx-class-name")).isEqualTo("");
+
+    parseResult = gfsh.parse("alter jdbc-mapping --region=testRegion-1 --connection=connection "
+        + "--table=myTable --pdx-class-name=myPdxClass " + "--field-mapping");
+    mappings = (String[]) parseResult.getParamValue("field-mapping");
+    assertThat(mappings).hasSize(1);
+    assertThat(mappings[0]).isEqualTo("");
+
+    parseResult = gfsh.parse("alter jdbc-mapping --region=testRegion-1 --connection=connection "
+        + "--table=myTable --pdx-class-name=myPdxClass ");
+    mappings = (String[]) parseResult.getParamValue("field-mapping");
+    assertThat(mappings).isNull();
+  }
+
+  @Test
+  public void whenCCServiceIsNotAvailable() {
+    doReturn(null).when(command).getConfigurationService();
+    results.add(result);
+    gfsh.executeAndAssertThat(command, COMMAND).statusIsSuccess();
+    verify(command).executeAndGetFunctionResult(any(), any(), any());
+  }
+
+  @Test
+  public void whenCCServiceIsRunningAndNoConnectorServiceFound() {
+    gfsh.executeAndAssertThat(command, COMMAND).statusIsError()
+        .containsOutput("mapping with name 'region' does not exist.");
+    verify(command, times(0)).executeAndGetFunctionResult(any(), any(), any());
+  }
+
+  @Test
+  public void whenCCServiceIsRunningAndNoMappingFound() {
+    ConnectorService connectorService = mock(ConnectorService.class);
+    when(ccService.getCustomCacheElement(any(), any(), any())).thenReturn(connectorService);
+    gfsh.executeAndAssertThat(command, COMMAND).statusIsError()
+        .containsOutput("mapping with name 'region' does not exist.");
+    verify(command, times(0)).executeAndGetFunctionResult(any(), any(), any());
+  }
+
+  @Test
+  public void noSuccessfulResult() {
+    // mapping found in CC
+    ConnectorService connectorService = mock(ConnectorService.class);
+    when(ccService.getCustomCacheElement(any(), any(), any())).thenReturn(connectorService);
+    when(ccService.findIdentifiable(any(), any()))
+        .thenReturn(mock(ConnectorService.RegionMapping.class));
+
+    // result is not successful
+    when(result.isSuccessful()).thenReturn(false);
+    results.add(result);
+
+    gfsh.executeAndAssertThat(command, COMMAND).statusIsError();
+    verify(command).executeAndGetFunctionResult(any(), any(), any());
+  }
+
+  @Test
+  public void successfulResult() {
+    // mapping found in CC
+    ConnectorService connectorService = mock(ConnectorService.class);
+    when(ccService.getCustomCacheElement(any(), any(), any())).thenReturn(connectorService);
+    when(ccService.findIdentifiable(any(), any()))
+        .thenReturn(mock(ConnectorService.RegionMapping.class));
+
+    // result is not successful
+    when(result.isSuccessful()).thenReturn(true);
+    results.add(result);
+
+    gfsh.executeAndAssertThat(command, COMMAND).statusIsSuccess();
+    verify(command).executeAndGetFunctionResult(any(), any(), any());
+  }
+}
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 5d59a02..4d77db7 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
@@ -16,7 +16,6 @@ package org.apache.geode.connectors.jdbc.internal.cli;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
-import static org.assertj.core.api.Assertions.entry;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doReturn;
@@ -28,8 +27,7 @@ import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import java.io.Serializable;
-import java.util.HashMap;
-import java.util.Map;
+import java.util.List;
 
 import org.apache.commons.lang.SerializationUtils;
 import org.junit.Before;
@@ -41,9 +39,8 @@ import org.apache.geode.cache.execute.FunctionContext;
 import org.apache.geode.cache.execute.ResultSender;
 import org.apache.geode.connectors.jdbc.internal.ConnectionConfigNotFoundException;
 import org.apache.geode.connectors.jdbc.internal.JdbcConnectorService;
-import org.apache.geode.connectors.jdbc.internal.RegionMapping;
-import org.apache.geode.connectors.jdbc.internal.RegionMappingBuilder;
 import org.apache.geode.connectors.jdbc.internal.RegionMappingNotFoundException;
+import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
 import org.apache.geode.distributed.DistributedMember;
 import org.apache.geode.distributed.DistributedSystem;
 import org.apache.geode.internal.cache.InternalCache;
@@ -55,10 +52,10 @@ public class AlterMappingFunctionTest {
 
   private static final String REGION_NAME = "testRegion";
 
-  private RegionMapping regionMapping;
-  private RegionMapping existingMapping;
-  private RegionMapping mappingToAlter;
-  private FunctionContext<RegionMapping> context;
+  private ConnectorService.RegionMapping regionMapping;
+  private ConnectorService.RegionMapping existingMapping;
+  private ConnectorService.RegionMapping mappingToAlter;
+  private FunctionContext<ConnectorService.RegionMapping> context;
   private ResultSender<Object> resultSender;
   private JdbcConnectorService service;
 
@@ -73,13 +70,11 @@ public class AlterMappingFunctionTest {
     DistributedMember distributedMember = mock(DistributedMember.class);
     service = mock(JdbcConnectorService.class);
 
-    regionMapping = new RegionMappingBuilder().withRegionName(REGION_NAME).build();
-    existingMapping = new RegionMappingBuilder().withRegionName(REGION_NAME).build();
-    Map<String, String> mappings = new HashMap<>();
-    mappings.put("field1", "column1");
-    mappings.put("field2", "column2");
+    regionMapping = new ConnectorService.RegionMapping(REGION_NAME, null, null, null, null);
+    existingMapping = new ConnectorService.RegionMapping(REGION_NAME, null, null, null, null);
     mappingToAlter =
-        new RegionMapping(REGION_NAME, "pdxClass", "myTable", "connection", true, mappings);
+        new ConnectorService.RegionMapping(REGION_NAME, "pdxClass", "myTable", "connection", true);
+    mappingToAlter.setFieldMapping(new String[] {"field1:column1", "field2:column2"});
 
     when(context.getResultSender()).thenReturn(resultSender);
     when(context.getCache()).thenReturn(cache);
@@ -144,98 +139,152 @@ public class AlterMappingFunctionTest {
 
   @Test
   public void alterMappingPdxClassName() {
-    RegionMapping newConfigValues =
-        new RegionMapping(REGION_NAME, "newClassName", null, null, null, null);
+    ConnectorService.RegionMapping newConfigValues =
+        new ConnectorService.RegionMapping(REGION_NAME, "newClassName", null, null, null);
 
-    RegionMapping alteredConfig = function.alterRegionMapping(newConfigValues, mappingToAlter);
+    ConnectorService.RegionMapping alteredConfig =
+        function.alterRegionMapping(newConfigValues, mappingToAlter);
 
     assertThat(alteredConfig.getRegionName()).isEqualTo(REGION_NAME);
     assertThat(alteredConfig.getPdxClassName()).isEqualTo("newClassName");
     assertThat(alteredConfig.getTableName()).isEqualTo("myTable");
     assertThat(alteredConfig.getConnectionConfigName()).isEqualTo("connection");
     assertThat(alteredConfig.isPrimaryKeyInValue()).isTrue();
-    Map<String, String> fieldMappings = alteredConfig.getFieldToColumnMap();
-    assertThat(fieldMappings).containsOnly(entry("field1", "column1"), entry("field2", "column2"));
+
+    assertFieldMapping(alteredConfig);
+  }
+
+  private void assertFieldMapping(ConnectorService.RegionMapping alteredConfig) {
+    List<ConnectorService.RegionMapping.FieldMapping> fieldMappings =
+        alteredConfig.getFieldMapping();
+    assertThat(fieldMappings).hasSize(2);
+    assertThat(fieldMappings.get(0).getFieldName()).isEqualTo("field1");
+    assertThat(fieldMappings.get(0).getColumnName()).isEqualTo("column1");
+    assertThat(fieldMappings.get(1).getFieldName()).isEqualTo("field2");
+    assertThat(fieldMappings.get(1).getColumnName()).isEqualTo("column2");
   }
 
   @Test
   public void alterRegionMappingTable() {
-    RegionMapping newConfigValues =
-        new RegionMapping(REGION_NAME, null, "newTable", null, null, null);
+    ConnectorService.RegionMapping newConfigValues =
+        new ConnectorService.RegionMapping(REGION_NAME, null, "newTable", null, null);
 
-    RegionMapping alteredConfig = function.alterRegionMapping(newConfigValues, mappingToAlter);
+    ConnectorService.RegionMapping alteredConfig =
+        function.alterRegionMapping(newConfigValues, mappingToAlter);
 
     assertThat(alteredConfig.getRegionName()).isEqualTo(REGION_NAME);
     assertThat(alteredConfig.getPdxClassName()).isEqualTo("pdxClass");
     assertThat(alteredConfig.getTableName()).isEqualTo("newTable");
     assertThat(alteredConfig.getConnectionConfigName()).isEqualTo("connection");
     assertThat(alteredConfig.isPrimaryKeyInValue()).isTrue();
-    Map<String, String> fieldMappings = alteredConfig.getFieldToColumnMap();
-    assertThat(fieldMappings).containsOnly(entry("field1", "column1"), entry("field2", "column2"));
+    assertFieldMapping(alteredConfig);
   }
 
   @Test
   public void alterRegionMappingPrimaryKeyInValue() {
-    RegionMapping newConfigValues = new RegionMapping(REGION_NAME, null, null, null, false, null);
+    ConnectorService.RegionMapping newConfigValues =
+        new ConnectorService.RegionMapping(REGION_NAME, null, null, null, false);
 
-    RegionMapping alteredConfig = function.alterRegionMapping(newConfigValues, mappingToAlter);
+    ConnectorService.RegionMapping alteredConfig =
+        function.alterRegionMapping(newConfigValues, mappingToAlter);
 
     assertThat(alteredConfig.getRegionName()).isEqualTo(REGION_NAME);
     assertThat(alteredConfig.getPdxClassName()).isEqualTo("pdxClass");
     assertThat(alteredConfig.getTableName()).isEqualTo("myTable");
     assertThat(alteredConfig.getConnectionConfigName()).isEqualTo("connection");
     assertThat(alteredConfig.isPrimaryKeyInValue()).isFalse();
-    Map<String, String> fieldMappings = alteredConfig.getFieldToColumnMap();
-    assertThat(fieldMappings).containsOnly(entry("field1", "column1"), entry("field2", "column2"));
+    assertFieldMapping(alteredConfig);
   }
 
   @Test
   public void alterRegionMappingConnectionName() {
-    RegionMapping newConfigValues =
-        new RegionMapping(REGION_NAME, null, null, "newConnection", null, null);
+    ConnectorService.RegionMapping newConfigValues =
+        new ConnectorService.RegionMapping(REGION_NAME, null, null, "newConnection", null);
 
-    RegionMapping alteredConfig = function.alterRegionMapping(newConfigValues, mappingToAlter);
+    ConnectorService.RegionMapping alteredConfig =
+        function.alterRegionMapping(newConfigValues, mappingToAlter);
 
     assertThat(alteredConfig.getRegionName()).isEqualTo(REGION_NAME);
     assertThat(alteredConfig.getPdxClassName()).isEqualTo("pdxClass");
     assertThat(alteredConfig.getTableName()).isEqualTo("myTable");
     assertThat(alteredConfig.getConnectionConfigName()).isEqualTo("newConnection");
     assertThat(alteredConfig.isPrimaryKeyInValue()).isTrue();
-    Map<String, String> fieldMappings = alteredConfig.getFieldToColumnMap();
-    assertThat(fieldMappings).containsOnly(entry("field1", "column1"), entry("field2", "column2"));
+    assertFieldMapping(alteredConfig);
   }
 
   @Test
   public void alterRegionMappingFieldMappings() {
-    Map<String, String> newMappings = new HashMap<>();
-    newMappings.put("field5", "column5");
-    newMappings.put("field6", "column6");
-    RegionMapping newConfigValues =
-        new RegionMapping(REGION_NAME, null, null, null, null, newMappings);
+    ConnectorService.RegionMapping newConfigValues =
+        new ConnectorService.RegionMapping(REGION_NAME, null, null, null, null);
+    newConfigValues.setFieldMapping(new String[] {"field5:column5", "field6:column6"});
+
+
+    ConnectorService.RegionMapping alteredConfig =
+        function.alterRegionMapping(newConfigValues, mappingToAlter);
+
+    assertThat(alteredConfig.getRegionName()).isEqualTo(REGION_NAME);
+    assertThat(alteredConfig.getPdxClassName()).isEqualTo("pdxClass");
+    assertThat(alteredConfig.getTableName()).isEqualTo("myTable");
+    assertThat(alteredConfig.getConnectionConfigName()).isEqualTo("connection");
+    assertThat(alteredConfig.isPrimaryKeyInValue()).isTrue();
+    List<ConnectorService.RegionMapping.FieldMapping> fieldMappings =
+        alteredConfig.getFieldMapping();
+    assertThat(fieldMappings).hasSize(2);
+    assertThat(fieldMappings)
+        .contains(new ConnectorService.RegionMapping.FieldMapping("field5", "column5"));
+    assertThat(fieldMappings)
+        .contains(new ConnectorService.RegionMapping.FieldMapping("field6", "column6"));
+  }
+
+  @Test
+  public void alterRegionMappingRemoveFieldMappings() {
+    ConnectorService.RegionMapping newConfigValues =
+        new ConnectorService.RegionMapping(REGION_NAME, null, null, null, null);
+    newConfigValues.setFieldMapping(new String[0]);
+    ConnectorService.RegionMapping alteredConfig =
+        function.alterRegionMapping(newConfigValues, mappingToAlter);
 
-    RegionMapping alteredConfig = function.alterRegionMapping(newConfigValues, mappingToAlter);
+    assertThat(alteredConfig.getRegionName()).isEqualTo(REGION_NAME);
+    assertThat(alteredConfig.getPdxClassName()).isEqualTo("pdxClass");
+    assertThat(alteredConfig.getTableName()).isEqualTo("myTable");
+    assertThat(alteredConfig.getConnectionConfigName()).isEqualTo("connection");
+    assertThat(alteredConfig.isPrimaryKeyInValue()).isTrue();
+    List<ConnectorService.RegionMapping.FieldMapping> fieldMappings =
+        alteredConfig.getFieldMapping();
+    assertThat(fieldMappings).hasSize(0);
+  }
+
+  @Test
+  public void alterRegionMappingWithEmptyString() {
+    ConnectorService.RegionMapping newConfigValues =
+        new ConnectorService.RegionMapping(REGION_NAME, null, null, null, null);
+    newConfigValues.setFieldMapping(new String[] {""});
+    ConnectorService.RegionMapping alteredConfig =
+        function.alterRegionMapping(newConfigValues, mappingToAlter);
 
     assertThat(alteredConfig.getRegionName()).isEqualTo(REGION_NAME);
     assertThat(alteredConfig.getPdxClassName()).isEqualTo("pdxClass");
     assertThat(alteredConfig.getTableName()).isEqualTo("myTable");
     assertThat(alteredConfig.getConnectionConfigName()).isEqualTo("connection");
     assertThat(alteredConfig.isPrimaryKeyInValue()).isTrue();
-    Map<String, String> fieldMappings = alteredConfig.getFieldToColumnMap();
-    assertThat(fieldMappings).containsOnly(entry("field5", "column5"), entry("field6", "column6"));
+    List<ConnectorService.RegionMapping.FieldMapping> fieldMappings =
+        alteredConfig.getFieldMapping();
+    assertThat(fieldMappings).hasSize(0);
   }
 
   @Test
   public void alterRegionMappingWithNothingToAlter() {
-    RegionMapping newConfigValues = new RegionMapping(REGION_NAME, null, null, null, null, null);
+    ConnectorService.RegionMapping newConfigValues =
+        new ConnectorService.RegionMapping(REGION_NAME, null, null, null, null);
 
-    RegionMapping alteredConfig = function.alterRegionMapping(newConfigValues, mappingToAlter);
+    ConnectorService.RegionMapping alteredConfig =
+        function.alterRegionMapping(newConfigValues, mappingToAlter);
 
     assertThat(alteredConfig.getRegionName()).isEqualTo(REGION_NAME);
     assertThat(alteredConfig.getPdxClassName()).isEqualTo("pdxClass");
     assertThat(alteredConfig.getTableName()).isEqualTo("myTable");
     assertThat(alteredConfig.getConnectionConfigName()).isEqualTo("connection");
     assertThat(alteredConfig.isPrimaryKeyInValue()).isTrue();
-    Map<String, String> fieldMappings = alteredConfig.getFieldToColumnMap();
-    assertThat(fieldMappings).containsOnly(entry("field1", "column1"), entry("field2", "column2"));
+    assertFieldMapping(alteredConfig);
   }
 }
diff --git a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/CreateConnectionCommandDUnitTest.java b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/CreateConnectionCommandDUnitTest.java
index 5f06fa5..f50d175 100644
--- a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/CreateConnectionCommandDUnitTest.java
+++ b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/CreateConnectionCommandDUnitTest.java
@@ -27,8 +27,8 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 
-import org.apache.geode.connectors.jdbc.internal.ConnectionConfiguration;
 import org.apache.geode.connectors.jdbc.internal.JdbcConnectorService;
+import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
 import org.apache.geode.distributed.internal.InternalLocator;
 import org.apache.geode.internal.cache.InternalCache;
 import org.apache.geode.management.internal.cli.util.CommandStringBuilder;
@@ -80,7 +80,7 @@ public class CreateConnectionCommandDUnitTest {
 
     server.invoke(() -> {
       InternalCache cache = ClusterStartupRule.getCache();
-      ConnectionConfiguration config =
+      ConnectorService.Connection config =
           cache.getService(JdbcConnectorService.class).getConnectionConfig("name");
       assertThat(config.getUrl()).isEqualTo("url");
       assertThat(config.getUser()).isEqualTo("username");
diff --git a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/CreateConnectionCommandIntegrationTest.java b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/CreateConnectionCommandIntegrationTest.java
index 7b2fc9b..d9e399e 100644
--- a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/CreateConnectionCommandIntegrationTest.java
+++ b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/CreateConnectionCommandIntegrationTest.java
@@ -23,8 +23,8 @@ import org.junit.Test;
 import org.junit.experimental.categories.Category;
 
 import org.apache.geode.cache.CacheFactory;
-import org.apache.geode.connectors.jdbc.internal.ConnectionConfiguration;
 import org.apache.geode.connectors.jdbc.internal.JdbcConnectorService;
+import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
 import org.apache.geode.internal.cache.InternalCache;
 import org.apache.geode.management.cli.Result;
 import org.apache.geode.test.junit.categories.IntegrationTest;
@@ -68,7 +68,7 @@ public class CreateConnectionCommandIntegrationTest {
     assertThat(result.getStatus()).isSameAs(Result.Status.OK);
 
     JdbcConnectorService service = cache.getService(JdbcConnectorService.class);
-    ConnectionConfiguration connectionConfig = service.getConnectionConfig(name);
+    ConnectorService.Connection connectionConfig = service.getConnectionConfig(name);
 
     assertThat(connectionConfig).isNotNull();
     assertThat(connectionConfig.getName()).isEqualTo(name);
@@ -84,7 +84,7 @@ public class CreateConnectionCommandIntegrationTest {
     createConnectionCommand.createConnection(name, url, user, password, params);
     JdbcConnectorService service = cache.getService(JdbcConnectorService.class);
 
-    ConnectionConfiguration connectionConfig = service.getConnectionConfig(name);
+    ConnectorService.Connection connectionConfig = service.getConnectionConfig(name);
 
     Result result = createConnectionCommand.createConnection(name, url, user, password, params);
     assertThat(result.getStatus()).isSameAs(Result.Status.ERROR);
@@ -99,7 +99,7 @@ public class CreateConnectionCommandIntegrationTest {
     assertThat(result.getStatus()).isSameAs(Result.Status.OK);
 
     JdbcConnectorService service = cache.getService(JdbcConnectorService.class);
-    ConnectionConfiguration connectionConfig = service.getConnectionConfig(name);
+    ConnectorService.Connection connectionConfig = service.getConnectionConfig(name);
 
     assertThat(connectionConfig).isNotNull();
     assertThat(connectionConfig.getName()).isEqualTo(name);
diff --git a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/CreateConnectionFunctionTest.java b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/CreateConnectionFunctionTest.java
index 78e735b..ebc9223 100644
--- a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/CreateConnectionFunctionTest.java
+++ b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/CreateConnectionFunctionTest.java
@@ -33,10 +33,9 @@ import org.mockito.ArgumentCaptor;
 
 import org.apache.geode.cache.execute.FunctionContext;
 import org.apache.geode.cache.execute.ResultSender;
-import org.apache.geode.connectors.jdbc.internal.ConnectionConfigBuilder;
 import org.apache.geode.connectors.jdbc.internal.ConnectionConfigExistsException;
-import org.apache.geode.connectors.jdbc.internal.ConnectionConfiguration;
 import org.apache.geode.connectors.jdbc.internal.JdbcConnectorService;
+import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
 import org.apache.geode.distributed.DistributedMember;
 import org.apache.geode.distributed.DistributedSystem;
 import org.apache.geode.internal.cache.InternalCache;
@@ -48,8 +47,8 @@ public class CreateConnectionFunctionTest {
 
   private static final String CONNECTION_NAME = "theConnection";
 
-  private ConnectionConfiguration connectionConfig;
-  private FunctionContext<ConnectionConfiguration> context;
+  private ConnectorService.Connection connectionConfig;
+  private FunctionContext<ConnectorService.Connection> context;
   private ResultSender<Object> resultSender;
   private JdbcConnectorService service;
 
@@ -64,7 +63,8 @@ public class CreateConnectionFunctionTest {
     DistributedMember distributedMember = mock(DistributedMember.class);
     service = mock(JdbcConnectorService.class);
 
-    connectionConfig = new ConnectionConfigBuilder().withName(CONNECTION_NAME).build();
+    connectionConfig =
+        new ConnectorService.Connection(CONNECTION_NAME, null, null, null, (String) null);;
 
     when(context.getResultSender()).thenReturn(resultSender);
     when(context.getCache()).thenReturn(cache);
diff --git a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingCommandDUnitTest.java b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingCommandDUnitTest.java
index a811f2b..16b9af7 100644
--- a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingCommandDUnitTest.java
+++ b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingCommandDUnitTest.java
@@ -23,13 +23,15 @@ import static org.apache.geode.connectors.jdbc.internal.cli.CreateMappingCommand
 import static org.apache.geode.connectors.jdbc.internal.cli.CreateMappingCommand.CREATE_MAPPING__VALUE_CONTAINS_PRIMARY_KEY;
 import static org.assertj.core.api.Assertions.assertThat;
 
+import java.util.List;
+
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 
 import org.apache.geode.connectors.jdbc.internal.JdbcConnectorService;
-import org.apache.geode.connectors.jdbc.internal.RegionMapping;
+import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
 import org.apache.geode.distributed.internal.InternalLocator;
 import org.apache.geode.internal.cache.InternalCache;
 import org.apache.geode.management.internal.cli.util.CommandStringBuilder;
@@ -84,14 +86,18 @@ public class CreateMappingCommandDUnitTest {
 
     server.invoke(() -> {
       InternalCache cache = ClusterStartupRule.getCache();
-      RegionMapping mapping =
+      ConnectorService.RegionMapping mapping =
           cache.getService(JdbcConnectorService.class).getMappingForRegion("testRegion");
       assertThat(mapping.getConnectionConfigName()).isEqualTo("connection");
       assertThat(mapping.getTableName()).isEqualTo("myTable");
       assertThat(mapping.getPdxClassName()).isEqualTo("myPdxClass");
       assertThat(mapping.isPrimaryKeyInValue()).isEqualTo(true);
-      assertThat(mapping.getFieldToColumnMap()).containsEntry("field1", "column1")
-          .containsEntry("field2", "column2");
+      List<ConnectorService.RegionMapping.FieldMapping> fieldMappings = mapping.getFieldMapping();
+      assertThat(fieldMappings).hasSize(2);
+      assertThat(fieldMappings.get(0).getFieldName()).isEqualTo("field1");
+      assertThat(fieldMappings.get(0).getColumnName()).isEqualTo("column1");
+      assertThat(fieldMappings.get(1).getFieldName()).isEqualTo("field2");
+      assertThat(fieldMappings.get(1).getColumnName()).isEqualTo("column2");
     });
   }
 
@@ -114,14 +120,18 @@ public class CreateMappingCommandDUnitTest {
 
     server.invoke(() -> {
       InternalCache cache = ClusterStartupRule.getCache();
-      RegionMapping mapping =
+      ConnectorService.RegionMapping mapping =
           cache.getService(JdbcConnectorService.class).getMappingForRegion("testRegion");
       assertThat(mapping.getConnectionConfigName()).isEqualTo("connection");
       assertThat(mapping.getTableName()).isEqualTo("myTable");
       assertThat(mapping.getPdxClassName()).isEqualTo("myPdxClass");
       assertThat(mapping.isPrimaryKeyInValue()).isEqualTo(false);
-      assertThat(mapping.getFieldToColumnMap()).containsEntry("field1", "column1")
-          .containsEntry("field2", "column2");
+      List<ConnectorService.RegionMapping.FieldMapping> fieldMappings = mapping.getFieldMapping();
+      assertThat(fieldMappings).hasSize(2);
+      assertThat(fieldMappings.get(0).getFieldName()).isEqualTo("field1");
+      assertThat(fieldMappings.get(0).getColumnName()).isEqualTo("column1");
+      assertThat(fieldMappings.get(1).getFieldName()).isEqualTo("field2");
+      assertThat(fieldMappings.get(1).getColumnName()).isEqualTo("column2");
     });
   }
 
diff --git a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingCommandIntegrationTest.java b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingCommandIntegrationTest.java
index 48bb2e0..8a89110 100644
--- a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingCommandIntegrationTest.java
+++ b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingCommandIntegrationTest.java
@@ -24,10 +24,9 @@ import org.junit.Test;
 import org.junit.experimental.categories.Category;
 
 import org.apache.geode.cache.CacheFactory;
-import org.apache.geode.connectors.jdbc.internal.ConnectionConfiguration;
 import org.apache.geode.connectors.jdbc.internal.JdbcConnectorService;
-import org.apache.geode.connectors.jdbc.internal.RegionMapping;
 import org.apache.geode.connectors.jdbc.internal.TableMetaDataView;
+import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
 import org.apache.geode.internal.cache.InternalCache;
 import org.apache.geode.management.cli.Result;
 import org.apache.geode.test.junit.categories.IntegrationTest;
@@ -74,7 +73,7 @@ public class CreateMappingCommandIntegrationTest {
     assertThat(result.getStatus()).isSameAs(Result.Status.OK);
 
     JdbcConnectorService service = cache.getService(JdbcConnectorService.class);
-    RegionMapping regionMapping = service.getMappingForRegion(regionName);
+    ConnectorService.RegionMapping regionMapping = service.getMappingForRegion(regionName);
 
     assertThat(regionMapping).isNotNull();
     assertThat(regionMapping.getRegionName()).isEqualTo(regionName);
@@ -94,7 +93,7 @@ public class CreateMappingCommandIntegrationTest {
         keyInValue, fieldMappings);
     JdbcConnectorService service = cache.getService(JdbcConnectorService.class);
 
-    ConnectionConfiguration connectionConfig = service.getConnectionConfig(regionName);
+    ConnectorService.Connection connectionConfig = service.getConnectionConfig(regionName);
 
     Result result = createRegionMappingCommand.createMapping(regionName, connectionName, tableName,
         pdxClass, keyInValue, fieldMappings);
@@ -112,7 +111,7 @@ public class CreateMappingCommandIntegrationTest {
     assertThat(result.getStatus()).isSameAs(Result.Status.OK);
 
     JdbcConnectorService service = cache.getService(JdbcConnectorService.class);
-    RegionMapping regionMapping = service.getMappingForRegion(regionName);
+    ConnectorService.RegionMapping regionMapping = service.getMappingForRegion(regionName);
 
     assertThat(regionMapping).isNotNull();
     assertThat(regionMapping.getRegionName()).isEqualTo(regionName);
@@ -120,6 +119,6 @@ public class CreateMappingCommandIntegrationTest {
     assertThat(regionMapping.getTableName()).isNull();
     assertThat(regionMapping.getPdxClassName()).isNull();
     assertThat(regionMapping.isPrimaryKeyInValue()).isFalse();
-    assertThat(regionMapping.getFieldToColumnMap()).isNull();
+    assertThat(regionMapping.getFieldMapping()).isEmpty();
   }
 }
diff --git a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingFunctionTest.java b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingFunctionTest.java
index b913e95..ed9f79d 100644
--- a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingFunctionTest.java
+++ b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingFunctionTest.java
@@ -35,9 +35,8 @@ import org.apache.geode.cache.execute.FunctionContext;
 import org.apache.geode.cache.execute.ResultSender;
 import org.apache.geode.connectors.jdbc.internal.ConnectionConfigExistsException;
 import org.apache.geode.connectors.jdbc.internal.JdbcConnectorService;
-import org.apache.geode.connectors.jdbc.internal.RegionMapping;
-import org.apache.geode.connectors.jdbc.internal.RegionMappingBuilder;
 import org.apache.geode.connectors.jdbc.internal.RegionMappingExistsException;
+import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
 import org.apache.geode.distributed.DistributedMember;
 import org.apache.geode.distributed.DistributedSystem;
 import org.apache.geode.internal.cache.InternalCache;
@@ -49,8 +48,8 @@ public class CreateMappingFunctionTest {
 
   private static final String REGION_NAME = "testRegion";
 
-  private RegionMapping regionMapping;
-  private FunctionContext<RegionMapping> context;
+  private ConnectorService.RegionMapping regionMapping;
+  private FunctionContext<ConnectorService.RegionMapping> context;
   private DistributedMember distributedMember;
   private ResultSender<Object> resultSender;
   private JdbcConnectorService service;
@@ -66,7 +65,7 @@ public class CreateMappingFunctionTest {
     distributedMember = mock(DistributedMember.class);
     service = mock(JdbcConnectorService.class);
 
-    regionMapping = new RegionMappingBuilder().withRegionName(REGION_NAME).build();
+    regionMapping = new ConnectorService.RegionMapping(REGION_NAME, null, null, null, null);
 
     when(context.getResultSender()).thenReturn(resultSender);
     when(context.getCache()).thenReturn(cache);
diff --git a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeConnectionCommandDUnitTest.java b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeConnectionCommandDUnitTest.java
index 30ab08e..a8b3808 100644
--- a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeConnectionCommandDUnitTest.java
+++ b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeConnectionCommandDUnitTest.java
@@ -14,9 +14,14 @@
  */
 package org.apache.geode.connectors.jdbc.internal.cli;
 
+import static org.apache.geode.connectors.jdbc.internal.cli.CreateConnectionCommand.CREATE_CONNECTION;
+import static org.apache.geode.connectors.jdbc.internal.cli.CreateConnectionCommand.CREATE_CONNECTION__NAME;
+import static org.apache.geode.connectors.jdbc.internal.cli.CreateConnectionCommand.CREATE_CONNECTION__PARAMS;
+import static org.apache.geode.connectors.jdbc.internal.cli.CreateConnectionCommand.CREATE_CONNECTION__PASSWORD;
+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 static org.apache.geode.connectors.jdbc.internal.cli.DescribeConnectionCommand.DESCRIBE_CONNECTION;
 import static org.apache.geode.connectors.jdbc.internal.cli.DescribeConnectionCommand.DESCRIBE_CONNECTION__NAME;
-import static org.assertj.core.api.Assertions.assertThat;
 
 import java.io.Serializable;
 
@@ -25,10 +30,6 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 
-import org.apache.geode.connectors.jdbc.internal.ConnectionConfigBuilder;
-import org.apache.geode.connectors.jdbc.internal.ConnectionConfigExistsException;
-import org.apache.geode.connectors.jdbc.internal.JdbcConnectorService;
-import org.apache.geode.internal.cache.InternalCache;
 import org.apache.geode.management.internal.cli.util.CommandStringBuilder;
 import org.apache.geode.test.dunit.rules.ClusterStartupRule;
 import org.apache.geode.test.dunit.rules.MemberVM;
@@ -63,9 +64,17 @@ public class DescribeConnectionCommandDUnitTest implements Serializable {
 
   @Test
   public void describesExistingConnection() {
-    server.invoke(this::createConnection);
-    CommandStringBuilder csb = new CommandStringBuilder(DESCRIBE_CONNECTION)
-        .addOption(DESCRIBE_CONNECTION__NAME, CONNECTION_NAME);
+    CommandStringBuilder csb = new CommandStringBuilder(CREATE_CONNECTION);
+    csb.addOption(CREATE_CONNECTION__NAME, CONNECTION_NAME);
+    csb.addOption(CREATE_CONNECTION__URL, "myUrl");
+    csb.addOption(CREATE_CONNECTION__USER, "username");
+    csb.addOption(CREATE_CONNECTION__PASSWORD, "secret");
+    csb.addOption(CREATE_CONNECTION__PARAMS, "key1:value1,key2:value2");
+
+    gfsh.executeAndAssertThat(csb.toString()).statusIsSuccess();
+
+    csb = new CommandStringBuilder(DESCRIBE_CONNECTION).addOption(DESCRIBE_CONNECTION__NAME,
+        CONNECTION_NAME);
 
     CommandResultAssert commandResultAssert = gfsh.executeAndAssertThat(csb.toString());
 
@@ -88,22 +97,8 @@ public class DescribeConnectionCommandDUnitTest implements Serializable {
 
     CommandResultAssert commandResultAssert = gfsh.executeAndAssertThat(csb.toString());
 
-    commandResultAssert.statusIsSuccess();
-    commandResultAssert
-        .containsOutput(String.format("Connection named '%s' not found", "nonExisting"));
-  }
-
-  private void createConnection() throws ConnectionConfigExistsException {
-    InternalCache cache = ClusterStartupRule.getCache();
-    JdbcConnectorService service = cache.getService(JdbcConnectorService.class);
-
-    String[] params = new String[] {"key1:value1", "key2:value2"};
-    service.createConnectionConfig(
-        new ConnectionConfigBuilder().withName(CONNECTION_NAME).withUrl("myUrl")
-            .withUser("username").withPassword("secret").withParameters(params).build());
-
-    assertThat(service.getConnectionConfig(CONNECTION_NAME)).isNotNull();
+    commandResultAssert.statusIsError();
+    commandResultAssert.containsOutput(
+        String.format("(Experimental) \n" + "connection named 'nonExisting' not found"));
   }
-
-
 }
diff --git a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeConnectionCommandIntegrationTest.java b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeConnectionCommandIntegrationTest.java
deleted file mode 100644
index 949001e..0000000
--- a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeConnectionCommandIntegrationTest.java
+++ /dev/null
@@ -1,150 +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.apache.geode.connectors.jdbc.internal.cli.CreateConnectionCommand.CREATE_CONNECTION__NAME;
-import static org.apache.geode.connectors.jdbc.internal.cli.CreateConnectionCommand.CREATE_CONNECTION__PARAMS;
-import static org.apache.geode.connectors.jdbc.internal.cli.CreateConnectionCommand.CREATE_CONNECTION__PASSWORD;
-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 static org.apache.geode.connectors.jdbc.internal.cli.DescribeConnectionCommand.OBSCURED_PASSWORD;
-import static org.apache.geode.connectors.jdbc.internal.cli.DescribeConnectionCommand.RESULT_SECTION_NAME;
-import static org.apache.geode.distributed.ConfigurationProperties.ENABLE_CLUSTER_CONFIGURATION;
-import static org.apache.geode.management.internal.cli.result.AbstractResultData.SECTION_DATA_ACCESSOR;
-import static org.apache.geode.management.internal.cli.result.AbstractResultData.TABLE_DATA_ACCESSOR;
-import static org.assertj.core.api.Assertions.assertThat;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-
-import org.apache.geode.cache.CacheFactory;
-import org.apache.geode.connectors.jdbc.internal.ConnectionConfigBuilder;
-import org.apache.geode.connectors.jdbc.internal.ConnectionConfiguration;
-import org.apache.geode.connectors.jdbc.internal.JdbcConnectorService;
-import org.apache.geode.internal.cache.InternalCache;
-import org.apache.geode.management.cli.Result;
-import org.apache.geode.management.internal.cli.json.GfJsonObject;
-import org.apache.geode.management.internal.cli.result.CommandResult;
-import org.apache.geode.test.junit.categories.IntegrationTest;
-
-@Category(IntegrationTest.class)
-public class DescribeConnectionCommandIntegrationTest {
-  private static final String CONNECTION = "connection";
-
-  private InternalCache cache;
-  private JdbcConnectorService service;
-  private ConnectionConfiguration connectionConfig;
-  private DescribeConnectionCommand command;
-
-  @Before
-  public void setup() {
-    String[] params = new String[] {"param1:value1", "param2:value2"};
-
-    connectionConfig = new ConnectionConfigBuilder().withName(CONNECTION).withUrl("myUrl")
-        .withUser("username").withPassword("secret").withParameters(params).build();
-
-    cache = (InternalCache) new CacheFactory().set("locators", "").set("mcast-port", "0")
-        .set(ENABLE_CLUSTER_CONFIGURATION, "true").create();
-    service = cache.getService(JdbcConnectorService.class);
-
-    command = new DescribeConnectionCommand();
-    command.setCache(cache);
-  }
-
-  @After
-  public void tearDown() {
-    cache.close();
-  }
-
-  @Test
-  public void displaysNoConnectionFoundMessageWhenConfigurationDoesNotExist() {
-    String notExistingConnectionName = "non existing";
-    Result result = command.describeConnection(notExistingConnectionName);
-
-    assertThat(result.getStatus()).isSameAs(Result.Status.OK);
-    CommandResult commandResult = (CommandResult) result;
-    String tableContent = commandResult.getTableContent().toString();
-    assertThat(tableContent)
-        .contains("Connection named '" + notExistingConnectionName + "' not found");
-  }
-
-  @Test
-  public void displaysConnectionInformationWhenConfigurationExists() throws Exception {
-    service.createConnectionConfig(connectionConfig);
-    Result result = command.describeConnection(CONNECTION);
-
-    assertThat(result.getStatus()).isSameAs(Result.Status.OK);
-    CommandResult commandResult = (CommandResult) result;
-    GfJsonObject sectionContent = commandResult.getTableContent()
-        .getJSONObject(SECTION_DATA_ACCESSOR + "-" + RESULT_SECTION_NAME);
-
-    assertThat(sectionContent.get(CREATE_CONNECTION__NAME)).isEqualTo(connectionConfig.getName());
-    assertThat(sectionContent.get(CREATE_CONNECTION__URL)).isEqualTo(connectionConfig.getUrl());
-    assertThat(sectionContent.get(CREATE_CONNECTION__USER)).isEqualTo(connectionConfig.getUser());
-    assertThat(sectionContent.get(CREATE_CONNECTION__PASSWORD)).isEqualTo(OBSCURED_PASSWORD);
-
-    GfJsonObject tableContent =
-        sectionContent.getJSONObject(TABLE_DATA_ACCESSOR + "-" + CREATE_CONNECTION__PARAMS)
-            .getJSONObject("content");
-    connectionConfig.getParameters().entrySet().forEach((entry) -> {
-      assertThat(tableContent.get("Param Name").toString()).contains(entry.getKey());
-      assertThat(tableContent.get("Value").toString()).contains(entry.getValue());
-    });
-
-  }
-
-  @Test
-  public void displaysConnectionInformationForConfigurationWithNullParameters() throws Exception {
-    connectionConfig = new ConnectionConfigBuilder().withName(CONNECTION).withUrl("myUrl")
-        .withParameters(null).build();
-    service.createConnectionConfig(connectionConfig);
-    Result result = command.describeConnection(CONNECTION);
-
-    assertThat(result.getStatus()).isSameAs(Result.Status.OK);
-    CommandResult commandResult = (CommandResult) result;
-    GfJsonObject sectionContent = commandResult.getTableContent()
-        .getJSONObject(SECTION_DATA_ACCESSOR + "-" + RESULT_SECTION_NAME);
-
-    assertThat(sectionContent.get(CREATE_CONNECTION__NAME)).isEqualTo(connectionConfig.getName());
-    assertThat(sectionContent.get(CREATE_CONNECTION__URL)).isEqualTo(connectionConfig.getUrl());
-    assertThat(sectionContent.get(CREATE_CONNECTION__USER)).isEqualTo(connectionConfig.getUser());
-    assertThat(sectionContent.get(CREATE_CONNECTION__PASSWORD)).isEqualTo(null);
-
-    GfJsonObject tableContent =
-        sectionContent.getJSONObject(TABLE_DATA_ACCESSOR + "-" + CREATE_CONNECTION__PARAMS)
-            .getJSONObject("content");
-    assertThat(tableContent.get("Param Name")).isNull();
-    assertThat(tableContent.get("Value")).isNull();
-  }
-
-  @Test
-  public void doesNotDisplayParametersWithNoValue() throws Exception {
-    connectionConfig = new ConnectionConfigBuilder().withName(CONNECTION).withUrl("myUrl").build();
-
-    service.createConnectionConfig(connectionConfig);
-    Result result = command.describeConnection(CONNECTION);
-
-    assertThat(result.getStatus()).isSameAs(Result.Status.OK);
-    CommandResult commandResult = (CommandResult) result;
-    GfJsonObject sectionContent = commandResult.getTableContent()
-        .getJSONObject(SECTION_DATA_ACCESSOR + "-" + RESULT_SECTION_NAME);
-
-    assertThat(sectionContent.get(CREATE_CONNECTION__NAME)).isEqualTo(connectionConfig.getName());
-    assertThat(sectionContent.get(CREATE_CONNECTION__URL)).isEqualTo(connectionConfig.getUrl());
-    assertThat(sectionContent.get(CREATE_CONNECTION__PASSWORD)).isNull();
-  }
-}
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
new file mode 100644
index 0000000..d1cba15
--- /dev/null
+++ b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeConnectionCommandTest.java
@@ -0,0 +1,92 @@
+/*
+ * 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.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
+import org.apache.geode.distributed.ClusterConfigurationService;
+import org.apache.geode.distributed.internal.InternalClusterConfigurationService;
+import org.apache.geode.test.junit.categories.UnitTest;
+import org.apache.geode.test.junit.rules.GfshParserRule;
+
+@Category(UnitTest.class)
+public class DescribeConnectionCommandTest {
+  public static final String COMMAND = "describe jdbc-connection --name=name ";
+  private DescribeConnectionCommand command;
+  private ClusterConfigurationService ccService;
+
+  @ClassRule
+  public static GfshParserRule gfsh = new GfshParserRule();
+
+  @Before
+  public void setUp() throws Exception {
+    command = spy(DescribeConnectionCommand.class);
+    ccService = mock(InternalClusterConfigurationService.class);
+    doReturn(ccService).when(command).getConfigurationService();
+  }
+
+  @Test
+  public void requiredParameter() {
+    gfsh.executeAndAssertThat(command, "describe jdbc-connection").statusIsError()
+        .containsOutput("Invalid command");
+  }
+
+  @Test
+  public void whenCCServiceIsNotAvailable() {
+    doReturn(null).when(command).getConfigurationService();
+    gfsh.executeAndAssertThat(command, COMMAND).statusIsSuccess()
+        .containsOutput("cluster configuration service is not running");
+  }
+
+  @Test
+  public void whenCCServiceIsRunningAndNoConnectorServiceFound() {
+    gfsh.executeAndAssertThat(command, COMMAND).statusIsError()
+        .containsOutput("connection named 'name' not found");
+  }
+
+  @Test
+  public void whenCCServiceIsRunningAndNoConnectionFound() {
+    ConnectorService connectorService = mock(ConnectorService.class);
+    when(ccService.getCustomCacheElement(any(), any(), any())).thenReturn(connectorService);
+    gfsh.executeAndAssertThat(command, COMMAND).statusIsError()
+        .containsOutput("connection named 'name' not found");
+  }
+
+  @Test
+  public void successfulResult() {
+    // connection found in CC
+    ConnectorService.Connection connection = new ConnectorService.Connection("name1", "url1",
+        "user1", "password1", "param1:value1,param2:value2");
+
+    ConnectorService connectorService = mock(ConnectorService.class);
+    when(ccService.getCustomCacheElement(any(), any(), any())).thenReturn(connectorService);
+    when(ccService.findIdentifiable(any(), any())).thenReturn(connection);
+
+    gfsh.executeAndAssertThat(command, COMMAND).statusIsSuccess().containsOutput("name", "name1")
+        .containsOutput("url", "url1").containsOutput("user", "user1")
+        .containsOutput("password", "********").containsOutput("param1", "value1")
+        .containsOutput("param2", "value2");
+  }
+}
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
deleted file mode 100644
index 1aa0c89..0000000
--- a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeConnectionFunctionTest.java
+++ /dev/null
@@ -1,138 +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 static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import java.io.Serializable;
-
-import org.apache.commons.lang.SerializationUtils;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.mockito.ArgumentCaptor;
-
-import org.apache.geode.cache.execute.FunctionContext;
-import org.apache.geode.cache.execute.ResultSender;
-import org.apache.geode.connectors.jdbc.internal.ConnectionConfiguration;
-import org.apache.geode.connectors.jdbc.internal.JdbcConnectorService;
-import org.apache.geode.distributed.DistributedMember;
-import org.apache.geode.distributed.DistributedSystem;
-import org.apache.geode.internal.cache.InternalCache;
-import org.apache.geode.management.internal.cli.functions.CliFunctionResult;
-import org.apache.geode.test.junit.categories.UnitTest;
-
-@Category(UnitTest.class)
-public class DescribeConnectionFunctionTest {
-
-  private static final String EXISTING_CONFIG = "existingConfig";
-
-  private DescribeConnectionFunction function;
-  private JdbcConnectorService service;
-  private FunctionContext<String> context;
-  private ConnectionConfiguration connectionConfig;
-  private ResultSender<Object> resultSender;
-
-  @Before
-  public void setUp() {
-    function = new DescribeConnectionFunction();
-
-    InternalCache cache = mock(InternalCache.class);
-    context = mock(FunctionContext.class);
-    service = mock(JdbcConnectorService.class);
-    connectionConfig = mock(ConnectionConfiguration.class);
-    resultSender = mock(ResultSender.class);
-
-    DistributedMember member = mock(DistributedMember.class);
-    DistributedSystem system = mock(DistributedSystem.class);
-
-    when(context.getResultSender()).thenReturn(resultSender);
-    when(context.getCache()).thenReturn(cache);
-    when(cache.getService(eq(JdbcConnectorService.class))).thenReturn(service);
-    when(service.getConnectionConfig(EXISTING_CONFIG)).thenReturn(connectionConfig);
-    when(cache.getDistributedSystem()).thenReturn(system);
-    when(system.getDistributedMember()).thenReturn(member);
-  }
-
-  @Test
-  public void isHAReturnsFalse() {
-    assertThat(function.isHA()).isFalse();
-  }
-
-  @Test
-  public void getIdReturnsNameOfClass() {
-    assertThat(function.getId()).isEqualTo(function.getClass().getName());
-  }
-
-  @Test
-  public void serializes() {
-    Serializable original = function;
-    Object copy = SerializationUtils.clone(original);
-    assertThat(copy).isNotSameAs(original).isInstanceOf(DescribeConnectionFunction.class);
-  }
-
-  @Test
-  public void returnsResultWithCorrectConfig() {
-    when(context.getArguments()).thenReturn(EXISTING_CONFIG);
-
-    function.execute(context);
-
-    ArgumentCaptor<Object> argument = ArgumentCaptor.forClass(Object.class);
-    verify(resultSender, times(1)).lastResult(argument.capture());
-    assertThat(argument.getValue()).isSameAs(connectionConfig);
-  }
-
-  @Test
-  public void returnNullWithNonExistingConfig() {
-    when(context.getArguments()).thenReturn("non existing");
-
-    function.execute(context);
-
-    ArgumentCaptor<Object> argument = ArgumentCaptor.forClass(Object.class);
-    verify(resultSender, times(1)).lastResult(argument.capture());
-    assertThat(argument.getValue()).isNull();
-
-  }
-
-  @Test
-  public void executeReturnsResultForExceptionWithoutMessage() {
-    when(service.getConnectionConfig(any())).thenThrow(new NullPointerException());
-
-    function.execute(context);
-
-    ArgumentCaptor<CliFunctionResult> argument = ArgumentCaptor.forClass(CliFunctionResult.class);
-    verify(resultSender, times(1)).lastResult(argument.capture());
-    assertThat(argument.getValue().getMessage()).contains(NullPointerException.class.getName());
-  }
-
-  @Test
-  public void executeReturnsResultForExceptionWithMessage() {
-    when(service.getConnectionConfig(any()))
-        .thenThrow(new IllegalArgumentException("some message"));
-
-    function.execute(context);
-
-    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());
-  }
-}
diff --git a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeMappingCommandDUnitTest.java b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeMappingCommandDUnitTest.java
index 736eb26..39b90a5 100644
--- a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeMappingCommandDUnitTest.java
+++ b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeMappingCommandDUnitTest.java
@@ -14,14 +14,15 @@
  */
 package org.apache.geode.connectors.jdbc.internal.cli;
 
+import static org.apache.geode.connectors.jdbc.internal.cli.CreateMappingCommand.CREATE_MAPPING;
 import static org.apache.geode.connectors.jdbc.internal.cli.CreateMappingCommand.CREATE_MAPPING__CONNECTION_NAME;
+import static org.apache.geode.connectors.jdbc.internal.cli.CreateMappingCommand.CREATE_MAPPING__FIELD_MAPPING;
 import static org.apache.geode.connectors.jdbc.internal.cli.CreateMappingCommand.CREATE_MAPPING__PDX_CLASS_NAME;
 import static org.apache.geode.connectors.jdbc.internal.cli.CreateMappingCommand.CREATE_MAPPING__REGION_NAME;
 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 static org.apache.geode.connectors.jdbc.internal.cli.DescribeMappingCommand.DESCRIBE_MAPPING;
 import static org.apache.geode.connectors.jdbc.internal.cli.DescribeMappingCommand.DESCRIBE_MAPPING__REGION_NAME;
-import static org.assertj.core.api.Assertions.assertThat;
 
 import java.io.Serializable;
 
@@ -30,11 +31,6 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 
-import org.apache.geode.connectors.jdbc.internal.JdbcConnectorService;
-import org.apache.geode.connectors.jdbc.internal.RegionMapping;
-import org.apache.geode.connectors.jdbc.internal.RegionMappingBuilder;
-import org.apache.geode.connectors.jdbc.internal.RegionMappingExistsException;
-import org.apache.geode.internal.cache.InternalCache;
 import org.apache.geode.management.internal.cli.util.CommandStringBuilder;
 import org.apache.geode.test.dunit.rules.ClusterStartupRule;
 import org.apache.geode.test.dunit.rules.MemberVM;
@@ -69,9 +65,18 @@ public class DescribeMappingCommandDUnitTest implements Serializable {
 
   @Test
   public void describesExistingMapping() {
-    server.invoke(this::createMapping);
-    CommandStringBuilder csb = new CommandStringBuilder(DESCRIBE_MAPPING)
-        .addOption(DESCRIBE_MAPPING__REGION_NAME, REGION_NAME);
+    CommandStringBuilder csb = new CommandStringBuilder(CREATE_MAPPING);
+    csb.addOption(CREATE_MAPPING__REGION_NAME, "testRegion");
+    csb.addOption(CREATE_MAPPING__CONNECTION_NAME, "connection");
+    csb.addOption(CREATE_MAPPING__TABLE_NAME, "testTable");
+    csb.addOption(CREATE_MAPPING__PDX_CLASS_NAME, "myPdxClass");
+    csb.addOption(CREATE_MAPPING__VALUE_CONTAINS_PRIMARY_KEY, "true");
+    csb.addOption(CREATE_MAPPING__FIELD_MAPPING, "field1:column1,field2:column2");
+
+    gfsh.executeAndAssertThat(csb.toString()).statusIsSuccess();
+
+    csb = new CommandStringBuilder(DESCRIBE_MAPPING).addOption(DESCRIBE_MAPPING__REGION_NAME,
+        REGION_NAME);
 
     CommandResultAssert commandResultAssert = gfsh.executeAndAssertThat(csb.toString());
 
@@ -94,24 +99,8 @@ public class DescribeMappingCommandDUnitTest implements Serializable {
 
     CommandResultAssert commandResultAssert = gfsh.executeAndAssertThat(csb.toString());
 
-    commandResultAssert.statusIsSuccess();
-    commandResultAssert
-        .containsOutput(String.format("Mapping for region '%s' not found", "nonExisting"));
-  }
-
-  private void createMapping() throws RegionMappingExistsException {
-    InternalCache cache = ClusterStartupRule.getCache();
-    JdbcConnectorService service = cache.getService(JdbcConnectorService.class);
-
-    String[] fieldMappings = new String[] {"field1:column1", "field2:column2"};
-    RegionMapping regionMapping = new RegionMappingBuilder().withRegionName(REGION_NAME)
-        .withConnectionConfigName("connection").withTableName("testTable")
-        .withPdxClassName("myPdxClass").withPrimaryKeyInValue(true)
-        .withFieldToColumnMappings(fieldMappings).build();
-    service.createRegionMapping(regionMapping);
-
-    assertThat(service.getMappingForRegion(REGION_NAME)).isNotNull();
+    commandResultAssert.statusIsError();
+    commandResultAssert.containsOutput(
+        String.format("(Experimental) \n" + "mapping for region 'nonExisting' not found"));
   }
-
-
 }
diff --git a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeMappingCommandIntegrationTest.java b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeMappingCommandIntegrationTest.java
deleted file mode 100644
index b5466ba..0000000
--- a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeMappingCommandIntegrationTest.java
+++ /dev/null
@@ -1,145 +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.apache.geode.connectors.jdbc.internal.cli.CreateMappingCommand.CREATE_MAPPING__CONNECTION_NAME;
-import static org.apache.geode.connectors.jdbc.internal.cli.CreateMappingCommand.CREATE_MAPPING__PDX_CLASS_NAME;
-import static org.apache.geode.connectors.jdbc.internal.cli.CreateMappingCommand.CREATE_MAPPING__REGION_NAME;
-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 static org.apache.geode.connectors.jdbc.internal.cli.DescribeMappingCommand.FIELD_TO_COLUMN_TABLE;
-import static org.apache.geode.connectors.jdbc.internal.cli.DescribeMappingCommand.RESULT_SECTION_NAME;
-import static org.apache.geode.distributed.ConfigurationProperties.ENABLE_CLUSTER_CONFIGURATION;
-import static org.apache.geode.management.internal.cli.result.AbstractResultData.SECTION_DATA_ACCESSOR;
-import static org.apache.geode.management.internal.cli.result.AbstractResultData.TABLE_DATA_ACCESSOR;
-import static org.assertj.core.api.Assertions.assertThat;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-
-import org.apache.geode.cache.CacheFactory;
-import org.apache.geode.connectors.jdbc.internal.JdbcConnectorService;
-import org.apache.geode.connectors.jdbc.internal.RegionMapping;
-import org.apache.geode.connectors.jdbc.internal.RegionMappingBuilder;
-import org.apache.geode.internal.cache.InternalCache;
-import org.apache.geode.management.cli.Result;
-import org.apache.geode.management.internal.cli.json.GfJsonObject;
-import org.apache.geode.management.internal.cli.result.CommandResult;
-import org.apache.geode.test.junit.categories.IntegrationTest;
-
-@Category(IntegrationTest.class)
-public class DescribeMappingCommandIntegrationTest {
-  private static final String REGION_NAME = "testRegion";
-
-  private InternalCache cache;
-  private JdbcConnectorService service;
-  private RegionMapping regionMapping;
-  private DescribeMappingCommand command;
-
-  @Before
-  public void setup() {
-    String[] fieldMappings = new String[] {"field1:column1", "field2:column2"};
-
-    cache = (InternalCache) new CacheFactory().set("locators", "").set("mcast-port", "0")
-        .set(ENABLE_CLUSTER_CONFIGURATION, "true").create();
-    service = cache.getService(JdbcConnectorService.class);
-    regionMapping = new RegionMappingBuilder().withRegionName(REGION_NAME)
-        .withConnectionConfigName("connection").withTableName("testTable")
-        .withPdxClassName("myPdxClass").withPrimaryKeyInValue(true)
-        .withFieldToColumnMappings(fieldMappings).build();
-    command = new DescribeMappingCommand();
-    command.setCache(cache);
-  }
-
-  @After
-  public void tearDown() {
-    cache.close();
-  }
-
-  @Test
-  public void displaysNoMappingFoundMessageWhenMappingDoesNotExist() {
-    String nonExistingMappingRegionName = "non existing";
-    Result result = command.describeMapping(nonExistingMappingRegionName);
-
-    assertThat(result.getStatus()).isSameAs(Result.Status.OK);
-    CommandResult commandResult = (CommandResult) result;
-    String tableContent = commandResult.getTableContent().toString();
-    assertThat(tableContent)
-        .contains("Mapping for region '" + nonExistingMappingRegionName + "' not found");
-  }
-
-  @Test
-  public void displaysMappingInformationWhenMappingExists() throws Exception {
-    service.createRegionMapping(regionMapping);
-    Result result = command.describeMapping(REGION_NAME);
-
-    assertThat(result.getStatus()).isSameAs(Result.Status.OK);
-    CommandResult commandResult = (CommandResult) result;
-    GfJsonObject sectionContent = commandResult.getTableContent()
-        .getJSONObject(SECTION_DATA_ACCESSOR + "-" + RESULT_SECTION_NAME);
-
-    assertThat(sectionContent.get(CREATE_MAPPING__REGION_NAME))
-        .isEqualTo(regionMapping.getRegionName());
-    assertThat(sectionContent.get(CREATE_MAPPING__CONNECTION_NAME))
-        .isEqualTo(regionMapping.getConnectionConfigName());
-    assertThat(sectionContent.get(CREATE_MAPPING__TABLE_NAME))
-        .isEqualTo(regionMapping.getTableName());
-    assertThat(sectionContent.get(CREATE_MAPPING__PDX_CLASS_NAME))
-        .isEqualTo(regionMapping.getPdxClassName());
-    assertThat(sectionContent.get(CREATE_MAPPING__VALUE_CONTAINS_PRIMARY_KEY))
-        .isEqualTo(regionMapping.isPrimaryKeyInValue());
-
-    GfJsonObject tableContent = sectionContent
-        .getJSONObject(TABLE_DATA_ACCESSOR + "-" + FIELD_TO_COLUMN_TABLE).getJSONObject("content");
-
-    regionMapping.getFieldToColumnMap().entrySet().forEach((entry) -> {
-      assertThat(tableContent.get("Field").toString()).contains(entry.getKey());
-      assertThat(tableContent.get("Column").toString()).contains(entry.getValue());
-    });
-  }
-
-  @Test
-  public void displaysMappingInformationWhenMappingWithNoFieldToColumnsExists() throws Exception {
-    regionMapping = new RegionMappingBuilder().withRegionName(REGION_NAME)
-        .withConnectionConfigName("connection").withTableName("testTable")
-        .withPdxClassName("myPdxClass").withPrimaryKeyInValue(true).withFieldToColumnMappings(null)
-        .build();
-    service.createRegionMapping(regionMapping);
-    Result result = command.describeMapping(REGION_NAME);
-
-    assertThat(result.getStatus()).isSameAs(Result.Status.OK);
-    CommandResult commandResult = (CommandResult) result;
-    GfJsonObject sectionContent = commandResult.getTableContent()
-        .getJSONObject(SECTION_DATA_ACCESSOR + "-" + RESULT_SECTION_NAME);
-
-    assertThat(sectionContent.get(CREATE_MAPPING__REGION_NAME))
-        .isEqualTo(regionMapping.getRegionName());
-    assertThat(sectionContent.get(CREATE_MAPPING__CONNECTION_NAME))
-        .isEqualTo(regionMapping.getConnectionConfigName());
-    assertThat(sectionContent.get(CREATE_MAPPING__TABLE_NAME))
-        .isEqualTo(regionMapping.getTableName());
-    assertThat(sectionContent.get(CREATE_MAPPING__PDX_CLASS_NAME))
-        .isEqualTo(regionMapping.getPdxClassName());
-    assertThat(sectionContent.get(CREATE_MAPPING__VALUE_CONTAINS_PRIMARY_KEY))
-        .isEqualTo(regionMapping.isPrimaryKeyInValue());
-
-    GfJsonObject tableContent = sectionContent
-        .getJSONObject(TABLE_DATA_ACCESSOR + "-" + FIELD_TO_COLUMN_TABLE).getJSONObject("content");
-    assertThat(tableContent.get("Field")).isNull();
-    assertThat(tableContent.get("Column")).isNull();
-  }
-}
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
new file mode 100644
index 0000000..d5fcb5d
--- /dev/null
+++ b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeMappingCommandTest.java
@@ -0,0 +1,98 @@
+/*
+ * 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.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
+import org.apache.geode.distributed.ClusterConfigurationService;
+import org.apache.geode.distributed.internal.InternalClusterConfigurationService;
+import org.apache.geode.test.junit.categories.UnitTest;
+import org.apache.geode.test.junit.rules.GfshParserRule;
+
+@Category(UnitTest.class)
+
+public class DescribeMappingCommandTest {
+  public static final String COMMAND = "describe jdbc-mapping --region=region ";
+  private DescribeMappingCommand command;
+  private ClusterConfigurationService ccService;
+
+  @ClassRule
+  public static GfshParserRule gfsh = new GfshParserRule();
+
+  @Before
+  public void setUp() {
+    command = spy(DescribeMappingCommand.class);
+    ccService = mock(InternalClusterConfigurationService.class);
+    doReturn(ccService).when(command).getConfigurationService();
+  }
+
+  @Test
+  public void requiredParameter() {
+    gfsh.executeAndAssertThat(command, "describe jdbc-mapping").statusIsError()
+        .containsOutput("Invalid command");
+  }
+
+  @Test
+  public void whenCCServiceIsNotAvailable() {
+    doReturn(null).when(command).getConfigurationService();
+    gfsh.executeAndAssertThat(command, COMMAND).statusIsSuccess()
+        .containsOutput("cluster configuration service is not running");
+  }
+
+  @Test
+  public void whenCCServiceIsRunningAndNoConnectorServiceFound() {
+    gfsh.executeAndAssertThat(command, COMMAND).statusIsError()
+        .containsOutput("mapping for region 'region' not found");
+  }
+
+  @Test
+  public void whenCCServiceIsRunningAndNoConnectionFound() {
+    ConnectorService connectorService = mock(ConnectorService.class);
+    when(ccService.getCustomCacheElement(any(), any(), any())).thenReturn(connectorService);
+    gfsh.executeAndAssertThat(command, COMMAND).statusIsError()
+        .containsOutput("mapping for region 'region' not found");
+  }
+
+  @Test
+  public void successfulResult() {
+    // mapping found in CC
+    ConnectorService.RegionMapping mapping =
+        new ConnectorService.RegionMapping("region1", "class1", "table1", "name1", true);
+    mapping.getFieldMapping()
+        .add(new ConnectorService.RegionMapping.FieldMapping("field1", "value1"));
+    mapping.getFieldMapping()
+        .add(new ConnectorService.RegionMapping.FieldMapping("field2", "value2"));
+
+    ConnectorService connectorService = mock(ConnectorService.class);
+    when(ccService.getCustomCacheElement(any(), any(), any())).thenReturn(connectorService);
+    when(ccService.findIdentifiable(any(), any())).thenReturn(mapping);
+
+    gfsh.executeAndAssertThat(command, COMMAND).statusIsSuccess()
+        .containsOutput("region", "region1").containsOutput("connection", "name1")
+        .containsOutput("table", "table1").containsOutput("pdx-class-name", "class1")
+        .containsOutput("value-contains-primary-key", "true").containsOutput("field1", "value1")
+        .containsOutput("field2", "value2");
+  }
+}
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
deleted file mode 100644
index 1cd423c..0000000
--- a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeMappingFunctionTest.java
+++ /dev/null
@@ -1,138 +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 static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import java.io.Serializable;
-
-import org.apache.commons.lang.SerializationUtils;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.mockito.ArgumentCaptor;
-
-import org.apache.geode.cache.execute.FunctionContext;
-import org.apache.geode.cache.execute.ResultSender;
-import org.apache.geode.connectors.jdbc.internal.JdbcConnectorService;
-import org.apache.geode.connectors.jdbc.internal.RegionMapping;
-import org.apache.geode.distributed.DistributedMember;
-import org.apache.geode.distributed.DistributedSystem;
-import org.apache.geode.internal.cache.InternalCache;
-import org.apache.geode.management.internal.cli.functions.CliFunctionResult;
-import org.apache.geode.test.junit.categories.UnitTest;
-
-@Category(UnitTest.class)
-public class DescribeMappingFunctionTest {
-
-  private static final String EXISTING_MAPPING = "existingMapping";
-
-  private DescribeMappingFunction function;
-  private JdbcConnectorService service;
-  private FunctionContext<String> context;
-  private RegionMapping regionMapping;
-  private ResultSender<Object> resultSender;
-
-  @Before
-  public void setUp() {
-    function = new DescribeMappingFunction();
-
-    InternalCache cache = mock(InternalCache.class);
-    context = mock(FunctionContext.class);
-    service = mock(JdbcConnectorService.class);
-    regionMapping = mock(RegionMapping.class);
-    resultSender = mock(ResultSender.class);
-
-    DistributedMember member = mock(DistributedMember.class);
-    DistributedSystem system = mock(DistributedSystem.class);
-
-    when(context.getResultSender()).thenReturn(resultSender);
-    when(context.getCache()).thenReturn(cache);
-    when(cache.getService(eq(JdbcConnectorService.class))).thenReturn(service);
-    when(service.getMappingForRegion(EXISTING_MAPPING)).thenReturn(regionMapping);
-    when(cache.getDistributedSystem()).thenReturn(system);
-    when(system.getDistributedMember()).thenReturn(member);
-  }
-
-  @Test
-  public void isHAReturnsFalse() {
-    assertThat(function.isHA()).isFalse();
-  }
-
-  @Test
-  public void getIdReturnsNameOfClass() {
-    assertThat(function.getId()).isEqualTo(function.getClass().getName());
-  }
-
-  @Test
-  public void serializes() {
-    Serializable original = function;
-    Object copy = SerializationUtils.clone(original);
-    assertThat(copy).isNotSameAs(original).isInstanceOf(DescribeMappingFunction.class);
-  }
-
-  @Test
-  public void returnsResultWithCorrectConfig() {
-    when(context.getArguments()).thenReturn(EXISTING_MAPPING);
-
-    function.execute(context);
-
-    ArgumentCaptor<Object> argument = ArgumentCaptor.forClass(Object.class);
-    verify(resultSender, times(1)).lastResult(argument.capture());
-    assertThat(argument.getValue()).isSameAs(regionMapping);
-  }
-
-  @Test
-  public void returnNullWithNonExistingConfig() {
-    when(context.getArguments()).thenReturn("non existing");
-
-    function.execute(context);
-
-    ArgumentCaptor<Object> argument = ArgumentCaptor.forClass(Object.class);
-    verify(resultSender, times(1)).lastResult(argument.capture());
-    assertThat(argument.getValue()).isNull();
-
-  }
-
-  @Test
-  public void executeReturnsResultForExceptionWithoutMessage() {
-    when(service.getMappingForRegion(any())).thenThrow(new NullPointerException());
-
-    function.execute(context);
-
-    ArgumentCaptor<CliFunctionResult> argument = ArgumentCaptor.forClass(CliFunctionResult.class);
-    verify(resultSender, times(1)).lastResult(argument.capture());
-    assertThat(argument.getValue().getMessage()).contains(NullPointerException.class.getName());
-  }
-
-  @Test
-  public void executeReturnsResultForExceptionWithMessage() {
-    when(service.getMappingForRegion(any()))
-        .thenThrow(new IllegalArgumentException("some message"));
-
-    function.execute(context);
-
-    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());
-  }
-}
diff --git a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyConnectionCommandDUnitTest.java b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyConnectionCommandDUnitTest.java
index 4d05314..c52946c 100644
--- a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyConnectionCommandDUnitTest.java
+++ b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyConnectionCommandDUnitTest.java
@@ -14,6 +14,12 @@
  */
 package org.apache.geode.connectors.jdbc.internal.cli;
 
+import static org.apache.geode.connectors.jdbc.internal.cli.CreateConnectionCommand.CREATE_CONNECTION;
+import static org.apache.geode.connectors.jdbc.internal.cli.CreateConnectionCommand.CREATE_CONNECTION__NAME;
+import static org.apache.geode.connectors.jdbc.internal.cli.CreateConnectionCommand.CREATE_CONNECTION__PARAMS;
+import static org.apache.geode.connectors.jdbc.internal.cli.CreateConnectionCommand.CREATE_CONNECTION__PASSWORD;
+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 static org.apache.geode.connectors.jdbc.internal.cli.DestroyConnectionCommand.DESTROY_CONNECTION;
 import static org.apache.geode.connectors.jdbc.internal.cli.DestroyConnectionCommand.DESTROY_CONNECTION__NAME;
 import static org.assertj.core.api.Assertions.assertThat;
@@ -25,10 +31,8 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 
-import org.apache.geode.connectors.jdbc.internal.ConnectionConfigBuilder;
-import org.apache.geode.connectors.jdbc.internal.ConnectionConfigExistsException;
-import org.apache.geode.connectors.jdbc.internal.ConnectionConfiguration;
 import org.apache.geode.connectors.jdbc.internal.JdbcConnectorService;
+import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
 import org.apache.geode.distributed.internal.InternalLocator;
 import org.apache.geode.internal.cache.InternalCache;
 import org.apache.geode.management.internal.cli.util.CommandStringBuilder;
@@ -62,9 +66,16 @@ public class DestroyConnectionCommandDUnitTest implements Serializable {
     locator = startupRule.startLocatorVM(0);
     server = startupRule.startServerVM(1, locator.getPort());
 
-    server.invoke(() -> createConnection());
-
     gfsh.connectAndVerify(locator);
+
+    CommandStringBuilder csb = new CommandStringBuilder(CREATE_CONNECTION);
+    csb.addOption(CREATE_CONNECTION__NAME, "name");
+    csb.addOption(CREATE_CONNECTION__URL, "url");
+    csb.addOption(CREATE_CONNECTION__USER, "username");
+    csb.addOption(CREATE_CONNECTION__PASSWORD, "secret");
+    csb.addOption(CREATE_CONNECTION__PARAMS, "param1:value1,param2:value2");
+
+    gfsh.executeAndAssertThat(csb.toString()).statusIsSuccess();
   }
 
   @Test
@@ -82,18 +93,9 @@ public class DestroyConnectionCommandDUnitTest implements Serializable {
 
     server.invoke(() -> {
       InternalCache cache = ClusterStartupRule.getCache();
-      ConnectionConfiguration config =
+      ConnectorService.Connection config =
           cache.getService(JdbcConnectorService.class).getConnectionConfig("name");
       assertThat(config).isNull();
     });
   }
-
-  private void createConnection() throws ConnectionConfigExistsException {
-    InternalCache cache = ClusterStartupRule.getCache();
-    JdbcConnectorService service = cache.getService(JdbcConnectorService.class);
-
-    service.createConnectionConfig(new ConnectionConfigBuilder().withName(connectionName).build());
-
-    assertThat(service.getConnectionConfig(connectionName)).isNotNull();
-  }
 }
diff --git a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyConnectionCommandIntegrationTest.java b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyConnectionCommandIntegrationTest.java
index 4335886..cc8287d 100644
--- a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyConnectionCommandIntegrationTest.java
+++ b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyConnectionCommandIntegrationTest.java
@@ -23,9 +23,8 @@ import org.junit.Test;
 import org.junit.experimental.categories.Category;
 
 import org.apache.geode.cache.CacheFactory;
-import org.apache.geode.connectors.jdbc.internal.ConnectionConfigBuilder;
-import org.apache.geode.connectors.jdbc.internal.ConnectionConfiguration;
 import org.apache.geode.connectors.jdbc.internal.JdbcConnectorService;
+import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
 import org.apache.geode.internal.cache.InternalCache;
 import org.apache.geode.management.cli.Result;
 import org.apache.geode.test.junit.categories.IntegrationTest;
@@ -35,7 +34,7 @@ public class DestroyConnectionCommandIntegrationTest {
 
   private String connectionName;
   private InternalCache cache;
-  private ConnectionConfiguration connectionConfig;
+  private ConnectorService.Connection connectionConfig;
 
   private DestroyConnectionCommand command;
 
@@ -44,8 +43,8 @@ public class DestroyConnectionCommandIntegrationTest {
     connectionName = "connectionName";
 
     String[] params = new String[] {"param1:value1", "param2:value2"};
-    connectionConfig = new ConnectionConfigBuilder().withName(connectionName).withUrl("url")
-        .withUser("user").withPassword("password").withParameters(params).build();
+    connectionConfig =
+        new ConnectorService.Connection(connectionName, "url", "user", "password", params);
 
     cache = (InternalCache) new CacheFactory().set("locators", "").set("mcast-port", "0")
         .set(ENABLE_CLUSTER_CONFIGURATION, "true").create();
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 3994b94..8911c71 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
@@ -31,9 +31,8 @@ import org.mockito.ArgumentCaptor;
 
 import org.apache.geode.cache.execute.FunctionContext;
 import org.apache.geode.cache.execute.ResultSender;
-import org.apache.geode.connectors.jdbc.internal.ConnectionConfigBuilder;
-import org.apache.geode.connectors.jdbc.internal.ConnectionConfiguration;
 import org.apache.geode.connectors.jdbc.internal.JdbcConnectorService;
+import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
 import org.apache.geode.distributed.DistributedMember;
 import org.apache.geode.distributed.DistributedSystem;
 import org.apache.geode.internal.cache.InternalCache;
@@ -48,7 +47,7 @@ public class DestroyConnectionFunctionTest {
   private DestroyConnectionFunction function;
   private FunctionContext<String> context;
   private ResultSender<Object> resultSender;
-  private ConnectionConfiguration configuration;
+  private ConnectorService.Connection configuration;
   private JdbcConnectorService service;
 
   @Before
@@ -67,7 +66,7 @@ public class DestroyConnectionFunctionTest {
     when(context.getArguments()).thenReturn(connectionName);
     when(cache.getService(eq(JdbcConnectorService.class))).thenReturn(service);
 
-    configuration = new ConnectionConfigBuilder().build();
+    configuration = new ConnectorService.Connection();
 
     function = new DestroyConnectionFunction();
   }
diff --git a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyMappingCommandDunitTest.java b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyMappingCommandDunitTest.java
index 23c200a..9fe5f5f 100644
--- a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyMappingCommandDunitTest.java
+++ b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyMappingCommandDunitTest.java
@@ -14,6 +14,13 @@
  */
 package org.apache.geode.connectors.jdbc.internal.cli;
 
+import static org.apache.geode.connectors.jdbc.internal.cli.CreateMappingCommand.CREATE_MAPPING;
+import static org.apache.geode.connectors.jdbc.internal.cli.CreateMappingCommand.CREATE_MAPPING__CONNECTION_NAME;
+import static org.apache.geode.connectors.jdbc.internal.cli.CreateMappingCommand.CREATE_MAPPING__FIELD_MAPPING;
+import static org.apache.geode.connectors.jdbc.internal.cli.CreateMappingCommand.CREATE_MAPPING__PDX_CLASS_NAME;
+import static org.apache.geode.connectors.jdbc.internal.cli.CreateMappingCommand.CREATE_MAPPING__REGION_NAME;
+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 static org.apache.geode.connectors.jdbc.internal.cli.DestroyMappingCommand.DESTROY_MAPPING;
 import static org.apache.geode.connectors.jdbc.internal.cli.DestroyMappingCommand.DESTROY_MAPPING__REGION_NAME;
 import static org.assertj.core.api.Assertions.assertThat;
@@ -26,9 +33,7 @@ import org.junit.Test;
 import org.junit.experimental.categories.Category;
 
 import org.apache.geode.connectors.jdbc.internal.JdbcConnectorService;
-import org.apache.geode.connectors.jdbc.internal.RegionMapping;
-import org.apache.geode.connectors.jdbc.internal.RegionMappingBuilder;
-import org.apache.geode.connectors.jdbc.internal.RegionMappingExistsException;
+import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
 import org.apache.geode.distributed.internal.InternalLocator;
 import org.apache.geode.internal.cache.InternalCache;
 import org.apache.geode.management.internal.cli.util.CommandStringBuilder;
@@ -63,9 +68,17 @@ public class DestroyMappingCommandDunitTest implements Serializable {
     locator = startupRule.startLocatorVM(0);
     server = startupRule.startServerVM(1, locator.getPort());
 
-    server.invoke(() -> createRegionMapping());
-
     gfsh.connectAndVerify(locator);
+
+    CommandStringBuilder csb = new CommandStringBuilder(CREATE_MAPPING);
+    csb.addOption(CREATE_MAPPING__REGION_NAME, "testRegion");
+    csb.addOption(CREATE_MAPPING__CONNECTION_NAME, "connection");
+    csb.addOption(CREATE_MAPPING__TABLE_NAME, "myTable");
+    csb.addOption(CREATE_MAPPING__PDX_CLASS_NAME, "myPdxClass");
+    csb.addOption(CREATE_MAPPING__VALUE_CONTAINS_PRIMARY_KEY, "true");
+    csb.addOption(CREATE_MAPPING__FIELD_MAPPING, "field1:column1,field2:column2");
+
+    gfsh.executeAndAssertThat(csb.toString()).statusIsSuccess();
   }
 
   @Test
@@ -83,19 +96,9 @@ public class DestroyMappingCommandDunitTest implements Serializable {
 
     server.invoke(() -> {
       InternalCache cache = ClusterStartupRule.getCache();
-      RegionMapping mapping =
+      ConnectorService.RegionMapping mapping =
           cache.getService(JdbcConnectorService.class).getMappingForRegion("testRegion");
       assertThat(mapping).isNull();
     });
   }
-
-  private void createRegionMapping() throws RegionMappingExistsException {
-    InternalCache cache = ClusterStartupRule.getCache();
-    JdbcConnectorService service = cache.getService(JdbcConnectorService.class);
-
-    service.createRegionMapping(new RegionMappingBuilder().withRegionName(regionName).build());
-
-    assertThat(service.getMappingForRegion(regionName)).isNotNull();
-  }
-
 }
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 f23e6b7..5ee7360 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
@@ -32,8 +32,7 @@ import org.mockito.ArgumentCaptor;
 import org.apache.geode.cache.execute.FunctionContext;
 import org.apache.geode.cache.execute.ResultSender;
 import org.apache.geode.connectors.jdbc.internal.JdbcConnectorService;
-import org.apache.geode.connectors.jdbc.internal.RegionMapping;
-import org.apache.geode.connectors.jdbc.internal.RegionMappingBuilder;
+import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
 import org.apache.geode.distributed.DistributedMember;
 import org.apache.geode.distributed.DistributedSystem;
 import org.apache.geode.internal.cache.InternalCache;
@@ -48,7 +47,7 @@ public class DestroyMappingCommandFunctionTest {
   private DestroyMappingFunction function;
   private FunctionContext<String> context;
   private ResultSender<Object> resultSender;
-  private RegionMapping mapping;
+  private ConnectorService.RegionMapping mapping;
   private JdbcConnectorService service;
 
   @Before
@@ -67,7 +66,7 @@ public class DestroyMappingCommandFunctionTest {
     when(context.getArguments()).thenReturn(regionName);
     when(cache.getService(eq(JdbcConnectorService.class))).thenReturn(service);
 
-    mapping = new RegionMappingBuilder().build();
+    mapping = new ConnectorService.RegionMapping();
 
     function = new DestroyMappingFunction();
   }
diff --git a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyMappingCommandIntegrationTest.java b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyMappingCommandIntegrationTest.java
index 8d02788..a651dc5 100644
--- a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyMappingCommandIntegrationTest.java
+++ b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyMappingCommandIntegrationTest.java
@@ -24,8 +24,7 @@ import org.junit.experimental.categories.Category;
 
 import org.apache.geode.cache.CacheFactory;
 import org.apache.geode.connectors.jdbc.internal.JdbcConnectorService;
-import org.apache.geode.connectors.jdbc.internal.RegionMapping;
-import org.apache.geode.connectors.jdbc.internal.RegionMappingBuilder;
+import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
 import org.apache.geode.internal.cache.InternalCache;
 import org.apache.geode.management.cli.Result;
 import org.apache.geode.test.junit.categories.IntegrationTest;
@@ -35,7 +34,7 @@ public class DestroyMappingCommandIntegrationTest {
 
   private String regionName;
   private InternalCache cache;
-  private RegionMapping mapping;
+  private ConnectorService.RegionMapping mapping;
 
   private DestroyMappingCommand command;
 
@@ -44,7 +43,7 @@ public class DestroyMappingCommandIntegrationTest {
     regionName = "testRegion";
 
     String[] params = new String[] {"param1:value1", "param2:value2"};
-    mapping = new RegionMappingBuilder().withRegionName(regionName).build();
+    mapping = new ConnectorService.RegionMapping(regionName, null, null, null, null);
 
     cache = (InternalCache) new CacheFactory().set("locators", "").set("mcast-port", "0")
         .set(ENABLE_CLUSTER_CONFIGURATION, "true").create();
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 951ca21..a9a0c61 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
@@ -67,12 +67,8 @@ public class JDBCConnectorFunctionsSecurityTest {
     functionStringMap.put(new AlterMappingFunction(), "*");
     functionStringMap.put(new CreateConnectionFunction(), "*");
     functionStringMap.put(new CreateMappingFunction(), "*");
-    functionStringMap.put(new DescribeConnectionFunction(), "*");
-    functionStringMap.put(new DescribeMappingFunction(), "*");
     functionStringMap.put(new DestroyConnectionFunction(), "*");
     functionStringMap.put(new DestroyMappingFunction(), "*");
-    functionStringMap.put(new ListConnectionFunction(), "*");
-    functionStringMap.put(new ListMappingFunction(), "*");
     functionStringMap.put(new InheritsDefaultPermissionsJDBCFunction(), "*");
     functionStringMap.keySet().forEach(FunctionService::registerFunction);
   }
diff --git a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/JdbcClusterConfigDistributedTest.java b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/JdbcClusterConfigDistributedTest.java
index d65e00e..64ca86a 100644
--- a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/JdbcClusterConfigDistributedTest.java
+++ b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/JdbcClusterConfigDistributedTest.java
@@ -36,8 +36,8 @@ import org.junit.experimental.categories.Category;
 
 import org.apache.geode.cache.CacheFactory;
 import org.apache.geode.connectors.jdbc.internal.JdbcConnectorService;
-import org.apache.geode.connectors.jdbc.internal.RegionMapping;
 import org.apache.geode.connectors.jdbc.internal.TableMetaDataView;
+import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
 import org.apache.geode.distributed.Locator;
 import org.apache.geode.distributed.internal.InternalLocator;
 import org.apache.geode.internal.cache.InternalCache;
@@ -136,7 +136,7 @@ public class JdbcClusterConfigDistributedTest implements Serializable {
     validateRegionMapping(service.getMappingForRegion(regionName));
   }
 
-  private void validateRegionMapping(RegionMapping regionMapping) {
+  private void validateRegionMapping(ConnectorService.RegionMapping regionMapping) {
     assertThat(regionMapping).isNotNull();
     assertThat(regionMapping.getRegionName()).isEqualTo(regionName);
     assertThat(regionMapping.getConnectionConfigName()).isEqualTo(connectionName);
diff --git a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/ListConnectionCommandDUnitTest.java b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/ListConnectionCommandDUnitTest.java
index e8bd92f..d38aa1e 100644
--- a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/ListConnectionCommandDUnitTest.java
+++ b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/ListConnectionCommandDUnitTest.java
@@ -16,7 +16,6 @@ package org.apache.geode.connectors.jdbc.internal.cli;
 
 import static org.apache.geode.connectors.jdbc.internal.cli.ListConnectionCommand.LIST_JDBC_CONNECTION;
 import static org.apache.geode.connectors.jdbc.internal.cli.ListConnectionCommand.LIST_OF_CONNECTIONS;
-import static org.assertj.core.api.Assertions.assertThat;
 
 import java.io.Serializable;
 
@@ -25,10 +24,6 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 
-import org.apache.geode.connectors.jdbc.internal.ConnectionConfigBuilder;
-import org.apache.geode.connectors.jdbc.internal.ConnectionConfigExistsException;
-import org.apache.geode.connectors.jdbc.internal.JdbcConnectorService;
-import org.apache.geode.internal.cache.InternalCache;
 import org.apache.geode.management.internal.cli.util.CommandStringBuilder;
 import org.apache.geode.test.dunit.rules.ClusterStartupRule;
 import org.apache.geode.test.dunit.rules.MemberVM;
@@ -65,10 +60,12 @@ public class ListConnectionCommandDUnitTest implements Serializable {
   }
 
   @Test
-  public void listsOneConnection() throws Exception {
-    server.invoke(() -> createOneConnection());
-    CommandStringBuilder csb = new CommandStringBuilder(LIST_JDBC_CONNECTION);
+  public void listsOneConnection() {
+    String conn1 =
+        "create jdbc-connection --name=name --url=url --user=user --password=pass --params=param1:value1,param2:value2";
+    gfsh.executeAndAssertThat(conn1).statusIsSuccess();
 
+    CommandStringBuilder csb = new CommandStringBuilder(LIST_JDBC_CONNECTION);
     CommandResultAssert commandResultAssert = gfsh.executeAndAssertThat(csb.toString());
 
     commandResultAssert.statusIsSuccess();
@@ -77,10 +74,18 @@ public class ListConnectionCommandDUnitTest implements Serializable {
   }
 
   @Test
-  public void listsMultipleConnections() throws Exception {
-    server.invoke(() -> createNConnections(3));
-    CommandStringBuilder csb = new CommandStringBuilder(LIST_JDBC_CONNECTION);
+  public void listsMultipleConnections() {
+    String conn1 =
+        "create jdbc-connection --name=name-1 --url=url --user=user --password=pass --params=param1:value1,param2:value2";
+    gfsh.executeAndAssertThat(conn1).statusIsSuccess();
+    String conn2 =
+        "create jdbc-connection --name=name-2 --url=url --user=user --password=pass --params=param1:value1,param2:value2";
+    gfsh.executeAndAssertThat(conn2).statusIsSuccess();
+    String conn3 =
+        "create jdbc-connection --name=name-3 --url=url --user=user --password=pass --params=param1:value1,param2:value2";
+    gfsh.executeAndAssertThat(conn3).statusIsSuccess();
 
+    CommandStringBuilder csb = new CommandStringBuilder(LIST_JDBC_CONNECTION);
     CommandResultAssert commandResultAssert = gfsh.executeAndAssertThat(csb.toString());
 
     commandResultAssert.statusIsSuccess();
@@ -90,7 +95,7 @@ public class ListConnectionCommandDUnitTest implements Serializable {
   }
 
   @Test
-  public void reportsNoConnectionsFound() throws Exception {
+  public void reportsNoConnectionsFound() {
     CommandStringBuilder csb = new CommandStringBuilder(LIST_JDBC_CONNECTION);
 
     CommandResultAssert commandResultAssert = gfsh.executeAndAssertThat(csb.toString());
@@ -98,24 +103,4 @@ public class ListConnectionCommandDUnitTest implements Serializable {
     commandResultAssert.statusIsSuccess();
     commandResultAssert.containsOutput("No connections found");
   }
-
-  private void createOneConnection() throws ConnectionConfigExistsException {
-    InternalCache cache = ClusterStartupRule.getCache();
-    JdbcConnectorService service = cache.getService(JdbcConnectorService.class);
-
-    service.createConnectionConfig(new ConnectionConfigBuilder().withName(connectionName).build());
-
-    assertThat(service.getConnectionConfig(connectionName)).isNotNull();
-  }
-
-  private void createNConnections(int N) throws ConnectionConfigExistsException {
-    InternalCache cache = ClusterStartupRule.getCache();
-    JdbcConnectorService service = cache.getService(JdbcConnectorService.class);
-    for (int i = 1; i <= N; i++) {
-      String name = connectionName + "-" + i;
-      service.createConnectionConfig(new ConnectionConfigBuilder().withName(name).build());
-      assertThat(service.getConnectionConfig(name)).isNotNull();
-    }
-  }
-
 }
diff --git a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/ListConnectionCommandIntegrationTest.java b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/ListConnectionCommandIntegrationTest.java
deleted file mode 100644
index bbd012f..0000000
--- a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/ListConnectionCommandIntegrationTest.java
+++ /dev/null
@@ -1,110 +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.apache.geode.connectors.jdbc.internal.cli.ListConnectionCommand.LIST_OF_CONNECTIONS;
-import static org.apache.geode.connectors.jdbc.internal.cli.ListConnectionCommand.NO_CONNECTIONS_FOUND;
-import static org.apache.geode.distributed.ConfigurationProperties.ENABLE_CLUSTER_CONFIGURATION;
-import static org.assertj.core.api.Assertions.assertThat;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-
-import org.apache.geode.cache.CacheFactory;
-import org.apache.geode.connectors.jdbc.internal.ConnectionConfigBuilder;
-import org.apache.geode.connectors.jdbc.internal.ConnectionConfiguration;
-import org.apache.geode.connectors.jdbc.internal.JdbcConnectorService;
-import org.apache.geode.internal.cache.InternalCache;
-import org.apache.geode.management.cli.Result;
-import org.apache.geode.management.internal.cli.result.CommandResult;
-import org.apache.geode.test.junit.categories.IntegrationTest;
-
-@Category(IntegrationTest.class)
-public class ListConnectionCommandIntegrationTest {
-
-  private InternalCache cache;
-  private JdbcConnectorService service;
-
-  private ConnectionConfiguration connectionConfig1;
-  private ConnectionConfiguration connectionConfig2;
-  private ConnectionConfiguration connectionConfig3;
-
-  private ListConnectionCommand command;
-
-  @Before
-  public void setup() throws Exception {
-    String[] params = new String[] {"param1:value1", "param2:value2"};
-
-    connectionConfig1 = new ConnectionConfigBuilder().withName("connection1").withUrl("url1")
-        .withUser("user1").withPassword("password1").withParameters(params).build();
-    connectionConfig2 = new ConnectionConfigBuilder().withName("connection2").withUrl("url2")
-        .withUser("user2").withPassword("password2").withParameters(params).build();
-    connectionConfig3 = new ConnectionConfigBuilder().withName("connection3").withUrl("url3")
-        .withUser("user3").withPassword("password3").withParameters(params).build();
-
-    cache = (InternalCache) new CacheFactory().set("locators", "").set("mcast-port", "0")
-        .set(ENABLE_CLUSTER_CONFIGURATION, "true").create();
-    service = cache.getService(JdbcConnectorService.class);
-
-    command = new ListConnectionCommand();
-    command.setCache(cache);
-  }
-
-  @After
-  public void tearDown() {
-    cache.close();
-  }
-
-  @Test
-  public void displaysNoConnectionsFoundWhenZeroConnectionsExist() throws Exception {
-    Result result = command.listConnection();
-
-    assertThat(result.getStatus()).isSameAs(Result.Status.OK);
-    CommandResult commandResult = (CommandResult) result;
-    String tableContent = commandResult.getTableContent().toString();
-    assertThat(tableContent).contains(NO_CONNECTIONS_FOUND);
-    assertThat(tableContent).doesNotContain(connectionConfig1.getName())
-        .doesNotContain(connectionConfig2.getName()).doesNotContain(connectionConfig3.getName());
-  }
-
-  @Test
-  public void displaysListOfConnectionsHeaderWhenOneConnectionExists() throws Exception {
-    service.createConnectionConfig(connectionConfig1);
-
-    Result result = command.listConnection();
-
-    assertThat(result.getStatus()).isSameAs(Result.Status.OK);
-    CommandResult commandResult = (CommandResult) result;
-    String tableContent = commandResult.getTableContent().toString();
-    assertThat(tableContent).contains(LIST_OF_CONNECTIONS);
-    assertThat(tableContent).contains(connectionConfig1.getName());
-  }
-
-  @Test
-  public void displaysMultipleConnectionsByName() throws Exception {
-    service.createConnectionConfig(connectionConfig1);
-    service.createConnectionConfig(connectionConfig2);
-    service.createConnectionConfig(connectionConfig3);
-
-    Result result = command.listConnection();
-
-    assertThat(result.getStatus()).isSameAs(Result.Status.OK);
-    CommandResult commandResult = (CommandResult) result;
-    assertThat(commandResult.getTableContent().toString()).contains(connectionConfig1.getName())
-        .contains(connectionConfig2.getName()).contains(connectionConfig3.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
new file mode 100644
index 0000000..e5c5c94
--- /dev/null
+++ b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/ListConnectionCommandTest.java
@@ -0,0 +1,92 @@
+/*
+ * 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.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
+import org.apache.geode.distributed.ClusterConfigurationService;
+import org.apache.geode.distributed.internal.InternalClusterConfigurationService;
+import org.apache.geode.test.junit.categories.UnitTest;
+import org.apache.geode.test.junit.rules.GfshParserRule;
+
+@Category(UnitTest.class)
+
+public class ListConnectionCommandTest {
+  public static final String COMMAND = "list jdbc-connection";
+  private ListConnectionCommand command;
+  private ClusterConfigurationService ccService;
+
+  @ClassRule
+  public static GfshParserRule gfsh = new GfshParserRule();
+
+  @Before
+  public void setUp() {
+    command = spy(ListConnectionCommand.class);
+    ccService = mock(InternalClusterConfigurationService.class);
+    doReturn(ccService).when(command).getConfigurationService();
+  }
+
+  @Test
+  public void whenCCServiceIsNotAvailable() {
+    doReturn(null).when(command).getConfigurationService();
+    gfsh.executeAndAssertThat(command, COMMAND).statusIsSuccess()
+        .containsOutput("cluster configuration service is not running");
+  }
+
+  @Test
+  public void whenCCServiceIsRunningAndNoConnectorServiceFound() {
+    gfsh.executeAndAssertThat(command, COMMAND).statusIsSuccess()
+        .containsOutput("(Experimental) \\nNo connections found");
+  }
+
+  @Test
+  public void whenCCServiceIsRunningAndNoConnectionFound() {
+    ConnectorService connectorService = mock(ConnectorService.class);
+    when(ccService.getCustomCacheElement(any(), any(), any())).thenReturn(connectorService);
+    gfsh.executeAndAssertThat(command, COMMAND).statusIsSuccess()
+        .containsOutput("(Experimental) \\nNo connections found");
+  }
+
+  @Test
+  public void successfulResult() {
+    // connections found in CC
+    ConnectorService.Connection connection1 = new ConnectorService.Connection("name1", "url1",
+        "user1", "password1", "param1:value1,param2:value2");
+    ConnectorService.Connection connection2 = new ConnectorService.Connection("name2", "url2",
+        "user2", "password2", "param3:value3,param4:value4");
+    ConnectorService.Connection connection3 = new ConnectorService.Connection("name3", "url3",
+        "user3", "password3", "param5:value5,param6:value6");
+
+    ConnectorService connectorService = new ConnectorService();
+    connectorService.getConnection().add(connection1);
+    connectorService.getConnection().add(connection2);
+    connectorService.getConnection().add(connection3);
+
+    when(ccService.getCustomCacheElement(any(), any(), any())).thenReturn(connectorService);
+
+    gfsh.executeAndAssertThat(command, COMMAND).statusIsSuccess().containsOutput("name1", "name2",
+        "name3");
+  }
+}
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
deleted file mode 100644
index 9c66d2a..0000000
--- a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/ListConnectionFunctionTest.java
+++ /dev/null
@@ -1,167 +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 static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import java.io.Serializable;
-import java.util.HashSet;
-import java.util.Set;
-
-import org.apache.commons.lang.SerializationUtils;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.mockito.ArgumentCaptor;
-
-import org.apache.geode.cache.execute.FunctionContext;
-import org.apache.geode.cache.execute.ResultSender;
-import org.apache.geode.connectors.jdbc.internal.ConnectionConfiguration;
-import org.apache.geode.connectors.jdbc.internal.JdbcConnectorService;
-import org.apache.geode.distributed.DistributedMember;
-import org.apache.geode.distributed.DistributedSystem;
-import org.apache.geode.internal.cache.InternalCache;
-import org.apache.geode.management.internal.cli.functions.CliFunctionResult;
-import org.apache.geode.test.junit.categories.UnitTest;
-
-@Category(UnitTest.class)
-public class ListConnectionFunctionTest {
-
-  private FunctionContext<Void> context;
-  private ResultSender<Object> resultSender;
-  private JdbcConnectorService service;
-
-  private ConnectionConfiguration connectionConfig1;
-  private ConnectionConfiguration connectionConfig2;
-  private ConnectionConfiguration connectionConfig3;
-
-  private Set<ConnectionConfiguration> expected;
-
-  private ListConnectionFunction function;
-
-  @Before
-  public void setUp() {
-    InternalCache cache = mock(InternalCache.class);
-    context = mock(FunctionContext.class);
-    DistributedMember member = mock(DistributedMember.class);
-    resultSender = mock(ResultSender.class);
-    service = mock(JdbcConnectorService.class);
-    DistributedSystem system = mock(DistributedSystem.class);
-
-    connectionConfig1 = mock(ConnectionConfiguration.class);
-    connectionConfig2 = mock(ConnectionConfiguration.class);
-    connectionConfig3 = mock(ConnectionConfiguration.class);
-
-    expected = new HashSet<>();
-
-    when(context.getResultSender()).thenReturn(resultSender);
-    when(context.getCache()).thenReturn(cache);
-    when(cache.getDistributedSystem()).thenReturn(system);
-    when(system.getDistributedMember()).thenReturn(member);
-    when(cache.getService(eq(JdbcConnectorService.class))).thenReturn(service);
-    when(service.getConnectionConfigs()).thenReturn(expected);
-
-    function = new ListConnectionFunction();
-  }
-
-  @Test
-  public void isHAReturnsFalse() {
-    assertThat(function.isHA()).isFalse();
-  }
-
-  @Test
-  public void getIdReturnsNameOfClass() {
-    assertThat(function.getId()).isEqualTo(function.getClass().getName());
-  }
-
-  @Test
-  public void serializes() {
-    Serializable original = function;
-
-    Object copy = SerializationUtils.clone(original);
-
-    assertThat(copy).isNotSameAs(original).isInstanceOf(ListConnectionFunction.class);
-  }
-
-  @Test
-  public void getConnectionConfigsReturnsMultiple() {
-    expected.add(connectionConfig1);
-    expected.add(connectionConfig2);
-    expected.add(connectionConfig3);
-
-    ConnectionConfiguration[] actual = function.getConnectionConfigAsArray(service);
-
-    assertThat(actual).containsExactlyInAnyOrder(connectionConfig1, connectionConfig2,
-        connectionConfig3);
-  }
-
-  @Test
-  public void getConnectionConfigsReturnsEmpty() {
-    ConnectionConfiguration[] actual = function.getConnectionConfigAsArray(service);
-
-    assertThat(actual).isEmpty();
-  }
-
-  @Test
-  public void executeReturnsResultWithAllConfigs() {
-    expected.add(connectionConfig1);
-    expected.add(connectionConfig2);
-    expected.add(connectionConfig3);
-
-    function.execute(context);
-
-    ArgumentCaptor<Object[]> argument = ArgumentCaptor.forClass(Object[].class);
-    verify(resultSender, times(1)).lastResult(argument.capture());
-    assertThat(argument.getValue()).containsExactlyInAnyOrder(connectionConfig1, connectionConfig2,
-        connectionConfig3);
-  }
-
-  @Test
-  public void executeReturnsEmptyResultForNoConfigs() {
-    function.execute(context);
-
-    ArgumentCaptor<Object[]> argument = ArgumentCaptor.forClass(Object[].class);
-    verify(resultSender, times(1)).lastResult(argument.capture());
-    assertThat(argument.getValue()).isEmpty();
-  }
-
-  @Test
-  public void executeReturnsResultForExceptionWithoutMessage() {
-    when(service.getConnectionConfigs()).thenThrow(new NullPointerException());
-
-    function.execute(context);
-
-    ArgumentCaptor<CliFunctionResult> argument = ArgumentCaptor.forClass(CliFunctionResult.class);
-    verify(resultSender, times(1)).lastResult(argument.capture());
-    assertThat(argument.getValue().getMessage()).contains(NullPointerException.class.getName());
-  }
-
-  @Test
-  public void executeReturnsResultForExceptionWithMessage() {
-    when(service.getConnectionConfigs()).thenThrow(new IllegalArgumentException("some message"));
-
-    function.execute(context);
-
-    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());
-  }
-}
diff --git a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/ListMappingCommandDUnitTest.java b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/ListMappingCommandDUnitTest.java
index 598b69b..e027db5 100644
--- a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/ListMappingCommandDUnitTest.java
+++ b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/ListMappingCommandDUnitTest.java
@@ -16,7 +16,6 @@ package org.apache.geode.connectors.jdbc.internal.cli;
 
 import static org.apache.geode.connectors.jdbc.internal.cli.ListMappingCommand.LIST_MAPPING;
 import static org.apache.geode.connectors.jdbc.internal.cli.ListMappingCommand.LIST_OF_MAPPINGS;
-import static org.assertj.core.api.Assertions.assertThat;
 
 import java.io.Serializable;
 
@@ -25,10 +24,6 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 
-import org.apache.geode.connectors.jdbc.internal.JdbcConnectorService;
-import org.apache.geode.connectors.jdbc.internal.RegionMappingBuilder;
-import org.apache.geode.connectors.jdbc.internal.RegionMappingExistsException;
-import org.apache.geode.internal.cache.InternalCache;
 import org.apache.geode.management.internal.cli.util.CommandStringBuilder;
 import org.apache.geode.test.dunit.rules.ClusterStartupRule;
 import org.apache.geode.test.dunit.rules.MemberVM;
@@ -65,10 +60,13 @@ public class ListMappingCommandDUnitTest implements Serializable {
   }
 
   @Test
-  public void listsOneRegionMapping() throws Exception {
-    server.invoke(() -> createOneRegionMapping());
-    CommandStringBuilder csb = new CommandStringBuilder(LIST_MAPPING);
+  public void listsOneRegionMapping() {
+    String mapping = "create jdbc-mapping --region=testRegion --connection=connection "
+        + "--table=myTable --pdx-class-name=myPdxClass --value-contains-primary-key=true "
+        + "--field-mapping=field1:column1,field2:column2";
+    gfsh.executeAndAssertThat(mapping).statusIsSuccess();
 
+    CommandStringBuilder csb = new CommandStringBuilder(LIST_MAPPING);
     CommandResultAssert commandResultAssert = gfsh.executeAndAssertThat(csb.toString());
 
     commandResultAssert.statusIsSuccess();
@@ -77,10 +75,21 @@ public class ListMappingCommandDUnitTest implements Serializable {
   }
 
   @Test
-  public void listsMultipleRegionMappings() throws Exception {
-    server.invoke(() -> createNRegionMappings(3));
-    CommandStringBuilder csb = new CommandStringBuilder(LIST_MAPPING);
+  public void listsMultipleRegionMappings() {
+    String mapping1 = "create jdbc-mapping --region=testRegion-1 --connection=connection "
+        + "--table=myTable --pdx-class-name=myPdxClass --value-contains-primary-key=true "
+        + "--field-mapping=field1:column1,field2:column2";
+    gfsh.executeAndAssertThat(mapping1).statusIsSuccess();
+    String mapping2 = "create jdbc-mapping --region=testRegion-2 --connection=connection "
+        + "--table=myTable --pdx-class-name=myPdxClass --value-contains-primary-key=true "
+        + "--field-mapping=field1:column1,field2:column2";
+    gfsh.executeAndAssertThat(mapping2).statusIsSuccess();
+    String mapping3 = "create jdbc-mapping --region=testRegion-3 --connection=connection "
+        + "--table=myTable --pdx-class-name=myPdxClass --value-contains-primary-key=true "
+        + "--field-mapping=field1:column1,field2:column2";
+    gfsh.executeAndAssertThat(mapping3).statusIsSuccess();
 
+    CommandStringBuilder csb = new CommandStringBuilder(LIST_MAPPING);
     CommandResultAssert commandResultAssert = gfsh.executeAndAssertThat(csb.toString());
 
     commandResultAssert.statusIsSuccess();
@@ -90,7 +99,7 @@ public class ListMappingCommandDUnitTest implements Serializable {
   }
 
   @Test
-  public void reportsNoRegionMappingsFound() throws Exception {
+  public void reportsNoRegionMappingsFound() {
     CommandStringBuilder csb = new CommandStringBuilder(LIST_MAPPING);
 
     CommandResultAssert commandResultAssert = gfsh.executeAndAssertThat(csb.toString());
@@ -98,26 +107,4 @@ public class ListMappingCommandDUnitTest implements Serializable {
     commandResultAssert.statusIsSuccess();
     commandResultAssert.containsOutput("No mappings found");
   }
-
-  private void createOneRegionMapping() throws RegionMappingExistsException {
-    InternalCache cache = ClusterStartupRule.getCache();
-    JdbcConnectorService service = cache.getService(JdbcConnectorService.class);
-
-    service.createRegionMapping(new RegionMappingBuilder().withRegionName(regionName)
-        .withPdxClassName("x.y.MyPdxClass").withPrimaryKeyInValue(true).build());
-
-    assertThat(service.getMappingForRegion(regionName)).isNotNull();
-  }
-
-  private void createNRegionMappings(int N) throws RegionMappingExistsException {
-    InternalCache cache = ClusterStartupRule.getCache();
-    JdbcConnectorService service = cache.getService(JdbcConnectorService.class);
-    for (int i = 1; i <= N; i++) {
-      String name = regionName + "-" + i;
-      service.createRegionMapping(new RegionMappingBuilder().withRegionName(name)
-          .withPdxClassName("x.y.MyPdxClass").withPrimaryKeyInValue(true).build());
-      assertThat(service.getMappingForRegion(name)).isNotNull();
-    }
-  }
-
 }
diff --git a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/ListMappingCommandIntegrationTest.java b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/ListMappingCommandIntegrationTest.java
deleted file mode 100644
index 7822b51..0000000
--- a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/ListMappingCommandIntegrationTest.java
+++ /dev/null
@@ -1,110 +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.apache.geode.connectors.jdbc.internal.cli.ListConnectionCommand.LIST_OF_CONNECTIONS;
-import static org.apache.geode.connectors.jdbc.internal.cli.ListConnectionCommand.NO_CONNECTIONS_FOUND;
-import static org.apache.geode.distributed.ConfigurationProperties.ENABLE_CLUSTER_CONFIGURATION;
-import static org.assertj.core.api.Assertions.assertThat;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-
-import org.apache.geode.cache.CacheFactory;
-import org.apache.geode.connectors.jdbc.internal.ConnectionConfigBuilder;
-import org.apache.geode.connectors.jdbc.internal.ConnectionConfiguration;
-import org.apache.geode.connectors.jdbc.internal.JdbcConnectorService;
-import org.apache.geode.internal.cache.InternalCache;
-import org.apache.geode.management.cli.Result;
-import org.apache.geode.management.internal.cli.result.CommandResult;
-import org.apache.geode.test.junit.categories.IntegrationTest;
-
-@Category(IntegrationTest.class)
-public class ListMappingCommandIntegrationTest {
-
-  private InternalCache cache;
-  private JdbcConnectorService service;
-
-  private ConnectionConfiguration connectionConfig1;
-  private ConnectionConfiguration connectionConfig2;
-  private ConnectionConfiguration connectionConfig3;
-
-  private ListConnectionCommand command;
-
-  @Before
-  public void setup() throws Exception {
-    String[] params = new String[] {"param1:value1", "param2:value2"};
-
-    connectionConfig1 = new ConnectionConfigBuilder().withName("connection1").withUrl("url1")
-        .withUser("user1").withPassword("password1").withParameters(params).build();
-    connectionConfig2 = new ConnectionConfigBuilder().withName("connection2").withUrl("url2")
-        .withUser("user2").withPassword("password2").withParameters(params).build();
-    connectionConfig3 = new ConnectionConfigBuilder().withName("connection3").withUrl("url3")
-        .withUser("user3").withPassword("password3").withParameters(params).build();
-
-    cache = (InternalCache) new CacheFactory().set("locators", "").set("mcast-port", "0")
-        .set(ENABLE_CLUSTER_CONFIGURATION, "true").create();
-    service = cache.getService(JdbcConnectorService.class);
-
-    command = new ListConnectionCommand();
-    command.setCache(cache);
-  }
-
-  @After
-  public void tearDown() {
-    cache.close();
-  }
-
-  @Test
-  public void displaysNoConnectionsFoundWhenZeroConnectionsExist() throws Exception {
-    Result result = command.listConnection();
-
-    assertThat(result.getStatus()).isSameAs(Result.Status.OK);
-    CommandResult commandResult = (CommandResult) result;
-    String tableContent = commandResult.getTableContent().toString();
-    assertThat(tableContent).contains(NO_CONNECTIONS_FOUND);
-    assertThat(tableContent).doesNotContain(connectionConfig1.getName())
-        .doesNotContain(connectionConfig2.getName()).doesNotContain(connectionConfig3.getName());
-  }
-
-  @Test
-  public void displaysListOfConnectionsHeaderWhenOneConnectionExists() throws Exception {
-    service.createConnectionConfig(connectionConfig1);
-
-    Result result = command.listConnection();
-
-    assertThat(result.getStatus()).isSameAs(Result.Status.OK);
-    CommandResult commandResult = (CommandResult) result;
-    String tableContent = commandResult.getTableContent().toString();
-    assertThat(tableContent).contains(LIST_OF_CONNECTIONS);
-    assertThat(tableContent).contains(connectionConfig1.getName());
-  }
-
-  @Test
-  public void displaysMultipleConnectionsByName() throws Exception {
-    service.createConnectionConfig(connectionConfig1);
-    service.createConnectionConfig(connectionConfig2);
-    service.createConnectionConfig(connectionConfig3);
-
-    Result result = command.listConnection();
-
-    assertThat(result.getStatus()).isSameAs(Result.Status.OK);
-    CommandResult commandResult = (CommandResult) result;
-    assertThat(commandResult.getTableContent().toString()).contains(connectionConfig1.getName())
-        .contains(connectionConfig2.getName()).contains(connectionConfig3.getName());
-  }
-}
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
new file mode 100644
index 0000000..5253dd5
--- /dev/null
+++ b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/ListMappingCommandTest.java
@@ -0,0 +1,93 @@
+/*
+ * 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.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
+import org.apache.geode.distributed.ClusterConfigurationService;
+import org.apache.geode.distributed.internal.InternalClusterConfigurationService;
+import org.apache.geode.test.junit.categories.UnitTest;
+import org.apache.geode.test.junit.rules.GfshParserRule;
+
+@Category(UnitTest.class)
+
+public class ListMappingCommandTest {
+  public static final String COMMAND = "list jdbc-mappings";
+  private ListMappingCommand command;
+  private ClusterConfigurationService ccService;
+
+  @ClassRule
+  public static GfshParserRule gfsh = new GfshParserRule();
+
+  @Before
+  public void setUp() {
+    command = spy(ListMappingCommand.class);
+    ccService = mock(InternalClusterConfigurationService.class);
+    doReturn(ccService).when(command).getConfigurationService();
+  }
+
+  @Test
+  public void whenCCServiceIsNotAvailable() {
+    doReturn(null).when(command).getConfigurationService();
+    gfsh.executeAndAssertThat(command, COMMAND).statusIsSuccess()
+        .containsOutput("cluster configuration service is not running");
+  }
+
+  @Test
+  public void whenCCServiceIsRunningAndNoConnectorServiceFound() {
+    gfsh.executeAndAssertThat(command, COMMAND).statusIsSuccess()
+        .containsOutput("(Experimental) \\nNo mappings found");
+  }
+
+  @Test
+  public void whenCCServiceIsRunningAndNoConnectionFound() {
+    ConnectorService connectorService = mock(ConnectorService.class);
+    when(ccService.getCustomCacheElement(any(), any(), any())).thenReturn(connectorService);
+    gfsh.executeAndAssertThat(command, COMMAND).statusIsSuccess()
+        .containsOutput("(Experimental) \\nNo mappings found");
+  }
+
+  @Test
+  public void successfulResult() {
+    // mappings found in CC
+    ConnectorService.RegionMapping mapping1 =
+        new ConnectorService.RegionMapping("region1", "class1", "table1", "name1", true);
+    mapping1.getFieldMapping()
+        .add(new ConnectorService.RegionMapping.FieldMapping("field1", "value1"));
+    ConnectorService.RegionMapping mapping2 =
+        new ConnectorService.RegionMapping("region2", "class2", "table2", "name2", true);
+    mapping2.getFieldMapping()
+        .add(new ConnectorService.RegionMapping.FieldMapping("field2", "value2"));
+
+    ConnectorService connectorService = new ConnectorService();
+    connectorService.getRegionMapping().add(mapping1);
+    connectorService.getRegionMapping().add(mapping2);
+
+    when(ccService.getCustomCacheElement(any(), any(), any())).thenReturn(connectorService);
+
+    gfsh.executeAndAssertThat(command, COMMAND).statusIsSuccess().containsOutput("region1",
+        "region2");
+  }
+}
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
deleted file mode 100644
index f82b0cc..0000000
--- a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/ListMappingFunctionTest.java
+++ /dev/null
@@ -1,166 +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 static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import java.io.Serializable;
-import java.util.HashSet;
-import java.util.Set;
-
-import org.apache.commons.lang.SerializationUtils;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.mockito.ArgumentCaptor;
-
-import org.apache.geode.cache.execute.FunctionContext;
-import org.apache.geode.cache.execute.ResultSender;
-import org.apache.geode.connectors.jdbc.internal.JdbcConnectorService;
-import org.apache.geode.connectors.jdbc.internal.RegionMapping;
-import org.apache.geode.distributed.DistributedMember;
-import org.apache.geode.distributed.DistributedSystem;
-import org.apache.geode.internal.cache.InternalCache;
-import org.apache.geode.management.internal.cli.functions.CliFunctionResult;
-import org.apache.geode.test.junit.categories.UnitTest;
-
-@Category(UnitTest.class)
-public class ListMappingFunctionTest {
-
-  private FunctionContext<Void> context;
-  private ResultSender<Object> resultSender;
-  private JdbcConnectorService service;
-
-  private RegionMapping regionMapping1;
-  private RegionMapping regionMapping2;
-  private RegionMapping regionMapping3;
-
-  private Set<RegionMapping> expected;
-
-  private ListMappingFunction function;
-
-  @Before
-  public void setUp() {
-    InternalCache cache = mock(InternalCache.class);
-    context = mock(FunctionContext.class);
-    DistributedMember member = mock(DistributedMember.class);
-    resultSender = mock(ResultSender.class);
-    service = mock(JdbcConnectorService.class);
-    DistributedSystem system = mock(DistributedSystem.class);
-
-    regionMapping1 = mock(RegionMapping.class);
-    regionMapping2 = mock(RegionMapping.class);
-    regionMapping3 = mock(RegionMapping.class);
-
-    expected = new HashSet<>();
-
-    when(context.getResultSender()).thenReturn(resultSender);
-    when(context.getCache()).thenReturn(cache);
-    when(cache.getDistributedSystem()).thenReturn(system);
-    when(system.getDistributedMember()).thenReturn(member);
-    when(cache.getService(eq(JdbcConnectorService.class))).thenReturn(service);
-    when(service.getRegionMappings()).thenReturn(expected);
-
-    function = new ListMappingFunction();
-  }
-
-  @Test
-  public void isHAReturnsFalse() {
-    assertThat(function.isHA()).isFalse();
-  }
-
-  @Test
-  public void getIdReturnsNameOfClass() {
-    assertThat(function.getId()).isEqualTo(function.getClass().getName());
-  }
-
-  @Test
-  public void serializes() {
-    Serializable original = function;
-
-    Object copy = SerializationUtils.clone(original);
-
-    assertThat(copy).isNotSameAs(original).isInstanceOf(ListMappingFunction.class);
-  }
-
-  @Test
-  public void getRegionMappingsReturnsMultiple() {
-    expected.add(regionMapping1);
-    expected.add(regionMapping2);
-    expected.add(regionMapping3);
-
-    RegionMapping[] actual = function.getRegionMappingsAsArray(service);
-
-    assertThat(actual).containsExactlyInAnyOrder(regionMapping1, regionMapping2, regionMapping3);
-  }
-
-  @Test
-  public void getRegionMappingsReturnsEmpty() {
-    RegionMapping[] actual = function.getRegionMappingsAsArray(service);
-
-    assertThat(actual).isEmpty();
-  }
-
-  @Test
-  public void executeReturnsResultWithAllRegionMappings() {
-    expected.add(regionMapping1);
-    expected.add(regionMapping2);
-    expected.add(regionMapping3);
-
-    function.execute(context);
-
-    ArgumentCaptor<Object[]> argument = ArgumentCaptor.forClass(Object[].class);
-    verify(resultSender, times(1)).lastResult(argument.capture());
-    assertThat(argument.getValue()).containsExactlyInAnyOrder(regionMapping1, regionMapping2,
-        regionMapping3);
-  }
-
-  @Test
-  public void executeReturnsEmptyResultForNoRegionMappings() {
-    function.execute(context);
-
-    ArgumentCaptor<Object[]> argument = ArgumentCaptor.forClass(Object[].class);
-    verify(resultSender, times(1)).lastResult(argument.capture());
-    assertThat(argument.getValue()).isEmpty();
-  }
-
-  @Test
-  public void executeReturnsResultForExceptionWithoutMessage() {
-    when(service.getRegionMappings()).thenThrow(new NullPointerException());
-
-    function.execute(context);
-
-    ArgumentCaptor<CliFunctionResult> argument = ArgumentCaptor.forClass(CliFunctionResult.class);
-    verify(resultSender, times(1)).lastResult(argument.capture());
-    assertThat(argument.getValue().getMessage()).contains(NullPointerException.class.getName());
-  }
-
-  @Test
-  public void executeReturnsResultForExceptionWithMessage() {
-    when(service.getRegionMappings()).thenThrow(new IllegalArgumentException("some message"));
-
-    function.execute(context);
-
-    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());
-  }
-}
diff --git a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/configuration/ConnectorServiceTest.java b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/configuration/ConnectorServiceTest.java
new file mode 100644
index 0000000..4f0afa2
--- /dev/null
+++ b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/configuration/ConnectorServiceTest.java
@@ -0,0 +1,102 @@
+/*
+ * 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.configuration;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.net.URL;
+import java.util.List;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import org.apache.geode.internal.ClassPathLoader;
+import org.apache.geode.internal.config.JAXBService;
+import org.apache.geode.test.junit.categories.UnitTest;
+
+
+@Category(UnitTest.class)
+public class ConnectorServiceTest {
+
+  private JAXBService jaxbService;
+
+  @Before
+  public void setUp() throws Exception {
+    jaxbService = new JAXBService();
+    jaxbService.registerBindClassWithSchema(ConnectorService.class, ConnectorService.SCHEMA);
+    // find the local jdbc-1.0.xsd
+    URL local_xsd = ClassPathLoader.getLatest()
+        .getResource("META-INF/schemas/geode.apache.org/schema/jdbc/jdbc-1.0.xsd");
+    jaxbService.validateWith(local_xsd);
+  }
+
+  @Test
+  public void connectorServiceCanBeCorrectlyMarshalled() {
+    ConnectorService service = new ConnectorService();
+    ConnectorService.Connection connection =
+        new ConnectorService.Connection("name", "url", "user", "password", (String[]) null);
+    connection.setParameters("key:value,key1:value1");
+    service.getConnection().add(connection);
+
+    assertThat(connection.getParameterMap()).hasSize(2);
+    assertThat(connection.getParameterMap()).containsOnlyKeys("key", "key1");
+    assertThat(connection.getParameterMap()).containsValues("value", "value1");
+
+    String xml = jaxbService.marshall(service);
+    System.out.println(xml);
+
+    assertThat(xml).contains("name=\"name\"").contains("url=\"url\"").contains("user=\"user\"")
+        .contains("password=\"password\"").contains("parameters=\"key:value,key1:value1\"");
+
+    assertThat(xml).contains("xmlns:jdbc=\"http://geode.apache.org/schema/jdbc\"");
+    assertThat(xml).contains("<jdbc:connection");
+  }
+
+  @Test
+  public void regionMappingTest() {
+    ConnectorService service = new ConnectorService();
+    ConnectorService.RegionMapping mapping = new ConnectorService.RegionMapping();
+    mapping.setConnectionConfigName("configName");
+    mapping.setPdxClassName("pdxClassName");
+    mapping.setRegionName("regionA");
+    mapping.setTableName("tableName");
+    mapping.getFieldMapping()
+        .add(new ConnectorService.RegionMapping.FieldMapping("field1", "column1"));
+    mapping.getFieldMapping()
+        .add(new ConnectorService.RegionMapping.FieldMapping("field2", "column2"));
+
+    service.getRegionMapping().add(mapping);
+    String xml = jaxbService.marshall(service);
+
+    assertThat(xml).contains("jdbc:connector-service").contains("connection-name=\"configName\" ")
+        .contains("pdx-class=\"pdxClassName\"")
+        .contains("<jdbc:field-mapping field-name=\"field1\" column-name=\"column1\"/>");
+    System.out.println(xml);
+
+    ConnectorService service2 = jaxbService.unMarshall(xml);
+    assertThat(service2.getRegionMapping()).hasSize(1);
+    List<ConnectorService.RegionMapping.FieldMapping> mappings =
+        service2.getRegionMapping().get(0).getFieldMapping();
+
+    assertThat(mappings.get(0).getFieldName()).isEqualTo("field1");
+    assertThat(mappings.get(0).getColumnName()).isEqualTo("column1");
+    assertThat(mappings.get(1).getFieldName()).isEqualTo("field2");
+    assertThat(mappings.get(1).getColumnName()).isEqualTo("column2");
+  }
+}
diff --git a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/xml/ElementTypeTest.java b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/xml/ElementTypeTest.java
index 912da68..8024860 100644
--- a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/xml/ElementTypeTest.java
+++ b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/xml/ElementTypeTest.java
@@ -34,8 +34,6 @@ import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyZeroInteractions;
 import static org.mockito.Mockito.when;
 
-import java.util.HashMap;
-import java.util.Map;
 import java.util.Stack;
 
 import org.junit.Before;
@@ -45,11 +43,8 @@ import org.xml.sax.Attributes;
 
 import org.apache.geode.cache.Cache;
 import org.apache.geode.cache.CacheXmlException;
-import org.apache.geode.connectors.jdbc.internal.ConnectionConfigBuilder;
-import org.apache.geode.connectors.jdbc.internal.ConnectionConfiguration;
-import org.apache.geode.connectors.jdbc.internal.RegionMapping;
-import org.apache.geode.connectors.jdbc.internal.RegionMappingBuilder;
 import org.apache.geode.connectors.jdbc.internal.TableMetaDataView;
+import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
 import org.apache.geode.internal.cache.extension.ExtensionPoint;
 import org.apache.geode.internal.cache.xmlcache.CacheCreation;
 import org.apache.geode.test.junit.categories.UnitTest;
@@ -134,7 +129,7 @@ public class ElementTypeTest {
 
     CONNECTION.startElement(stack, attributes);
 
-    ConnectionConfiguration config = ((ConnectionConfigBuilder) stack.pop()).build();
+    ConnectorService.Connection config = (ConnectorService.Connection) stack.pop();
     assertThat(config.getName()).isEqualTo("connectionName");
     assertThat(config.getUrl()).isEqualTo("url");
     assertThat(config.getUser()).isEqualTo("username");
@@ -153,23 +148,20 @@ public class ElementTypeTest {
 
     CONNECTION.startElement(stack, attributes);
 
-    ConnectionConfiguration config = ((ConnectionConfigBuilder) stack.pop()).build();
+    ConnectorService.Connection config = (ConnectorService.Connection) stack.pop();
     assertThat(config.getName()).isEqualTo("connectionName");
     assertThat(config.getUrl()).isEqualTo("url");
     assertThat(config.getUser()).isNull();
     assertThat(config.getPassword()).isNull();
-    Map<String, String> expectedParams = new HashMap<>();
-    expectedParams.put("key1", "value1");
-    expectedParams.put("key2", "value2");
-    assertThat(config.getParameters()).isEqualTo(expectedParams);
+    assertThat(config.getParameters()).isEqualTo("key1:value1,key2:value2");
   }
 
   @Test
   public void endElementConnection() {
-    ConnectionConfigBuilder builder = mock(ConnectionConfigBuilder.class);
+    ConnectorService.Connection connection = mock(ConnectorService.Connection.class);
     JdbcServiceConfiguration serviceConfiguration = mock(JdbcServiceConfiguration.class);
     stack.push(serviceConfiguration);
-    stack.push(builder);
+    stack.push(connection);
 
     CONNECTION.endElement(stack);
 
@@ -196,7 +188,7 @@ public class ElementTypeTest {
 
     ElementType.REGION_MAPPING.startElement(stack, attributes);
 
-    RegionMapping regionMapping = ((RegionMappingBuilder) stack.pop()).build();
+    ConnectorService.RegionMapping regionMapping = (ConnectorService.RegionMapping) stack.pop();
     assertThat(regionMapping.getRegionName()).isEqualTo("region");
     assertThat(regionMapping.getConnectionConfigName()).isEqualTo("connectionName");
     assertThat(regionMapping.getTableName()).isEqualTo("table");
@@ -206,10 +198,10 @@ public class ElementTypeTest {
 
   @Test
   public void endElementRegionMapping() {
-    RegionMappingBuilder builder = mock(RegionMappingBuilder.class);
+    ConnectorService.RegionMapping mapping = mock(ConnectorService.RegionMapping.class);
     JdbcServiceConfiguration serviceConfiguration = mock(JdbcServiceConfiguration.class);
     stack.push(serviceConfiguration);
-    stack.push(builder);
+    stack.push(mapping);
 
     ElementType.REGION_MAPPING.endElement(stack);
 
@@ -227,28 +219,28 @@ public class ElementTypeTest {
 
   @Test
   public void startElementFieldMapping() {
-    RegionMappingBuilder builder = new RegionMappingBuilder();
-    stack.push(builder);
+    ConnectorService.RegionMapping mapping = new ConnectorService.RegionMapping();
+    stack.push(mapping);
     when(attributes.getValue(FIELD_NAME)).thenReturn("fieldName");
     when(attributes.getValue(COLUMN_NAME)).thenReturn("columnName");
 
     ElementType.FIELD_MAPPING.startElement(stack, attributes);
 
-    RegionMapping regionMapping = ((RegionMappingBuilder) stack.pop()).build();
-    assertThat(regionMapping.getColumnNameForField("fieldName", mock(TableMetaDataView.class)))
+    ConnectorService.RegionMapping mapping1 = (ConnectorService.RegionMapping) stack.pop();
+    assertThat(mapping1.getColumnNameForField("fieldName", mock(TableMetaDataView.class)))
         .isEqualTo("columnName");
   }
 
   @Test
   public void endElementFieldMapping() {
-    RegionMappingBuilder builder = mock(RegionMappingBuilder.class);
+    ConnectorService.RegionMapping mapping = mock(ConnectorService.RegionMapping.class);
     JdbcServiceConfiguration serviceConfiguration = mock(JdbcServiceConfiguration.class);
     stack.push(serviceConfiguration);
-    stack.push(builder);
+    stack.push(mapping);
 
     ElementType.FIELD_MAPPING.endElement(stack);
 
     assertThat(stack.size()).isEqualTo(2);
-    verifyZeroInteractions(builder);
+    verifyZeroInteractions(mapping);
   }
 }
diff --git a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/xml/JdbcConnectorServiceXmlGeneratorIntegrationTest.java b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/xml/JdbcConnectorServiceXmlGeneratorIntegrationTest.java
deleted file mode 100644
index a3caac5..0000000
--- a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/xml/JdbcConnectorServiceXmlGeneratorIntegrationTest.java
+++ /dev/null
@@ -1,334 +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.xml;
-
-import static org.apache.geode.connectors.jdbc.internal.xml.JdbcConnectorServiceXmlGenerator.PREFIX;
-import static org.apache.geode.connectors.jdbc.internal.xml.JdbcConnectorServiceXmlParser.COLUMN_NAME;
-import static org.apache.geode.connectors.jdbc.internal.xml.JdbcConnectorServiceXmlParser.CONNECTION_NAME;
-import static org.apache.geode.connectors.jdbc.internal.xml.JdbcConnectorServiceXmlParser.FIELD_NAME;
-import static org.apache.geode.connectors.jdbc.internal.xml.JdbcConnectorServiceXmlParser.NAME;
-import static org.apache.geode.connectors.jdbc.internal.xml.JdbcConnectorServiceXmlParser.NAMESPACE;
-import static org.apache.geode.connectors.jdbc.internal.xml.JdbcConnectorServiceXmlParser.PASSWORD;
-import static org.apache.geode.connectors.jdbc.internal.xml.JdbcConnectorServiceXmlParser.PDX_CLASS;
-import static org.apache.geode.connectors.jdbc.internal.xml.JdbcConnectorServiceXmlParser.PRIMARY_KEY_IN_VALUE;
-import static org.apache.geode.connectors.jdbc.internal.xml.JdbcConnectorServiceXmlParser.REGION;
-import static org.apache.geode.connectors.jdbc.internal.xml.JdbcConnectorServiceXmlParser.TABLE;
-import static org.apache.geode.connectors.jdbc.internal.xml.JdbcConnectorServiceXmlParser.URL;
-import static org.apache.geode.connectors.jdbc.internal.xml.JdbcConnectorServiceXmlParser.USER;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.fail;
-
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.PrintWriter;
-
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.apache.commons.io.FileUtils;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.TemporaryFolder;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.NodeList;
-import org.xml.sax.SAXException;
-
-import org.apache.geode.cache.CacheFactory;
-import org.apache.geode.connectors.jdbc.internal.ConnectionConfigBuilder;
-import org.apache.geode.connectors.jdbc.internal.ConnectionConfiguration;
-import org.apache.geode.connectors.jdbc.internal.JdbcConnectorService;
-import org.apache.geode.connectors.jdbc.internal.RegionMapping;
-import org.apache.geode.connectors.jdbc.internal.RegionMappingBuilder;
-import org.apache.geode.internal.cache.InternalCache;
-import org.apache.geode.internal.cache.xmlcache.CacheXmlGenerator;
-import org.apache.geode.test.junit.categories.IntegrationTest;
-
-@Category(IntegrationTest.class)
-public class JdbcConnectorServiceXmlGeneratorIntegrationTest {
-
-  private InternalCache cache;
-  private File cacheXmlFile;
-
-  @Rule
-  public TemporaryFolder temporaryFolder = new TemporaryFolder();
-
-  @Before
-  public void setup() throws IOException {
-    cache = (InternalCache) new CacheFactory().set("locators", "").set("mcast-port", "0").create();
-    cacheXmlFile = temporaryFolder.newFile("cache.xml");
-  }
-
-  @After
-  public void tearDown() {
-    cache.close();
-    cache = null;
-  }
-
-  @Test
-  public void cacheGetServiceReturnsJdbcConnectorService() {
-    assertThat(cache.getService(JdbcConnectorService.class)).isNotNull();
-  }
-
-  @Test
-  public void serviceWithoutInformationDoesNotPersist() throws Exception {
-    cache.getService(JdbcConnectorService.class);
-
-    generateXml();
-
-    Document document = getCacheXmlDocument();
-    NodeList elements = getElementsByName(document, ElementType.CONNECTION_SERVICE);
-    assertThat(elements.getLength()).isZero();
-  }
-
-  @Test
-  public void serviceWithConnectionsHasCorrectXml() throws Exception {
-    JdbcConnectorService service = cache.getService(JdbcConnectorService.class);
-    ConnectionConfiguration config = new ConnectionConfigBuilder().withName("name").withUrl("url")
-        .withUser("username").withPassword("secret").build();
-    service.createConnectionConfig(config);
-
-    generateXml();
-
-    Document document = getCacheXmlDocument();
-    NodeList serviceElements = getElementsByName(document, ElementType.CONNECTION_SERVICE);
-    assertThat(serviceElements.getLength()).isEqualTo(1);
-
-    Element serviceElement = (Element) serviceElements.item(0);
-    assertThat(serviceElement.getAttribute("xmlns:" + PREFIX)).isEqualTo(NAMESPACE);
-    assertThat(serviceElement.getAttribute(NAME))
-        .isEqualTo(ElementType.CONNECTION_SERVICE.getTypeName());
-
-    NodeList connectionElements = getElementsByName(document, ElementType.CONNECTION);
-    assertThat(connectionElements.getLength()).isEqualTo(1);
-
-    Element connectionElement = (Element) connectionElements.item(0);
-    assertThat(connectionElement.getAttribute(NAME)).isEqualTo("name");
-    assertThat(connectionElement.getAttribute(URL)).isEqualTo("url");
-    assertThat(connectionElement.getAttribute(USER)).isEqualTo("username");
-    assertThat(connectionElement.getAttribute(PASSWORD)).isEqualTo("secret");
-  }
-
-  @Test
-  public void generatesXmlContainingRegionMapping() throws Exception {
-    JdbcConnectorService service = cache.getService(JdbcConnectorService.class);
-    RegionMappingBuilder regionMappingBuilder = new RegionMappingBuilder()
-        .withRegionName("regionName").withPdxClassName("pdxClassName").withTableName("tableName")
-        .withConnectionConfigName("connectionConfigName").withPrimaryKeyInValue("true");
-    regionMappingBuilder.withFieldToColumnMapping("fieldName1", "columnMapping1");
-    regionMappingBuilder.withFieldToColumnMapping("fieldName2", "columnMapping2");
-    RegionMapping regionMapping = regionMappingBuilder.build();
-    service.createRegionMapping(regionMapping);
-
-    generateXml();
-
-    Document document = getCacheXmlDocument();
-    NodeList serviceElements = getElementsByName(document, ElementType.CONNECTION_SERVICE);
-    assertThat(serviceElements.getLength()).isEqualTo(1);
-
-    NodeList mappingElements = getElementsByName(document, ElementType.REGION_MAPPING);
-    assertThat(mappingElements.getLength()).isEqualTo(1);
-
-    Element mappingElement = (Element) mappingElements.item(0);
-    assertThat(mappingElement.getAttribute(REGION)).isEqualTo("regionName");
-    assertThat(mappingElement.getAttribute(PDX_CLASS)).isEqualTo("pdxClassName");
-    assertThat(mappingElement.getAttribute(TABLE)).isEqualTo("tableName");
-    assertThat(mappingElement.getAttribute(CONNECTION_NAME)).isEqualTo("connectionConfigName");
-    assertThat(mappingElement.getAttribute(PRIMARY_KEY_IN_VALUE)).isEqualTo("true");
-
-    NodeList fieldMappingElements = getElementsByName(mappingElement, ElementType.FIELD_MAPPING);
-    assertThat(fieldMappingElements.getLength()).isEqualTo(2);
-    validatePresenceOfFieldMapping(fieldMappingElements, "fieldName1", "columnMapping1");
-    validatePresenceOfFieldMapping(fieldMappingElements, "fieldName2", "columnMapping2");
-  }
-
-  @Test
-  public void generatesXmlContainingRegionMappingWithoutFieldMap() throws Exception {
-    JdbcConnectorService service = cache.getService(JdbcConnectorService.class);
-    RegionMappingBuilder regionMappingBuilder =
-        new RegionMappingBuilder().withRegionName("regionName").withPdxClassName("pdxClassName")
-            .withTableName("tableName").withConnectionConfigName("connectionConfigName")
-            .withPrimaryKeyInValue("true").withFieldToColumnMappings(null);
-    RegionMapping regionMapping = regionMappingBuilder.build();
-    service.createRegionMapping(regionMapping);
-
-    generateXml();
-
-    Document document = getCacheXmlDocument();
-    NodeList serviceElements = getElementsByName(document, ElementType.CONNECTION_SERVICE);
-    assertThat(serviceElements.getLength()).isEqualTo(1);
-
-    NodeList mappingElements = getElementsByName(document, ElementType.REGION_MAPPING);
-    assertThat(mappingElements.getLength()).isEqualTo(1);
-
-    Element mappingElement = (Element) mappingElements.item(0);
-    assertThat(mappingElement.getAttribute(REGION)).isEqualTo("regionName");
-    assertThat(mappingElement.getAttribute(PDX_CLASS)).isEqualTo("pdxClassName");
-    assertThat(mappingElement.getAttribute(TABLE)).isEqualTo("tableName");
-    assertThat(mappingElement.getAttribute(CONNECTION_NAME)).isEqualTo("connectionConfigName");
-    assertThat(mappingElement.getAttribute(PRIMARY_KEY_IN_VALUE)).isEqualTo("true");
-
-    NodeList fieldMappingElements = getElementsByName(mappingElement, ElementType.FIELD_MAPPING);
-    assertThat(fieldMappingElements.getLength()).isEqualTo(0);
-  }
-
-  @Test
-  public void generatedXmlWithConnectionConfigurationCanBeParsed() throws Exception {
-    JdbcConnectorService service = cache.getService(JdbcConnectorService.class);
-    ConnectionConfiguration config = new ConnectionConfigBuilder().withName("name").withUrl("url")
-        .withUser("username").withPassword("secret").build();
-    service.createConnectionConfig(config);
-    generateXml();
-    cache.close();
-
-    createCacheUsingXml();
-    service = cache.getService(JdbcConnectorService.class);
-    assertThat(service.getConnectionConfig("name")).isEqualTo(config);
-  }
-
-  @Test
-  public void generatedXmlWithConnectionConfigurationWithNoUserNameAndPasswordCanBeParsed()
-      throws Exception {
-    JdbcConnectorService service = cache.getService(JdbcConnectorService.class);
-    ConnectionConfiguration config =
-        new ConnectionConfigBuilder().withName("name").withUrl("url").build();
-    service.createConnectionConfig(config);
-    generateXml();
-    cache.close();
-
-    createCacheUsingXml();
-    service = cache.getService(JdbcConnectorService.class);
-    assertThat(service.getConnectionConfig("name")).isEqualTo(config);
-  }
-
-  @Test
-  public void generatedXmlWithConnectionConfigurationWithParametersCanBeParsed() throws Exception {
-    JdbcConnectorService service = cache.getService(JdbcConnectorService.class);
-    ConnectionConfiguration config = new ConnectionConfigBuilder().withName("name").withUrl("url")
-        .withParameters(new String[] {"key1:value1", "key2:value2"}).build();
-    service.createConnectionConfig(config);
-    generateXml();
-    cache.close();
-
-    createCacheUsingXml();
-    service = cache.getService(JdbcConnectorService.class);
-    assertThat(service.getConnectionConfig("name")).isEqualTo(config);
-  }
-
-  @Test
-  public void generatedXmlWithRegionMappingCanBeParsed() throws Exception {
-    JdbcConnectorService service = cache.getService(JdbcConnectorService.class);
-    RegionMapping mapping = new RegionMappingBuilder().withRegionName("region")
-        .withPdxClassName("class").withTableName("table").withConnectionConfigName("connection")
-        .withPrimaryKeyInValue(true).withFieldToColumnMapping("field1", "columnMapping1")
-        .withFieldToColumnMapping("field2", "columnMapping2").build();
-    service.createRegionMapping(mapping);
-    generateXml();
-    cache.close();
-
-    createCacheUsingXml();
-    service = cache.getService(JdbcConnectorService.class);
-    assertThat(service.getMappingForRegion("region")).isEqualTo(mapping);
-  }
-
-  @Test
-  public void generatedXmlWithRegionMappingWithNoOptionalParametersCanBeParsed() throws Exception {
-    JdbcConnectorService service = cache.getService(JdbcConnectorService.class);
-    RegionMapping mapping = new RegionMappingBuilder().withRegionName("region")
-        .withConnectionConfigName("connection").build();
-    service.createRegionMapping(mapping);
-    generateXml();
-    cache.close();
-
-    createCacheUsingXml();
-    service = cache.getService(JdbcConnectorService.class);
-    assertThat(service.getMappingForRegion("region")).isEqualTo(mapping);
-  }
-
-  @Test
-  public void generatedXmlWithEverythingCanBeParsed() throws Exception {
-    JdbcConnectorService service = cache.getService(JdbcConnectorService.class);
-    ConnectionConfiguration config = new ConnectionConfigBuilder().withName("name").withUrl("url")
-        .withUser("username").withPassword("secret").build();
-    service.createConnectionConfig(config);
-    RegionMapping mapping = new RegionMappingBuilder().withRegionName("region")
-        .withPdxClassName("class").withTableName("table").withConnectionConfigName("connection")
-        .withPrimaryKeyInValue(true).withFieldToColumnMapping("field1", "columnMapping1")
-        .withFieldToColumnMapping("field2", "columnMapping2").build();
-    service.createRegionMapping(mapping);
-    generateXml();
-    cache.close();
-
-    createCacheUsingXml();
-    service = cache.getService(JdbcConnectorService.class);
-    assertThat(service.getConnectionConfig("name")).isEqualTo(config);
-    assertThat(service.getMappingForRegion("region")).isEqualTo(mapping);
-  }
-
-  private void validatePresenceOfFieldMapping(NodeList elements, String fieldName,
-      String columnName) {
-    for (int i = 0; i < elements.getLength(); i++) {
-      Element fieldMapping = (Element) elements.item(i);
-      if (fieldMapping.getAttribute(FIELD_NAME).equals(fieldName)) {
-        assertThat(fieldMapping.getAttribute(COLUMN_NAME)).isEqualTo(columnName);
-        return;
-      }
-    }
-    fail("Field name '" + fieldName + "' did not match those provided");
-  }
-
-  private NodeList getElementsByName(Document document, ElementType elementType) {
-    String name = getTagName(elementType);
-    return document.getElementsByTagName(name);
-  }
-
-  private NodeList getElementsByName(Element element, ElementType elementType) {
-    String name = getTagName(elementType);
-    return element.getElementsByTagName(name);
-  }
-
-  private String getTagName(ElementType elementType) {
-    return PREFIX + ":" + elementType.getTypeName();
-  }
-
-  private Document getCacheXmlDocument()
-      throws IOException, SAXException, ParserConfigurationException {
-    DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
-    dbFactory.setNamespaceAware(false);
-    dbFactory.setValidating(false);
-    DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
-    Document document = dBuilder.parse(cacheXmlFile);
-    document.getDocumentElement().normalize();
-    return document;
-  }
-
-  private void generateXml() throws IOException {
-    PrintWriter printWriter = new PrintWriter(new FileWriter(cacheXmlFile));
-    CacheXmlGenerator.generate(cache, printWriter, true, false, false);
-    printWriter.flush();
-  }
-
-  private void createCacheUsingXml() throws IOException {
-    byte[] bytes = FileUtils.readFileToByteArray(cacheXmlFile);
-    cache = (InternalCache) new CacheFactory().set("locators", "").set("mcast-port", "0").create();
-    cache.loadCacheXml(new ByteArrayInputStream(bytes));
-  }
-}
diff --git a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/xml/JdbcConnectorServiceXmlGeneratorTest.java b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/xml/JdbcConnectorServiceXmlGeneratorTest.java
deleted file mode 100644
index 3ae5587..0000000
--- a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/xml/JdbcConnectorServiceXmlGeneratorTest.java
+++ /dev/null
@@ -1,34 +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.xml;
-
-import static org.apache.geode.connectors.jdbc.internal.xml.JdbcConnectorServiceXmlParser.NAMESPACE;
-import static org.assertj.core.api.Assertions.assertThat;
-
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-
-import org.apache.geode.test.junit.categories.UnitTest;
-
-@Category(UnitTest.class)
-public class JdbcConnectorServiceXmlGeneratorTest {
-
-  @Test
-  public void returnsCorrectNamespace() {
-    JdbcConnectorServiceXmlGenerator generator = new JdbcConnectorServiceXmlGenerator(null, null);
-
-    assertThat(generator.getNamespaceUri()).isEqualTo(NAMESPACE);
-  }
-}
diff --git a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/xml/JdbcConnectorServiceXmlIntegrationTest.java b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/xml/JdbcConnectorServiceXmlIntegrationTest.java
deleted file mode 100644
index 0b33d71..0000000
--- a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/xml/JdbcConnectorServiceXmlIntegrationTest.java
+++ /dev/null
@@ -1,127 +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.xml;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.PrintWriter;
-
-import org.apache.commons.io.FileUtils;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.TemporaryFolder;
-
-import org.apache.geode.cache.CacheFactory;
-import org.apache.geode.connectors.jdbc.internal.ConnectionConfigBuilder;
-import org.apache.geode.connectors.jdbc.internal.ConnectionConfigExistsException;
-import org.apache.geode.connectors.jdbc.internal.ConnectionConfiguration;
-import org.apache.geode.connectors.jdbc.internal.JdbcConnectorService;
-import org.apache.geode.connectors.jdbc.internal.JdbcConnectorServiceImpl;
-import org.apache.geode.connectors.jdbc.internal.RegionMapping;
-import org.apache.geode.connectors.jdbc.internal.RegionMappingBuilder;
-import org.apache.geode.connectors.jdbc.internal.RegionMappingExistsException;
-import org.apache.geode.internal.cache.InternalCache;
-import org.apache.geode.internal.cache.xmlcache.CacheXmlGenerator;
-import org.apache.geode.test.junit.categories.IntegrationTest;
-
-@Category(IntegrationTest.class)
-public class JdbcConnectorServiceXmlIntegrationTest {
-
-  private InternalCache cache;
-  private File cacheXml;
-  private ConnectionConfiguration config1;
-  private ConnectionConfiguration config2;
-  private RegionMapping regionMapping1;
-  private RegionMapping regionMapping2;
-
-  @Rule
-  public TemporaryFolder temporaryFolder = new TemporaryFolder();
-
-  @Before
-  public void setup() throws Exception {
-    cache = (InternalCache) new CacheFactory().set("locators", "").set("mcast-port", "0").create();
-    configureService();
-    cacheXml = generateXml();
-    cache.close();
-  }
-
-  @After
-  public void tearDown() {
-    cache.close();
-  }
-
-  @Test
-  public void canRecreateJdbcConnectorServiceFromXml() throws Exception {
-    createCacheUsingXml();
-    JdbcConnectorServiceImpl service =
-        (JdbcConnectorServiceImpl) cache.getExtensionPoint().getExtensions().iterator().next();
-    assertThat(service.getConnectionConfig(config1.getName())).isEqualTo(config1);
-    assertThat(service.getConnectionConfig(config2.getName())).isEqualTo(config2);
-    assertThat(service.getMappingForRegion(regionMapping1.getRegionName()))
-        .isEqualTo(regionMapping1);
-    assertThat(service.getMappingForRegion(regionMapping2.getRegionName()))
-        .isEqualTo(regionMapping2);
-  }
-
-  private void configureService()
-      throws ConnectionConfigExistsException, RegionMappingExistsException {
-    JdbcConnectorService service = cache.getService(JdbcConnectorService.class);
-    config1 = new ConnectionConfigBuilder().withName("connection1").withUrl("url1")
-        .withUser("username1").withPassword("secret1")
-        .withParameters(new String[] {"param1:value1", "param2:value2"}).build();
-    config2 = new ConnectionConfigBuilder().withName("connection2").withUrl("url2")
-        .withUser("username2").withPassword("secret2").build();
-    service.createConnectionConfig(config1);
-    service.createConnectionConfig(config2);
-
-    RegionMappingBuilder regionMappingBuilder1 = new RegionMappingBuilder()
-        .withRegionName("regionName1").withPdxClassName("pdxClassName1").withTableName("tableName1")
-        .withConnectionConfigName("connection1").withPrimaryKeyInValue("true");
-    regionMappingBuilder1.withFieldToColumnMapping("fieldName1", "columnMapping1");
-    regionMappingBuilder1.withFieldToColumnMapping("fieldName2", "columnMapping2");
-    regionMapping1 = regionMappingBuilder1.build();
-
-    RegionMappingBuilder regionMappingBuilder2 = new RegionMappingBuilder()
-        .withRegionName("regionName2").withPdxClassName("pdxClassName2").withTableName("tableName2")
-        .withConnectionConfigName("connection2").withPrimaryKeyInValue("false");
-    regionMappingBuilder1.withFieldToColumnMapping("fieldName3", "columnMapping3");
-    regionMappingBuilder1.withFieldToColumnMapping("fieldName4", "columnMapping4");
-    regionMapping2 = regionMappingBuilder2.build();
-
-    service.createRegionMapping(regionMapping1);
-    service.createRegionMapping(regionMapping2);
-  }
-
-  private File generateXml() throws IOException {
-    File cacheXml = new File(temporaryFolder.getRoot(), "cache.xml");
-    PrintWriter printWriter = new PrintWriter(new FileWriter(cacheXml));
-    CacheXmlGenerator.generate(cache, printWriter, true, false, false);
-    printWriter.flush();
-    return cacheXml;
-  }
-
-  private void createCacheUsingXml() throws IOException {
-    byte[] bytes = FileUtils.readFileToByteArray(cacheXml);
-    cache = (InternalCache) new CacheFactory().set("locators", "").set("mcast-port", "0").create();
-    cache.loadCacheXml(new ByteArrayInputStream(bytes));
-  }
-}
diff --git a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/xml/JdbcServiceConfigurationTest.java b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/xml/JdbcServiceConfigurationTest.java
index 3fd9e97..6586548 100644
--- a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/xml/JdbcServiceConfigurationTest.java
+++ b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/xml/JdbcServiceConfigurationTest.java
@@ -14,8 +14,6 @@
  */
 package org.apache.geode.connectors.jdbc.internal.xml;
 
-import static org.apache.geode.connectors.jdbc.internal.xml.JdbcConnectorServiceXmlParser.NAMESPACE;
-import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
@@ -26,12 +24,9 @@ import org.junit.Before;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 
-import org.apache.geode.cache.Cache;
-import org.apache.geode.connectors.jdbc.internal.ConnectionConfiguration;
 import org.apache.geode.connectors.jdbc.internal.JdbcConnectorService;
-import org.apache.geode.connectors.jdbc.internal.RegionMapping;
+import org.apache.geode.connectors.jdbc.internal.configuration.ConnectorService;
 import org.apache.geode.internal.cache.InternalCache;
-import org.apache.geode.internal.cache.xmlcache.XmlGenerator;
 import org.apache.geode.test.junit.categories.UnitTest;
 
 @Category(UnitTest.class)
@@ -39,19 +34,19 @@ public class JdbcServiceConfigurationTest {
 
   private InternalCache cache;
   private JdbcConnectorService service;
-  private ConnectionConfiguration connection1;
-  private ConnectionConfiguration connection2;
-  private RegionMapping mapping1;
-  private RegionMapping mapping2;
+  private ConnectorService.Connection connection1;
+  private ConnectorService.Connection connection2;
+  private ConnectorService.RegionMapping mapping1;
+  private ConnectorService.RegionMapping mapping2;
 
   private JdbcServiceConfiguration configuration;
 
   @Before
   public void setUp() throws Exception {
-    connection1 = mock(ConnectionConfiguration.class);
-    connection2 = mock(ConnectionConfiguration.class);
-    mapping1 = mock(RegionMapping.class);
-    mapping2 = mock(RegionMapping.class);
+    connection1 = mock(ConnectorService.Connection.class);
+    connection2 = mock(ConnectorService.Connection.class);
+    mapping1 = mock(ConnectorService.RegionMapping.class);
+    mapping2 = mock(ConnectorService.RegionMapping.class);
     service = mock(JdbcConnectorService.class);
     cache = mock(InternalCache.class);
 
@@ -61,51 +56,6 @@ public class JdbcServiceConfigurationTest {
   }
 
   @Test
-  public void getXmlGeneratorReturnsJdbcConnectorServiceXmlGenerator() throws Exception {
-    XmlGenerator<Cache> generator = configuration.getXmlGenerator();
-
-    assertThat(generator).isInstanceOf(JdbcConnectorServiceXmlGenerator.class);
-  }
-
-  @Test
-  public void getXmlGeneratorReturnsGeneratorWithJdbcConnectorNamespace() throws Exception {
-    XmlGenerator<Cache> generator = configuration.getXmlGenerator();
-
-    assertThat(generator.getNamespaceUri()).isEqualTo(NAMESPACE);
-  }
-
-  @Test
-  public void getXmlGeneratorReturnsEmptyGeneratorByDefault() throws Exception {
-    JdbcConnectorServiceXmlGenerator generator =
-        (JdbcConnectorServiceXmlGenerator) configuration.getXmlGenerator();
-
-    assertThat(generator.getConnections()).isEmpty();
-    assertThat(generator.getMappings()).isEmpty();
-  }
-
-  @Test
-  public void getXmlGeneratorWithConnections() throws Exception {
-    configuration.addConnectionConfig(connection1);
-    configuration.addConnectionConfig(connection2);
-
-    JdbcConnectorServiceXmlGenerator generator =
-        (JdbcConnectorServiceXmlGenerator) configuration.getXmlGenerator();
-
-    assertThat(generator.getConnections()).containsExactly(connection1, connection2);
-  }
-
-  @Test
-  public void getXmlGeneratorWithRegionMappings() throws Exception {
-    configuration.addRegionMapping(mapping1);
-    configuration.addRegionMapping(mapping2);
-
-    JdbcConnectorServiceXmlGenerator generator =
-        (JdbcConnectorServiceXmlGenerator) configuration.getXmlGenerator();
-
-    assertThat(generator.getMappings()).containsExactly(mapping1, mapping2);
-  }
-
-  @Test
   public void onCreateWithNoConnectionsOrMappings() throws Exception {
     configuration.onCreate(cache, cache);
 
diff --git a/geode-core/src/main/java/org/apache/geode/distributed/ClusterConfigurationService.java b/geode-core/src/main/java/org/apache/geode/distributed/ClusterConfigurationService.java
index 65a3066..f882430 100644
--- a/geode-core/src/main/java/org/apache/geode/distributed/ClusterConfigurationService.java
+++ b/geode-core/src/main/java/org/apache/geode/distributed/ClusterConfigurationService.java
@@ -18,6 +18,7 @@
 package org.apache.geode.distributed;
 
 import java.util.ArrayList;
+import java.util.Iterator;
 import java.util.List;
 import java.util.function.UnaryOperator;
 
@@ -143,6 +144,14 @@ public interface ClusterConfigurationService {
     return list.stream().filter(o -> o.getId().equals(id)).findFirst().orElse(null);
   }
 
+  default <T extends Identifiable<String>> void removeFromList(List<T> list, String id) {
+    for (Iterator<T> iter = list.listIterator(); iter.hasNext();) {
+      if (iter.next().getId().equals(id)) {
+        iter.remove();
+      }
+    }
+  }
+
   default RegionConfig findRegionConfiguration(CacheConfig cacheConfig, String regionPath) {
     return findIdentifiable(cacheConfig.getRegion(), regionPath);
   }
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 fad6922..3cfdb11 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
@@ -40,6 +40,7 @@ import org.apache.geode.security.ResourcePermission;
 
 @Experimental
 public abstract class GfshCommand implements CommandMarker {
+  public static final String EXPERIMENTAL = "(Experimental) ";
   private InternalCache cache;
 
   public boolean isConnectedAndReady() {
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/InternalGfshCommand.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/InternalGfshCommand.java
index e32df99..6edf94c 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/InternalGfshCommand.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/InternalGfshCommand.java
@@ -33,7 +33,6 @@ import org.apache.geode.management.internal.configuration.domain.XmlEntity;
  */
 @SuppressWarnings("unused")
 public abstract class InternalGfshCommand extends GfshCommand {
-  public static final String EXPERIMENTAL = "(Experimental) ";
 
   public void persistClusterConfiguration(Result result, Runnable runnable) {
     if (result == null) {
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/CliFunctionResult.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/CliFunctionResult.java
index bc360bb..71ff4c7 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/CliFunctionResult.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/CliFunctionResult.java
@@ -31,50 +31,50 @@ import org.apache.geode.management.internal.configuration.domain.XmlEntity;
 public class CliFunctionResult implements Comparable<CliFunctionResult>, DataSerializableFixedID {
   private String memberIdOrName;
   private Serializable[] serializables = new String[0];
-  private Throwable throwable;
+  private Object resultObject;
   private boolean successful;
   private XmlEntity xmlEntity;
   private byte[] byteData = new byte[0];
 
+  @Deprecated
   public CliFunctionResult() {}
 
+  @Deprecated
   public CliFunctionResult(final String memberIdOrName) {
     this.memberIdOrName = memberIdOrName;
-
     this.successful = true;
   }
 
+  @Deprecated
   public CliFunctionResult(final String memberIdOrName, final Serializable[] serializables) {
     this.memberIdOrName = memberIdOrName;
     this.serializables = serializables;
-
     this.successful = true;
   }
 
+  @Deprecated
   public CliFunctionResult(final String memberIdOrName, final XmlEntity xmlEntity) {
     this.memberIdOrName = memberIdOrName;
     this.xmlEntity = xmlEntity;
-
     this.successful = true;
   }
 
-
+  @Deprecated
   public CliFunctionResult(final String memberIdOrName, final XmlEntity xmlEntity,
       final Serializable[] serializables) {
     this.memberIdOrName = memberIdOrName;
     this.xmlEntity = xmlEntity;
     this.serializables = serializables;
-
     this.successful = true;
   }
 
+  @Deprecated
   public CliFunctionResult(final String memberIdOrName, XmlEntity xmlEntity, final String message) {
     this.memberIdOrName = memberIdOrName;
     this.xmlEntity = xmlEntity;
     if (message != null) {
       this.serializables = new String[] {message};
     }
-
     this.successful = true;
   }
 
@@ -87,21 +87,29 @@ public class CliFunctionResult implements Comparable<CliFunctionResult>, DataSer
     }
   }
 
-  public CliFunctionResult(final String memberIdOrName, final Throwable throwable,
+  public CliFunctionResult(final String memberIdOrName, final Object resultObject,
       final String message) {
     this.memberIdOrName = memberIdOrName;
-    this.throwable = throwable;
+    this.resultObject = resultObject;
     if (message != null) {
       this.serializables = new String[] {message};
     }
+    if (resultObject instanceof Throwable) {
+      this.successful = false;
+    } else {
+      this.successful = true;
+    }
+  }
 
-    this.successful = false;
+  public CliFunctionResult(final String memberIdOrName, final Object resultObject) {
+    this(memberIdOrName, resultObject, null);
   }
 
   public String getMemberIdOrName() {
     return this.memberIdOrName;
   }
 
+  @Deprecated
   public String getMessage() {
     if (this.serializables.length == 0 || !(this.serializables[0] instanceof String)) {
       return null;
@@ -118,24 +126,34 @@ public class CliFunctionResult implements Comparable<CliFunctionResult>, DataSer
     }
 
     String errorMessage = "ERROR: ";
-    if (message != null && (throwable == null || !throwable.getMessage().contains(message))) {
+    if (message != null
+        && (resultObject == null || !((Throwable) resultObject).getMessage().contains(message))) {
       errorMessage += message;
     }
 
-    if (throwable != null) {
-      errorMessage = errorMessage.trim() + " " + throwable.getClass().getName() + ": "
-          + throwable.getMessage();
+    if (resultObject != null) {
+      errorMessage = errorMessage.trim() + " " + ((Throwable) resultObject).getClass().getName()
+          + ": " + ((Throwable) resultObject).getMessage();
     }
 
     return errorMessage;
   }
 
+  @Deprecated
   public Serializable[] getSerializables() {
     return this.serializables;
   }
 
+  @Deprecated
   public Throwable getThrowable() {
-    return this.throwable;
+    if (successful) {
+      return null;
+    }
+    return ((Throwable) resultObject);
+  }
+
+  public Object getResultObject() {
+    return resultObject;
   }
 
   @Override
@@ -149,14 +167,14 @@ public class CliFunctionResult implements Comparable<CliFunctionResult>, DataSer
     DataSerializer.writePrimitiveBoolean(this.successful, out);
     DataSerializer.writeObject(this.xmlEntity, out);
     DataSerializer.writeObjectArray(this.serializables, out);
-    DataSerializer.writeObject(this.throwable, out);
+    DataSerializer.writeObject(this.resultObject, out);
     DataSerializer.writeByteArray(this.byteData, out);
   }
 
   public void toDataPre_GFE_8_0_0_0(DataOutput out) throws IOException {
     DataSerializer.writeString(this.memberIdOrName, out);
     DataSerializer.writeObjectArray(this.serializables, out);
-    DataSerializer.writeObject(this.throwable, out);
+    DataSerializer.writeObject(this.resultObject, out);
   }
 
   @Override
@@ -165,13 +183,13 @@ public class CliFunctionResult implements Comparable<CliFunctionResult>, DataSer
     this.successful = DataSerializer.readPrimitiveBoolean(in);
     this.xmlEntity = DataSerializer.readObject(in);
     this.serializables = (Serializable[]) DataSerializer.readObjectArray(in);
-    this.throwable = DataSerializer.readObject(in);
+    this.resultObject = DataSerializer.readObject(in);
     this.byteData = DataSerializer.readByteArray(in);
   }
 
   public void fromDataPre_GFE_8_0_0_0(DataInput in) throws IOException, ClassNotFoundException {
     this.memberIdOrName = DataSerializer.readString(in);
-    this.throwable = DataSerializer.readObject(in);
+    this.resultObject = DataSerializer.readObject(in);
     this.serializables = (Serializable[]) DataSerializer.readObjectArray(in);
   }
 
@@ -179,10 +197,12 @@ public class CliFunctionResult implements Comparable<CliFunctionResult>, DataSer
     return this.successful;
   }
 
+  @Deprecated
   public XmlEntity getXmlEntity() {
     return this.xmlEntity;
   }
 
+  @Deprecated
   public byte[] getByteData() {
     return this.byteData;
   }
@@ -230,7 +250,7 @@ public class CliFunctionResult implements Comparable<CliFunctionResult>, DataSer
   public String toString() {
     return "CliFunctionResult [memberId=" + this.memberIdOrName + ", successful=" + this.successful
         + ", xmlEntity=" + this.xmlEntity + ", serializables=" + Arrays.toString(this.serializables)
-        + ", throwable=" + this.throwable + ", byteData=" + Arrays.toString(this.byteData) + "]";
+        + ", throwable=" + this.resultObject + ", byteData=" + Arrays.toString(this.byteData) + "]";
   }
 
   /**
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/result/ResultBuilder.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/result/ResultBuilder.java
index 1e03137..ae98985 100755
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/result/ResultBuilder.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/result/ResultBuilder.java
@@ -185,6 +185,11 @@ public class ResultBuilder {
   }
 
   public static CommandResult buildResult(List<CliFunctionResult> functionResults) {
+    return buildResult(functionResults, null, null);
+  }
+
+  public static CommandResult buildResult(List<CliFunctionResult> functionResults, String header,
+      String footer) {
     TabularResultData tabularData = ResultBuilder.createTabularResultData();
     boolean success = false;
     for (CliFunctionResult result : functionResults) {
@@ -196,14 +201,22 @@ public class ResultBuilder {
       }
     }
 
+    if (header != null) {
+      tabularData.setHeader(header);
+    }
+    if (footer != null) {
+      tabularData.setFooter(footer);
+    }
+
     tabularData.setStatus(success ? Result.Status.OK : Result.Status.ERROR);
     return ResultBuilder.buildResult(tabularData);
   }
 
+
   /**
    * Prepare Result from JSON. Type of result is expected to there in the JSON as 'contentType'
    * which should be one of {@link ResultData#TYPE_TABULAR}, {@link ResultData#TYPE_COMPOSITE},
-   * {@link ResultData#TYPE_INFO}, {@link ResultData#TYPE_ERROR}, {@link ResultData#TYPE_OBJECT}.
+   * {@link ResultData#TYPE_INFO}, {@link ResultData#TYPE_ERROR}.
    *
    * @param gfJsonObject GemFire JSON Object to use to prepare Result
    */
diff --git a/geode-core/src/test/resources/org/apache/geode/codeAnalysis/sanctionedDataSerializables.txt b/geode-core/src/test/resources/org/apache/geode/codeAnalysis/sanctionedDataSerializables.txt
index f22486f..256f947 100644
--- a/geode-core/src/test/resources/org/apache/geode/codeAnalysis/sanctionedDataSerializables.txt
+++ b/geode-core/src/test/resources/org/apache/geode/codeAnalysis/sanctionedDataSerializables.txt
@@ -2069,8 +2069,8 @@ fromData,41
 toData,41
 
 org/apache/geode/management/internal/cli/functions/CliFunctionResult,4
-fromData,61
-fromDataPre_GFE_8_0_0_0,34
+fromData,58
+fromDataPre_GFE_8_0_0_0,31
 toData,49
 toDataPre_GFE_8_0_0_0,25
 

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