You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by ji...@apache.org on 2019/02/15 02:46:52 UTC

[geode] branch develop updated: GEODE-6322: refactor createRegionCommand to use RegionConfig only (#3156)

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

jinmeiliao 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 189d6fb  GEODE-6322: refactor createRegionCommand to use RegionConfig only (#3156)
189d6fb is described below

commit 189d6fb94f3a7e0a0eb8f5c3bca52d613b6e5760
Author: jinmeiliao <ji...@pivotal.io>
AuthorDate: Fri Feb 15 10:46:40 2019 +0800

    GEODE-6322: refactor createRegionCommand to use RegionConfig only (#3156)
    
    * get rid of usages of xxxArgs and RegionConfigFactory
    * the resulting cluster configuration xml for region does not have excessive default values
---
 .../cli/commands/CreateIndexCommandDUnitTest.java  |   4 +-
 .../cli/commands/CreateRegionCommandDUnitTest.java |  67 +++-
 ...egionCommandPersistsConfigurationDUnitTest.java |   6 +-
 ...eRegionCommandWithNoClusterConfigDUnitTest.java |  86 +++++
 .../commands/DestroyRegionCommandDUnitTest.java    |   4 +-
 ...ExportClusterConfigurationCommandDUnitTest.java |  10 +-
 .../cli/commands/CreateRegionCommandDUnitTest.xml} |  34 +-
 .../CreateRegionCommandIntegrationTest.java        |   7 +-
 .../java/org/apache/geode/cache/DataPolicy.java    |   6 -
 .../ConfigurationPersistenceService.java           |   7 +
 .../internal/cache/PartitionAttributesImpl.java    |  57 ---
 .../internal/cli/commands/AlterRegionCommand.java  |  64 +---
 .../internal/cli/commands/CreateRegionCommand.java | 409 ++++++++++-----------
 .../internal/cli/domain/ExpirationArgs.java        |  59 ---
 .../internal/cli/domain/PartitionArgs.java         |  92 -----
 .../internal/cli/domain/RegionConfigFactory.java   | 404 --------------------
 .../functions/FetchRegionAttributesFunction.java   |  91 +----
 .../realizers/RegionConfigRealizer.java            |  59 ++-
 .../configuration/RegionAttributesTypeTest.java    |  90 ++++-
 .../cli/commands/CreateRegionCommandTest.java      |  23 +-
 .../cli/domain/RegionConfigFactoryTest.java        | 354 ------------------
 .../realizers/RegionConfigRealizerTest.java        |   6 +-
 .../geode/cache/configuration/RegionConfigTest.xml |   6 +-
 .../configuration/RegionAttributesDataPolicy.java  |  12 +-
 .../cache/configuration/RegionAttributesType.java  | 232 +++++++++++-
 .../geode/cache/configuration/RegionConfig.java    |   3 +
 26 files changed, 765 insertions(+), 1427 deletions(-)

diff --git a/geode-core/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/CreateIndexCommandDUnitTest.java b/geode-core/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/CreateIndexCommandDUnitTest.java
index fd6d088..31c04c0 100644
--- a/geode-core/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/CreateIndexCommandDUnitTest.java
+++ b/geode-core/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/CreateIndexCommandDUnitTest.java
@@ -112,7 +112,7 @@ public class CreateIndexCommandDUnitTest {
       InternalConfigurationPersistenceService configurationService =
           ClusterStartupRule.getLocator().getConfigurationPersistenceService();
       assertThat(configurationService.getConfiguration("cluster").getCacheXmlContent())
-          .contains("<region name=\"regionB\">");
+          .contains("<region name=\"regionB\"");
     });
 
     gfsh.executeAndAssertThat("create index --name=myIndex --expression=id --region=regionB")
@@ -122,7 +122,7 @@ public class CreateIndexCommandDUnitTest {
       InternalConfigurationPersistenceService configurationService =
           ClusterStartupRule.getLocator().getConfigurationPersistenceService();
       assertThat(configurationService.getConfiguration("cluster").getCacheXmlContent())
-          .contains("<region name=\"regionB\">").contains("<index").contains("expression=\"id\" ")
+          .contains("<region name=\"regionB\"").contains("<index").contains("expression=\"id\" ")
           .contains("from-clause=\"/regionB\"").contains("name=\"myIndex\"")
           .contains("type=\"range\"");
     });
diff --git a/geode-core/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/CreateRegionCommandDUnitTest.java b/geode-core/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/CreateRegionCommandDUnitTest.java
index 4ed5da7..b9e332c 100644
--- a/geode-core/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/CreateRegionCommandDUnitTest.java
+++ b/geode-core/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/CreateRegionCommandDUnitTest.java
@@ -19,13 +19,14 @@ import static org.assertj.core.api.Assertions.assertThat;
 
 import java.io.File;
 import java.io.Serializable;
+import java.net.URL;
 import java.util.Arrays;
 import java.util.List;
 import java.util.stream.Collectors;
 
+import org.apache.commons.io.FileUtils;
 import org.junit.BeforeClass;
 import org.junit.ClassRule;
-import org.junit.Ignore;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
@@ -37,6 +38,7 @@ import org.apache.geode.cache.Declarable;
 import org.apache.geode.cache.EntryOperation;
 import org.apache.geode.cache.PartitionResolver;
 import org.apache.geode.cache.Region;
+import org.apache.geode.cache.RegionShortcut;
 import org.apache.geode.cache.asyncqueue.AsyncEvent;
 import org.apache.geode.cache.asyncqueue.AsyncEventListener;
 import org.apache.geode.cache.configuration.CacheConfig;
@@ -45,6 +47,7 @@ import org.apache.geode.cache.configuration.RegionConfig;
 import org.apache.geode.cache.util.CacheListenerAdapter;
 import org.apache.geode.compression.Compressor;
 import org.apache.geode.compression.SnappyCompressor;
+import org.apache.geode.distributed.internal.InternalConfigurationPersistenceService;
 import org.apache.geode.internal.cache.InternalRegion;
 import org.apache.geode.internal.cache.PartitionedRegion;
 import org.apache.geode.internal.cache.RegionEntryContext;
@@ -120,6 +123,22 @@ public class CreateRegionCommandDUnitTest {
   }
 
   @Test
+  public void multipleTemplateRegionTypes() throws Exception {
+    String regionName = testName.getMethodName();
+    gfsh.executeAndAssertThat(
+        "create region --name=" + regionName + " --type=REPLICATE --group=group1")
+        .statusIsSuccess();
+    gfsh.executeAndAssertThat(
+        "create region --name=" + regionName + " --type=REPLICATE_PROXY --group=group2")
+        .statusIsSuccess();
+
+    gfsh.executeAndAssertThat("create region --name=failed --template-region=" + regionName)
+        .statusIsError()
+        .hasInfoSection().hasOutput()
+        .contains("Multiple types of template region /multipleTemplateRegionTypes exist.");
+  }
+
+  @Test
   public void testCreateRegionWithGoodCompressor() throws Exception {
     String regionName = testName.getMethodName();
     gfsh.executeAndAssertThat("create region --name=" + regionName
@@ -295,7 +314,7 @@ public class CreateRegionCommandDUnitTest {
     String regionName = testName.getMethodName();
     gfsh.executeAndAssertThat("create region --name=" + regionName
         + " --type=REPLICATE --partition-resolver=InvalidPartitionResolver")
-        .containsOutput("\"/" + regionName + "\" is not a Partitioned Region").statusIsError();
+        .containsOutput("can be used only for creating a Partitioned Region").statusIsError();
   }
 
   @Test
@@ -303,8 +322,7 @@ public class CreateRegionCommandDUnitTest {
     gfsh.executeAndAssertThat("create region --template-region=/TEMPLATE --name=/TEST"
         + TestCacheListener.class.getName())
         .statusIsError()
-        .containsOutput("Specify a valid region path for template-region")
-        .containsOutput("TEMPLATE not found");
+        .containsOutput("Template region /TEMPLATE does not exist");
   }
 
   @Test
@@ -707,12 +725,6 @@ public class CreateRegionCommandDUnitTest {
         .containsOutput("There are no GatewaySenders");
   }
 
-  /**
-   * Ignored this test until we refactor the FetchRegionAttributesFunction to not use
-   * AttributesFactory, and instead use RegionConfig, which we will do as part of implementing
-   * GEODE-6104
-   */
-  @Ignore
   @Test
   public void testCreateRegionFromTemplateWithAsyncEventListeners() {
     String queueId = "queue1";
@@ -742,12 +754,6 @@ public class CreateRegionCommandDUnitTest {
     });
   }
 
-  /**
-   * Ignored this test until we refactor the FetchRegionAttributesFunction to not use
-   * AttributesFactory, and instead use RegionConfig, which we will do as part of implementing
-   * GEODE-6104
-   */
-  @Ignore
   @Test
   public void testCreateRegionFromTemplateWithPartitionResolver() {
     String regionName = testName.getMethodName();
@@ -770,7 +776,34 @@ public class CreateRegionCommandDUnitTest {
               .isNotNull();
       assertThat(((InternalRegion) regionFromTemplate).getPartitionAttributes()
           .getPartitionResolver().getName())
-              .isEqualTo(DummyPartitionResolver.class.getName());
+              .isEqualTo("dummy");
+    });
+  }
+
+  @Test
+  public void createRegionCommandCreateCorrectClusterConfigXml() throws Exception {
+    URL xmlResource =
+        CreateRegionCommandDUnitTest.class.getResource("CreateRegionCommandDUnitTest.xml");
+
+    RegionShortcut[] shortcuts = RegionShortcut.values();
+    for (RegionShortcut shortcut : shortcuts) {
+      gfsh.executeAndAssertThat(
+          "create region --name=" + shortcut.name() + " --type=" + shortcut.name());
+    }
+
+    locator.invoke(() -> {
+      InternalConfigurationPersistenceService persistenceService =
+          ClusterStartupRule.getLocator().getConfigurationPersistenceService();
+      CacheConfig expected = persistenceService.getJaxbService()
+          .unMarshall(FileUtils.readFileToString(new File(xmlResource.getFile()), "UTF-8"));
+
+      CacheConfig actual = persistenceService.getCacheConfig("cluster");
+
+      for (RegionShortcut shortcut : shortcuts) {
+        assertThat(CacheElement.findElement(actual.getRegions(), shortcut.name()))
+            .isEqualToComparingFieldByFieldRecursively(
+                CacheElement.findElement(expected.getRegions(), shortcut.name()));
+      }
     });
   }
 
diff --git a/geode-core/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/CreateRegionCommandPersistsConfigurationDUnitTest.java b/geode-core/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/CreateRegionCommandPersistsConfigurationDUnitTest.java
index 9f53889..a5cbe02 100644
--- a/geode-core/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/CreateRegionCommandPersistsConfigurationDUnitTest.java
+++ b/geode-core/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/CreateRegionCommandPersistsConfigurationDUnitTest.java
@@ -310,10 +310,7 @@ public class CreateRegionCommandPersistsConfigurationDUnitTest {
         assertThat(attr.isStatisticsEnabled())
             .describedAs("Expecting statistics to be enabled for region " + name)
             .isTrue();
-        assertThat(attr.isCloningEnabled())
-            .describedAs("Expecting cloning to be enabled for region " + name
-                + " since compressor is provided")
-            .isTrue();
+        assertThat(attr.isCloningEnabled()).isNull();
         assertThat(attr.isEnableSubscriptionConflation())
             .describedAs("Expecting subscription conflation to be enabled for region "
                 + name)
@@ -505,7 +502,6 @@ public class CreateRegionCommandPersistsConfigurationDUnitTest {
       List<String> regionNames = Arrays.asList(regionName, regionNameFromTemplate);
       regionNames.forEach(name -> {
         RegionConfig regionConfig = CacheElement.findElement(config.getRegions(), name);
-        assertThat(regionConfig).isNotNull();
         assertThat(regionConfig.getName()).isEqualTo(name);
 
         RegionAttributesType regionAttributes = regionConfig.getRegionAttributes();
diff --git a/geode-core/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/CreateRegionCommandWithNoClusterConfigDUnitTest.java b/geode-core/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/CreateRegionCommandWithNoClusterConfigDUnitTest.java
new file mode 100644
index 0000000..9278636
--- /dev/null
+++ b/geode-core/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/CreateRegionCommandWithNoClusterConfigDUnitTest.java
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.apache.geode.management.internal.cli.commands;
+
+import org.junit.BeforeClass;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.rules.TemporaryFolder;
+import org.junit.rules.TestName;
+
+import org.apache.geode.test.dunit.rules.ClusterStartupRule;
+import org.apache.geode.test.dunit.rules.MemberVM;
+import org.apache.geode.test.junit.categories.RegionsTest;
+import org.apache.geode.test.junit.rules.GfshCommandRule;
+import org.apache.geode.test.junit.rules.serializable.SerializableTestName;
+
+@Category({RegionsTest.class})
+public class CreateRegionCommandWithNoClusterConfigDUnitTest {
+
+  private static MemberVM locator, server1, server2;
+
+  @ClassRule
+  public static ClusterStartupRule lsRule = new ClusterStartupRule();
+
+  @ClassRule
+  public static GfshCommandRule gfsh = new GfshCommandRule();
+
+  @Rule
+  public TestName testName = new SerializableTestName();
+
+  @Rule
+  public TemporaryFolder tmpDir = new TemporaryFolder();
+
+  @BeforeClass
+  public static void before() throws Exception {
+    locator = lsRule.startLocatorVM(0, l -> l.withoutClusterConfigurationService());
+    server1 = lsRule.startServerVM(1, "group1", locator.getPort());
+    server2 = lsRule.startServerVM(2, "group2", locator.getPort());
+
+    gfsh.connectAndVerify(locator);
+  }
+
+  @Test
+  public void multipleTemplateRegionTypes() throws Exception {
+    String regionName = testName.getMethodName();
+    gfsh.executeAndAssertThat(
+        "create region --name=" + regionName + " --type=REPLICATE --group=group1")
+        .statusIsSuccess();
+    gfsh.executeAndAssertThat(
+        "create region --name=" + regionName + " --type=REPLICATE_PROXY --group=group2")
+        .statusIsSuccess();
+
+    locator.waitUntilRegionIsReadyOnExactlyThisManyServers("/" + regionName, 2);
+
+    gfsh.executeAndAssertThat("create region --name=failed --template-region=" + regionName)
+        .statusIsError()
+        .hasInfoSection().hasOutput()
+        .contains("Multiple types of template region /multipleTemplateRegionTypes exist.");
+  }
+
+  @Test
+  public void multipleTemplateRegionWithSameType() throws Exception {
+    String regionName = testName.getMethodName();
+    gfsh.executeAndAssertThat("create region --name=" + regionName + " --type=REPLICATE")
+        .statusIsSuccess();
+
+    locator.waitUntilRegionIsReadyOnExactlyThisManyServers("/" + regionName, 2);
+    gfsh.executeAndAssertThat("create region --name=success --template-region=" + regionName)
+        .statusIsSuccess();
+  }
+}
diff --git a/geode-core/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/DestroyRegionCommandDUnitTest.java b/geode-core/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/DestroyRegionCommandDUnitTest.java
index 511fe14..9135580 100644
--- a/geode-core/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/DestroyRegionCommandDUnitTest.java
+++ b/geode-core/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/DestroyRegionCommandDUnitTest.java
@@ -116,13 +116,13 @@ public class DestroyRegionCommandDUnitTest {
           ClusterStartupRule.getLocator().getConfigurationPersistenceService();
       Configuration group1Config = service.getConfiguration("group1");
       assertThat(group1Config.getCacheXmlContent())
-          .containsOnlyOnce("<region name=\"region1\">")
+          .containsOnlyOnce("<region name=\"region1\"")
           .containsOnlyOnce("data-policy=\"empty\"")
           .containsOnlyOnce("scope=\"distributed-ack\"");
 
       Configuration clusterConfig = service.getConfiguration("group2");
       assertThat(clusterConfig.getCacheXmlContent())
-          .containsOnlyOnce("<region name=\"region1\">")
+          .containsOnlyOnce("<region name=\"region1\"")
           .containsOnlyOnce("data-policy=\"replicate\"")
           .containsOnlyOnce("scope=\"distributed-ack\"");
     });
diff --git a/geode-core/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/ExportClusterConfigurationCommandDUnitTest.java b/geode-core/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/ExportClusterConfigurationCommandDUnitTest.java
index 75ffc25..1d4506e 100644
--- a/geode-core/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/ExportClusterConfigurationCommandDUnitTest.java
+++ b/geode-core/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/ExportClusterConfigurationCommandDUnitTest.java
@@ -71,16 +71,16 @@ public class ExportClusterConfigurationCommandDUnitTest {
   @Test
   public void getClusterConfig() {
     gfsh.executeAndAssertThat(EXPORT_SHARED_CONFIG).statusIsSuccess()
-        .containsOutput("<region name=\"regionA\">").containsOutput("cluster.xml")
-        .doesNotContainOutput("<region name=\"regionB\">");
+        .containsOutput("<region name=\"regionA\"").containsOutput("cluster.xml")
+        .doesNotContainOutput("<region name=\"regionB\"");
   }
 
 
   @Test
   public void getClusterConfigInGroup() {
     gfsh.executeAndAssertThat(EXPORT_SHARED_CONFIG + " --group=groupB")
-        .containsOutput("<region name=\"regionB\">")
-        .doesNotContainOutput("<region name=\"regionA\">");
+        .containsOutput("<region name=\"regionB\"")
+        .doesNotContainOutput("<region name=\"regionA\"");
   }
 
   @Test
@@ -92,7 +92,7 @@ public class ExportClusterConfigurationCommandDUnitTest {
     assertThat(xmlFile).exists();
     String content = FileUtils.readFileToString(xmlFile, Charset.defaultCharset());
     assertThat(content).startsWith("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>")
-        .contains("<region name=\"regionA\">");
+        .contains("<region name=\"regionA\"");
   }
 
   @Test
diff --git a/geode-core/src/test/resources/org/apache/geode/cache/configuration/RegionConfigTest.xml b/geode-core/src/distributedTest/resources/org/apache/geode/management/internal/cli/commands/CreateRegionCommandDUnitTest.xml
similarity index 85%
copy from geode-core/src/test/resources/org/apache/geode/cache/configuration/RegionConfigTest.xml
copy to geode-core/src/distributedTest/resources/org/apache/geode/management/internal/cli/commands/CreateRegionCommandDUnitTest.xml
index ba8af9c..d29b58e 100644
--- a/geode-core/src/test/resources/org/apache/geode/cache/configuration/RegionConfigTest.xml
+++ b/geode-core/src/distributedTest/resources/org/apache/geode/management/internal/cli/commands/CreateRegionCommandDUnitTest.xml
@@ -1,20 +1,18 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!--
-  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.
--->
+  ~ 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.
+  -->
 <cache>
     <region name="PARTITION" refid="PARTITION">
         <region-attributes data-policy="partition"/>
@@ -107,20 +105,20 @@
         </region-attributes>
     </region>
     <region name="LOCAL" refid="LOCAL">
-        <region-attributes scope="local"/>
+        <region-attributes data-policy="normal" scope="local"/>
     </region>
     <region name="LOCAL_PERSISTENT" refid="LOCAL_PERSISTENT">
         <region-attributes data-policy="persistent-replicate" scope="local"/>
     </region>
     <region name="LOCAL_HEAP_LRU" refid="LOCAL_HEAP_LRU">
-        <region-attributes scope="local">
+        <region-attributes data-policy="normal" scope="local">
             <eviction-attributes>
                 <lru-heap-percentage action="local-destroy"/>
             </eviction-attributes>
         </region-attributes>
     </region>
     <region name="LOCAL_OVERFLOW" refid="LOCAL_OVERFLOW">
-        <region-attributes scope="local">
+        <region-attributes data-policy="normal" scope="local">
             <eviction-attributes>
                 <lru-heap-percentage action="overflow-to-disk"/>
             </eviction-attributes>
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/management/internal/cli/commands/CreateRegionCommandIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/management/internal/cli/commands/CreateRegionCommandIntegrationTest.java
index de189fe..665a093 100644
--- a/geode-core/src/integrationTest/java/org/apache/geode/management/internal/cli/commands/CreateRegionCommandIntegrationTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/management/internal/cli/commands/CreateRegionCommandIntegrationTest.java
@@ -77,7 +77,7 @@ public class CreateRegionCommandIntegrationTest {
   @Test
   public void templateRegionDoesNotExist() throws Exception {
     gfsh.executeAndAssertThat("create region --name=/FOO --template-region=/BAR").statusIsError()
-        .containsOutput("Specify a valid region path for template-region");
+        .containsOutput("Template region /BAR does not exist");
   }
 
   @Test
@@ -85,14 +85,13 @@ public class CreateRegionCommandIntegrationTest {
     gfsh.executeAndAssertThat(
         "create region --name=/FOO --template-region=REPLICATED --redundant-copies=2")
         .statusIsError().containsOutput(
-            "Parameter(s) \"[redundant-copies]\" can be used only for creating a Partitioned Region");
+            "can be used only for creating a Partitioned Region");
   }
 
   @Test
   public void conflictingPartitionAttributesWithShortCut() throws Exception {
     gfsh.executeAndAssertThat("create region --name=/FOO --type=REPLICATE --redundant-copies=2")
-        .statusIsError().containsOutput(
-            "Parameter(s) \"[redundant-copies]\" can be used only for creating a Partitioned Region");
+        .statusIsError().containsOutput("can be used only for creating a Partitioned Region");
   }
 
   @Test
diff --git a/geode-core/src/main/java/org/apache/geode/cache/DataPolicy.java b/geode-core/src/main/java/org/apache/geode/cache/DataPolicy.java
index 3b6e933..6219bd5 100644
--- a/geode-core/src/main/java/org/apache/geode/cache/DataPolicy.java
+++ b/geode-core/src/main/java/org/apache/geode/cache/DataPolicy.java
@@ -19,7 +19,6 @@ package org.apache.geode.cache;
 import java.io.ObjectStreamException;
 
 import org.apache.geode.annotations.Immutable;
-import org.apache.geode.cache.configuration.RegionAttributesDataPolicy;
 
 
 /**
@@ -303,11 +302,6 @@ public class DataPolicy implements java.io.Serializable {
     return this.name;
   }
 
-  public RegionAttributesDataPolicy toConfigType() {
-    String configName = this.name.toLowerCase().replace("_", "-");
-    return RegionAttributesDataPolicy.fromValue(configName);
-  }
-
   public static DataPolicy fromString(String s) {
     String[] allowedValues =
         new String[] {"EMPTY", "NORMAL", "REPLICATE", "PERSISTENT_REPLICATE", "PARTITION",
diff --git a/geode-core/src/main/java/org/apache/geode/distributed/ConfigurationPersistenceService.java b/geode-core/src/main/java/org/apache/geode/distributed/ConfigurationPersistenceService.java
index 8c64fe6..44ae6a6 100644
--- a/geode-core/src/main/java/org/apache/geode/distributed/ConfigurationPersistenceService.java
+++ b/geode-core/src/main/java/org/apache/geode/distributed/ConfigurationPersistenceService.java
@@ -17,6 +17,7 @@
 
 package org.apache.geode.distributed;
 
+import java.util.Set;
 import java.util.function.UnaryOperator;
 
 import org.apache.geode.annotations.Experimental;
@@ -27,6 +28,12 @@ public interface ConfigurationPersistenceService {
   String CLUSTER_CONFIG = "cluster";
 
   /**
+   * retrieves all the group names in the cluster
+   */
+
+  Set<String> getGroups();
+
+  /**
    * retrieves the configuration object of a member group
    *
    * @param group the member group name, if null, then "cluster" is assumed
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/PartitionAttributesImpl.java b/geode-core/src/main/java/org/apache/geode/internal/cache/PartitionAttributesImpl.java
index c1ac874..68d0d0e 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/PartitionAttributesImpl.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/PartitionAttributesImpl.java
@@ -37,14 +37,11 @@ import org.apache.geode.cache.PartitionAttributes;
 import org.apache.geode.cache.PartitionAttributesFactory;
 import org.apache.geode.cache.PartitionResolver;
 import org.apache.geode.cache.Region;
-import org.apache.geode.cache.configuration.DeclarableType;
-import org.apache.geode.cache.configuration.RegionAttributesType;
 import org.apache.geode.cache.partition.PartitionListener;
 import org.apache.geode.distributed.internal.InternalDistributedSystem;
 import org.apache.geode.internal.InternalDataSerializer;
 import org.apache.geode.internal.logging.LogService;
 import org.apache.geode.internal.offheap.OffHeapStorage;
-import org.apache.geode.management.internal.configuration.domain.DeclarableTypeInstantiator;
 
 /**
  * Internal implementation of PartitionAttributes. New attributes existing only in this class and
@@ -794,58 +791,4 @@ public class PartitionAttributesImpl implements PartitionAttributes, Cloneable,
 
     return computeOffHeapLocalMaxMemory();
   }
-
-  public static PartitionAttributesImpl fromConfig(
-      RegionAttributesType.PartitionAttributes configAttributes, Cache cache) {
-    PartitionAttributesImpl partitionAttributes = new PartitionAttributesImpl();
-    if (configAttributes == null) {
-      return null;
-    }
-
-    if (configAttributes.getRedundantCopies() != null) {
-      partitionAttributes
-          .setRedundantCopies(Integer.valueOf(configAttributes.getRedundantCopies()));
-    }
-
-    if (configAttributes.getTotalMaxMemory() != null) {
-      partitionAttributes.setTotalMaxMemory(Integer.valueOf(configAttributes.getTotalMaxMemory()));
-    }
-
-    if (configAttributes.getTotalNumBuckets() != null) {
-      partitionAttributes
-          .setTotalNumBuckets(Integer.valueOf(configAttributes.getTotalNumBuckets()));
-    }
-
-    if (configAttributes.getLocalMaxMemory() != null) {
-      partitionAttributes.setLocalMaxMemory(Integer.valueOf(configAttributes.getLocalMaxMemory()));
-    }
-
-    if (configAttributes.getColocatedWith() != null) {
-      partitionAttributes.setColocatedWith(configAttributes.getColocatedWith());
-    }
-
-    if (configAttributes.getPartitionResolver() != null) {
-      partitionAttributes.setPartitionResolver(
-          DeclarableTypeInstantiator.newInstance(configAttributes.getPartitionResolver(), cache));
-    }
-
-    if (configAttributes.getRecoveryDelay() != null) {
-      partitionAttributes.setRecoveryDelay(Long.valueOf(configAttributes.getRecoveryDelay()));
-    }
-
-    if (configAttributes.getStartupRecoveryDelay() != null) {
-      partitionAttributes
-          .setStartupRecoveryDelay(Long.valueOf(configAttributes.getStartupRecoveryDelay()));
-    }
-
-    if (configAttributes.getPartitionListeners() != null) {
-      List<DeclarableType> configListeners = configAttributes.getPartitionListeners();
-      for (int i = 0; i < configListeners.size(); i++) {
-        partitionAttributes.addPartitionListener(
-            DeclarableTypeInstantiator.newInstance(configListeners.get(i), cache));
-      }
-    }
-
-    return partitionAttributes;
-  }
 }
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/AlterRegionCommand.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/AlterRegionCommand.java
index 0e72116..8dac6dd 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/AlterRegionCommand.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/AlterRegionCommand.java
@@ -137,14 +137,15 @@ public class AlterRegionCommand extends SingleGfshCommand {
     deltaConfig.setName(regionPath);
     RegionAttributesType regionAttributesType = new RegionAttributesType();
     deltaConfig.setRegionAttributes(regionAttributesType);
-    regionAttributesType.setEntryIdleTime(getExpirationAttributes(entryExpirationIdleTime,
+    regionAttributesType.setEntryIdleTime(ExpirationAttributesType.generate(entryExpirationIdleTime,
         entryExpirationIdleTimeAction, entryIdleTimeCustomExpiry));
-    regionAttributesType.setEntryTimeToLive(getExpirationAttributes(entryExpirationTTL,
+    regionAttributesType.setEntryTimeToLive(ExpirationAttributesType.generate(entryExpirationTTL,
         entryExpirationTTLAction, entryTTLCustomExpiry));
     regionAttributesType.setRegionIdleTime(
-        getExpirationAttributes(regionExpirationIdleTime, regionExpirationIdleTimeAction, null));
+        ExpirationAttributesType.generate(regionExpirationIdleTime, regionExpirationIdleTimeAction,
+            null));
     regionAttributesType.setRegionTimeToLive(
-        getExpirationAttributes(regionExpirationTTL, regionExpirationTTLAction, null));
+        ExpirationAttributesType.generate(regionExpirationTTL, regionExpirationTTLAction, null));
     if (cacheLoader != null) {
       regionAttributesType.setCacheLoader(
           new DeclarableType(cacheLoader.getClassName(), cacheLoader.getInitProperties()));
@@ -207,13 +208,17 @@ public class AlterRegionCommand extends SingleGfshCommand {
     RegionAttributesType existingAttributes = existingConfig.getRegionAttributes();
 
     existingAttributes.setEntryIdleTime(
-        combine(existingAttributes.getEntryIdleTime(), deltaAttributes.getEntryIdleTime()));
+        ExpirationAttributesType.combine(existingAttributes.getEntryIdleTime(),
+            deltaAttributes.getEntryIdleTime()));
     existingAttributes.setEntryTimeToLive(
-        combine(existingAttributes.getEntryTimeToLive(), deltaAttributes.getEntryTimeToLive()));
+        ExpirationAttributesType.combine(existingAttributes.getEntryTimeToLive(),
+            deltaAttributes.getEntryTimeToLive()));
     existingAttributes.setRegionIdleTime(
-        combine(existingAttributes.getRegionIdleTime(), deltaAttributes.getRegionIdleTime()));
+        ExpirationAttributesType.combine(existingAttributes.getRegionIdleTime(),
+            deltaAttributes.getRegionIdleTime()));
     existingAttributes.setRegionTimeToLive(
-        combine(existingAttributes.getRegionTimeToLive(), deltaAttributes.getRegionTimeToLive()));
+        ExpirationAttributesType.combine(existingAttributes.getRegionTimeToLive(),
+            deltaAttributes.getRegionTimeToLive()));
 
     if (deltaAttributes.getCacheLoader() != null) {
       if (deltaAttributes.getCacheLoader().equals(DeclarableType.EMPTY)) {
@@ -270,47 +275,4 @@ public class AlterRegionCommand extends SingleGfshCommand {
     }
     return true;
   }
-
-  ExpirationAttributesType getExpirationAttributes(Integer timeout,
-      ExpirationAction action, ClassName expiry) {
-    if (timeout == null && action == null && expiry == null) {
-      return null;
-    }
-    if (expiry != null) {
-      return new ExpirationAttributesType(timeout, action,
-          expiry.getClassName(), expiry.getInitProperties());
-    } else {
-      return new ExpirationAttributesType(timeout, action, null, null);
-    }
-  }
-
-  // this is a helper method to combine the existing with the delta ExpirationAttributesType
-  ExpirationAttributesType combine(ExpirationAttributesType existing,
-      ExpirationAttributesType delta) {
-    if (delta == null) {
-      return existing;
-    }
-
-    if (existing == null) {
-      existing = new ExpirationAttributesType();
-      existing.setAction(ExpirationAction.INVALIDATE.toXmlString());
-      existing.setTimeout("0");
-    }
-
-    if (delta.getTimeout() != null) {
-      existing.setTimeout(delta.getTimeout());
-    }
-    if (delta.getAction() != null) {
-      existing.setAction(delta.getAction());
-    }
-    if (delta.getCustomExpiry() != null) {
-      if (delta.getCustomExpiry().equals(DeclarableType.EMPTY)) {
-        existing.setCustomExpiry(null);
-      } else {
-        existing.setCustomExpiry(delta.getCustomExpiry());
-      }
-    }
-    return existing;
-  }
-
 }
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/CreateRegionCommand.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/CreateRegionCommand.java
index e752d8a..f69eb3d 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/CreateRegionCommand.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/CreateRegionCommand.java
@@ -14,20 +14,18 @@
  */
 package org.apache.geode.management.internal.cli.commands;
 
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
-import java.util.Optional;
 import java.util.Set;
 import java.util.stream.Collectors;
 
-import javax.management.ObjectName;
-
+import joptsimple.internal.Strings;
 import org.apache.commons.lang3.ArrayUtils;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.apache.commons.lang3.builder.EqualsBuilder;
 import org.springframework.shell.core.annotation.CliCommand;
 import org.springframework.shell.core.annotation.CliOption;
 
@@ -38,36 +36,31 @@ import org.apache.geode.cache.CustomExpiry;
 import org.apache.geode.cache.EvictionAction;
 import org.apache.geode.cache.ExpirationAction;
 import org.apache.geode.cache.Region;
-import org.apache.geode.cache.RegionAttributes;
 import org.apache.geode.cache.RegionShortcut;
 import org.apache.geode.cache.configuration.CacheConfig;
 import org.apache.geode.cache.configuration.CacheElement;
+import org.apache.geode.cache.configuration.ClassNameType;
+import org.apache.geode.cache.configuration.DeclarableType;
+import org.apache.geode.cache.configuration.RegionAttributesType;
 import org.apache.geode.cache.configuration.RegionConfig;
-import org.apache.geode.cache.execute.ResultCollector;
 import org.apache.geode.distributed.DistributedMember;
 import org.apache.geode.distributed.internal.InternalConfigurationPersistenceService;
 import org.apache.geode.internal.cache.InternalCache;
+import org.apache.geode.internal.config.JAXBService;
 import org.apache.geode.internal.logging.LogService;
 import org.apache.geode.management.DistributedRegionMXBean;
 import org.apache.geode.management.DistributedSystemMXBean;
 import org.apache.geode.management.ManagementService;
-import org.apache.geode.management.RegionAttributesData;
-import org.apache.geode.management.RegionMXBean;
 import org.apache.geode.management.cli.CliMetaData;
 import org.apache.geode.management.cli.ConverterHint;
 import org.apache.geode.management.cli.Result;
 import org.apache.geode.management.cli.SingleGfshCommand;
 import org.apache.geode.management.internal.cli.AbstractCliAroundInterceptor;
-import org.apache.geode.management.internal.cli.CliUtil;
 import org.apache.geode.management.internal.cli.GfshParseResult;
-import org.apache.geode.management.internal.cli.LogWrapper;
 import org.apache.geode.management.internal.cli.domain.ClassName;
-import org.apache.geode.management.internal.cli.domain.PartitionArgs;
-import org.apache.geode.management.internal.cli.domain.RegionConfigFactory;
 import org.apache.geode.management.internal.cli.functions.CliFunctionResult;
 import org.apache.geode.management.internal.cli.functions.CreateRegionFunctionArgs;
 import org.apache.geode.management.internal.cli.functions.FetchRegionAttributesFunction;
-import org.apache.geode.management.internal.cli.functions.RegionAttributesWrapper;
 import org.apache.geode.management.internal.cli.functions.RegionCreateFunction;
 import org.apache.geode.management.internal.cli.i18n.CliStrings;
 import org.apache.geode.management.internal.cli.result.ResultBuilder;
@@ -78,6 +71,17 @@ import org.apache.geode.management.internal.security.ResourceOperation;
 import org.apache.geode.security.ResourcePermission;
 
 public class CreateRegionCommand extends SingleGfshCommand {
+  private static final String[] PARTITION_ATTRIBUTES = new String[] {
+      CliStrings.CREATE_REGION__COLOCATEDWITH,
+      CliStrings.CREATE_REGION__LOCALMAXMEMORY,
+      CliStrings.CREATE_REGION__RECOVERYDELAY,
+      CliStrings.CREATE_REGION__REDUNDANTCOPIES,
+      CliStrings.CREATE_REGION__STARTUPRECOVERYDDELAY,
+      CliStrings.CREATE_REGION__TOTALMAXMEMORY,
+      CliStrings.CREATE_REGION__TOTALNUMBUCKETS,
+      CliStrings.CREATE_REGION__PARTITION_RESOLVER
+  };
+
   @CliCommand(value = CliStrings.CREATE_REGION, help = CliStrings.CREATE_REGION__HELP)
   @CliMetaData(relatedTopic = CliStrings.TOPIC_GEODE_REGION,
       interceptor = "org.apache.geode.management.internal.cli.commands.CreateRegionCommand$Interceptor")
@@ -216,18 +220,84 @@ public class CreateRegionCommand extends SingleGfshCommand {
               new Object[] {regionPath}));
     }
 
+    RegionConfig regionConfig = new RegionConfig();
+
+    // get the initial set of attributes either from shortcut or from the template region
+    InternalConfigurationPersistenceService persistenceService =
+        getConfigurationPersistenceService();
+    if (regionShortcut != null) {
+      regionConfig.setType(regionShortcut.name());
+    }
+    // get the attributes from the template region
+    else {
+      List<RegionConfig> templateRegionConfigs = new ArrayList<>();
+      // get the potential template region config from the cluster configuration
+      if (persistenceService != null) {
+        templateRegionConfigs = persistenceService.getGroups().stream()
+            .flatMap(g -> persistenceService.getCacheConfig(g, true).getRegions().stream())
+            .filter(c -> c.getName().equals(templateRegion.substring(1)))
+            .collect(Collectors.toList());
+      }
+      // as a last resort, go the member that hosts this region to retrieve the template's region
+      // xml
+      else {
+        // we would need to execute a function to the member hosting the template region to get the
+        // region xml. cluster configuration isn't always enabled, so we cannot guarantee that we
+        // can
+        // get the template region configuration from the cluster configuration.
+        Set<DistributedMember> regionAssociatedMembers = findMembersForRegion(templateRegion);
+
+        if (!regionAssociatedMembers.isEmpty()) {
+          List<CliFunctionResult> regionXmlResults = executeAndGetFunctionResult(
+              FetchRegionAttributesFunction.INSTANCE, templateRegion, regionAssociatedMembers);
+
+          JAXBService jaxbService = new JAXBService(CacheConfig.class);
+          templateRegionConfigs = regionXmlResults.stream().filter(CliFunctionResult::isSuccessful)
+              .map(CliFunctionResult::getResultObject).map(String.class::cast)
+              .map(s -> jaxbService.unMarshall(s, RegionConfig.class))
+              .collect(Collectors.toList());
+        }
+      }
+
+      if (templateRegionConfigs.isEmpty()) {
+        return ResultModel.createError("Template region " + templateRegion + " does not exist.");
+      }
+      if (templateRegionConfigs.size() == 1) {
+        regionConfig = templateRegionConfigs.get(0);
+      }
+      // found more than one configuration with this name. fail ff they have different attributes.
+      else {
+        RegionConfig first = templateRegionConfigs.get(0);
+        for (int i = 1; i < templateRegionConfigs.size(); i++) {
+          if (!EqualsBuilder.reflectionEquals(first, templateRegionConfigs.get(i), false, null,
+              true)) {
+            return ResultModel.createError("Multiple types of template region " + templateRegion
+                + " exist. Can not resolve template region attributes.");
+          }
+        }
+        regionConfig = first;
+      }
+    }
+
+    regionConfig.setName(regionPathData.getName());
+
+    // set partition attributes
+    RegionAttributesType regionAttributes = regionConfig.getRegionAttributes();
+    RegionAttributesType.PartitionAttributes delta =
+        RegionAttributesType.PartitionAttributes.generate(partitionResolver, null, prLocalMaxMemory,
+            prRecoveryDelay, prRedundantCopies, prStartupRecoveryDelay, prTotalMaxMemory,
+            prTotalNumBuckets, prColocatedWith);
+
+    RegionAttributesType.PartitionAttributes partitionAttributes =
+        RegionAttributesType.PartitionAttributes.combine(
+            regionAttributes.getPartitionAttributes(), delta);
+    regionAttributes.setPartitionAttributes(partitionAttributes);
+
     // validate if partition args are supplied only for partitioned regions
-    PartitionArgs partitionArgs =
-        new PartitionArgs(prColocatedWith, prLocalMaxMemory, prRecoveryDelay,
-            prRedundantCopies, prStartupRecoveryDelay, prTotalMaxMemory, prTotalNumBuckets,
-            partitionResolver);
-    if (regionShortcut != null && !regionShortcut.name().startsWith("PARTITION")
-        && !partitionArgs.isEmpty()) {
-      return ResultModel.createError(CliStrings.format(
-          CliStrings.CREATE_REGION__MSG__OPTION_0_CAN_BE_USED_ONLY_FOR_PARTITIONEDREGION,
-          partitionArgs.getUserSpecifiedPartitionAttributes()) + " "
-          + CliStrings.format(CliStrings.CREATE_REGION__MSG__0_IS_NOT_A_PARITIONEDREGION,
-              regionPath));
+    if (!regionAttributes.getDataPolicy().isPartition() && partitionAttributes != null) {
+      return ResultModel.createError(
+          String.format("Parameters %s can be used only for creating a Partitioned Region",
+              Strings.join(PARTITION_ATTRIBUTES, ", ")));
     }
 
     // validate colocation for partitioned regions
@@ -249,7 +319,7 @@ public class CreateRegionCommand extends SingleGfshCommand {
       }
     }
 
-    // validate gateway senders
+    // validate and set gateway senders
     if (gatewaySenderIds != null) {
       Set<String> existingGatewaySenders =
           Arrays.stream(getDSMBean().listGatewaySenders()).collect(Collectors.toSet());
@@ -263,61 +333,31 @@ public class CreateRegionCommand extends SingleGfshCommand {
             CliStrings.CREATE_REGION__MSG__SPECIFY_VALID_GATEWAYSENDER_ID_UNKNOWN_0,
             (Object[]) gatewaySenderIds));
       }
-    }
-
-    // validate if template region exists, if provided
-    if (templateRegion != null && !regionExists(templateRegion)) {
-      return ResultModel.createError(CliStrings.format(
-          CliStrings.CREATE_REGION__MSG__SPECIFY_VALID_REGION_PATH_FOR_0_REGIONPATH_1_NOT_FOUND,
-          CliStrings.CREATE_REGION__USEATTRIBUTESFROM, templateRegion));
-    }
-
-    // get predefined attributes for a template region
-    RegionAttributesWrapper<?, ?> wrappedTemplateAttributes = null;
-    if (templateRegion != null) {
-      wrappedTemplateAttributes = getRegionAttributes(cache, templateRegion);
-      if (wrappedTemplateAttributes == null) {
-        return ResultModel.createError(CliStrings.format(
-            CliStrings.CREATE_REGION__MSG__COULD_NOT_RETRIEVE_REGION_ATTRS_FOR_PATH_0_VERIFY_REGION_EXISTS,
-            templateRegion));
+      regionAttributes.setGatewaySenderIds(StringUtils.join(gatewaySenderIds, ","));
+    }
+
+    // validating and set diskstore
+    if (diskStore != null) {
+      if (!regionAttributes.getDataPolicy().isPersistent()) {
+        String subMessage =
+            "Only regions with persistence or overflow to disk can specify DiskStore";
+        String message = subMessage + ". "
+            + CliStrings.format(
+                CliStrings.CREATE_REGION__MSG__USE_ATTRIBUTES_FROM_REGION_0_IS_NOT_WITH_PERSISTENCE,
+                new Object[] {templateRegion});
+        return ResultModel.createError(message);
       }
 
-      if (wrappedTemplateAttributes.getRegionAttributes().getPartitionAttributes() == null
-          && !partitionArgs.isEmpty()) {
+      if (!diskStoreExists(diskStore)) {
         return ResultModel.createError(CliStrings.format(
-            CliStrings.CREATE_REGION__MSG__OPTION_0_CAN_BE_USED_ONLY_FOR_PARTITIONEDREGION,
-            partitionArgs.getUserSpecifiedPartitionAttributes()) + " "
-            + CliStrings.format(CliStrings.CREATE_REGION__MSG__0_IS_NOT_A_PARITIONEDREGION,
-                templateRegion));
+            CliStrings.CREATE_REGION__MSG__SPECIFY_VALID_DISKSTORE_UNKNOWN_DISKSTORE_0,
+            new Object[] {diskStore}));
       }
-    }
-
-    RegionAttributes<?, ?> regionAttributes;
-    if (wrappedTemplateAttributes != null) {
-      regionAttributes = wrappedTemplateAttributes.getRegionAttributes();
-    } else {
-      regionAttributes = cache.getRegionAttributes(regionShortcut.toString());
-    }
-
-    // validating diskstore with other attributes
-    if (diskStore != null && !regionAttributes.getDataPolicy().withPersistence()) {
-      String subMessage = "Only regions with persistence or overflow to disk can specify DiskStore";
-      String message = subMessage + ". "
-          + CliStrings.format(
-              CliStrings.CREATE_REGION__MSG__USE_ATTRIBUTES_FROM_REGION_0_IS_NOT_WITH_PERSISTENCE,
-              new Object[] {templateRegion});
-
-      return ResultModel.createError(message);
-    }
-
-    if (diskStore != null && !diskStoreExists(diskStore)) {
-      return ResultModel.createError(CliStrings.format(
-          CliStrings.CREATE_REGION__MSG__SPECIFY_VALID_DISKSTORE_UNKNOWN_DISKSTORE_0,
-          new Object[] {diskStore}));
+      regionAttributes.setDiskStoreName(diskStore);
     }
 
     // additional authorization
-    if (isAttributePersistent(regionAttributes)) {
+    if (regionAttributes.getDataPolicy().isPersistent()) {
       authorize(ResourcePermission.Resource.CLUSTER, ResourcePermission.Operation.WRITE,
           ResourcePermission.Target.DISK);
     }
@@ -328,84 +368,95 @@ public class CreateRegionCommand extends SingleGfshCommand {
       if (groups == null || groups.length == 0) {
         return ResultModel.createError(CliStrings.NO_MEMBERS_FOUND_MESSAGE);
       }
-
       return ResultModel.createError(
           CliStrings.format(CliStrings.CREATE_REGION__MSG__GROUPS_0_ARE_INVALID,
               (Object[]) groups));
     }
 
     // generate the RegionConfig object for passing to distributed function and persisting
-    Set<ClassName<CacheListener>> cacheListeners = new HashSet<>();
     if (cacheListener != null) {
-      Arrays.stream(cacheListener).forEach(c -> cacheListeners.add(c));
-    } else if (wrappedTemplateAttributes != null
-        && wrappedTemplateAttributes.getCacheListenerClasses() != null) {
-      cacheListeners.addAll(wrappedTemplateAttributes.getCacheListenerClasses());
+      // clean the old tempalte region's cache listener
+      regionAttributes.getCacheListeners().clear();
+      Arrays.stream(cacheListener)
+          .map(cl -> new DeclarableType(cl.getClassName(), cl.getInitProperties()))
+          .forEach(regionAttributes.getCacheListeners()::add);
     }
 
-    ClassName<CacheLoader> cacheLoaderClassNameToPersist = null;
     if (cacheLoader != null) {
-      cacheLoaderClassNameToPersist = cacheLoader;
-    } else if (wrappedTemplateAttributes != null
-        && wrappedTemplateAttributes.getCacheLoaderClass() != null) {
-      cacheLoaderClassNameToPersist = wrappedTemplateAttributes.getCacheLoaderClass();
+      regionAttributes.setCacheLoader(
+          new DeclarableType(cacheLoader.getClassName(), cacheLoader.getInitProperties()));
     }
 
-    ClassName<CacheWriter> cacheWriterClassNameToPersist = null;
     if (cacheWriter != null) {
-      cacheWriterClassNameToPersist = cacheWriter;
-    } else if (wrappedTemplateAttributes != null
-        && wrappedTemplateAttributes.getCacheWriterClass() != null) {
-      cacheWriterClassNameToPersist = wrappedTemplateAttributes.getCacheWriterClass();
+      regionAttributes.setCacheWriter(
+          new DeclarableType(cacheWriter.getClassName(), cacheWriter.getInitProperties()));
     }
 
-    String compressorClassNameToPersist = null;
     if (compressor != null) {
-      compressorClassNameToPersist = compressor;
-    } else if (wrappedTemplateAttributes != null
-        && wrappedTemplateAttributes.getCompressorClass() != null) {
-      compressorClassNameToPersist = wrappedTemplateAttributes.getCompressorClass();
+      regionAttributes.setCompressor(new ClassNameType(compressor));
     }
 
-    String keyConstraintToPersist = null;
     if (keyConstraint != null) {
-      keyConstraintToPersist = keyConstraint;
-    } else if (wrappedTemplateAttributes != null
-        && wrappedTemplateAttributes.getKeyConstraintClass() != null) {
-      keyConstraintToPersist = wrappedTemplateAttributes.getKeyConstraintClass();
+      regionAttributes.setKeyConstraint(keyConstraint);
     }
 
-    String valueConstraintToPersist = null;
     if (valueConstraint != null) {
-      valueConstraintToPersist = valueConstraint;
-    } else if (wrappedTemplateAttributes != null
-        && wrappedTemplateAttributes.getValueConstraintClass() != null) {
-      valueConstraintToPersist = wrappedTemplateAttributes.getValueConstraintClass();
-    }
-
-    Set<String> asyncEventQueueIdSet = Optional.ofNullable(asyncEventQueueIds)
-        .map(a -> Arrays.stream(a).collect(Collectors.toSet()))
-        .orElse(null);
-    Set<String> gatewaySenderIdSet = Optional.ofNullable(gatewaySenderIds)
-        .map(a -> Arrays.stream(a).collect(Collectors.toSet()))
-        .orElse(null);
-
-    RegionConfig config = (new RegionConfigFactory()).generate(regionPath, keyConstraintToPersist,
-        valueConstraintToPersist, statisticsEnabled, entryExpirationIdleTime,
-        entryExpirationIdleTimeAction, entryExpirationTTL, entryExpirationTTLAction,
-        entryIdleTimeCustomExpiry,
-        entryTTLCustomExpiry, regionExpirationIdleTime, regionExpirationIdleTimeAction,
-        regionExpirationTTL, regionExpirationTTLAction, evictionAction, evictionMaxMemory,
-        evictionEntryCount, evictionObjectSizer, diskStore, diskSynchronous, enableAsyncConflation,
-        enableSubscriptionConflation, cacheListeners, cacheLoaderClassNameToPersist,
-        cacheWriterClassNameToPersist,
-        asyncEventQueueIdSet, gatewaySenderIdSet, concurrencyChecksEnabled, cloningEnabled,
-        mcastEnabled,
-        concurrencyLevel, partitionArgs, compressorClassNameToPersist, offHeap, regionAttributes);
+      regionAttributes.setValueConstraint(valueConstraint);
+    }
+
+    if (asyncEventQueueIds != null) {
+      regionAttributes.setAsyncEventQueueIds(Strings.join(asyncEventQueueIds, ","));
+    }
+
+    if (offHeap != null) {
+      regionAttributes.setOffHeap(offHeap);
+    }
+    if (concurrencyLevel != null) {
+      regionAttributes.setConcurrencyLevel(concurrencyLevel.toString());
+    }
+    if (enableAsyncConflation != null) {
+      regionAttributes.setEnableAsyncConflation(enableAsyncConflation);
+    }
+    if (cloningEnabled != null) {
+      regionAttributes.setCloningEnabled(cloningEnabled);
+    }
+    if (concurrencyChecksEnabled != null) {
+      regionAttributes.setConcurrencyChecksEnabled(concurrencyChecksEnabled);
+    }
+    if (mcastEnabled != null) {
+      regionAttributes.setMulticastEnabled(mcastEnabled);
+    }
+    if (statisticsEnabled != null) {
+      regionAttributes.setStatisticsEnabled(statisticsEnabled);
+    }
+    if (enableSubscriptionConflation != null) {
+      regionAttributes.setEnableSubscriptionConflation(enableSubscriptionConflation);
+    }
+    if (diskSynchronous != null) {
+      regionAttributes.setDiskSynchronous(diskSynchronous);
+    }
+
+    regionAttributes.updateEntryIdleTime(entryExpirationIdleTime, entryExpirationIdleTimeAction,
+        entryIdleTimeCustomExpiry);
+    regionAttributes.updateEntryTimeToLive(entryExpirationTTL, entryExpirationTTLAction,
+        entryTTLCustomExpiry);
+    regionAttributes.updateRegionIdleTime(regionExpirationIdleTime, regionExpirationIdleTimeAction,
+        null);
+    regionAttributes.updateRegionTimeToLive(regionExpirationTTL, regionExpirationTTLAction, null);
+
+    // unlike expiration attributes, if any single eviction attributes is set, we will replace
+    // the template eviction attributes with this new eviction attributes. we do not combine
+    // the old and new.
+    RegionAttributesType.EvictionAttributes evictionAttributes =
+        RegionAttributesType.EvictionAttributes
+            .generate(evictionAction, evictionMaxMemory, evictionEntryCount, evictionObjectSizer);
+    if (evictionAttributes != null) {
+      regionAttributes.setEvictionAttributes(evictionAttributes);
+    }
 
     // creating the RegionFunctionArgs
     CreateRegionFunctionArgs functionArgs =
-        new CreateRegionFunctionArgs(regionPath, config, ifNotExists);
+        new CreateRegionFunctionArgs(regionPath, regionConfig, ifNotExists);
 
     List<CliFunctionResult> regionCreateResults = executeAndGetFunctionResult(
         RegionCreateFunction.INSTANCE, functionArgs, membersToCreateRegionOn);
@@ -437,9 +488,9 @@ public class CreateRegionCommand extends SingleGfshCommand {
       RegionConfig regionConfigFromServer =
           service.getJaxbService().unMarshall(regionXml, RegionConfig.class);
       List<CacheElement> extensions = regionConfigFromServer.getCustomRegionElements();
-      config.getCustomRegionElements().addAll(extensions);
+      regionConfig.getCustomRegionElements().addAll(extensions);
 
-      resultModel.setConfigObject(new CreateRegionResult(config, regionPath));
+      resultModel.setConfigObject(new CreateRegionResult(regionConfig, regionPath));
     }
 
     return resultModel;
@@ -524,57 +575,6 @@ public class CreateRegionCommand extends SingleGfshCommand {
     return false;
   }
 
-  RegionAttributesWrapper getRegionAttributes(InternalCache cache, String regionPath) {
-    if (!isClusterWideSameConfig(cache, regionPath)) {
-      throw new IllegalStateException(CliStrings.format(
-          CliStrings.CREATE_REGION__MSG__USE_ATTRIBUTES_FORM_REGIONS_EXISTS_BUT_DIFFERENT_SCOPE_OR_DATAPOLICY_USE_DESCRIBE_REGION_FOR_0,
-          regionPath));
-    }
-    RegionAttributesWrapper attributes = null;
-
-    // First check whether the region exists on a this manager, if yes then no
-    // need to use FetchRegionAttributesFunction to fetch RegionAttributes
-    try {
-      attributes = FetchRegionAttributesFunction.getRegionAttributes(cache, regionPath);
-    } catch (IllegalArgumentException e) {
-      /* region doesn't exist on the manager */
-    }
-
-    if (attributes == null) {
-      // find first member which has the region
-      Set<DistributedMember> regionAssociatedMembers = findMembersForRegion(regionPath);
-      if (regionAssociatedMembers != null && !regionAssociatedMembers.isEmpty()) {
-        DistributedMember distributedMember = regionAssociatedMembers.iterator().next();
-        ResultCollector<?, ?> resultCollector =
-            executeFunction(FetchRegionAttributesFunction.INSTANCE, regionPath, distributedMember);
-        List<?> resultsList = (List<?>) resultCollector.getResult();
-
-        if (resultsList != null && !resultsList.isEmpty()) {
-          for (Object object : resultsList) {
-            if (object instanceof IllegalArgumentException) {
-              throw (IllegalArgumentException) object;
-            } else if (object instanceof Throwable) {
-              Throwable th = (Throwable) object;
-              LogWrapper.getInstance(getCache()).info(ExceptionUtils.getStackTrace((th)));
-              throw new IllegalArgumentException(CliStrings.format(
-                  CliStrings.CREATE_REGION__MSG__COULD_NOT_RETRIEVE_REGION_ATTRS_FOR_PATH_0_REASON_1,
-                  regionPath, th.getMessage()));
-            } else { // has to be RegionAttributes
-              @SuppressWarnings("unchecked") // to avoid warning :(
-              RegionAttributesWrapper regAttr = ((RegionAttributesWrapper) object);
-              if (attributes == null) {
-                attributes = regAttr;
-                break;
-              } // attributes null check
-            } // not IllegalArgumentException or other throwable
-          } // iterate over list - there should be only one result in the list
-        } // result list is not null or empty
-      } // regionAssociatedMembers is not-empty
-    } // attributes are null because do not exist on local member
-
-    return attributes;
-  }
-
   private void failIfRegionAlreadyExists(String regionPath, RegionShortcut regionShortcut,
       String[] groups) throws EntityExistsException {
     /*
@@ -589,10 +589,12 @@ public class CreateRegionCommand extends SingleGfshCommand {
     }
 
     String existingDataPolicy = regionBean.getRegionType();
-    // either C is local, or E is local or E and C are both non-proxy regions. this is to make
-    // sure local, replicate or partition regions have unique names across the entire cluster
-    if (regionShortcut.isLocal() || existingDataPolicy.equals("NORMAL") || !regionShortcut.isProxy()
-        && (regionBean.getMemberCount() > regionBean.getEmptyNodes())) {
+    // fail if either C is local, or E is local or E and C are both non-proxy regions. this is to
+    // make sure local, replicate or partition regions have unique names across the entire cluster
+    boolean existingRegionIsNotProxy = regionBean.getMemberCount() > regionBean.getEmptyNodes();
+    boolean toBeCreatedIsNotProxy = !regionShortcut.isProxy();
+    if (regionShortcut.isLocal() || existingDataPolicy.equals("NORMAL") || (toBeCreatedIsNotProxy
+        && existingRegionIsNotProxy)) {
       throw new EntityExistsException(
           String.format("Region %s already exists on the cluster.", regionPath));
     }
@@ -622,39 +624,6 @@ public class CreateRegionCommand extends SingleGfshCommand {
     }
   }
 
-  private boolean isClusterWideSameConfig(InternalCache cache, String regionPath) {
-    ManagementService managementService = getManagementService();
-
-    DistributedSystemMXBean dsMXBean = managementService.getDistributedSystemMXBean();
-
-    Set<DistributedMember> allMembers = getAllNormalMembers();
-
-    RegionAttributesData regionAttributesToValidateAgainst = null;
-    for (DistributedMember distributedMember : allMembers) {
-      ObjectName regionObjectName;
-      try {
-        regionObjectName = dsMXBean
-            .fetchRegionObjectName(CliUtil.getMemberNameOrId(distributedMember), regionPath);
-        RegionMXBean regionMBean =
-            managementService.getMBeanInstance(regionObjectName, RegionMXBean.class);
-        RegionAttributesData regionAttributes = regionMBean.listRegionAttributes();
-
-        if (regionAttributesToValidateAgainst == null) {
-          regionAttributesToValidateAgainst = regionAttributes;
-        } else if (!(regionAttributesToValidateAgainst.getScope()
-            .equals(regionAttributes.getScope())
-            || regionAttributesToValidateAgainst.getDataPolicy()
-                .equals(regionAttributes.getDataPolicy()))) {
-          return false;
-        }
-      } catch (Exception e) {
-        // ignore
-      }
-    }
-
-    return true;
-  }
-
   boolean regionExists(String regionPath) {
     if (regionPath == null || Region.SEPARATOR.equals(regionPath)) {
       return false;
@@ -684,17 +653,11 @@ public class CreateRegionCommand extends SingleGfshCommand {
     return false;
   }
 
-  private boolean isAttributePersistent(RegionAttributes attributes) {
-    return attributes != null && attributes.getDataPolicy() != null
-        && attributes.getDataPolicy().toString().contains("PERSISTENT");
-  }
-
   DistributedSystemMXBean getDSMBean() {
     ManagementService managementService = getManagementService();
     return managementService.getDistributedSystemMXBean();
   }
 
-
   public static class Interceptor extends AbstractCliAroundInterceptor {
     @Override
     public Result preExecution(GfshParseResult parseResult) {
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/domain/ExpirationArgs.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/domain/ExpirationArgs.java
deleted file mode 100644
index 97835aa..0000000
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/domain/ExpirationArgs.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
- * agreements. See the NOTICE file distributed with this work for additional information regarding
- * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance with the License. You may obtain a
- * copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-package org.apache.geode.management.internal.cli.domain;
-
-import org.apache.geode.cache.ExpirationAction;
-import org.apache.geode.cache.ExpirationAttributes;
-
-public class ExpirationArgs {
-  private final Integer time;
-  private final ExpirationAction action;
-
-  public ExpirationArgs(Integer time, ExpirationAction action) {
-    this.time = time;
-    this.action = action;
-  }
-
-  public Integer getTime() {
-    return time;
-  }
-
-  public ExpirationAction getAction() {
-    return action;
-  }
-
-  public ExpirationAttributes getExpirationAttributes() {
-    return getExpirationAttributes(null);
-  }
-
-  public ExpirationAttributes getExpirationAttributes(ExpirationAttributes existing) {
-    // default values
-    int timeToUse = 0;
-    ExpirationAction actionToUse = ExpirationAction.INVALIDATE;
-
-    if (existing != null) {
-      timeToUse = existing.getTimeout();
-      actionToUse = existing.getAction();
-    }
-    if (time != null) {
-      timeToUse = time;
-    }
-
-    if (action != null) {
-      actionToUse = action;
-    }
-    return new ExpirationAttributes(timeToUse, actionToUse);
-  }
-}
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/domain/PartitionArgs.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/domain/PartitionArgs.java
deleted file mode 100644
index 30b4644..0000000
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/domain/PartitionArgs.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
- * agreements. See the NOTICE file distributed with this work for additional information regarding
- * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance with the License. You may obtain a
- * copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-package org.apache.geode.management.internal.cli.domain;
-
-import java.util.HashSet;
-import java.util.Set;
-
-import org.apache.geode.management.internal.cli.i18n.CliStrings;
-
-public class PartitionArgs {
-  public String prColocatedWith;
-  public Integer prLocalMaxMemory;
-  public Long prRecoveryDelay;
-  public Integer prRedundantCopies;
-  public Long prStartupRecoveryDelay;
-  public Long prTotalMaxMemory;
-  public Integer prTotalNumBuckets;
-  public String partitionResolver;
-
-  public PartitionArgs(String prColocatedWith, Integer prLocalMaxMemory, Long prRecoveryDelay,
-      Integer prRedundantCopies, Long prStartupRecoveryDelay, Long prTotalMaxMemory,
-      Integer prTotalNumBuckets, String partitionResolver) {
-    this.prColocatedWith = prColocatedWith;
-    this.prLocalMaxMemory = prLocalMaxMemory;
-    this.prRecoveryDelay = prRecoveryDelay;
-    this.prRedundantCopies = prRedundantCopies;
-    this.prStartupRecoveryDelay = prStartupRecoveryDelay;
-    this.prTotalMaxMemory = prTotalMaxMemory;
-    this.prTotalNumBuckets = prTotalNumBuckets;
-    this.partitionResolver = partitionResolver;
-  }
-
-  public boolean isEmpty() {
-    return prColocatedWith == null &&
-        prLocalMaxMemory == null &&
-        prRecoveryDelay == null &&
-        prRedundantCopies == null &&
-        prStartupRecoveryDelay == null &&
-        prTotalMaxMemory == null &&
-        prTotalNumBuckets == null &&
-        partitionResolver == null;
-  }
-
-  /*
-   * This method is duplicated in RegionFunctionArgs.PartitionArgs, but the latter
-   * will be removed after we refactor AlterRegionCommand to not use RegionFunctionArgs,
-   * because at that point RegionFunctionArgs will be unused.
-   * GEODE-5971
-   */
-  public Set<String> getUserSpecifiedPartitionAttributes() {
-    Set<String> userSpecifiedPartitionAttributes = new HashSet<>();
-
-    if (this.prColocatedWith != null) {
-      userSpecifiedPartitionAttributes.add(CliStrings.CREATE_REGION__COLOCATEDWITH);
-    }
-    if (this.prLocalMaxMemory != null) {
-      userSpecifiedPartitionAttributes.add(CliStrings.CREATE_REGION__LOCALMAXMEMORY);
-    }
-    if (this.prRecoveryDelay != null) {
-      userSpecifiedPartitionAttributes.add(CliStrings.CREATE_REGION__RECOVERYDELAY);
-    }
-    if (this.prRedundantCopies != null) {
-      userSpecifiedPartitionAttributes.add(CliStrings.CREATE_REGION__REDUNDANTCOPIES);
-    }
-    if (this.prStartupRecoveryDelay != null) {
-      userSpecifiedPartitionAttributes.add(CliStrings.CREATE_REGION__STARTUPRECOVERYDDELAY);
-    }
-    if (this.prTotalMaxMemory != null) {
-      userSpecifiedPartitionAttributes.add(CliStrings.CREATE_REGION__TOTALMAXMEMORY);
-    }
-    if (this.prTotalNumBuckets != null) {
-      userSpecifiedPartitionAttributes.add(CliStrings.CREATE_REGION__TOTALNUMBUCKETS);
-    }
-    if (this.partitionResolver != null) {
-      userSpecifiedPartitionAttributes.add(CliStrings.CREATE_REGION__PARTITION_RESOLVER);
-    }
-
-    return userSpecifiedPartitionAttributes;
-  }
-}
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/domain/RegionConfigFactory.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/domain/RegionConfigFactory.java
deleted file mode 100644
index f7f7aaf..0000000
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/domain/RegionConfigFactory.java
+++ /dev/null
@@ -1,404 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
- * agreements. See the NOTICE file distributed with this work for additional information regarding
- * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance with the License. You may obtain a
- * copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-package org.apache.geode.management.internal.cli.domain;
-
-import java.util.Objects;
-import java.util.Optional;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-import org.apache.geode.cache.CacheListener;
-import org.apache.geode.cache.CacheLoader;
-import org.apache.geode.cache.CacheWriter;
-import org.apache.geode.cache.CustomExpiry;
-import org.apache.geode.cache.ExpirationAction;
-import org.apache.geode.cache.ExpirationAttributes;
-import org.apache.geode.cache.RegionAttributes;
-import org.apache.geode.cache.configuration.ClassNameType;
-import org.apache.geode.cache.configuration.DeclarableType;
-import org.apache.geode.cache.configuration.EnumActionDestroyOverflow;
-import org.apache.geode.cache.configuration.RegionAttributesScope;
-import org.apache.geode.cache.configuration.RegionAttributesType;
-import org.apache.geode.cache.configuration.RegionConfig;
-
-public class RegionConfigFactory {
-  public RegionConfig generate(
-      String regionPath,
-      String keyConstraint,
-      String valueConstraint,
-      Boolean statisticsEnabled,
-      Integer entryExpirationIdleTime,
-      ExpirationAction entryExpirationIdleAction,
-      Integer entryExpirationTTL,
-      ExpirationAction entryExpirationTTLAction,
-      ClassName<CustomExpiry> entryIdleTimeCustomExpiry,
-      ClassName<CustomExpiry> entryTTLCustomExpiry,
-      Integer regionExpirationIdleTime,
-      ExpirationAction regionExpirationIdleAction,
-      Integer regionExpirationTTL,
-      ExpirationAction regionExpirationTTLAction,
-      String evictionAction,
-      Integer evictionMaxMemory,
-      Integer evictionEntryCount,
-      String evictionObjectSizer,
-      String diskStore,
-      Boolean diskSynchronous,
-      Boolean enableAsyncConflation,
-      Boolean enableSubscriptionConflation,
-      Set<ClassName<CacheListener>> cacheListeners,
-      ClassName<CacheLoader> cacheLoader,
-      ClassName<CacheWriter> cacheWriter,
-      Set<String> asyncEventQueueIds,
-      Set<String> gatewaySenderIds,
-      Boolean concurrencyChecksEnabled,
-      Boolean cloningEnabled,
-      Boolean mcastEnabled,
-      Integer concurrencyLevel,
-      PartitionArgs partitionArgs,
-      String compressor,
-      Boolean offHeap,
-      RegionAttributes<?, ?> regionAttributes) {
-
-    RegionConfig regionConfig = new RegionConfig();
-    regionConfig.setName(getLeafRegion(regionPath));
-    RegionAttributesType regionAttributesType = new RegionAttributesType();
-    regionConfig.setRegionAttributes(regionAttributesType);
-
-    if (keyConstraint != null) {
-      regionAttributesType.setKeyConstraint(keyConstraint);
-    }
-
-    if (valueConstraint != null) {
-      regionAttributesType.setValueConstraint(valueConstraint);
-    }
-
-    if (statisticsEnabled != null) {
-      regionAttributesType.setStatisticsEnabled(statisticsEnabled);
-    } else if (regionAttributes != null) {
-      regionAttributesType.setStatisticsEnabled(regionAttributes.getStatisticsEnabled());
-    }
-
-    // first get the expiration attributes from the command options
-    regionAttributesType.setEntryIdleTime(
-        getExpirationAttributes(entryExpirationIdleTime, entryExpirationIdleAction,
-            entryIdleTimeCustomExpiry));
-    regionAttributesType
-        .setEntryTimeToLive(getExpirationAttributes(entryExpirationTTL, entryExpirationTTLAction,
-            entryTTLCustomExpiry));
-    regionAttributesType.setRegionIdleTime(
-        getExpirationAttributes(regionExpirationIdleTime, regionExpirationIdleAction,
-            null));
-    regionAttributesType
-        .setRegionTimeToLive(getExpirationAttributes(regionExpirationTTL, regionExpirationTTLAction,
-            null));
-
-    // if regionAttributes has these attributes, then use them instead
-    if (regionAttributes != null) {
-      ExpirationAttributes entryIdleTimeout = regionAttributes.getEntryIdleTimeout();
-      if (entryIdleTimeout != null && !entryIdleTimeout.isDefault()
-          && regionAttributesType.getEntryIdleTime() == null) {
-        regionAttributesType.setEntryIdleTime(getExpirationAttributes(
-            entryIdleTimeout.getTimeout(), entryIdleTimeout.getAction(),
-            getClassName(regionAttributes.getCustomEntryIdleTimeout())));
-      }
-
-      ExpirationAttributes entryTimeToLive = regionAttributes.getEntryTimeToLive();
-      if (entryTimeToLive != null && !entryTimeToLive.isDefault()
-          && regionAttributesType.getEntryTimeToLive() == null) {
-        regionAttributesType.setEntryTimeToLive(getExpirationAttributes(
-            entryTimeToLive.getTimeout(), entryTimeToLive.getAction(),
-            getClassName(regionAttributes.getCustomEntryTimeToLive())));
-      }
-
-      ExpirationAttributes regionIdleTimeout = regionAttributes.getRegionIdleTimeout();
-      if (regionIdleTimeout != null && !regionIdleTimeout.isDefault()
-          && regionAttributesType.getRegionIdleTime() == null) {
-        regionAttributesType.setRegionIdleTime(
-            getExpirationAttributes(regionIdleTimeout.getTimeout(),
-                regionIdleTimeout.getAction(), null));
-      }
-
-      ExpirationAttributes regionTimeToLive = regionAttributes.getRegionTimeToLive();
-      if (regionTimeToLive != null && !regionTimeToLive.isDefault()
-          && regionAttributesType.getRegionTimeToLive() == null) {
-        regionAttributesType.setRegionTimeToLive(
-            getExpirationAttributes(regionTimeToLive.getTimeout(),
-                regionTimeToLive.getAction(), null));
-      }
-    }
-
-    if (diskStore != null) {
-      regionAttributesType.setDiskStoreName(diskStore);
-    } else if (regionAttributes != null) {
-      regionAttributesType.setDiskStoreName(regionAttributes.getDiskStoreName());
-    }
-
-    if (diskSynchronous != null) {
-      regionAttributesType.setDiskSynchronous(diskSynchronous);
-    } else if (regionAttributes != null) {
-      regionAttributesType.setDiskSynchronous(regionAttributes.isDiskSynchronous());
-    }
-
-    if (enableAsyncConflation != null) {
-      regionAttributesType.setEnableAsyncConflation(enableAsyncConflation);
-    } else if (regionAttributes != null) {
-      regionAttributesType.setEnableAsyncConflation(regionAttributes.getEnableAsyncConflation());
-    }
-
-    if (enableSubscriptionConflation != null) {
-      regionAttributesType.setEnableSubscriptionConflation(enableSubscriptionConflation);
-    } else if (regionAttributes != null) {
-      regionAttributesType
-          .setEnableSubscriptionConflation(regionAttributes.getEnableSubscriptionConflation());
-    }
-
-    if (concurrencyChecksEnabled != null) {
-      regionAttributesType.setConcurrencyChecksEnabled(concurrencyChecksEnabled);
-    } else if (regionAttributes != null) {
-      regionAttributesType
-          .setConcurrencyChecksEnabled(regionAttributes.getConcurrencyChecksEnabled());
-    }
-
-    if (cloningEnabled != null) {
-      regionAttributesType.setCloningEnabled(cloningEnabled);
-    } else if (regionAttributes != null) {
-      regionAttributesType.setCloningEnabled(regionAttributes.getCloningEnabled());
-    }
-
-    if (offHeap != null) {
-      regionAttributesType.setOffHeap(offHeap);
-    } else if (regionAttributes != null) {
-      regionAttributesType.setOffHeap(regionAttributes.getOffHeap());
-    }
-
-    if (mcastEnabled != null) {
-      regionAttributesType.setMulticastEnabled(mcastEnabled);
-    } else if (regionAttributes != null) {
-      regionAttributesType.setMulticastEnabled(regionAttributes.getMulticastEnabled());
-    }
-
-    if (partitionArgs != null && !partitionArgs.isEmpty()) {
-      RegionAttributesType.PartitionAttributes partitionAttributes =
-          new RegionAttributesType.PartitionAttributes();
-      regionAttributesType.setPartitionAttributes(partitionAttributes);
-
-      partitionAttributes.setColocatedWith(partitionArgs.prColocatedWith);
-      partitionAttributes.setLocalMaxMemory(int2string(partitionArgs.prLocalMaxMemory));
-      partitionAttributes.setRecoveryDelay(long2string(partitionArgs.prRecoveryDelay));
-      partitionAttributes.setRedundantCopies(int2string(partitionArgs.prRedundantCopies));
-      partitionAttributes
-          .setStartupRecoveryDelay(long2string(partitionArgs.prStartupRecoveryDelay));
-      partitionAttributes.setTotalMaxMemory(long2string(partitionArgs.prTotalMaxMemory));
-      partitionAttributes.setTotalNumBuckets(int2string(partitionArgs.prTotalNumBuckets));
-
-      if (partitionArgs.partitionResolver != null) {
-        DeclarableType partitionResolverType = new DeclarableType();
-        partitionResolverType.setClassName(partitionArgs.partitionResolver);
-        partitionAttributes.setPartitionResolver(partitionResolverType);
-      }
-    }
-
-    if (regionAttributes != null && regionAttributes.getPartitionAttributes() != null) {
-      RegionAttributesType.PartitionAttributes partitionAttributes = Optional.ofNullable(
-          regionAttributesType.getPartitionAttributes())
-          .orElse(new RegionAttributesType.PartitionAttributes());
-      regionAttributesType.setPartitionAttributes(partitionAttributes);
-
-      RegionAttributesType.PartitionAttributes implicitPartitionAttributes =
-          regionAttributes.getPartitionAttributes().convertToConfigPartitionAttributes();
-
-      String implicitColocatedWith = implicitPartitionAttributes.getColocatedWith();
-      if (partitionAttributes.getColocatedWith() == null && implicitColocatedWith != null) {
-        partitionAttributes.setColocatedWith(implicitColocatedWith);
-      }
-
-      String implicitLocalMaxMemory = implicitPartitionAttributes.getLocalMaxMemory();
-      if (partitionAttributes.getLocalMaxMemory() == null && implicitLocalMaxMemory != null) {
-        partitionAttributes.setLocalMaxMemory(implicitLocalMaxMemory);
-      }
-
-      String implicitRecoveryDelay = implicitPartitionAttributes.getRecoveryDelay();
-      if (partitionAttributes.getRecoveryDelay() == null && implicitRecoveryDelay != null) {
-        partitionAttributes.setRecoveryDelay(implicitRecoveryDelay);
-      }
-
-      String implicitRedundantCopies = implicitPartitionAttributes.getRedundantCopies();
-      if (partitionAttributes.getRedundantCopies() == null && implicitRedundantCopies != null) {
-        partitionAttributes.setRedundantCopies(implicitRedundantCopies);
-      }
-
-      String implicitStartupRecoveryDelay = implicitPartitionAttributes.getStartupRecoveryDelay();
-      if (partitionAttributes.getStartupRecoveryDelay() == null
-          && implicitStartupRecoveryDelay != null) {
-        partitionAttributes.setStartupRecoveryDelay(implicitStartupRecoveryDelay);
-      }
-
-      String implicitTotalMaxMemory = implicitPartitionAttributes.getTotalMaxMemory();
-      if (partitionAttributes.getTotalMaxMemory() == null && implicitTotalMaxMemory != null) {
-        partitionAttributes.setTotalMaxMemory(implicitTotalMaxMemory);
-      }
-
-      String implicitTotalNumBuckets = implicitPartitionAttributes.getTotalNumBuckets();
-      if (partitionAttributes.getTotalNumBuckets() == null && implicitTotalNumBuckets != null) {
-        partitionAttributes.setTotalNumBuckets(implicitTotalNumBuckets);
-      }
-
-      DeclarableType implicitPartitionResolver = implicitPartitionAttributes.getPartitionResolver();
-      if (partitionAttributes.getPartitionResolver() == null && implicitPartitionResolver != null) {
-        partitionAttributes.setPartitionResolver(implicitPartitionResolver);
-      }
-    }
-
-    if (gatewaySenderIds != null && !gatewaySenderIds.isEmpty()) {
-      regionAttributesType.setGatewaySenderIds(String.join(",", gatewaySenderIds));
-    }
-
-    if (evictionAction != null) {
-      RegionAttributesType.EvictionAttributes evictionAttributes =
-          generateEvictionAttributes(evictionAction, evictionMaxMemory, evictionEntryCount,
-              evictionObjectSizer);
-      regionAttributesType.setEvictionAttributes(evictionAttributes);
-    } else if (regionAttributes != null && regionAttributes.getEvictionAttributes() != null
-        && !regionAttributes.getEvictionAttributes().isNoEviction()) {
-      regionAttributesType.setEvictionAttributes(regionAttributes.getEvictionAttributes()
-          .convertToConfigEvictionAttributes());
-    }
-
-    if (asyncEventQueueIds != null && !asyncEventQueueIds.isEmpty()) {
-      regionAttributesType.setAsyncEventQueueIds(String.join(",", asyncEventQueueIds));
-    }
-
-    if (cacheListeners != null && !cacheListeners.isEmpty()) {
-      regionAttributesType.getCacheListeners().addAll(cacheListeners.stream().map(l -> {
-        DeclarableType declarableType = new DeclarableType();
-        declarableType.setClassName(l.getClassName());
-        return declarableType;
-      }).collect(Collectors.toList()));
-    }
-
-    if (cacheLoader != null) {
-      DeclarableType declarableType = new DeclarableType();
-      declarableType.setClassName(cacheLoader.getClassName());
-      regionAttributesType.setCacheLoader(declarableType);
-    }
-
-    if (cacheWriter != null) {
-      DeclarableType declarableType = new DeclarableType();
-      declarableType.setClassName(cacheWriter.getClassName());
-      regionAttributesType.setCacheWriter(declarableType);
-    }
-
-    if (compressor != null) {
-      regionAttributesType.setCompressor(new ClassNameType(compressor));
-      regionAttributesType.setCloningEnabled(true);
-    }
-
-    if (concurrencyLevel != null) {
-      regionAttributesType.setConcurrencyLevel(concurrencyLevel.toString());
-    } else if (regionAttributes != null) {
-      regionAttributesType
-          .setConcurrencyLevel(Integer.toString(regionAttributes.getConcurrencyLevel()));
-    }
-
-    if (regionAttributes != null && regionAttributes.getDataPolicy() != null) {
-      regionAttributesType.setDataPolicy(regionAttributes.getDataPolicy().toConfigType());
-    }
-
-    if (regionAttributes != null && regionAttributes.getScope() != null
-        && !regionAttributes.getDataPolicy().withPartitioning()) {
-      regionAttributesType.setScope(
-          RegionAttributesScope.fromValue(regionAttributes.getScope().toConfigTypeString()));
-    }
-
-    return regionConfig;
-  }
-
-  private RegionAttributesType.EvictionAttributes generateEvictionAttributes(String evictionAction,
-      Integer maxMemory, Integer maxEntryCount,
-      String objectSizer) {
-    RegionAttributesType.EvictionAttributes configAttributes =
-        new RegionAttributesType.EvictionAttributes();
-    EnumActionDestroyOverflow action = EnumActionDestroyOverflow.fromValue(evictionAction);
-
-    if (maxMemory == null && maxEntryCount == null) {
-      RegionAttributesType.EvictionAttributes.LruHeapPercentage heapPercentage =
-          new RegionAttributesType.EvictionAttributes.LruHeapPercentage();
-      heapPercentage.setAction(action);
-      heapPercentage.setClassName(objectSizer);
-      configAttributes.setLruHeapPercentage(heapPercentage);
-    } else if (maxMemory != null) {
-      RegionAttributesType.EvictionAttributes.LruMemorySize memorySize =
-          new RegionAttributesType.EvictionAttributes.LruMemorySize();
-      memorySize.setAction(action);
-      memorySize.setClassName(objectSizer);
-      memorySize.setMaximum(maxMemory.toString());
-      configAttributes.setLruMemorySize(memorySize);
-    } else {
-      RegionAttributesType.EvictionAttributes.LruEntryCount entryCount =
-          new RegionAttributesType.EvictionAttributes.LruEntryCount();
-      entryCount.setAction(action);
-      entryCount.setMaximum(maxEntryCount.toString());
-      configAttributes.setLruEntryCount(entryCount);
-    }
-
-    return configAttributes;
-  }
-
-  public static RegionAttributesType.ExpirationAttributesType getExpirationAttributes(
-      Integer timeout, ExpirationAction action, ClassName<CustomExpiry> expiry) {
-    if (timeout == null && action == null && expiry == null) {
-      return null;
-    }
-
-    RegionAttributesType.ExpirationAttributesType attributesType =
-        new RegionAttributesType.ExpirationAttributesType();
-
-    attributesType.setTimeout(Objects.toString(timeout, "0"));
-    if (action == null) {
-      action = ExpirationAction.INVALIDATE;
-    }
-
-    attributesType.setAction(action.toXmlString());
-
-    if (expiry != null) {
-      attributesType.setCustomExpiry(new DeclarableType(expiry.getClassName()));
-    }
-
-    return attributesType;
-  }
-
-  private static ClassName<CustomExpiry> getClassName(CustomExpiry expiry) {
-    if (expiry == null) {
-      return null;
-    }
-
-    return new ClassName<>(expiry.getClass().getName());
-  }
-
-  private static String int2string(Integer x) {
-    return Optional.ofNullable(x).map(v -> v.toString()).orElse(null);
-  }
-
-  private static String long2string(Long x) {
-    return Optional.ofNullable(x).map(v -> v.toString()).orElse(null);
-  }
-
-  private String getLeafRegion(String fullPath) {
-    String regionPath = fullPath;
-    String[] regions = regionPath.split("/");
-
-    return regions[regions.length - 1];
-  }
-}
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/FetchRegionAttributesFunction.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/FetchRegionAttributesFunction.java
index 0bef1c5..bb9ebfc 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/FetchRegionAttributesFunction.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/FetchRegionAttributesFunction.java
@@ -14,28 +14,21 @@
  */
 package org.apache.geode.management.internal.cli.functions;
 
-import java.util.Arrays;
-import java.util.List;
-import java.util.stream.Collectors;
-
 import org.apache.logging.log4j.Logger;
 
 import org.apache.geode.annotations.Immutable;
-import org.apache.geode.cache.AttributesFactory;
-import org.apache.geode.cache.Cache;
-import org.apache.geode.cache.CacheListener;
 import org.apache.geode.cache.execute.FunctionContext;
-import org.apache.geode.internal.cache.AbstractRegion;
-import org.apache.geode.internal.cache.execute.InternalFunction;
+import org.apache.geode.internal.cache.xmlcache.CacheXml;
 import org.apache.geode.internal.logging.LogService;
-import org.apache.geode.management.internal.cli.domain.ClassName;
+import org.apache.geode.management.cli.CliFunction;
 import org.apache.geode.management.internal.cli.i18n.CliStrings;
+import org.apache.geode.management.internal.configuration.domain.XmlEntity;
 
 /**
  *
  * @since GemFire 7.0
  */
-public class FetchRegionAttributesFunction implements InternalFunction {
+public class FetchRegionAttributesFunction extends CliFunction<String> {
   private static final Logger logger = LogService.getLogger();
 
   private static final long serialVersionUID = 4366812590788342070L;
@@ -50,74 +43,18 @@ public class FetchRegionAttributesFunction implements InternalFunction {
     return false;
   }
 
+  /**
+   * this returns the region xml definition back to the caller
+   */
   @Override
-  public void execute(FunctionContext context) {
-    try {
-      Cache cache = context.getCache();
-      String regionPath = (String) context.getArguments();
-      if (regionPath == null) {
-        throw new IllegalArgumentException(
-            CliStrings.CREATE_REGION__MSG__SPECIFY_VALID_REGION_PATH);
-      }
-      RegionAttributesWrapper regionAttributesWrapper = getRegionAttributes(cache, regionPath);
-      context.getResultSender().lastResult(regionAttributesWrapper);
-    } catch (IllegalArgumentException e) {
-      if (logger.isDebugEnabled()) {
-        logger.debug(e.getMessage(), e);
-      }
-      context.getResultSender().lastResult(e);
-    }
-  }
-
-  @SuppressWarnings("deprecation")
-  public static RegionAttributesWrapper getRegionAttributes(Cache cache, String regionPath) {
-    AbstractRegion foundRegion = (AbstractRegion) cache.getRegion(regionPath);
-
-    if (foundRegion == null) {
-      throw new IllegalArgumentException(CliStrings.format(
-          CliStrings.CREATE_REGION__MSG__SPECIFY_VALID_REGION_PATH_FOR_0_REGIONPATH_1_NOT_FOUND,
-          CliStrings.CREATE_REGION__USEATTRIBUTESFROM, regionPath));
-    }
-
-    AttributesFactory afactory = new AttributesFactory(foundRegion.getAttributes());
-    RegionAttributesWrapper result = new RegionAttributesWrapper();
-
-    CacheListener[] cacheListeners = foundRegion.getCacheListeners();
-    List existingCacheListeners = Arrays.stream(cacheListeners)
-        .map((c) -> new ClassName(c.getClass().getName())).collect(Collectors.toList());
-
-    result.setCacheListenerClasses(existingCacheListeners);
-    afactory.initCacheListeners(null);
-
-    if (foundRegion.getCacheLoader() != null) {
-      result
-          .setCacheLoaderClass(new ClassName<>(foundRegion.getCacheLoader().getClass().getName()));
-      afactory.setCacheLoader(null);
+  public CliFunctionResult executeFunction(FunctionContext<String> context) throws Exception {
+    String regionPath = context.getArguments();
+    if (regionPath == null) {
+      throw new IllegalArgumentException(
+          CliStrings.CREATE_REGION__MSG__SPECIFY_VALID_REGION_PATH);
     }
-
-    if (foundRegion.getCacheWriter() != null) {
-      result
-          .setCacheWriterClass(new ClassName<>(foundRegion.getCacheWriter().getClass().getName()));
-      afactory.setCacheWriter(null);
-    }
-
-    if (foundRegion.getCompressor() != null) {
-      result.setCompressorClass(foundRegion.getCompressor().getClass().getName());
-      afactory.setCompressor(null);
-    }
-
-    if (foundRegion.getKeyConstraint() != null) {
-      result.setKeyConstraintClass(foundRegion.getKeyConstraint().getName());
-      afactory.setKeyConstraint(null);
-    }
-
-    if (foundRegion.getValueConstraint() != null) {
-      result.setValueConstraintClass(foundRegion.getValueConstraint().getName());
-      afactory.setValueConstraint(null);
-    }
-
-    result.setRegionAttributes(afactory.create());
-    return result;
+    XmlEntity xmlEntity = new XmlEntity(CacheXml.REGION, "name", regionPath.substring(1));
+    return new CliFunctionResult(context.getMemberName(), xmlEntity.getXmlDefinition());
   }
 
   @Override
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/configuration/realizers/RegionConfigRealizer.java b/geode-core/src/main/java/org/apache/geode/management/internal/configuration/realizers/RegionConfigRealizer.java
index 67ceb2c..e1c6263 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/configuration/realizers/RegionConfigRealizer.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/configuration/realizers/RegionConfigRealizer.java
@@ -74,7 +74,7 @@ public class RegionConfigRealizer implements ConfigurationRealizer<RegionConfig>
     factory.createSubregion(parentRegion, regionName);
   }
 
-  private RegionFactory getRegionFactory(Cache cache, RegionAttributesType regionAttributes) {
+  RegionFactory getRegionFactory(Cache cache, RegionAttributesType regionAttributes) {
     RegionFactory factory = cache.createRegionFactory();
 
     factory.setDataPolicy(DataPolicy.fromString(regionAttributes.getDataPolicy().name()));
@@ -125,7 +125,8 @@ public class RegionConfigRealizer implements ConfigurationRealizer<RegionConfig>
 
     if (regionAttributes.getPartitionAttributes() != null) {
       factory.setPartitionAttributes(
-          PartitionAttributesImpl.fromConfig(regionAttributes.getPartitionAttributes(), cache));
+          convertToRegionFactoryPartitionAttributes(regionAttributes.getPartitionAttributes(),
+              cache));
     }
 
     if (regionAttributes.getEntryIdleTime() != null) {
@@ -229,6 +230,60 @@ public class RegionConfigRealizer implements ConfigurationRealizer<RegionConfig>
     return factory;
   }
 
+  PartitionAttributesImpl convertToRegionFactoryPartitionAttributes(
+      RegionAttributesType.PartitionAttributes configAttributes, Cache cache) {
+    PartitionAttributesImpl partitionAttributes = new PartitionAttributesImpl();
+    if (configAttributes == null) {
+      return null;
+    }
+
+    if (configAttributes.getRedundantCopies() != null) {
+      partitionAttributes
+          .setRedundantCopies(Integer.valueOf(configAttributes.getRedundantCopies()));
+    }
+
+    if (configAttributes.getTotalMaxMemory() != null) {
+      partitionAttributes.setTotalMaxMemory(Integer.valueOf(configAttributes.getTotalMaxMemory()));
+    }
+
+    if (configAttributes.getTotalNumBuckets() != null) {
+      partitionAttributes
+          .setTotalNumBuckets(Integer.valueOf(configAttributes.getTotalNumBuckets()));
+    }
+
+    if (configAttributes.getLocalMaxMemory() != null) {
+      partitionAttributes.setLocalMaxMemory(Integer.valueOf(configAttributes.getLocalMaxMemory()));
+    }
+
+    if (configAttributes.getColocatedWith() != null) {
+      partitionAttributes.setColocatedWith(configAttributes.getColocatedWith());
+    }
+
+    if (configAttributes.getPartitionResolver() != null) {
+      partitionAttributes.setPartitionResolver(
+          DeclarableTypeInstantiator.newInstance(configAttributes.getPartitionResolver(), cache));
+    }
+
+    if (configAttributes.getRecoveryDelay() != null) {
+      partitionAttributes.setRecoveryDelay(Long.valueOf(configAttributes.getRecoveryDelay()));
+    }
+
+    if (configAttributes.getStartupRecoveryDelay() != null) {
+      partitionAttributes
+          .setStartupRecoveryDelay(Long.valueOf(configAttributes.getStartupRecoveryDelay()));
+    }
+
+    if (configAttributes.getPartitionListeners() != null) {
+      List<DeclarableType> configListeners = configAttributes.getPartitionListeners();
+      for (int i = 0; i < configListeners.size(); i++) {
+        partitionAttributes.addPartitionListener(
+            DeclarableTypeInstantiator.newInstance(configListeners.get(i), cache));
+      }
+    }
+
+    return partitionAttributes;
+  }
+
   @Override
   public boolean exists(RegionConfig config, Cache cache) {
     return false;
diff --git a/geode-core/src/test/java/org/apache/geode/cache/configuration/RegionAttributesTypeTest.java b/geode-core/src/test/java/org/apache/geode/cache/configuration/RegionAttributesTypeTest.java
index 40b9584..8010c72 100644
--- a/geode-core/src/test/java/org/apache/geode/cache/configuration/RegionAttributesTypeTest.java
+++ b/geode-core/src/test/java/org/apache/geode/cache/configuration/RegionAttributesTypeTest.java
@@ -15,35 +15,38 @@
 package org.apache.geode.cache.configuration;
 
 import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
 
 import org.junit.Before;
 import org.junit.Test;
 
 import org.apache.geode.cache.ExpirationAction;
+import org.apache.geode.cache.configuration.RegionAttributesType.EvictionAttributes;
+import org.apache.geode.cache.configuration.RegionAttributesType.ExpirationAttributesType;
 
 public class RegionAttributesTypeTest {
 
-  private RegionAttributesType.ExpirationAttributesType expirationAttributes;
+  private ExpirationAttributesType expirationAttributes;
   private RegionAttributesType regionAttributes;
 
   @Before
   public void before() throws Exception {
     regionAttributes = new RegionAttributesType();
-    expirationAttributes = new RegionAttributesType.ExpirationAttributesType();
+    expirationAttributes = new ExpirationAttributesType();
   }
 
   @Test
   public void emptyConstructor() {
-    expirationAttributes = new RegionAttributesType.ExpirationAttributesType();
+    expirationAttributes = new ExpirationAttributesType();
     assertThat(expirationAttributes.getAction()).isNull();
     assertThat(expirationAttributes.getTimeout()).isNull();
     assertThat(expirationAttributes.getCustomExpiry()).isNull();
   }
 
   @Test
-  public void constructorWithParameter() {
+  public void expirationAttributesConstructor() {
     expirationAttributes =
-        new RegionAttributesType.ExpirationAttributesType(null, ExpirationAction.DESTROY, null,
+        new ExpirationAttributesType(null, ExpirationAction.DESTROY, null,
             null);
     assertThat(expirationAttributes.getAction()).isEqualTo("destroy");
     assertThat(expirationAttributes.getTimeout()).isNull();
@@ -51,7 +54,7 @@ public class RegionAttributesTypeTest {
     assertThat(expirationAttributes.hasTimoutOrAction()).isTrue();
     assertThat(expirationAttributes.hasCustomExpiry()).isFalse();
 
-    expirationAttributes = new RegionAttributesType.ExpirationAttributesType(10, null, null, null);
+    expirationAttributes = new ExpirationAttributesType(10, null, null, null);
     assertThat(expirationAttributes.getAction()).isNull();
     assertThat(expirationAttributes.getTimeout()).isEqualTo("10");
     assertThat(expirationAttributes.getCustomExpiry()).isNull();
@@ -59,7 +62,7 @@ public class RegionAttributesTypeTest {
     assertThat(expirationAttributes.hasCustomExpiry()).isFalse();
 
     expirationAttributes =
-        new RegionAttributesType.ExpirationAttributesType(null, null, "abc", null);
+        new ExpirationAttributesType(null, null, "abc", null);
     assertThat(expirationAttributes.getAction()).isNull();
     assertThat(expirationAttributes.getTimeout()).isNull();
     assertThat(expirationAttributes.getCustomExpiry()).isNotNull();
@@ -68,6 +71,79 @@ public class RegionAttributesTypeTest {
   }
 
   @Test
+  public void generateExpirationAttributes() {
+    expirationAttributes = ExpirationAttributesType.generate(null, null, null);
+    assertThat(expirationAttributes).isNull();
+
+    expirationAttributes = ExpirationAttributesType.generate(8, null, null);
+    assertThat(expirationAttributes.getTimeout()).isEqualTo("8");
+    assertThat(expirationAttributes.getAction()).isNull();
+    assertThat(expirationAttributes.getCustomExpiry()).isNull();
+  }
+
+  @Test
+  public void combineExpirationAttributes() throws Exception {
+    expirationAttributes = new ExpirationAttributesType(8, null, null, null);
+    expirationAttributes = ExpirationAttributesType.combine(null, expirationAttributes);
+    assertThat(expirationAttributes.getTimeout()).isEqualTo("8");
+    assertThat(expirationAttributes.getAction())
+        .isEqualTo(ExpirationAction.INVALIDATE.toXmlString());
+    assertThat(expirationAttributes.getCustomExpiry()).isNull();
+    assertThat(ExpirationAttributesType.combine(expirationAttributes, null))
+        .isEqualToComparingFieldByFieldRecursively(expirationAttributes);
+
+    ExpirationAttributesType another =
+        new ExpirationAttributesType(null, ExpirationAction.DESTROY, "abc", null);
+    expirationAttributes = ExpirationAttributesType.combine(expirationAttributes, another);
+    assertThat(expirationAttributes.getTimeout()).isEqualTo("8");
+    assertThat(expirationAttributes.getAction()).isEqualTo(ExpirationAction.DESTROY.toXmlString());
+    assertThat(expirationAttributes.getCustomExpiry().getClassName()).isEqualTo("abc");
+  }
+
+  @Test
+  public void generateEvictionAttributes() {
+    EvictionAttributes evictionAttributes = EvictionAttributes.generate(null, null, null, null);
+    assertThat(evictionAttributes).isNull();
+
+    assertThatThrownBy(() -> EvictionAttributes.generate(null, 8, null, null))
+        .isInstanceOf(IllegalArgumentException.class);
+
+    evictionAttributes = EvictionAttributes.generate("local-destroy", null, null, null);
+    assertThat(evictionAttributes.getLruHeapPercentage().getAction().value())
+        .isEqualTo("local-destroy");
+    assertThat(evictionAttributes.getLruMemorySize()).isNull();
+    assertThat(evictionAttributes.getLruEntryCount()).isNull();
+
+    evictionAttributes = EvictionAttributes.generate("local-destroy", 10, null, null);
+    assertThat(evictionAttributes.getLruHeapPercentage()).isNull();
+    assertThat(evictionAttributes.getLruMemorySize().getMaximum()).isEqualTo("10");
+    assertThat(evictionAttributes.getLruMemorySize().getAction().value())
+        .isEqualTo("local-destroy");
+    assertThat(evictionAttributes.getLruEntryCount()).isNull();
+
+    // maxEntryCount is ignored when maxMemory is specified
+    evictionAttributes = EvictionAttributes.generate("local-destroy", 10, 20, null);
+    assertThat(evictionAttributes.getLruHeapPercentage()).isNull();
+    assertThat(evictionAttributes.getLruMemorySize().getMaximum()).isEqualTo("10");
+    assertThat(evictionAttributes.getLruMemorySize().getAction().value())
+        .isEqualTo("local-destroy");
+    assertThat(evictionAttributes.getLruEntryCount()).isNull();
+
+    evictionAttributes = EvictionAttributes.generate("local-destroy", null, 20, null);
+    assertThat(evictionAttributes.getLruHeapPercentage()).isNull();
+    assertThat(evictionAttributes.getLruMemorySize()).isNull();
+    assertThat(evictionAttributes.getLruEntryCount().getMaximum()).isEqualTo("20");
+    assertThat(evictionAttributes.getLruEntryCount().getAction().value())
+        .isEqualTo("local-destroy");
+  }
+
+  @Test
+  public void generatePartitionAttributes() throws Exception {
+    assertThat(RegionAttributesType.PartitionAttributes.generate(null, null, null, null, null, null,
+        null, null, null)).isNull();
+  }
+
+  @Test
   public void gatewaySender() {
     regionAttributes.setGatewaySenderIds(null);
     assertThat(regionAttributes.getGatewaySenderIdsAsSet()).isNull();
diff --git a/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/CreateRegionCommandTest.java b/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/CreateRegionCommandTest.java
index 1b334b4..c451762 100644
--- a/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/CreateRegionCommandTest.java
+++ b/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/CreateRegionCommandTest.java
@@ -17,7 +17,6 @@ package org.apache.geode.management.internal.cli.commands;
 
 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.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
@@ -75,9 +74,9 @@ public class CreateRegionCommandTest {
 
   @Test
   public void missingName() throws Exception {
-    CommandResult result = parser.executeCommandWithInstance(command, "create region");
-    assertThat(result.getStatus()).isEqualTo(Result.Status.ERROR);
-    assertThat(result.getMessageFromContent()).contains("Invalid command");
+    parser.executeAndAssertThat(command, "create region")
+        .statusIsError()
+        .hasInfoSection().hasOutput().contains("Invalid command");
   }
 
   @Test
@@ -134,22 +133,6 @@ public class CreateRegionCommandTest {
   }
 
   @Test
-  public void templateRegionAttributesNotAvailable() throws Exception {
-    doReturn(null).when(command).getRegionAttributes(eq(cache), any());
-    DistributedSystemMXBean dsMBean = mock(DistributedSystemMXBean.class);
-    doReturn(dsMBean).when(command).getDSMBean();
-    doReturn(new String[] {}).when(dsMBean).listGatewaySenders();
-    doReturn(Collections.emptySet()).when(command).findMembers(any(), any());
-    doReturn(true).when(command).regionExists(any());
-
-    CommandResult result = parser.executeCommandWithInstance(command,
-        "create region --name=region --template-region=regionA");
-    assertThat(result.getStatus()).isEqualTo(Result.Status.ERROR);
-    assertThat(result.getMessageFromContent())
-        .contains("Could not retrieve region attributes for given path");
-  }
-
-  @Test
   public void defaultValues() throws Exception {
     ResultCollector resultCollector = mock(ResultCollector.class);
     doReturn(resultCollector).when(command).executeFunction(any(), any(), any(Set.class));
diff --git a/geode-core/src/test/java/org/apache/geode/management/internal/cli/domain/RegionConfigFactoryTest.java b/geode-core/src/test/java/org/apache/geode/management/internal/cli/domain/RegionConfigFactoryTest.java
deleted file mode 100644
index 6d257a7..0000000
--- a/geode-core/src/test/java/org/apache/geode/management/internal/cli/domain/RegionConfigFactoryTest.java
+++ /dev/null
@@ -1,354 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
- * agreements. See the NOTICE file distributed with this work for additional information regarding
- * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance with the License. You may obtain a
- * copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-package org.apache.geode.management.internal.cli.domain;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import org.apache.geode.cache.CacheListener;
-import org.apache.geode.cache.CacheLoader;
-import org.apache.geode.cache.CacheWriter;
-import org.apache.geode.cache.CustomExpiry;
-import org.apache.geode.cache.EvictionAction;
-import org.apache.geode.cache.ExpirationAction;
-import org.apache.geode.cache.RegionAttributes;
-import org.apache.geode.cache.configuration.DeclarableType;
-import org.apache.geode.cache.configuration.EnumActionDestroyOverflow;
-import org.apache.geode.cache.configuration.RegionAttributesType;
-import org.apache.geode.cache.configuration.RegionConfig;
-
-public class RegionConfigFactoryTest {
-
-  RegionConfigFactory subject;
-  RegionConfig config;
-
-  String regionPath;
-  String keyConstraint;
-  String valueConstraint;
-  Boolean statisticsEnabled;
-  Integer entryExpirationIdleTime;
-  ExpirationAction entryExpirationIdleAction;
-  Integer entryExpirationTTL;
-  ExpirationAction entryExpirationTTLAction;
-  ClassName<CustomExpiry> entryIdleTimeCustomExpiry;
-  ClassName<CustomExpiry> entryTTLCustomExpiry;
-
-  Integer regionExpirationIdleTime;
-  ExpirationAction regionExpirationIdleAction;
-  Integer regionExpirationTTL;
-  ExpirationAction regionExpirationTTLAction;
-
-  String evictionAction;
-  Integer evictionMaxMemory;
-  Integer evictionEntryCount;
-  String evictionObjectSizer;
-
-  String diskStore;
-  Boolean diskSynchronous;
-  Boolean enableAsyncConflation;
-  Boolean enableSubscriptionConflation;
-  Set<ClassName<CacheListener>> cacheListeners;
-  ClassName<CacheLoader> cacheLoader;
-  ClassName<CacheWriter> cacheWriter;
-  Set<String> asyncEventQueueIds;
-  Set<String> gatewaySenderIds;
-  Boolean concurrencyChecksEnabled;
-  Boolean cloningEnabled;
-  Boolean mcastEnabled;
-  Integer concurrencyLevel;
-  PartitionArgs partitionArgs;
-  String compressor;
-  Boolean offHeap;
-  RegionAttributes<?, ?> regionAttributes;
-
-  @Before
-  public void setup() {
-    subject = new RegionConfigFactory();
-    regionPath = "region-name";
-    keyConstraint = null;
-    valueConstraint = null;
-    statisticsEnabled = null;
-    entryExpirationIdleTime = null;
-    entryExpirationIdleAction = null;
-    entryExpirationTTL = null;
-    entryExpirationTTLAction = null;
-    entryIdleTimeCustomExpiry = null;
-    entryTTLCustomExpiry = null;
-    regionExpirationIdleTime = null;
-    regionExpirationIdleAction = null;
-    regionExpirationTTL = null;
-    regionExpirationTTLAction = null;
-    evictionAction = null;
-    evictionMaxMemory = null;
-    evictionEntryCount = null;
-    evictionObjectSizer = null;
-    diskStore = null;
-    diskSynchronous = null;
-    enableAsyncConflation = null;
-    enableSubscriptionConflation = null;
-    cacheListeners = null;
-    cacheLoader = null;
-    cacheWriter = null;
-    asyncEventQueueIds = null;
-    gatewaySenderIds = null;
-    concurrencyChecksEnabled = null;
-    cloningEnabled = null;
-    mcastEnabled = null;
-    concurrencyLevel = null;
-    partitionArgs = null;
-    compressor = null;
-    offHeap = null;
-    regionAttributes = null;
-  }
-
-  private void generate() {
-    config = subject.generate(regionPath, keyConstraint, valueConstraint, statisticsEnabled,
-        entryExpirationIdleTime, entryExpirationIdleAction, entryExpirationTTL,
-        entryExpirationTTLAction,
-        entryIdleTimeCustomExpiry, entryTTLCustomExpiry, regionExpirationIdleTime,
-        regionExpirationIdleAction,
-        regionExpirationTTL, regionExpirationTTLAction, evictionAction, evictionMaxMemory,
-        evictionEntryCount,
-        evictionObjectSizer, diskStore, diskSynchronous, enableAsyncConflation,
-        enableSubscriptionConflation,
-        cacheListeners, cacheLoader,
-        cacheWriter,
-        asyncEventQueueIds, gatewaySenderIds, concurrencyChecksEnabled, cloningEnabled,
-        mcastEnabled,
-        concurrencyLevel, partitionArgs, compressor, offHeap, regionAttributes);
-  }
-
-  @Test
-  public void generatesConfigForRegion() {
-    generate();
-    assertThat(config.getName()).isEqualTo("region-name");
-  }
-
-  @Test
-  public void generatesConfigForSubRegion() {
-    regionPath = "region-name/subregion";
-
-    generate();
-    assertThat(config.getName()).isEqualTo("subregion");
-  }
-
-  @Test
-  public void generatesWithConstraintAttributes() {
-    keyConstraint = "key-const";
-    valueConstraint = "value-const";
-
-    generate();
-    assertThat(config.getRegionAttributes().getKeyConstraint()).isEqualTo("key-const");
-    assertThat(config.getRegionAttributes().getValueConstraint())
-        .isEqualTo("value-const");
-  }
-
-  @Test
-  public void generatesWithExpirationIdleTimeAttributes() {
-    regionExpirationTTL = 10;
-    regionExpirationTTLAction = ExpirationAction.DESTROY;
-
-    regionExpirationIdleTime = 3;
-    regionExpirationIdleAction = ExpirationAction.INVALIDATE;
-
-    entryExpirationTTL = 1;
-    entryExpirationTTLAction = ExpirationAction.LOCAL_DESTROY;
-
-    entryExpirationIdleTime = 12;
-    entryExpirationIdleAction = ExpirationAction.LOCAL_DESTROY;
-    entryIdleTimeCustomExpiry = new ClassName<>("java.lang.String");
-
-    generate();
-    RegionAttributesType.ExpirationAttributesType regionTimeToLive =
-        config.getRegionAttributes().getRegionTimeToLive();
-    assertThat(regionTimeToLive.getTimeout()).isEqualTo("10");
-
-    RegionAttributesType.ExpirationAttributesType entryTimeToLive =
-        config.getRegionAttributes().getEntryTimeToLive();
-    assertThat(entryTimeToLive.getAction())
-        .isEqualTo(ExpirationAction.LOCAL_DESTROY.toXmlString());
-
-    RegionAttributesType.ExpirationAttributesType entryIdleTime =
-        config.getRegionAttributes().getEntryIdleTime();
-    DeclarableType customExpiry = entryIdleTime.getCustomExpiry();
-    assertThat(customExpiry.getClassName()).isEqualTo("java.lang.String");
-    assertThat(entryIdleTime.getAction())
-        .isEqualTo(ExpirationAction.LOCAL_DESTROY.toXmlString());
-    assertThat(entryIdleTime.getTimeout())
-        .isEqualTo("12");
-  }
-
-  @Test
-  public void generatesWithDiskAttributes() {
-    diskStore = "disk-store";
-    diskSynchronous = false;
-
-    generate();
-    assertThat(config.getRegionAttributes().getDiskStoreName()).isEqualTo("disk-store");
-    assertThat(config.getRegionAttributes().isDiskSynchronous()).isEqualTo(false);
-  }
-
-  @Test
-  public void generatesWithPrAttributes() {
-    partitionArgs = new PartitionArgs("colo-with", 100,
-        100L, 100, 100L,
-        100L, 100, "java.lang.String");
-
-    generate();
-    RegionAttributesType.PartitionAttributes partitionAttributes =
-        config.getRegionAttributes().getPartitionAttributes();
-    assertThat(partitionAttributes).isNotNull();
-    assertThat(partitionAttributes.getColocatedWith()).isEqualTo("colo-with");
-    assertThat(partitionAttributes.getLocalMaxMemory()).isEqualTo("100");
-    assertThat(partitionAttributes.getRecoveryDelay()).isEqualTo("100");
-    assertThat(partitionAttributes.getRedundantCopies()).isEqualTo("100");
-    assertThat(partitionAttributes.getStartupRecoveryDelay()).isEqualTo("100");
-    assertThat(partitionAttributes.getTotalMaxMemory()).isEqualTo("100");
-    assertThat(partitionAttributes.getTotalNumBuckets()).isEqualTo("100");
-
-    DeclarableType partitionResolverType = partitionAttributes.getPartitionResolver();
-    assertThat(partitionResolverType.getClassName()).isEqualTo("java.lang.String");
-  }
-
-  @Test
-  public void generatesWithMiscBooleanFlags() {
-    statisticsEnabled = false;
-    enableAsyncConflation = false;
-    concurrencyChecksEnabled = true;
-    enableSubscriptionConflation = true;
-    mcastEnabled = false;
-    cloningEnabled = false;
-    offHeap = true;
-    generate();
-
-    assertThat(config.getRegionAttributes().isStatisticsEnabled()).isEqualTo(false);
-    assertThat(config.getRegionAttributes().isEnableSubscriptionConflation())
-        .isEqualTo(true);
-    assertThat(config.getRegionAttributes().isConcurrencyChecksEnabled())
-        .isEqualTo(true);
-    assertThat(config.getRegionAttributes().isEnableSubscriptionConflation())
-        .isEqualTo(true);
-    assertThat(config.getRegionAttributes().isMulticastEnabled())
-        .isEqualTo(false);
-    assertThat(config.getRegionAttributes().isCloningEnabled()).isEqualTo(false);
-    assertThat(config.getRegionAttributes().isOffHeap()).isEqualTo(true);
-  }
-
-  @Test
-  public void generatesWithGatewayFlags() {
-    gatewaySenderIds =
-        Arrays.stream(new String[] {"some-id", "some-other-id"}).collect(Collectors.toSet());
-    generate();
-
-    assertThat(config.getRegionAttributes().getGatewaySenderIds())
-        .contains("some-id");
-    assertThat(config.getRegionAttributes().getGatewaySenderIds())
-        .contains("some-other-id");
-  }
-
-  @Test
-  public void generatesWithEvictionHeapPercentageFlags() {
-    evictionAction = EvictionAction.LOCAL_DESTROY.toString();
-    evictionObjectSizer = "java.lang.String";
-    generate();
-
-    RegionAttributesType.EvictionAttributes evictionAttributes =
-        config.getRegionAttributes().getEvictionAttributes();
-    assertThat(evictionAttributes).isNotNull();
-    assertThat(evictionAttributes.getLruHeapPercentage().getAction())
-        .isSameAs(EnumActionDestroyOverflow.LOCAL_DESTROY);
-    assertThat(evictionAttributes.getLruHeapPercentage().getClassName())
-        .isEqualTo("java.lang.String");
-  }
-
-  @Test
-  public void generatesWithEvictionMaxMemory() {
-    evictionAction = EvictionAction.LOCAL_DESTROY.toString();
-    evictionMaxMemory = 100;
-    generate();
-
-    RegionAttributesType.EvictionAttributes evictionAttributes =
-        config.getRegionAttributes().getEvictionAttributes();
-    assertThat(evictionAttributes).isNotNull();
-    assertThat(evictionAttributes.getLruMemorySize().getAction())
-        .isSameAs(EnumActionDestroyOverflow.LOCAL_DESTROY);
-    assertThat(evictionAttributes.getLruMemorySize().getMaximum()).isEqualTo("100");
-  }
-
-  @Test
-  public void generatesWithEvictionMaxEntry() {
-    evictionAction = EvictionAction.OVERFLOW_TO_DISK.toString();
-    evictionEntryCount = 1;
-    generate();
-    RegionAttributesType.EvictionAttributes evictionAttributes =
-        config.getRegionAttributes().getEvictionAttributes();
-    assertThat(evictionAttributes).isNotNull();
-    assertThat(evictionAttributes.getLruEntryCount().getAction())
-        .isSameAs(EnumActionDestroyOverflow.OVERFLOW_TO_DISK);
-    assertThat(evictionAttributes.getLruEntryCount().getMaximum()).isEqualTo("1");
-  }
-
-  @Test
-  public void generatesWithAsyncEventQueueIds() {
-    asyncEventQueueIds = Arrays.stream(new String[] {"id-1", "id-2"}).collect(Collectors.toSet());
-    generate();
-
-    assertThat(config.getRegionAttributes().getAsyncEventQueueIds())
-        .contains("id-1");
-    assertThat(config.getRegionAttributes().getAsyncEventQueueIds())
-        .contains("id-2");
-  }
-
-  @Test
-  public void generatesWithCacheClasses() {
-    cacheListeners = new HashSet<>();
-    cacheListeners.add(new ClassName<>("java.lang.String"));
-    cacheLoader = new ClassName("java.lang.String");
-    cacheWriter = new ClassName("java.lang.String");
-    generate();
-
-    List<DeclarableType> cacheListeners = config.getRegionAttributes().getCacheListeners();
-
-    assertThat(cacheListeners).isNotNull();
-    assertThat(cacheListeners.get(0).getClassName()).isEqualTo("java.lang.String");
-    assertThat(
-        config.getRegionAttributes().getCacheLoader().getClassName())
-            .isEqualTo("java.lang.String");
-    assertThat(
-        config.getRegionAttributes().getCacheWriter().getClassName())
-            .isEqualTo("java.lang.String");
-  }
-
-  @Test
-  public void generatesWithOtherMiscSimpleFlags() {
-    compressor = "java.lang.String";
-    concurrencyLevel = 1;
-    generate();
-
-    assertThat(
-        config.getRegionAttributes().getCompressor().getClassName())
-            .isEqualTo("java.lang.String");
-    assertThat(config.getRegionAttributes().getConcurrencyLevel()).isEqualTo("1");
-  }
-
-}
diff --git a/geode-core/src/test/java/org/apache/geode/management/internal/configuration/realizers/RegionConfigRealizerTest.java b/geode-core/src/test/java/org/apache/geode/management/internal/configuration/realizers/RegionConfigRealizerTest.java
index dcb3ade..9706de4 100644
--- a/geode-core/src/test/java/org/apache/geode/management/internal/configuration/realizers/RegionConfigRealizerTest.java
+++ b/geode-core/src/test/java/org/apache/geode/management/internal/configuration/realizers/RegionConfigRealizerTest.java
@@ -33,12 +33,14 @@ import org.apache.geode.internal.cache.InternalCache;
 public class RegionConfigRealizerTest {
   InternalCache cache;
   RegionFactory regionFactory;
+  RegionConfigRealizer realizer;
 
   @Before
   public void setup() {
     cache = mock(InternalCache.class);
     regionFactory = mock(RegionFactory.class);
     when(cache.createRegionFactory()).thenReturn(regionFactory);
+    realizer = new RegionConfigRealizer();
   }
 
   @Test
@@ -47,7 +49,6 @@ public class RegionConfigRealizerTest {
     config.setName("regionName");
     config.setType("PARTITION");
 
-    RegionConfigRealizer realizer = new RegionConfigRealizer();
     realizer.create(config, cache);
 
     ArgumentCaptor<DataPolicy> dataPolicyArgumentCaptor = ArgumentCaptor.forClass(DataPolicy.class);
@@ -63,8 +64,7 @@ public class RegionConfigRealizerTest {
     config.setName("regionName");
     config.setType("REPLICATE");
 
-    RegionConfigRealizer subject = new RegionConfigRealizer();
-    subject.create(config, cache);
+    realizer.create(config, cache);
 
     ArgumentCaptor<DataPolicy> dataPolicyArgumentCaptor = ArgumentCaptor.forClass(DataPolicy.class);
     verify(regionFactory).setDataPolicy(dataPolicyArgumentCaptor.capture());
diff --git a/geode-core/src/test/resources/org/apache/geode/cache/configuration/RegionConfigTest.xml b/geode-core/src/test/resources/org/apache/geode/cache/configuration/RegionConfigTest.xml
index ba8af9c..36f5563 100644
--- a/geode-core/src/test/resources/org/apache/geode/cache/configuration/RegionConfigTest.xml
+++ b/geode-core/src/test/resources/org/apache/geode/cache/configuration/RegionConfigTest.xml
@@ -107,20 +107,20 @@
         </region-attributes>
     </region>
     <region name="LOCAL" refid="LOCAL">
-        <region-attributes scope="local"/>
+        <region-attributes data-policy="normal" scope="local"/>
     </region>
     <region name="LOCAL_PERSISTENT" refid="LOCAL_PERSISTENT">
         <region-attributes data-policy="persistent-replicate" scope="local"/>
     </region>
     <region name="LOCAL_HEAP_LRU" refid="LOCAL_HEAP_LRU">
-        <region-attributes scope="local">
+        <region-attributes data-policy="normal" scope="local">
             <eviction-attributes>
                 <lru-heap-percentage action="local-destroy"/>
             </eviction-attributes>
         </region-attributes>
     </region>
     <region name="LOCAL_OVERFLOW" refid="LOCAL_OVERFLOW">
-        <region-attributes scope="local">
+        <region-attributes data-policy="normal" scope="local">
             <eviction-attributes>
                 <lru-heap-percentage action="overflow-to-disk"/>
             </eviction-attributes>
diff --git a/geode-management/src/main/java/org/apache/geode/cache/configuration/RegionAttributesDataPolicy.java b/geode-management/src/main/java/org/apache/geode/cache/configuration/RegionAttributesDataPolicy.java
index 6230f24..a3f0b59 100644
--- a/geode-management/src/main/java/org/apache/geode/cache/configuration/RegionAttributesDataPolicy.java
+++ b/geode-management/src/main/java/org/apache/geode/cache/configuration/RegionAttributesDataPolicy.java
@@ -78,13 +78,11 @@ public enum RegionAttributesDataPolicy implements Serializable {
     return value;
   }
 
-  public static RegionAttributesDataPolicy fromValue(String v) {
-    for (RegionAttributesDataPolicy c : RegionAttributesDataPolicy.values()) {
-      if (c.value.equals(v)) {
-        return c;
-      }
-    }
-    throw new IllegalArgumentException(v);
+  public boolean isPersistent() {
+    return this.value.startsWith("persistent");
   }
 
+  public boolean isPartition() {
+    return this.value.endsWith("partition");
+  }
 }
diff --git a/geode-management/src/main/java/org/apache/geode/cache/configuration/RegionAttributesType.java b/geode-management/src/main/java/org/apache/geode/cache/configuration/RegionAttributesType.java
index 94e2e7d..cbabd08 100644
--- a/geode-management/src/main/java/org/apache/geode/cache/configuration/RegionAttributesType.java
+++ b/geode-management/src/main/java/org/apache/geode/cache/configuration/RegionAttributesType.java
@@ -37,6 +37,7 @@ import org.apache.commons.lang3.StringUtils;
 
 import org.apache.geode.annotations.Experimental;
 import org.apache.geode.cache.ExpirationAction;
+import org.apache.geode.management.internal.cli.domain.ClassName;
 
 
 /**
@@ -500,6 +501,20 @@ public class RegionAttributesType implements Serializable {
   }
 
   /**
+   * update the region time to live using timeout, action or expiry. If all three are null, there
+   * would be no update to the existing value
+   *
+   * @param timeout could be null
+   * @param action could be null
+   * @param expiry could be null
+   */
+  public void updateRegionTimeToLive(Integer timeout,
+      ExpirationAction action, ClassName expiry) {
+    regionTimeToLive = ExpirationAttributesType.combine(regionTimeToLive,
+        ExpirationAttributesType.generate(timeout, action, expiry));
+  }
+
+  /**
    * Gets the value of the regionIdleTime property.
    *
    * possible object is
@@ -522,6 +537,21 @@ public class RegionAttributesType implements Serializable {
   }
 
   /**
+   * update the region idle time using timeout, action or expiry. If all three are null, there
+   * would be no update to the existing value
+   *
+   * @param timeout could be null
+   * @param action could be null
+   * @param expiry could be null
+   */
+  public void updateRegionIdleTime(Integer timeout,
+      ExpirationAction action, ClassName expiry) {
+    regionIdleTime = ExpirationAttributesType.combine(regionIdleTime,
+        ExpirationAttributesType.generate(timeout, action, expiry));
+  }
+
+
+  /**
    * Gets the value of the entryTimeToLive property.
    *
    * possible object is
@@ -544,6 +574,20 @@ public class RegionAttributesType implements Serializable {
   }
 
   /**
+   * update the entry time to live using timeout, action or expiry. If all three are null, there
+   * would be no update to the existing value
+   *
+   * @param timeout could be null
+   * @param action could be null
+   * @param expiry could be null
+   */
+  public void updateEntryTimeToLive(Integer timeout,
+      ExpirationAction action, ClassName expiry) {
+    entryTimeToLive = ExpirationAttributesType.combine(entryTimeToLive,
+        ExpirationAttributesType.generate(timeout, action, expiry));
+  }
+
+  /**
    * Gets the value of the entryIdleTime property.
    *
    * possible object is
@@ -566,6 +610,20 @@ public class RegionAttributesType implements Serializable {
   }
 
   /**
+   * update the entry idle time using timeout, action or expiry. If all three are null, there
+   * would be no update to the existing value
+   *
+   * @param timeout could be null
+   * @param action could be null
+   * @param expiry could be null
+   */
+  public void updateEntryIdleTime(Integer timeout,
+      ExpirationAction action, ClassName expiry) {
+    entryIdleTime = ExpirationAttributesType.combine(entryIdleTime,
+        ExpirationAttributesType.generate(timeout, action, expiry));
+  }
+
+  /**
    * Gets the value of the diskWriteAttributes property.
    *
    * possible object is
@@ -1724,6 +1782,48 @@ public class RegionAttributesType implements Serializable {
       }
     }
 
+    public static ExpirationAttributesType generate(Integer timeout,
+        ExpirationAction action, ClassName expiry) {
+      if (timeout == null && action == null && expiry == null) {
+        return null;
+      }
+      if (expiry != null) {
+        return new ExpirationAttributesType(timeout, action,
+            expiry.getClassName(), expiry.getInitProperties());
+      } else {
+        return new ExpirationAttributesType(timeout, action, null, null);
+      }
+    }
+
+    // this is a helper method to combine the existing with the delta ExpirationAttributesType
+    public static ExpirationAttributesType combine(ExpirationAttributesType existing,
+        ExpirationAttributesType delta) {
+      if (delta == null) {
+        return existing;
+      }
+
+      if (existing == null) {
+        existing = new ExpirationAttributesType();
+        existing.setAction(ExpirationAction.INVALIDATE.toXmlString());
+        existing.setTimeout("0");
+      }
+
+      if (delta.getTimeout() != null) {
+        existing.setTimeout(delta.getTimeout());
+      }
+      if (delta.getAction() != null) {
+        existing.setAction(delta.getAction());
+      }
+      if (delta.getCustomExpiry() != null) {
+        if (delta.getCustomExpiry().equals(DeclarableType.EMPTY)) {
+          existing.setCustomExpiry(null);
+        } else {
+          existing.setCustomExpiry(delta.getCustomExpiry());
+        }
+      }
+      return existing;
+    }
+
     /**
      * @return true if timeout or action is specified
      */
@@ -1949,15 +2049,39 @@ public class RegionAttributesType implements Serializable {
     @XmlElement(name = "lru-memory-size", namespace = "http://geode.apache.org/schema/cache")
     protected RegionAttributesType.EvictionAttributes.LruMemorySize lruMemorySize;
 
-    public String toStringRep() {
-      return "lru-entry-count: " +
-          this.lruEntryCount.getMaximum() + ", " +
-          this.lruEntryCount.getAction().toString() + ", " +
-          "\nlru-heap-percentage: " +
-          this.lruHeapPercentage.getAction().toString() +
-          "\nlru-memory-size: " +
-          this.lruMemorySize.getMaximum() +
-          this.lruMemorySize.getAction().toString();
+    public static EvictionAttributes generate(String evictionAction,
+        Integer maxMemory, Integer maxEntryCount,
+        String objectSizer) {
+      if (evictionAction == null && maxMemory == null && maxEntryCount == null
+          && objectSizer == null) {
+        return null;
+      }
+
+      RegionAttributesType.EvictionAttributes evictionAttributes =
+          new RegionAttributesType.EvictionAttributes();
+      EnumActionDestroyOverflow action = EnumActionDestroyOverflow.fromValue(evictionAction);
+
+      if (maxMemory == null && maxEntryCount == null) {
+        LruHeapPercentage heapPercentage =
+            new LruHeapPercentage();
+        heapPercentage.setAction(action);
+        heapPercentage.setClassName(objectSizer);
+        evictionAttributes.setLruHeapPercentage(heapPercentage);
+      } else if (maxMemory != null) {
+        LruMemorySize memorySize =
+            new LruMemorySize();
+        memorySize.setAction(action);
+        memorySize.setClassName(objectSizer);
+        memorySize.setMaximum(maxMemory.toString());
+        evictionAttributes.setLruMemorySize(memorySize);
+      } else {
+        LruEntryCount entryCount =
+            new LruEntryCount();
+        entryCount.setAction(action);
+        entryCount.setMaximum(maxEntryCount.toString());
+        evictionAttributes.setLruEntryCount(entryCount);
+      }
+      return evictionAttributes;
     }
 
     /**
@@ -2489,6 +2613,96 @@ public class RegionAttributesType implements Serializable {
     @XmlAttribute(name = "colocated-with")
     protected String colocatedWith;
 
+    public static PartitionAttributes generate(String partitionResolver,
+        List<String> partitionListeners, Integer localMaxMemory,
+        Long recoveryDelay, Integer redundantCopies,
+        Long startupRecoveryDelay, Long totalMaxMemory,
+        Integer totalNumBuckets, String colocatedWith) {
+      if (partitionResolver == null &&
+          (partitionListeners == null || partitionListeners.isEmpty()) &&
+          localMaxMemory == null &&
+          recoveryDelay == null &&
+          redundantCopies == null &&
+          startupRecoveryDelay == null &&
+          totalMaxMemory == null &&
+          totalNumBuckets == null &&
+          colocatedWith == null) {
+        return null;
+      }
+
+      RegionAttributesType.PartitionAttributes partitionAttributes =
+          new RegionAttributesType.PartitionAttributes();
+      partitionAttributes.setColocatedWith(colocatedWith);
+      partitionAttributes.setLocalMaxMemory(Objects.toString(localMaxMemory, null));
+      partitionAttributes.setTotalMaxMemory(Objects.toString(totalMaxMemory, null));
+      partitionAttributes.setRecoveryDelay(Objects.toString(recoveryDelay, null));
+      partitionAttributes.setRedundantCopies(Objects.toString(redundantCopies, null));
+      partitionAttributes.setStartupRecoveryDelay(Objects.toString(startupRecoveryDelay, null));
+      partitionAttributes.setTotalNumBuckets(Objects.toString(totalNumBuckets, null));
+      if (partitionResolver != null) {
+        partitionAttributes.setPartitionResolver(new DeclarableType(partitionResolver));
+      }
+
+      if (partitionListeners != null) {
+        partitionListeners.stream().map(DeclarableType::new)
+            .forEach(partitionAttributes.getPartitionListeners()::add);
+      }
+      return partitionAttributes;
+    }
+
+    public static PartitionAttributes combine(PartitionAttributes existing,
+        PartitionAttributes delta) {
+      if (existing == null) {
+        return delta;
+      }
+      if (delta == null) {
+        return existing;
+      }
+
+      if (delta.getRedundantCopies() != null) {
+        existing.setRedundantCopies(delta.getRedundantCopies());
+      }
+
+      if (delta.getPartitionListeners() != null) {
+        existing.getPartitionListeners().clear();
+        existing.getPartitionListeners().addAll(delta.getPartitionListeners());
+      }
+
+      if (delta.getColocatedWith() != null) {
+        existing.setColocatedWith(delta.getColocatedWith());
+      }
+
+      if (delta.getLocalMaxMemory() != null) {
+        existing.setLocalMaxMemory(delta.getLocalMaxMemory());
+      }
+
+      if (delta.getPartitionResolver() != null) {
+        existing.setPartitionResolver(delta.getPartitionResolver());
+      }
+
+      if (delta.getRecoveryDelay() != null) {
+        existing.setRecoveryDelay(delta.getRecoveryDelay());
+      }
+
+      if (delta.getStartupRecoveryDelay() != null) {
+        existing.setStartupRecoveryDelay(delta.getStartupRecoveryDelay());
+      }
+
+      if (delta.getTotalMaxMemory() != null) {
+        existing.setTotalMaxMemory(delta.getTotalMaxMemory());
+      }
+
+      if (delta.getTotalNumBuckets() != null) {
+        existing.setTotalNumBuckets(delta.getTotalNumBuckets());
+      }
+
+      if (delta.getFixedPartitionAttributes() != null) {
+        existing.getFixedPartitionAttributes().clear();
+        existing.getFixedPartitionAttributes().addAll(delta.getFixedPartitionAttributes());
+      }
+      return existing;
+    }
+
     /**
      * Gets the value of the partitionResolver property.
      *
diff --git a/geode-management/src/main/java/org/apache/geode/cache/configuration/RegionConfig.java b/geode-management/src/main/java/org/apache/geode/cache/configuration/RegionConfig.java
index 7c25433..7522af8 100644
--- a/geode-management/src/main/java/org/apache/geode/cache/configuration/RegionConfig.java
+++ b/geode-management/src/main/java/org/apache/geode/cache/configuration/RegionConfig.java
@@ -446,6 +446,7 @@ public class RegionConfig implements CacheElement {
         break;
       }
       case "LOCAL": {
+        regionAttributes.setDataPolicy(RegionAttributesDataPolicy.NORMAL);
         regionAttributes.setScope(RegionAttributesScope.LOCAL);
         break;
       }
@@ -455,11 +456,13 @@ public class RegionConfig implements CacheElement {
         break;
       }
       case "LOCAL_HEAP_LRU": {
+        regionAttributes.setDataPolicy(RegionAttributesDataPolicy.NORMAL);
         regionAttributes.setScope(RegionAttributesScope.LOCAL);
         regionAttributes.setLruHeapPercentage(EnumActionDestroyOverflow.LOCAL_DESTROY);
         break;
       }
       case "LOCAL_OVERFLOW": {
+        regionAttributes.setDataPolicy(RegionAttributesDataPolicy.NORMAL);
         regionAttributes.setScope(RegionAttributesScope.LOCAL);
         regionAttributes.setLruHeapPercentage(EnumActionDestroyOverflow.OVERFLOW_TO_DISK);
         break;