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 2018/12/06 19:13:34 UTC
[geode] 01/03: GEODE-5971: Refactor CreateRegionCommand to extend
SingleGfshCommand
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
commit e9f5cd35b64ffa63ca6ebddee8aba3ef91a76d4b
Author: Aditya Anchuri <aa...@pivotal.io>
AuthorDate: Thu Nov 8 10:06:36 2018 -0800
GEODE-5971: Refactor CreateRegionCommand to extend SingleGfshCommand
- Store config via generating a RegionConfig object rather than an XML
entity
Signed-off-by: Peter Tran <pt...@pivotal.io>
Signed-off-by: Aditya Anchuri <aa...@pivotal.io>
Signed-off-by: Jens Deppe <jd...@pivotal.io>
---
.gitignore | 1 +
.../cli/commands/ConfigureEvictionThroughGfsh.java | 6 +-
.../integrationTest/resources/assembly_content.txt | 2 +-
geode-core/build.gradle | 1 -
.../CreateDefinedIndexesCommandDUnitTest.java | 13 +-
.../cli/commands/CreateRegionCommandDUnitTest.java | 120 +++-
...egionCommandPersistsConfigurationDUnitTest.java | 789 +++++++++++++++++++++
.../ImportOldClusterConfigDUnitTest.java | 2 +-
.../java/org/apache/geode/cache/DataPolicy.java | 7 +
.../org/apache/geode/cache/EvictionAttributes.java | 39 +
.../org/apache/geode/cache/ExpirationAction.java | 15 +
.../apache/geode/cache/ExpirationAttributes.java | 16 +-
.../apache/geode/cache/PartitionAttributes.java | 19 +
.../cache/configuration/RegionAttributesType.java | 11 +
.../InternalConfigurationPersistenceService.java | 23 -
.../apache/geode/internal/config/JAXBService.java | 4 +-
.../internal/cli/commands/AlterRegionCommand.java | 3 +-
.../internal/cli/commands/CreateRegionCommand.java | 123 +++-
.../cli/domain/RegionAttributeGetFunction.java | 22 +
.../cli/domain/RegionAttributeSetFunction.java | 22 +
.../internal/cli/domain/RegionConfigFactory.java | 331 +++++++++
.../cli/functions/RegionAlterFunction.java | 12 +-
.../cli/functions/RegionCreateFunction.java | 157 ++--
.../internal/cli/functions/RegionFunctionArgs.java | 86 ++-
.../management/internal/cli/i18n/CliStrings.java | 2 +
.../management/internal/cli/util/RegionPath.java | 16 +
.../geode/redis/internal/RegionProvider.java | 20 +-
.../cli/commands/CreateRegionCommandTest.java | 26 +-
.../cli/domain/RegionConfigFactoryTest.java | 273 +++++++
.../cli/functions/RegionFunctionArgsTest.java | 45 +-
.../cli/commands/CreateRegionCommandDUnitTest.java | 55 +-
31 files changed, 2061 insertions(+), 200 deletions(-)
diff --git a/.gitignore b/.gitignore
index 47d635b..1525f4a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -28,6 +28,7 @@ out/
*.orig
geode-pulse/screenshots/
/jpf.properties
+geode-assembly/assembly_content.txt
.git-together
bin/
diff --git a/geode-assembly/src/acceptanceTest/java/org/apache/geode/management/internal/cli/commands/ConfigureEvictionThroughGfsh.java b/geode-assembly/src/acceptanceTest/java/org/apache/geode/management/internal/cli/commands/ConfigureEvictionThroughGfsh.java
index 125d327..29ea9a5 100644
--- a/geode-assembly/src/acceptanceTest/java/org/apache/geode/management/internal/cli/commands/ConfigureEvictionThroughGfsh.java
+++ b/geode-assembly/src/acceptanceTest/java/org/apache/geode/management/internal/cli/commands/ConfigureEvictionThroughGfsh.java
@@ -57,7 +57,7 @@ public class ConfigureEvictionThroughGfsh {
"create region --name=region6 --eviction-action=local-destroy --eviction-entry-count=1000 --type=REPLICATE_PERSISTENT")
.expectFailure().execute(gfsh);
assertThat(execution.getOutputText()).contains(
- "ERROR: An Eviction Controller with local destroy eviction action is incompatible with");
+ "An Eviction Controller with local destroy eviction action is incompatible with");
execution = GfshScript
.of("connect --locator=localhost[10334]", "describe region --name=region1").execute(gfsh);
@@ -112,7 +112,7 @@ public class ConfigureEvictionThroughGfsh {
"create region --name=region6 --eviction-action=local-destroy --eviction-max-memory=1000 --type=REPLICATE_PERSISTENT")
.expectFailure().execute(gfsh);
assertThat(execution.getOutputText()).contains(
- "ERROR: An Eviction Controller with local destroy eviction action is incompatible with");
+ "An Eviction Controller with local destroy eviction action is incompatible with");
execution = GfshScript
.of("connect --locator=localhost[10334]", "describe region --name=region1").execute(gfsh);
@@ -181,7 +181,7 @@ public class ConfigureEvictionThroughGfsh {
"create region --name=region6 --eviction-action=local-destroy --eviction-max-memory=1000 --eviction-object-sizer=MySizer --type=REPLICATE_PERSISTENT")
.expectFailure().execute(gfsh);
assertThat(execution.getOutputText()).contains(
- "ERROR: An Eviction Controller with local destroy eviction action is incompatible with");
+ "An Eviction Controller with local destroy eviction action is incompatible with");
execution = GfshScript
.of("connect --locator=localhost[10334]", "describe region --name=region1").execute(gfsh);
diff --git a/geode-assembly/src/integrationTest/resources/assembly_content.txt b/geode-assembly/src/integrationTest/resources/assembly_content.txt
index 9cd4c19..f216ab3 100644
--- a/geode-assembly/src/integrationTest/resources/assembly_content.txt
+++ b/geode-assembly/src/integrationTest/resources/assembly_content.txt
@@ -957,4 +957,4 @@ tools/Modules/Apache_Geode_Modules-0.0.0-AppServer.zip
tools/Modules/Apache_Geode_Modules-0.0.0-Tomcat.zip
tools/Modules/Apache_Geode_Modules-0.0.0-tcServer.zip
tools/Modules/Apache_Geode_Modules-0.0.0-tcServer30.zip
-tools/Pulse/geode-pulse-0.0.0.war
+tools/Pulse/geode-pulse-0.0.0.war
\ No newline at end of file
diff --git a/geode-core/build.gradle b/geode-core/build.gradle
index 3f89a6f..668b2f1 100755
--- a/geode-core/build.gradle
+++ b/geode-core/build.gradle
@@ -15,7 +15,6 @@
* limitations under the License.
*/
-
apply plugin: 'antlr'
apply plugin: 'me.champeau.gradle.jmh'
diff --git a/geode-core/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/CreateDefinedIndexesCommandDUnitTest.java b/geode-core/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/CreateDefinedIndexesCommandDUnitTest.java
index 093a536..9b2df1b 100644
--- a/geode-core/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/CreateDefinedIndexesCommandDUnitTest.java
+++ b/geode-core/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/CreateDefinedIndexesCommandDUnitTest.java
@@ -15,6 +15,7 @@
package org.apache.geode.management.internal.cli.commands;
+import static org.apache.geode.management.internal.cli.result.model.ResultModel.MEMBER_STATUS_SECTION;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.List;
@@ -188,13 +189,15 @@ public class CreateDefinedIndexesCommandDUnitTest {
CommandResult result = gfsh
.executeCommand("create region --name=" + region1Name + " --type=REPLICATE --group=group1");
assertThat(result.getStatus()).isEqualTo(Result.Status.OK);
- assertThat(result.getMapFromTableContent("0", "0").get("Member")).contains("server-1",
+ assertThat(result.getMapFromTableContent(MEMBER_STATUS_SECTION).get("Member")).contains(
+ "server-1",
"server-2");
result = gfsh
.executeCommand("create region --name=" + region2Name + " --type=REPLICATE --group=group1");
assertThat(result.getStatus()).isEqualTo(Result.Status.OK);
- assertThat(result.getMapFromTableContent("0", "0").get("Member")).contains("server-1",
+ assertThat(result.getMapFromTableContent(MEMBER_STATUS_SECTION).get("Member")).contains(
+ "server-1",
"server-2");
VMProvider.invokeInEveryMember(() -> {
@@ -251,13 +254,15 @@ public class CreateDefinedIndexesCommandDUnitTest {
CommandResult result = gfsh
.executeCommand("create region --name=" + region1Name + " --type=REPLICATE --group=group1");
assertThat(result.getStatus()).isEqualTo(Result.Status.OK);
- assertThat(result.getMapFromTableContent("0", "0").get("Member")).contains("server-1",
+ assertThat(result.getMapFromTableContent(MEMBER_STATUS_SECTION).get("Member")).contains(
+ "server-1",
"server-2");
result = gfsh
.executeCommand("create region --name=" + region2Name + " --type=REPLICATE --group=group2");
assertThat(result.getStatus()).isEqualTo(Result.Status.OK);
- assertThat(result.getMapFromTableContent("0", "0").get("Member")).contains("server-3");
+ assertThat(result.getMapFromTableContent(MEMBER_STATUS_SECTION).get("Member"))
+ .contains("server-3");
gfsh.executeAndAssertThat(
"define index --name=" + index1Name + " --expression=value1 --region=" + region1Name)
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 8d8dc19..0c50623 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
@@ -20,10 +20,12 @@ import static org.assertj.core.api.Assertions.assertThat;
import java.io.File;
import java.io.Serializable;
import java.util.Arrays;
+import java.util.List;
import java.util.stream.Collectors;
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;
@@ -31,13 +33,19 @@ import org.junit.rules.TemporaryFolder;
import org.junit.rules.TestName;
import org.apache.geode.cache.Cache;
+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.asyncqueue.AsyncEvent;
+import org.apache.geode.cache.asyncqueue.AsyncEventListener;
import org.apache.geode.cache.configuration.CacheConfig;
import org.apache.geode.cache.configuration.CacheElement;
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.internal.cache.InternalRegion;
import org.apache.geode.internal.cache.PartitionedRegion;
import org.apache.geode.internal.cache.RegionEntryContext;
import org.apache.geode.test.compiler.JarBuilder;
@@ -59,6 +67,37 @@ public class CreateRegionCommandDUnitTest {
implements Serializable {
}
+ public static class DummyAEQListener implements AsyncEventListener, Declarable {
+ @Override
+ public boolean processEvents(List<AsyncEvent> events) {
+ return false;
+ }
+ }
+
+ public static class DummyPartitionResolver implements PartitionResolver, Declarable {
+ @Override
+ public Object getRoutingObject(EntryOperation opDetails) {
+ return null;
+ }
+
+ @Override
+ public String getName() {
+ return "dummy";
+ }
+ }
+
+ public static class DummyCompressor implements Compressor, Declarable {
+ @Override
+ public byte[] compress(byte[] input) {
+ return new byte[0];
+ }
+
+ @Override
+ public byte[] decompress(byte[] input) {
+ return new byte[0];
+ }
+ }
+
@ClassRule
public static ClusterStartupRule lsRule = new ClusterStartupRule();
@@ -230,6 +269,7 @@ public class CreateRegionCommandDUnitTest {
gfsh.executeAndAssertThat("destroy region --name=/TEMPLATE").statusIsSuccess();
}
+
@Test
public void cannotSetRegionExpirationForPartitionedTemplate() {
gfsh.executeAndAssertThat("create region --name=/TEMPLATE --type=PARTITION")
@@ -431,11 +471,12 @@ public class CreateRegionCommandDUnitTest {
}
@Test
- public void startWithReplicateProxyThenPartitionRegion() {
+ public void startWithReplicateProxyThenPartitionRegion() throws Exception {
String regionName = testName.getMethodName();
gfsh.executeAndAssertThat(
"create region --type=REPLICATE_PROXY --group=group1 --name=" + regionName)
.statusIsSuccess().tableHasRowWithValues("Member", "server-1");
+
gfsh.executeAndAssertThat("create region --type=PARTITION --group=group2 --name=" + regionName)
.statusIsError().containsOutput("The existing region is not a partitioned region");
gfsh.executeAndAssertThat(
@@ -560,6 +601,83 @@ public class CreateRegionCommandDUnitTest {
.containsOutput("Region /startWithLocalRegion already exists on the cluster");
}
+ @Test
+ public void cannotDisableCloningWhenCompressorIsSet() {
+ String regionName = testName.getMethodName();
+ gfsh.executeAndAssertThat("create region"
+ + " --name=" + regionName
+ + " --type=REPLICATE"
+ + " --compressor=" + DummyCompressor.class.getName()
+ + " --enable-cloning=false").statusIsError();
+ }
+
+ /**
+ * 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-6103
+ */
+ @Ignore
+ @Test
+ public void testCreateRegionFromTemplateWithAsyncEventListeners() {
+ String queueId = "queue1";
+ gfsh.executeAndAssertThat(
+ "create async-event-queue --id=" + queueId
+ + " --listener=" + CreateRegionCommandDUnitTest.DummyAEQListener.class.getName())
+ .statusIsSuccess();
+
+ String regionName = testName.getMethodName();
+ gfsh.executeAndAssertThat(
+ "create region --name=" + regionName
+ + " --type=REPLICATE"
+ + " --async-event-queue-id=" + queueId)
+ .statusIsSuccess();
+
+ gfsh.executeAndAssertThat(
+ "create region --name=" + regionName + "-from-template"
+ + " --template-region=" + regionName)
+ .statusIsSuccess();
+
+ server1.invoke(() -> {
+ Region regionFromTemplate = ClusterStartupRule.getCache()
+ .getRegion(regionName + "-from-template");
+ assertThat(regionFromTemplate).isNotNull();
+ assertThat(((InternalRegion) regionFromTemplate).getAsyncEventQueueIds())
+ .contains(queueId);
+ });
+ }
+
+ /**
+ * 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-6103
+ */
+ @Ignore
+ @Test
+ public void testCreateRegionFromTemplateWithPartitionResolver() {
+ String regionName = testName.getMethodName();
+ String regionFromTemplateName = regionName + "-from-template";
+
+ gfsh.executeAndAssertThat("create region"
+ + " --name=" + regionName
+ + " --type=PARTITION"
+ + " --partition-resolver=" + DummyPartitionResolver.class.getName()).statusIsSuccess();
+ gfsh.executeAndAssertThat("create region"
+ + " --name=" + regionFromTemplateName
+ + " --template-region=" + regionName).statusIsSuccess();
+
+ server1.invoke(() -> {
+ Region regionFromTemplate = ClusterStartupRule.getCache()
+ .getRegion(regionName + "-from-template");
+ assertThat(regionFromTemplate).isNotNull();
+ assertThat(((InternalRegion) regionFromTemplate).getPartitionAttributes()
+ .getPartitionResolver())
+ .isNotNull();
+ assertThat(((InternalRegion) regionFromTemplate).getPartitionAttributes()
+ .getPartitionResolver().getName())
+ .isEqualTo(DummyPartitionResolver.class.getName());
+ });
+ }
+
private String getUniversalClassCode(String classname) {
String code = "package io.pivotal;" + "import org.apache.geode.cache.CacheLoader;"
+ "import org.apache.geode.cache.CacheLoaderException;"
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
new file mode 100644
index 0000000..275fac9
--- /dev/null
+++ b/geode-core/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/CreateRegionCommandPersistsConfigurationDUnitTest.java
@@ -0,0 +1,789 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.geode.management.internal.cli.commands;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.rules.TestName;
+
+import org.apache.geode.cache.CacheLoader;
+import org.apache.geode.cache.CacheLoaderException;
+import org.apache.geode.cache.CustomExpiry;
+import org.apache.geode.cache.Declarable;
+import org.apache.geode.cache.EntryOperation;
+import org.apache.geode.cache.ExpirationAttributes;
+import org.apache.geode.cache.LoaderHelper;
+import org.apache.geode.cache.PartitionResolver;
+import org.apache.geode.cache.Region;
+import org.apache.geode.cache.configuration.CacheConfig;
+import org.apache.geode.cache.configuration.CacheElement;
+import org.apache.geode.cache.configuration.ExpirationAttributesType;
+import org.apache.geode.cache.configuration.RegionAttributesDataPolicy;
+import org.apache.geode.cache.configuration.RegionAttributesType;
+import org.apache.geode.cache.configuration.RegionConfig;
+import org.apache.geode.cache.util.CacheListenerAdapter;
+import org.apache.geode.cache.util.CacheWriterAdapter;
+import org.apache.geode.compression.Compressor;
+import org.apache.geode.distributed.internal.InternalConfigurationPersistenceService;
+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 CreateRegionCommandPersistsConfigurationDUnitTest {
+
+ private MemberVM locator, server1;
+
+ @Rule
+ public ClusterStartupRule clusterRule = new ClusterStartupRule();
+
+ @Rule
+ public GfshCommandRule gfsh = new GfshCommandRule();
+
+ @Rule
+ public TestName testName = new SerializableTestName();
+
+ public static class DummyCacheListener extends CacheListenerAdapter {
+ }
+
+ public static class DummyCustomExpiry implements CustomExpiry, Declarable {
+ @Override
+ public ExpirationAttributes getExpiry(Region.Entry entry) {
+ return null;
+ }
+ }
+
+ public static class DummyPartitionResolver implements PartitionResolver, Declarable {
+ @Override
+ public Object getRoutingObject(EntryOperation opDetails) {
+ return null;
+ }
+
+ @Override
+ public String getName() {
+ return "dummy";
+ }
+ }
+
+ public static class DummyCompressor implements Compressor, Declarable {
+ @Override
+ public byte[] compress(byte[] input) {
+ return new byte[0];
+ }
+
+ @Override
+ public byte[] decompress(byte[] input) {
+ return new byte[0];
+ }
+ }
+
+ public static class DummyCacheLoader implements CacheLoader, Declarable {
+ @Override
+ public Object load(LoaderHelper helper) throws CacheLoaderException {
+ return null;
+ }
+ }
+
+ public static class DummyCacheWriter extends CacheWriterAdapter {
+ }
+
+ @Before
+ public void before() throws Exception {
+ locator = clusterRule.startLocatorVM(0);
+ server1 = clusterRule.startServerVM(1, locator.getPort());
+
+ gfsh.connectAndVerify(locator);
+ }
+
+ @Test
+ public void createRegionPersistsEmptyConfig() {
+ String regionName = testName.getMethodName();
+ gfsh.executeAndAssertThat("create region --name=" + regionName + " --type=REPLICATE")
+ .statusIsSuccess();
+
+ server1.stop();
+ server1 = clusterRule.startServerVM(1, "group1", locator.getPort());
+
+ gfsh.executeAndAssertThat("list regions")
+ .statusIsSuccess().containsOutput(regionName);
+
+ locator.invoke(() -> {
+ InternalConfigurationPersistenceService cc =
+ ClusterStartupRule.getLocator().getConfigurationPersistenceService();
+ CacheConfig config = cc.getCacheConfig("cluster");
+
+ List<RegionConfig> regions = config.getRegions();
+ assertThat(regions).isNotEmpty();
+ RegionConfig regionConfig = regions.get(0);
+ assertThat(regionConfig).isNotNull();
+ assertThat(regionConfig.getName()).isEqualTo(regionName);
+ assertThat(regionConfig.getIndexes()).isEmpty();
+ assertThat(regionConfig.getRegions()).isEmpty();
+ assertThat(regionConfig.getEntries()).isEmpty();
+ assertThat(regionConfig.getCustomRegionElements()).isEmpty();
+ });
+ }
+
+ @Test
+ public void createRegionPersistsConfigParams() {
+ String regionName = testName.getMethodName();
+ gfsh.executeAndAssertThat("create region --name=" + regionName + " --type=PARTITION"
+ + " --enable-statistics=true" + " --enable-async-conflation=true"
+ + " --entry-idle-time-expiration=100").statusIsSuccess();
+
+ server1.stop();
+ server1 = clusterRule.startServerVM(1, "group1", locator.getPort());
+
+ gfsh.executeAndAssertThat("list regions")
+ .statusIsSuccess().containsOutput(regionName);
+
+ locator.invoke(() -> {
+ InternalConfigurationPersistenceService cc =
+ ClusterStartupRule.getLocator().getConfigurationPersistenceService();
+ CacheConfig config = cc.getCacheConfig("cluster");
+
+ List<RegionConfig> regions = config.getRegions();
+ assertThat(regions).isNotEmpty();
+ RegionConfig regionConfig = regions.get(0);
+ assertThat(regionConfig).isNotNull();
+ assertThat(regionConfig.getName()).isEqualTo(regionName);
+ assertThat(regionConfig.getRegionAttributes()).hasSize(1);
+
+ RegionAttributesType attr = regionConfig.getRegionAttributes().get(0);
+ assertThat(attr.isStatisticsEnabled()).isTrue();
+ assertThat(attr.isEnableAsyncConflation()).isTrue();
+
+ ExpirationAttributesType entryIdleTimeExp = attr.getEntryIdleTime().getExpirationAttributes();
+ assertThat(entryIdleTimeExp.getTimeout()).isEqualTo("100");
+ });
+
+ server1.invoke(() -> {
+ Region<?, ?> region = ClusterStartupRule.getCache().getRegion(regionName);
+ assertThat(region.getAttributes().getStatisticsEnabled())
+ .describedAs("Expecting statistics to be enabled")
+ .isTrue();
+ assertThat(region.getAttributes().getEnableAsyncConflation())
+ .describedAs("Expecting async conflation to be enabled")
+ .isTrue();
+ assertThat(region.getAttributes().getEntryIdleTimeout().getTimeout())
+ .describedAs("Expecting entry idle time exp timeout to be 100")
+ .isEqualTo(100);
+ });
+ }
+
+ @Test
+ public void createRegionFromTemplateCreatesCorrectConfig() {
+ String regionName = testName.getMethodName();
+ String templateRegionName = regionName + "_template";
+ gfsh.executeAndAssertThat("create region"
+ + " --name=" + templateRegionName
+ + " --type=PARTITION"
+ + " --cache-listener=" + DummyCacheListener.class.getName()
+ + " --enable-statistics=true"
+ + " --enable-async-conflation=true"
+ + " --entry-idle-time-expiration=100").statusIsSuccess();
+
+ gfsh.executeAndAssertThat(
+ "create region --name=" + regionName + " --template-region=" + templateRegionName);
+
+ locator.invoke(() -> {
+ InternalConfigurationPersistenceService cc =
+ ClusterStartupRule.getLocator().getConfigurationPersistenceService();
+ CacheConfig config = cc.getCacheConfig("cluster");
+
+ List<RegionConfig> regions = config.getRegions();
+ assertThat(regions).isNotEmpty();
+ RegionConfig regionConfig = CacheElement.findElement(config.getRegions(), regionName);
+
+ assertThat(regionConfig).isNotNull();
+ assertThat(regionConfig.getName()).isEqualTo(regionName);
+ assertThat(regionConfig.getRegionAttributes()).hasSize(1);
+
+ RegionAttributesType attr = regionConfig.getRegionAttributes().get(0);
+ assertThat(attr.isStatisticsEnabled()).isTrue();
+ assertThat(attr.isEnableAsyncConflation()).isTrue();
+
+ ExpirationAttributesType entryIdleTimeExp = attr.getEntryIdleTime().getExpirationAttributes();
+ assertThat(entryIdleTimeExp.getTimeout()).isEqualTo("100");
+ });
+ }
+
+ @Test
+ public void createRegionAndValidateAllConfigIsPersistedForReplicatedRegion() {
+ String regionName = testName.getMethodName();
+ gfsh.executeAndAssertThat("create region"
+ + " --name=" + regionName
+ + " --type=REPLICATE"
+ + " --cache-listener=" + DummyCacheListener.class.getName()
+ + " --cache-loader=" + DummyCacheLoader.class.getName()
+ + " --cache-writer=" + DummyCacheWriter.class.getName()
+ + " --compressor=" + DummyCompressor.class.getName()
+ + " --enable-async-conflation=false"
+ + " --enable-concurrency-checks=false"
+ + " --enable-multicast=false"
+ + " --concurrency-level=1"
+ + " --enable-statistics=true"
+ + " --enable-subscription-conflation=true"
+ + " --entry-idle-time-expiration=100"
+ + " --entry-idle-time-expiration-action=local-destroy"
+ + " --entry-time-to-live-expiration=200"
+ + " --entry-time-to-live-expiration-action=local-destroy"
+ + " --eviction-action=local-destroy"
+ + " --key-constraint=" + Object.class.getName()
+ + " --off-heap=false"
+ + " --region-idle-time-expiration=100"
+ + " --region-idle-time-expiration-action=local-destroy"
+ + " --region-time-to-live-expiration=200"
+ + " --region-time-to-live-expiration-action=local-destroy"
+ + " --value-constraint=" + Object.class.getName()).statusIsSuccess();
+
+ String regionNameFromTemplate = regionName + "-from-template";
+ gfsh.executeAndAssertThat("create region --name=" + regionNameFromTemplate
+ + " --template-region=" + regionName)
+ .statusIsSuccess();
+
+ locator.invoke(() -> {
+ InternalConfigurationPersistenceService cc =
+ ClusterStartupRule.getLocator().getConfigurationPersistenceService();
+ CacheConfig config = cc.getCacheConfig("cluster");
+
+ List<RegionConfig> regions = config.getRegions();
+ assertThat(regions).isNotEmpty();
+ assertThat(regions).hasSize(2);
+
+ 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);
+ assertThat(regionConfig.getRegionAttributes())
+ .describedAs("Expecting region attributes to exist")
+ .hasSize(1);
+
+ RegionAttributesType attr = regionConfig.getRegionAttributes().get(0);
+ assertThat(attr.getCacheListeners().get(0).toString())
+ .describedAs("Expecting one cache listener for region " + name)
+ .isEqualTo(DummyCacheListener.class.getName());
+ assertThat(attr.getCacheLoader().toString())
+ .describedAs("Expecting a DummyCacheLoader for region " + name)
+ .isEqualTo(DummyCacheLoader.class.getName());
+ assertThat(attr.getCacheWriter().toString())
+ .describedAs("Expecting a DummyCacheWriter for region " + name)
+ .isEqualTo(DummyCacheWriter.class.getName());
+ assertThat(attr.getCompressor().toString())
+ .describedAs("Expecting a DummyCompressor for region " + name)
+ .isEqualTo(DummyCompressor.class.getName());
+ assertThat(attr.isEnableAsyncConflation())
+ .describedAs("Expecting async conflation to not be enabled for region "
+ + name)
+ .isFalse();
+ assertThat(attr.isConcurrencyChecksEnabled())
+ .describedAs("Expecting concurrency checks not to be enabled for region "
+ + name)
+ .isFalse();
+ assertThat(attr.isMulticastEnabled())
+ .describedAs("Expecting multicast is not enabled for region " + name)
+ .isFalse();
+ assertThat(attr.getConcurrencyLevel())
+ .describedAs("Expecting concurrency level to be 1 for region " + name)
+ .isEqualTo("1");
+ 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.isEnableSubscriptionConflation())
+ .describedAs("Expecting subscription conflation to be enabled for region "
+ + name)
+ .isTrue();
+ assertThat(attr.getEntryIdleTime().getExpirationAttributes().getTimeout())
+ .describedAs("Entry idle time timeout should be 100 for region " + name)
+ .isEqualTo("100");
+ assertThat(attr.getEntryIdleTime().getExpirationAttributes().getAction())
+ .describedAs("Entry idle time expiration action should be local-destroy for region "
+ + name)
+ .isEqualTo("local-destroy");
+ assertThat(attr.getEntryTimeToLive().getExpirationAttributes().getTimeout())
+ .describedAs("Expecting entry time to live expiration to be 200 for region "
+ + name)
+ .isEqualTo("200");
+ assertThat(attr.getEntryTimeToLive().getExpirationAttributes().getAction())
+ .describedAs("Entry time to live expiration action should be local-destroy "
+ + "for region " + name)
+ .isEqualTo("local-destroy");
+ assertThat(attr.getEvictionAttributes().getLruHeapPercentage().getAction().value())
+ .describedAs("Eviction action should be local-destroy for region " + name)
+ .isEqualTo("local-destroy");
+ assertThat(attr.getKeyConstraint())
+ .describedAs("Expected key constraint to be " + Object.class.getName() +
+ " for region " + name)
+ .isEqualTo(Object.class.getName());
+ assertThat(attr.isOffHeap())
+ .describedAs("Expected off heap to be false for region " + name)
+ .isFalse();
+ assertThat(attr.getRegionIdleTime().getExpirationAttributes().getTimeout())
+ .describedAs("Expecting region idle time expiration to be 100 for region "
+ + name)
+ .isEqualTo("100");
+ assertThat(attr.getRegionIdleTime().getExpirationAttributes().getAction())
+ .describedAs("Expecting region idle time expiration action to be "
+ + "local-destroy for region " + name)
+ .isEqualTo("local-destroy");
+ assertThat(attr.getRegionTimeToLive().getExpirationAttributes().getTimeout())
+ .describedAs("Expecting region idle time timeout to be 200 for "
+ + "region " + name)
+ .isEqualTo("200");
+ assertThat(attr.getRegionTimeToLive().getExpirationAttributes().getAction())
+ .describedAs("Expecting region ttl action to be local-destroy for "
+ + "region " + name)
+ .isEqualTo("local-destroy");
+ assertThat(attr.getValueConstraint())
+ .describedAs("Expecting value constraint to be Object.class for "
+ + "region " + name)
+ .isEqualTo(Object.class.getName());
+ });
+ });
+ }
+
+ @Test
+ public void createRegionDoesNotPersistEmptyOrDefaultEvictionAttributes() {
+ String regionName = testName.getMethodName();
+ gfsh.executeAndAssertThat("create region"
+ + " --name=" + regionName
+ + " --type=REPLICATE").statusIsSuccess();
+
+ locator.invoke(() -> {
+ InternalConfigurationPersistenceService cc =
+ ClusterStartupRule.getLocator().getConfigurationPersistenceService();
+ CacheConfig config = cc.getCacheConfig("cluster");
+
+ List<RegionConfig> regions = config.getRegions();
+ assertThat(regions).isNotEmpty();
+ assertThat(regions).hasSize(1);
+
+ List<String> regionNames = Arrays.asList(regionName);
+ regionNames.forEach(name -> {
+ RegionConfig regionConfig = CacheElement.findElement(config.getRegions(), name);
+ assertThat(regionConfig).isNotNull();
+ assertThat(regionConfig.getName()).isEqualTo(name);
+ assertThat(regionConfig.getRegionAttributes())
+ .describedAs("Expecting region attributes to exist")
+ .hasSize(1);
+
+ RegionAttributesType attr = regionConfig.getRegionAttributes().get(0);
+ assertThat(attr.getEvictionAttributes())
+ .describedAs("Eviction attributes should be null for " + name)
+ .isNull();
+ });
+ });
+ }
+
+ @Test
+ public void createRegionPersistsAEQConfig() {
+ String queueId = "queue1";
+ gfsh.executeAndAssertThat(
+ "create async-event-queue --id=" + queueId
+ + " --listener=" + CreateRegionCommandDUnitTest.DummyAEQListener.class.getName())
+ .statusIsSuccess();
+
+ String regionName = testName.getMethodName();
+ gfsh.executeAndAssertThat(
+ "create region --name=" + regionName
+ + " --type=REPLICATE"
+ + " --async-event-queue-id=" + queueId)
+ .statusIsSuccess();
+
+ locator.invoke(() -> {
+ InternalConfigurationPersistenceService cc =
+ ClusterStartupRule.getLocator().getConfigurationPersistenceService();
+ CacheConfig config = cc.getCacheConfig("cluster");
+
+ List<RegionConfig> regions = config.getRegions();
+ assertThat(regions).isNotEmpty();
+ assertThat(regions).hasSize(1);
+ RegionConfig regionConfig = CacheElement.findElement(regions, regionName);
+ assertThat(regionConfig.getRegionAttributes().get(0).getAsyncEventQueueIds())
+ .contains(queueId);
+ });
+ }
+
+ @Test
+ public void createRegionWithColocation() {
+ String regionName = testName.getMethodName();
+ String colocatedRegionName = regionName + "-colocated";
+ String colocatedRegionFromTemplateName = colocatedRegionName + "-from-template";
+
+ gfsh.executeAndAssertThat("create region"
+ + " --name=" + regionName
+ + " --type=PARTITION");
+ gfsh.executeAndAssertThat("create region"
+ + " --name=" + colocatedRegionName
+ + " --colocated-with=" + regionName
+ + " --type=PARTITION");
+
+ gfsh.executeAndAssertThat("create region"
+ + " --name=" + colocatedRegionFromTemplateName
+ + " --template-region=" + colocatedRegionName);
+
+ locator.invoke(() -> {
+ InternalConfigurationPersistenceService cc =
+ ClusterStartupRule.getLocator().getConfigurationPersistenceService();
+ CacheConfig config = cc.getCacheConfig("cluster");
+
+ List<RegionConfig> regions = config.getRegions();
+ assertThat(regions).isNotEmpty();
+ assertThat(regions).hasSize(3);
+
+ RegionConfig colocatedConfig = CacheElement.findElement(regions, colocatedRegionName);
+ assertThat(
+ colocatedConfig.getRegionAttributes().get(0).getPartitionAttributes().getColocatedWith())
+ .isEqualTo("/" + regionName);
+
+ RegionConfig colocatedConfigFromTemplate = CacheElement.findElement(regions,
+ colocatedRegionFromTemplateName);
+ assertThat(
+ colocatedConfigFromTemplate.getRegionAttributes().get(0).getPartitionAttributes()
+ .getColocatedWith())
+ .isEqualTo("/" + regionName);
+ });
+ }
+
+ @Test
+ public void createRegionPersistsDiskstores() throws Exception {
+ String regionName = testName.getMethodName();
+ String store = "Store1";
+ gfsh.executeAndAssertThat("create disk-store"
+ + " --name=" + store
+ + " --dir=/tmp/foo").statusIsSuccess();
+
+ // Give disk store time to get created
+ Thread.sleep(2000);
+
+ gfsh.executeAndAssertThat("create region"
+ + " --name=" + regionName
+ + " --type=REPLICATE_PERSISTENT"
+ + " --disk-store=" + store
+ + " --enable-synchronous-disk=true").statusIsSuccess();
+
+ String regionNameFromTemplate = regionName + "-from-template";
+ gfsh.executeAndAssertThat("create region --name=" + regionNameFromTemplate
+ + " --template-region=" + regionName)
+ .statusIsSuccess();
+
+ locator.invoke(() -> {
+ InternalConfigurationPersistenceService cc =
+ ClusterStartupRule.getLocator().getConfigurationPersistenceService();
+ CacheConfig config = cc.getCacheConfig("cluster");
+
+ List<RegionConfig> regions = config.getRegions();
+ assertThat(regions).isNotEmpty();
+ assertThat(regions).hasSize(2);
+
+ 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().get(0);
+ assertThat(regionAttributes.getDiskStoreName())
+ .isEqualTo(store);
+ assertThat(regionAttributes.isDiskSynchronous())
+ .isTrue();
+ });
+ });
+ }
+
+ @Test
+ public void createRegionPersistsPartitionAttributes() {
+ String regionName = testName.getMethodName();
+ String regionFromTemplateName = regionName + "-from-template";
+
+ gfsh.executeAndAssertThat("create region"
+ + " --name=" + regionName
+ + " --type=PARTITION"
+ + " --recovery-delay=1"
+ + " --local-max-memory=1000"
+ + " --redundant-copies=1"
+ + " --startup-recovery-delay=1"
+ + " --total-max-memory=100"
+ + " --total-num-buckets=1").statusIsSuccess();
+ gfsh.executeAndAssertThat("create region"
+ + " --name=" + regionFromTemplateName
+ + " --template-region=" + regionName);
+
+ locator.invoke(() -> {
+ InternalConfigurationPersistenceService cc =
+ ClusterStartupRule.getLocator().getConfigurationPersistenceService();
+ CacheConfig config = cc.getCacheConfig("cluster");
+
+ List<RegionConfig> regions = config.getRegions();
+ assertThat(regions).isNotEmpty();
+ assertThat(regions).hasSize(2);
+
+ List<String> regionNames = Arrays.asList(regionName, regionFromTemplateName);
+ regionNames.forEach(name -> {
+ RegionConfig regionConfig = CacheElement.findElement(config.getRegions(), name);
+ assertThat(regionConfig).isNotNull();
+ assertThat(regionConfig.getName()).isEqualTo(name);
+
+ RegionAttributesType regionAttributes = regionConfig.getRegionAttributes().get(0);
+ RegionAttributesType.PartitionAttributes partitionAttributes =
+ regionAttributes.getPartitionAttributes();
+
+ assertThat(partitionAttributes.getRecoveryDelay())
+ .describedAs("Recovery delay should be 1 for region " + name)
+ .isEqualTo("1");
+ assertThat(partitionAttributes.getLocalMaxMemory())
+ .describedAs("Local max memory should be 1000 for region " + name)
+ .isEqualTo("1000");
+ assertThat(partitionAttributes.getRedundantCopies())
+ .describedAs("Redundant copies should be 1 for region " + name)
+ .isEqualTo("1");
+ assertThat(partitionAttributes.getStartupRecoveryDelay())
+ .describedAs("Startup recovery delay should be 1 for region " + name)
+ .isEqualTo("1");
+ assertThat(partitionAttributes.getTotalMaxMemory())
+ .describedAs("Total max memory should be 100 for region " + name)
+ .isEqualTo("100");
+ assertThat(partitionAttributes.getTotalNumBuckets())
+ .describedAs("Total num buckets should be 1 for region " + name)
+ .isEqualTo("1");
+ });
+ });
+ }
+
+ @Test
+ public void createRegionPersistsPartitionResolver() {
+ String regionName = testName.getMethodName();
+
+ gfsh.executeAndAssertThat("create region"
+ + " --name=" + regionName
+ + " --type=PARTITION"
+ + " --partition-resolver=" + DummyPartitionResolver.class.getName()).statusIsSuccess();
+
+ locator.invoke(() -> {
+ InternalConfigurationPersistenceService cc =
+ ClusterStartupRule.getLocator().getConfigurationPersistenceService();
+ CacheConfig config = cc.getCacheConfig("cluster");
+
+ List<RegionConfig> regions = config.getRegions();
+ assertThat(regions).isNotEmpty();
+ assertThat(regions).hasSize(1);
+
+ RegionConfig regionConfig = CacheElement.findElement(config.getRegions(), regionName);
+ assertThat(regionConfig).isNotNull();
+ assertThat(regionConfig.getName()).isEqualTo(regionName);
+
+ RegionAttributesType regionAttributes = regionConfig.getRegionAttributes().get(0);
+ RegionAttributesType.PartitionAttributes partitionAttributes =
+ regionAttributes.getPartitionAttributes();
+
+ assertThat(partitionAttributes.getPartitionResolver().getClassName())
+ .isEqualTo(DummyPartitionResolver.class.getName());
+ });
+ }
+
+ @Test
+ public void createRegionDoesNotPersistEmptyOrDefaultPartitionAttributes() {
+ String regionName = testName.getMethodName();
+ String regionFromTemplateName = regionName + "-from-template";
+
+ gfsh.executeAndAssertThat("create region"
+ + " --name=" + regionName
+ + " --type=REPLICATE").statusIsSuccess();
+
+ gfsh.executeAndAssertThat("create region"
+ + " --name=" + regionFromTemplateName
+ + " --template-region=" + regionName);
+
+ locator.invoke(() -> {
+ InternalConfigurationPersistenceService cc =
+ ClusterStartupRule.getLocator().getConfigurationPersistenceService();
+ CacheConfig config = cc.getCacheConfig("cluster");
+
+ List<RegionConfig> regions = config.getRegions();
+ assertThat(regions).isNotEmpty();
+ assertThat(regions).hasSize(2);
+
+ RegionConfig regionConfig =
+ CacheElement.findElement(config.getRegions(), regionFromTemplateName);
+ assertThat(regionConfig).isNotNull();
+ assertThat(regionConfig.getName()).isEqualTo(regionFromTemplateName);
+ assertThat(regionConfig.getRegionAttributes())
+ .describedAs("Expecting region attributes to exist")
+ .hasSize(1);
+
+ RegionAttributesType attr = regionConfig.getRegionAttributes().get(0);
+ assertThat(attr.getPartitionAttributes())
+ .describedAs("Partition attributes should be null for " + regionFromTemplateName)
+ .isNull();
+ });
+ }
+
+ @Test
+ public void createRegionDoestNotPersistEmptyOrDefaultExpirationAttributes() {
+ String regionName = testName.getMethodName();
+ gfsh.executeAndAssertThat("create region"
+ + " --name=" + regionName
+ + " --type=REPLICATE").statusIsSuccess();
+
+ locator.invoke(() -> {
+ InternalConfigurationPersistenceService cc =
+ ClusterStartupRule.getLocator().getConfigurationPersistenceService();
+ CacheConfig config = cc.getCacheConfig("cluster");
+
+ List<RegionConfig> regions = config.getRegions();
+ assertThat(regions).isNotEmpty();
+ assertThat(regions).hasSize(1);
+
+ RegionConfig regionConfig =
+ CacheElement.findElement(config.getRegions(), regionName);
+ assertThat(regionConfig).isNotNull();
+ assertThat(regionConfig.getName()).isEqualTo(regionName);
+ assertThat(regionConfig.getRegionAttributes())
+ .describedAs("Expecting region attributes to exist")
+ .hasSize(1);
+
+ RegionAttributesType attr = regionConfig.getRegionAttributes().get(0);
+ assertThat(attr.getRegionTimeToLive())
+ .describedAs("Expiration attributes should be null for " + regionName)
+ .isNull();
+ assertThat(attr.getRegionIdleTime())
+ .describedAs("Expiration attributes should be null for " + regionName)
+ .isNull();
+ assertThat(attr.getEntryIdleTime())
+ .describedAs("Expiration attributes should be null for " + regionName)
+ .isNull();
+ assertThat(attr.getEntryTimeToLive())
+ .describedAs("Expiration attributes should be null for " + regionName)
+ .isNull();
+ });
+ }
+
+ @Test
+ public void createRegionPersistsDisableCloningSetting() {
+ String regionName = testName.getMethodName();
+ String regionFromTemplateName = regionName + "-from-template";
+
+ gfsh.executeAndAssertThat("create region"
+ + " --name=" + regionName
+ + " --type=REPLICATE"
+ + " --enable-cloning=false").statusIsSuccess();
+
+ gfsh.executeAndAssertThat("create region"
+ + " --name=" + regionFromTemplateName
+ + " --template-region=" + regionName);
+
+ locator.invoke(() -> {
+ InternalConfigurationPersistenceService cc =
+ ClusterStartupRule.getLocator().getConfigurationPersistenceService();
+ CacheConfig config = cc.getCacheConfig("cluster");
+
+ List<RegionConfig> regions = config.getRegions();
+ assertThat(regions).isNotEmpty();
+ assertThat(regions).hasSize(2);
+
+ List<String> regionNames = Arrays.asList(regionName, regionFromTemplateName);
+ regionNames.forEach(name -> {
+ RegionConfig regionConfig = CacheElement.findElement(config.getRegions(), name);
+ assertThat(regionConfig).isNotNull();
+ assertThat(regionConfig.getName()).isEqualTo(name);
+ assertThat(regionConfig.getRegionAttributes())
+ .describedAs("Expecting region attributes to exist for " + name)
+ .hasSize(1);
+
+ RegionAttributesType attr = regionConfig.getRegionAttributes().get(0);
+ assertThat(attr.isCloningEnabled())
+ .describedAs("Cloning should be disabled for " + name)
+ .isFalse();
+ });
+ });
+ }
+
+ @Test
+ public void createRegionPersistsCustomExpiryClass() {
+ String regionName = testName.getMethodName();
+ gfsh.executeAndAssertThat("create region"
+ + " --name=" + regionName
+ + " --type=REPLICATE"
+ + " --enable-statistics=true"
+ + " --entry-idle-time-custom-expiry=" + DummyCustomExpiry.class.getName())
+ .statusIsSuccess();
+
+ locator.invoke(() -> {
+ InternalConfigurationPersistenceService cc =
+ ClusterStartupRule.getLocator().getConfigurationPersistenceService();
+ CacheConfig config = cc.getCacheConfig("cluster");
+
+ List<RegionConfig> regions = config.getRegions();
+ assertThat(regions).isNotEmpty();
+ assertThat(regions).hasSize(1);
+
+ RegionConfig regionConfig = CacheElement.findElement(config.getRegions(), regionName);
+ assertThat(regionConfig).isNotNull();
+ assertThat(regionConfig.getName()).isEqualTo(regionName);
+ assertThat(regionConfig.getRegionAttributes())
+ .describedAs("Expecting region attributes to exist for " + regionName)
+ .hasSize(1);
+ RegionAttributesType attr = regionConfig.getRegionAttributes().get(0);
+ assertThat(attr.getEntryIdleTime().getExpirationAttributes().getCustomExpiry().toString())
+ .describedAs("Entry expiration custom expiration should be DummyCustomExpiry")
+ .isEqualTo(DummyCustomExpiry.class.getName());
+ });
+ }
+
+ @Test
+ public void createRegionPersistsImplicitTemplateAttributes() {
+ String regionName = testName.getMethodName();
+ gfsh.executeAndAssertThat("create region"
+ + " --name=" + regionName
+ + " --type=PARTITION")
+ .statusIsSuccess();
+
+ locator.invoke(() -> {
+ InternalConfigurationPersistenceService cc =
+ ClusterStartupRule.getLocator().getConfigurationPersistenceService();
+ CacheConfig config = cc.getCacheConfig("cluster");
+
+ List<RegionConfig> regions = config.getRegions();
+ assertThat(regions).isNotEmpty();
+ assertThat(regions).hasSize(1);
+
+ RegionConfig regionConfig = CacheElement.findElement(config.getRegions(), regionName);
+ assertThat(regionConfig).isNotNull();
+ assertThat(regionConfig.getName()).isEqualTo(regionName);
+ assertThat(regionConfig.getRegionAttributes())
+ .describedAs("Expecting region attributes to exist for " + regionName)
+ .hasSize(1);
+
+ RegionAttributesType attr = regionConfig.getRegionAttributes().get(0);
+ assertThat(attr.getDataPolicy())
+ .describedAs("Data policy for partitioned region should be persisted correctly")
+ .isEqualTo(RegionAttributesDataPolicy.PARTITION);
+ });
+ }
+}
diff --git a/geode-core/src/distributedTest/java/org/apache/geode/management/internal/configuration/ImportOldClusterConfigDUnitTest.java b/geode-core/src/distributedTest/java/org/apache/geode/management/internal/configuration/ImportOldClusterConfigDUnitTest.java
index 287ed83..e6974a2 100644
--- a/geode-core/src/distributedTest/java/org/apache/geode/management/internal/configuration/ImportOldClusterConfigDUnitTest.java
+++ b/geode-core/src/distributedTest/java/org/apache/geode/management/internal/configuration/ImportOldClusterConfigDUnitTest.java
@@ -62,7 +62,7 @@ public class ImportOldClusterConfigDUnitTest {
}
@Test
- public void importOldConfigThenCreateRegionCorruptsCachXml() throws Exception {
+ public void importOldConfigThenCreateRegionCorruptsCacheXml() throws Exception {
locator = lsRule.startLocatorVM(0);
gfsh.connectAndVerify(locator);
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 5ba6e53..06221fd 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
@@ -18,6 +18,8 @@ package org.apache.geode.cache;
import java.io.ObjectStreamException;
+import org.apache.geode.cache.configuration.RegionAttributesDataPolicy;
+
/**
* Enumerated type for region data policy. The data policy specifies how this local cache will
@@ -289,4 +291,9 @@ public class DataPolicy implements java.io.Serializable {
public String toString() {
return this.name;
}
+
+ public RegionAttributesDataPolicy toConfigType() {
+ String configName = this.name.toLowerCase().replace("_", "-");
+ return RegionAttributesDataPolicy.fromValue(configName);
+ }
}
diff --git a/geode-core/src/main/java/org/apache/geode/cache/EvictionAttributes.java b/geode-core/src/main/java/org/apache/geode/cache/EvictionAttributes.java
index 66a1bb7..b333b2e 100644
--- a/geode-core/src/main/java/org/apache/geode/cache/EvictionAttributes.java
+++ b/geode-core/src/main/java/org/apache/geode/cache/EvictionAttributes.java
@@ -16,6 +16,8 @@
package org.apache.geode.cache;
import org.apache.geode.DataSerializable;
+import org.apache.geode.cache.configuration.EnumActionDestroyOverflow;
+import org.apache.geode.cache.configuration.RegionAttributesType;
import org.apache.geode.cache.control.ResourceManager;
import org.apache.geode.cache.util.ObjectSizer;
import org.apache.geode.internal.cache.EvictionAttributesImpl;
@@ -505,4 +507,41 @@ public abstract class EvictionAttributes implements DataSerializable {
.setAction(evictionAction).setMaximum(maximumMegabytes).setObjectSizer(null);
}
+ public RegionAttributesType.EvictionAttributes convertToConfigEvictionAttributes() {
+ RegionAttributesType.EvictionAttributes configAttributes =
+ new RegionAttributesType.EvictionAttributes();
+ EnumActionDestroyOverflow action = EnumActionDestroyOverflow.fromValue(this.getAction()
+ .toString());
+ EvictionAlgorithm algorithm = getAlgorithm();
+ String objectSizerClass = getObjectSizer().getClass().toString();
+ Integer maximum = getMaximum();
+
+ if (algorithm.isLRUHeap()) {
+ RegionAttributesType.EvictionAttributes.LruHeapPercentage heapPercentage =
+ new RegionAttributesType.EvictionAttributes.LruHeapPercentage();
+ heapPercentage.setAction(action);
+ heapPercentage.setClassName(objectSizerClass);
+ configAttributes.setLruHeapPercentage(heapPercentage);
+ } else if (algorithm.isLRUMemory()) {
+ RegionAttributesType.EvictionAttributes.LruMemorySize memorySize =
+ new RegionAttributesType.EvictionAttributes.LruMemorySize();
+ memorySize.setAction(action);
+ memorySize.setClassName(objectSizerClass);
+ memorySize.setMaximum(maximum.toString());
+ configAttributes.setLruMemorySize(memorySize);
+ } else {
+ RegionAttributesType.EvictionAttributes.LruEntryCount entryCount =
+ new RegionAttributesType.EvictionAttributes.LruEntryCount();
+ entryCount.setAction(action);
+ entryCount.setMaximum(maximum.toString());
+ configAttributes.setLruEntryCount(entryCount);
+ }
+
+ return configAttributes;
+ }
+
+ public boolean isEmpty() {
+ return getAction() == EvictionAction.NONE && getAlgorithm() == EvictionAlgorithm.NONE;
+ }
+
}
diff --git a/geode-core/src/main/java/org/apache/geode/cache/ExpirationAction.java b/geode-core/src/main/java/org/apache/geode/cache/ExpirationAction.java
index ea7df84..0b66ddc 100644
--- a/geode-core/src/main/java/org/apache/geode/cache/ExpirationAction.java
+++ b/geode-core/src/main/java/org/apache/geode/cache/ExpirationAction.java
@@ -120,6 +120,21 @@ public class ExpirationAction implements Serializable {
return this.name;
}
+ public String toXmlString() {
+ switch (this.name) {
+ case "INVALIDATE":
+ return "invalidate";
+ case "DESTROY":
+ return "destroy";
+ case "LOCAL_DESTROY":
+ return "local-destroy";
+ case "LOCAL_INVALIDATE":
+ return "local-invalidate";
+ default:
+ return null;
+ }
+ }
+
// The 4 declarations below are necessary for serialization
private static int nextOrdinal = 0;
public final int ordinal = nextOrdinal++;
diff --git a/geode-core/src/main/java/org/apache/geode/cache/ExpirationAttributes.java b/geode-core/src/main/java/org/apache/geode/cache/ExpirationAttributes.java
index 8cf2fb0..ebd08ee 100644
--- a/geode-core/src/main/java/org/apache/geode/cache/ExpirationAttributes.java
+++ b/geode-core/src/main/java/org/apache/geode/cache/ExpirationAttributes.java
@@ -21,6 +21,7 @@ import java.io.IOException;
import org.apache.geode.DataSerializable;
import org.apache.geode.DataSerializer;
+import org.apache.geode.cache.configuration.ExpirationAttributesType;
import org.apache.geode.internal.InternalDataSerializer;
/**
@@ -149,7 +150,7 @@ public class ExpirationAttributes implements DataSerializable {
public void fromData(DataInput in) throws IOException, ClassNotFoundException {
this.timeout = in.readInt();
- this.action = (ExpirationAction) DataSerializer.readObject(in);
+ this.action = DataSerializer.readObject(in);
}
@@ -157,4 +158,17 @@ public class ExpirationAttributes implements DataSerializable {
out.writeInt(this.timeout);
DataSerializer.writeObject(this.action, out);
}
+
+ public ExpirationAttributesType toConfigType() {
+ ExpirationAttributesType t = new ExpirationAttributesType();
+ t.setTimeout(Integer.toString(this.timeout));
+ t.setAction(this.action.toXmlString());
+
+ return t;
+ }
+
+ public boolean isDefault() {
+ return (this.action == null || this.action == ExpirationAction.INVALIDATE)
+ && (this.timeout == 0);
+ }
}
diff --git a/geode-core/src/main/java/org/apache/geode/cache/PartitionAttributes.java b/geode-core/src/main/java/org/apache/geode/cache/PartitionAttributes.java
index d137fa3..2cab775 100644
--- a/geode-core/src/main/java/org/apache/geode/cache/PartitionAttributes.java
+++ b/geode-core/src/main/java/org/apache/geode/cache/PartitionAttributes.java
@@ -18,6 +18,8 @@ package org.apache.geode.cache;
import java.util.List;
import java.util.Properties;
+import org.apache.geode.cache.configuration.DeclarableType;
+import org.apache.geode.cache.configuration.RegionAttributesType;
import org.apache.geode.cache.partition.PartitionListener;
/**
@@ -153,4 +155,21 @@ public interface PartitionAttributes<K, V> {
*/
List<FixedPartitionAttributes> getFixedPartitionAttributes();
+ default RegionAttributesType.PartitionAttributes convertToConfigPartitionAttributes() {
+ RegionAttributesType.PartitionAttributes configAttributes =
+ new RegionAttributesType.PartitionAttributes();
+ configAttributes.setColocatedWith(getColocatedWith());
+ configAttributes.setLocalMaxMemory(Integer.toString(getLocalMaxMemory()));
+ if (getPartitionResolver() != null) {
+ configAttributes.setPartitionResolver(new DeclarableType(getPartitionResolver().getName()));
+ }
+ configAttributes.setRecoveryDelay(Long.toString(getRecoveryDelay()));
+ configAttributes.setStartupRecoveryDelay(Long.toString(getStartupRecoveryDelay()));
+ configAttributes.setRedundantCopies(Integer.toString(getRedundantCopies()));
+ configAttributes.setTotalMaxMemory(Long.toString(getTotalMaxMemory()));
+ configAttributes.setTotalNumBuckets(Long.toString(getTotalNumBuckets()));
+
+ return configAttributes;
+ }
+
}
diff --git a/geode-core/src/main/java/org/apache/geode/cache/configuration/RegionAttributesType.java b/geode-core/src/main/java/org/apache/geode/cache/configuration/RegionAttributesType.java
index e579879..436bd36 100644
--- a/geode-core/src/main/java/org/apache/geode/cache/configuration/RegionAttributesType.java
+++ b/geode-core/src/main/java/org/apache/geode/cache/configuration/RegionAttributesType.java
@@ -1795,6 +1795,17 @@ public class RegionAttributesType {
@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();
+ }
+
/**
* Gets the value of the lruEntryCount property.
*
diff --git a/geode-core/src/main/java/org/apache/geode/distributed/internal/InternalConfigurationPersistenceService.java b/geode-core/src/main/java/org/apache/geode/distributed/internal/InternalConfigurationPersistenceService.java
index 74aba94..c86a969 100644
--- a/geode-core/src/main/java/org/apache/geode/distributed/internal/InternalConfigurationPersistenceService.java
+++ b/geode-core/src/main/java/org/apache/geode/distributed/internal/InternalConfigurationPersistenceService.java
@@ -226,29 +226,6 @@ public class InternalConfigurationPersistenceService implements ConfigurationPer
}
/**
- * Finds xml element in a group's xml, with the tagName that has given attribute and value
- */
- public Element getXmlElement(String group, String tagName, String attribute, String value)
- throws IOException, SAXException, ParserConfigurationException {
- if (group == null) {
- group = "cluster";
- }
- Configuration config = getConfiguration(group);
- Document document = XmlUtils.createDocumentFromXml(config.getCacheXmlContent());
- NodeList elements = document.getElementsByTagName(tagName);
- if (elements == null || elements.getLength() == 0) {
- return null;
- } else {
- for (int i = 0; i < elements.getLength(); i++) {
- Element eachElement = (Element) elements.item(i);
- if (eachElement.getAttribute(attribute).equals(value))
- return eachElement;
- }
- }
- return null;
- }
-
- /**
* Adds/replaces the xml entity in the shared configuration we don't need to trigger the change
* listener for this modification, so it's ok to operate on the original configuration object
*/
diff --git a/geode-core/src/main/java/org/apache/geode/internal/config/JAXBService.java b/geode-core/src/main/java/org/apache/geode/internal/config/JAXBService.java
index 6927d2f..221e154 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/config/JAXBService.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/config/JAXBService.java
@@ -51,6 +51,7 @@ public class JAXBService {
marshaller = jaxbContext.createMarshaller();
unmarshaller = jaxbContext.createUnmarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
+ marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
String schemas = Arrays.stream(xsdRootClasses).map(c -> {
XSDRootElement element = c.getAnnotation(XSDRootElement.class);
@@ -69,7 +70,7 @@ public class JAXBService {
public void validateWith(URL url) {
SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
- Schema schema = null;
+ Schema schema;
try {
schema = factory.newSchema(url);
} catch (SAXException e) {
@@ -88,6 +89,7 @@ public class JAXBService {
public String marshall(Object object) {
StringWriter sw = new StringWriter();
try {
+ sw.write("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>");
marshaller.marshal(object, sw);
} catch (Exception e) {
throw new RuntimeException(e.getMessage(), e);
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 9c24efe..6d8175d 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
@@ -26,7 +26,6 @@ import org.apache.geode.cache.CacheWriter;
import org.apache.geode.cache.CustomExpiry;
import org.apache.geode.cache.ExpirationAction;
import org.apache.geode.distributed.DistributedMember;
-import org.apache.geode.distributed.internal.InternalConfigurationPersistenceService;
import org.apache.geode.internal.cache.InternalCache;
import org.apache.geode.management.cli.CliMetaData;
import org.apache.geode.management.cli.ConverterHint;
@@ -139,7 +138,7 @@ public class AlterRegionCommand extends InternalGfshCommand {
XmlEntity xmlEntity = findXmlEntity(regionAlterResults);
if (xmlEntity != null) {
persistClusterConfiguration(result,
- () -> ((InternalConfigurationPersistenceService) getConfigurationPersistenceService())
+ () -> getConfigurationPersistenceService()
.addXmlEntity(xmlEntity, groups));
}
return result;
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 b28569a..4686f01 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
@@ -39,9 +39,12 @@ 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.RegionConfig;
import org.apache.geode.cache.execute.ResultCollector;
import org.apache.geode.distributed.DistributedMember;
import org.apache.geode.internal.cache.InternalCache;
+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;
@@ -50,11 +53,13 @@ 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.RegionConfigFactory;
import org.apache.geode.management.internal.cli.exceptions.EntityExistsException;
import org.apache.geode.management.internal.cli.functions.CliFunctionResult;
import org.apache.geode.management.internal.cli.functions.FetchRegionAttributesFunction;
@@ -63,18 +68,18 @@ import org.apache.geode.management.internal.cli.functions.RegionCreateFunction;
import org.apache.geode.management.internal.cli.functions.RegionFunctionArgs;
import org.apache.geode.management.internal.cli.i18n.CliStrings;
import org.apache.geode.management.internal.cli.result.ResultBuilder;
+import org.apache.geode.management.internal.cli.result.model.ResultModel;
import org.apache.geode.management.internal.cli.util.RegionPath;
-import org.apache.geode.management.internal.configuration.domain.XmlEntity;
import org.apache.geode.management.internal.security.ResourceOperation;
import org.apache.geode.security.ResourcePermission;
-public class CreateRegionCommand extends InternalGfshCommand {
+public class CreateRegionCommand extends SingleGfshCommand {
@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")
@ResourceOperation(resource = ResourcePermission.Resource.DATA,
operation = ResourcePermission.Operation.MANAGE)
- public Result createRegion(
+ public ResultModel createRegion(
@CliOption(key = CliStrings.CREATE_REGION__REGION, mandatory = true,
optionContext = ConverterHint.REGION_PATH,
help = CliStrings.CREATE_REGION__REGION__HELP) String regionPath,
@@ -180,15 +185,13 @@ public class CreateRegionCommand extends InternalGfshCommand {
help = CliStrings.CREATE_REGION__VALUECONSTRAINT__HELP) String valueConstraint
// NOTICE: keep the region attributes params in alphabetical order
) {
- Result result;
-
if (regionShortcut != null && templateRegion != null) {
- return ResultBuilder.createUserErrorResult(
+ return ResultModel.createError(
CliStrings.CREATE_REGION__MSG__ONLY_ONE_OF_REGIONSHORTCUT_AND_USEATTRIBUESFROM_CAN_BE_SPECIFIED);
}
if (regionShortcut == null && templateRegion == null) {
- return ResultBuilder.createUserErrorResult(
+ return ResultModel.createError(
CliStrings.CREATE_REGION__MSG__ONE_OF_REGIONSHORTCUT_AND_USEATTRIBUTESFROM_IS_REQUIRED);
}
@@ -217,6 +220,7 @@ public class CreateRegionCommand extends InternalGfshCommand {
// we first make sure E and C have the compatible data policy
if (regionShortcut.isPartition() && !existingDataPolicy.contains("PARTITION")) {
+ LogService.getLogger().info("Create region command: got EntityExists exception");
throw new EntityExistsException("The existing region is not a partitioned region",
ifNotExists);
}
@@ -244,7 +248,7 @@ public class CreateRegionCommand extends InternalGfshCommand {
String parentRegionPath = regionPathData.getParent();
if (parentRegionPath != null && !Region.SEPARATOR.equals(parentRegionPath)) {
if (!regionExists(cache, parentRegionPath)) {
- return ResultBuilder.createUserErrorResult(
+ return ResultModel.createError(
CliStrings.format(CliStrings.CREATE_REGION__MSG__PARENT_REGION_FOR_0_DOES_NOT_EXIST,
new Object[] {regionPath}));
}
@@ -282,16 +286,17 @@ public class CreateRegionCommand extends InternalGfshCommand {
RegionAttributes<?, ?> regionAttributes = null;
if (regionShortcut != null) {
if (!regionShortcut.name().startsWith("PARTITION") && functionArgs.hasPartitionAttributes()) {
- return ResultBuilder.createUserErrorResult(CliStrings.format(
+ return ResultModel.createError(CliStrings.format(
CliStrings.CREATE_REGION__MSG__OPTION_0_CAN_BE_USED_ONLY_FOR_PARTITIONEDREGION,
functionArgs.getPartitionArgs().getUserSpecifiedPartitionAttributes()) + " "
+ CliStrings.format(CliStrings.CREATE_REGION__MSG__0_IS_NOT_A_PARITIONEDREGION,
regionPath));
}
functionArgs.setRegionShortcut(regionShortcut);
+ functionArgs.setRegionAttributes(cache.getRegionAttributes(regionShortcut.toString()));
} else { // templateRegion != null
if (!regionExists(cache, templateRegion)) {
- return ResultBuilder.createUserErrorResult(CliStrings.format(
+ return ResultModel.createError(CliStrings.format(
CliStrings.CREATE_REGION__MSG__SPECIFY_VALID_REGION_PATH_FOR_0_REGIONPATH_1_NOT_FOUND,
CliStrings.CREATE_REGION__USEATTRIBUTESFROM, templateRegion));
}
@@ -299,14 +304,14 @@ public class CreateRegionCommand extends InternalGfshCommand {
RegionAttributesWrapper<?, ?> wrappedAttributes = getRegionAttributes(cache, templateRegion);
if (wrappedAttributes == null) {
- return ResultBuilder.createGemFireErrorResult(CliStrings.format(
+ return ResultModel.createError(CliStrings.format(
CliStrings.CREATE_REGION__MSG__COULD_NOT_RETRIEVE_REGION_ATTRS_FOR_PATH_0_VERIFY_REGION_EXISTS,
templateRegion));
}
if (wrappedAttributes.getRegionAttributes().getPartitionAttributes() == null
&& functionArgs.hasPartitionAttributes()) {
- return ResultBuilder.createUserErrorResult(CliStrings.format(
+ return ResultModel.createError(CliStrings.format(
CliStrings.CREATE_REGION__MSG__OPTION_0_CAN_BE_USED_ONLY_FOR_PARTITIONEDREGION,
functionArgs.getPartitionArgs().getUserSpecifiedPartitionAttributes()) + " "
+ CliStrings.format(CliStrings.CREATE_REGION__MSG__0_IS_NOT_A_PARITIONEDREGION,
@@ -358,14 +363,14 @@ public class CreateRegionCommand extends InternalGfshCommand {
DistributedRegionMXBean distributedRegionMXBean =
mgmtService.getDistributedRegionMXBean(prColocatedWith);
if (distributedRegionMXBean == null) {
- return ResultBuilder.createUserErrorResult(CliStrings.format(
+ return ResultModel.createError(CliStrings.format(
CliStrings.CREATE_REGION__MSG__SPECIFY_VALID_REGION_PATH_FOR_0_REGIONPATH_1_NOT_FOUND,
CliStrings.CREATE_REGION__COLOCATEDWITH, prColocatedWith));
}
String regionType = distributedRegionMXBean.getRegionType();
if (!(DataPolicy.PARTITION.toString().equals(regionType)
|| DataPolicy.PERSISTENT_PARTITION.toString().equals(regionType))) {
- return ResultBuilder.createUserErrorResult(CliStrings.format(
+ return ResultModel.createError(CliStrings.format(
CliStrings.CREATE_REGION__MSG__COLOCATEDWITH_REGION_0_IS_NOT_PARTITIONEDREGION,
new Object[] {prColocatedWith}));
}
@@ -377,14 +382,14 @@ public class CreateRegionCommand extends InternalGfshCommand {
Set<String> existingGatewaySenders =
Arrays.stream(dsMBean.listGatewaySenders()).collect(Collectors.toSet());
if (existingGatewaySenders.size() == 0) {
- return ResultBuilder
- .createUserErrorResult(CliStrings.CREATE_REGION__MSG__NO_GATEWAYSENDERS_IN_THE_SYSTEM);
+ return ResultModel
+ .createError(CliStrings.CREATE_REGION__MSG__NO_GATEWAYSENDERS_IN_THE_SYSTEM);
} else {
Set<String> specifiedGatewaySenders =
Arrays.stream(gatewaySenderIds).collect(Collectors.toSet());
specifiedGatewaySenders.removeAll(existingGatewaySenders);
if (!specifiedGatewaySenders.isEmpty()) {
- return ResultBuilder.createUserErrorResult(CliStrings.format(
+ return ResultModel.createError(CliStrings.format(
CliStrings.CREATE_REGION__MSG__SPECIFY_VALID_GATEWAYSENDER_ID_UNKNOWN_0,
(Object[]) gatewaySenderIds));
}
@@ -402,11 +407,11 @@ public class CreateRegionCommand extends InternalGfshCommand {
CliStrings.CREATE_REGION__MSG__USE_ATTRIBUTES_FROM_REGION_0_IS_NOT_WITH_PERSISTENCE,
new Object[] {String.valueOf(functionArgs.getTemplateRegion())});
- return ResultBuilder.createUserErrorResult(message);
+ return ResultModel.createError(message);
}
if (!diskStoreExists(cache, diskStore)) {
- return ResultBuilder.createUserErrorResult(CliStrings.format(
+ return ResultModel.createError(CliStrings.format(
CliStrings.CREATE_REGION__MSG__SPECIFY_VALID_DISKSTORE_UNKNOWN_DISKSTORE_0,
new Object[] {diskStore}));
}
@@ -425,9 +430,9 @@ public class CreateRegionCommand extends InternalGfshCommand {
// just in case we found no members with this group name
if (membersToCreateRegionOn.isEmpty()) {
if (groups == null || groups.length == 0) {
- return ResultBuilder.createUserErrorResult(CliStrings.NO_MEMBERS_FOUND_MESSAGE);
+ return ResultModel.createError(CliStrings.NO_MEMBERS_FOUND_MESSAGE);
} else {
- return ResultBuilder.createUserErrorResult(
+ return ResultModel.createError(
CliStrings.format(CliStrings.CREATE_REGION__MSG__GROUPS_0_ARE_INVALID,
(Object[]) groups));
}
@@ -436,14 +441,70 @@ public class CreateRegionCommand extends InternalGfshCommand {
List<CliFunctionResult> regionCreateResults = executeAndGetFunctionResult(
RegionCreateFunction.INSTANCE, functionArgs, membersToCreateRegionOn);
- result = ResultBuilder.buildResult(regionCreateResults);
- XmlEntity xmlEntity = findXmlEntity(regionCreateResults);
- if (xmlEntity != null) {
+ ResultModel resultModel = ResultModel.createMemberStatusResult(regionCreateResults);
+ if (resultModel.isSuccessful()) {
verifyDistributedRegionMbean(cache, regionPath);
- persistClusterConfiguration(result,
- () -> getConfigurationPersistenceService().addXmlEntity(xmlEntity, groups));
+ RegionConfig config = (new RegionConfigFactory()).generate(functionArgs);
+ resultModel.setConfigObject(new CreateRegionResultConfig(config,
+ functionArgs.getRegionPath()));
+ }
+
+ return resultModel;
+ }
+
+ private class CreateRegionResultConfig {
+ RegionConfig getRegionConfig() {
+ return regionConfig;
+ }
+
+ String getFullRegionPath() {
+ return fullRegionPath;
+ }
+
+ private final RegionConfig regionConfig;
+ private final String fullRegionPath;
+
+ public CreateRegionResultConfig(RegionConfig regionConfig, String fullRegionPath) {
+ this.regionConfig = regionConfig;
+ this.fullRegionPath = fullRegionPath;
+ }
+ }
+
+ @Override
+ public boolean updateConfigForGroup(String group, CacheConfig config, Object configObject) {
+ if (configObject == null) {
+ return false;
+ }
+
+ CreateRegionResultConfig regionResultConfigObject = (CreateRegionResultConfig) configObject;
+ RegionConfig regionConfig = regionResultConfigObject.getRegionConfig();
+ String regionPath = regionResultConfigObject.getFullRegionPath();
+
+ RegionPath regionPathData = new RegionPath(regionPath);
+ if (regionPathData.getParent() == null) {
+ config.getRegions().add(regionConfig);
+ return true;
+ }
+
+ String[] regionsOnPath = regionPathData.getRegionsOnParentPath();
+ RegionConfig rootConfig = config.getRegions().stream()
+ .filter(r -> r.getName().equals(regionsOnPath[0]))
+ .findFirst()
+ .get();
+
+ RegionConfig currentConfig = rootConfig;
+ for (int i = 1; i < regionsOnPath.length; i++) {
+ final String curRegionName = regionsOnPath[i];
+ currentConfig = currentConfig.getRegions()
+ .stream()
+ .filter(r -> r.getName().equals(curRegionName))
+ .findFirst()
+ .get();
}
- return result;
+
+ currentConfig.getRegions().add(regionConfig);
+
+ return true;
}
boolean verifyDistributedRegionMbean(InternalCache cache, String regionName) {
@@ -655,6 +716,14 @@ public class CreateRegionCommand extends InternalGfshCommand {
.format(CliStrings.CREATE_REGION__MSG__INVALID_COMPRESSOR, new Object[] {compressor}));
}
+ Boolean cloningEnabled =
+ (Boolean) parseResult.getParamValue(CliStrings.CREATE_REGION__CLONINGENABLED);
+ if (compressor != null && cloningEnabled != null && !cloningEnabled) {
+ return ResultBuilder.createUserErrorResult(CliStrings
+ .format(CliStrings.CREATE_REGION__MSG__CANNOT_DISABLE_CLONING_WITH_COMPRESSOR,
+ new Object[] {compressor}));
+ }
+
String diskStore = parseResult.getParamValueAsString(CliStrings.CREATE_REGION__DISKSTORE);
if (diskStore != null) {
String regionShortcut =
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/domain/RegionAttributeGetFunction.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/domain/RegionAttributeGetFunction.java
new file mode 100644
index 0000000..ebee2db
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/domain/RegionAttributeGetFunction.java
@@ -0,0 +1,22 @@
+/*
+ * 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.configuration.RegionAttributesType;
+
+@FunctionalInterface
+public interface RegionAttributeGetFunction {
+ Object getValue(RegionAttributesType attributesType);
+}
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/domain/RegionAttributeSetFunction.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/domain/RegionAttributeSetFunction.java
new file mode 100644
index 0000000..051e815
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/domain/RegionAttributeSetFunction.java
@@ -0,0 +1,22 @@
+/*
+ * 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.configuration.RegionAttributesType;
+
+@FunctionalInterface
+public interface RegionAttributeSetFunction {
+ void setAttributeValue(RegionAttributesType attributesType);
+}
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
new file mode 100644
index 0000000..59a01a7
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/domain/RegionConfigFactory.java
@@ -0,0 +1,331 @@
+/*
+ * 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.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+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.ExpirationAttributesType;
+import org.apache.geode.cache.configuration.RegionAttributesType;
+import org.apache.geode.cache.configuration.RegionConfig;
+import org.apache.geode.management.internal.cli.functions.RegionFunctionArgs;
+
+public class RegionConfigFactory {
+ public RegionConfig generate(RegionFunctionArgs args) {
+ RegionConfig regionConfig = new RegionConfig();
+ regionConfig.setName(getLeafRegion(args.getRegionPath()));
+
+ RegionAttributes<?, ?> regionAttributes = args.getRegionAttributes();
+ if (args.getKeyConstraint() != null) {
+ addAttribute(regionConfig, a -> a.setKeyConstraint(args.getKeyConstraint()));
+ }
+
+ if (args.getValueConstraint() != null) {
+ addAttribute(regionConfig, a -> a.setValueConstraint(args.getValueConstraint()));
+ }
+
+ if (args.getStatisticsEnabled() != null) {
+ addAttribute(regionConfig, a -> a.setStatisticsEnabled(args.getStatisticsEnabled()));
+ } else if (regionAttributes != null) {
+ addAttribute(regionConfig, a -> a.setStatisticsEnabled(regionAttributes
+ .getStatisticsEnabled()));
+ }
+
+ if (args.getEntryExpirationIdleTime() != null) {
+ RegionAttributesType.EntryIdleTime entryIdleTime = new RegionAttributesType.EntryIdleTime();
+ entryIdleTime.setExpirationAttributes(
+ args.getEntryExpirationIdleTime().getExpirationAttributes().toConfigType());
+ addAttribute(regionConfig, a -> a.setEntryIdleTime(entryIdleTime));
+ } else if (regionAttributes != null &&
+ regionAttributes.getEntryIdleTimeout() != null &&
+ !regionAttributes.getEntryIdleTimeout().isDefault()) {
+ RegionAttributesType.EntryIdleTime entryIdleTime = new RegionAttributesType.EntryIdleTime();
+ entryIdleTime.setExpirationAttributes(regionAttributes
+ .getEntryIdleTimeout().toConfigType());
+ addAttribute(regionConfig, a -> a.setEntryIdleTime(entryIdleTime));
+ }
+
+ if (args.getEntryIdleTimeCustomExpiry() != null) {
+ Object maybeEntryIdleAttr = getRegionAttributeValue(regionConfig, a -> a.getEntryIdleTime());
+ RegionAttributesType.EntryIdleTime entryIdleTime =
+ maybeEntryIdleAttr != null ? (RegionAttributesType.EntryIdleTime) maybeEntryIdleAttr
+ : new RegionAttributesType.EntryIdleTime();
+
+ ExpirationAttributesType expirationAttributes;
+ if (entryIdleTime.getExpirationAttributes() == null) {
+ expirationAttributes = new ExpirationAttributesType();
+ expirationAttributes.setTimeout("0");
+ } else {
+ expirationAttributes = entryIdleTime.getExpirationAttributes();
+ }
+
+ DeclarableType customExpiry = new DeclarableType();
+ customExpiry.setClassName(args.getEntryIdleTimeCustomExpiry().getClassName());
+ expirationAttributes.setCustomExpiry(customExpiry);
+ entryIdleTime.setExpirationAttributes(expirationAttributes);
+
+ if (maybeEntryIdleAttr == null) {
+ addAttribute(regionConfig, a -> a.setEntryIdleTime(entryIdleTime));
+ }
+ }
+
+ if (args.getEntryExpirationTTL() != null) {
+ RegionAttributesType.EntryTimeToLive entryExpTime =
+ new RegionAttributesType.EntryTimeToLive();
+ entryExpTime.setExpirationAttributes(
+ args.getEntryExpirationTTL().getExpirationAttributes().toConfigType());
+ addAttribute(regionConfig, a -> a.setEntryTimeToLive(entryExpTime));
+ } else if (regionAttributes != null
+ && regionAttributes.getEntryTimeToLive() != null
+ && !regionAttributes.getEntryTimeToLive().isDefault()) {
+ RegionAttributesType.EntryTimeToLive entryExpTime =
+ new RegionAttributesType.EntryTimeToLive();
+ entryExpTime.setExpirationAttributes(
+ regionAttributes.getEntryTimeToLive().toConfigType());
+ addAttribute(regionConfig, a -> a.setEntryTimeToLive(entryExpTime));
+ }
+
+ if (args.getRegionExpirationIdleTime() != null) {
+ RegionAttributesType.RegionIdleTime regionIdleTime =
+ new RegionAttributesType.RegionIdleTime();
+ regionIdleTime.setExpirationAttributes(
+ args.getRegionExpirationIdleTime().getExpirationAttributes().toConfigType());
+ addAttribute(regionConfig, a -> a.setRegionIdleTime(regionIdleTime));
+ } else if (regionAttributes != null
+ && regionAttributes.getRegionIdleTimeout() != null
+ && !regionAttributes.getRegionIdleTimeout().isDefault()) {
+ RegionAttributesType.RegionIdleTime regionIdleTime =
+ new RegionAttributesType.RegionIdleTime();
+ regionIdleTime.setExpirationAttributes(
+ regionAttributes.getRegionIdleTimeout().toConfigType());
+ addAttribute(regionConfig, a -> a.setRegionIdleTime(regionIdleTime));
+ }
+
+ if (args.getRegionExpirationTTL() != null) {
+ RegionAttributesType.RegionTimeToLive regionExpTime =
+ new RegionAttributesType.RegionTimeToLive();
+ regionExpTime.setExpirationAttributes(
+ args.getRegionExpirationTTL().getExpirationAttributes().toConfigType());
+ addAttribute(regionConfig, a -> a.setRegionTimeToLive(regionExpTime));
+ } else if (regionAttributes != null
+ && regionAttributes.getRegionTimeToLive() != null
+ && !regionAttributes.getRegionTimeToLive().isDefault()) {
+ RegionAttributesType.RegionTimeToLive regionExpTime =
+ new RegionAttributesType.RegionTimeToLive();
+ regionExpTime.setExpirationAttributes(
+ regionAttributes.getRegionTimeToLive().toConfigType());
+ addAttribute(regionConfig, a -> a.setRegionTimeToLive(regionExpTime));
+ }
+
+ if (args.getEntryTTLCustomExpiry() != null) {
+ Object maybeEntryTTLAttr = getRegionAttributeValue(regionConfig, a -> a.getEntryTimeToLive());
+ RegionAttributesType.EntryTimeToLive entryTimeToLive =
+ maybeEntryTTLAttr != null ? (RegionAttributesType.EntryTimeToLive) maybeEntryTTLAttr
+ : new RegionAttributesType.EntryTimeToLive();
+
+ ExpirationAttributesType expirationAttributes;
+ if (entryTimeToLive.getExpirationAttributes() == null) {
+ expirationAttributes = new ExpirationAttributesType();
+ expirationAttributes.setTimeout("0");
+ } else {
+ expirationAttributes = entryTimeToLive.getExpirationAttributes();
+ }
+
+ DeclarableType customExpiry = new DeclarableType();
+ customExpiry.setClassName(args.getEntryTTLCustomExpiry().getClassName());
+ expirationAttributes.setCustomExpiry(customExpiry);
+ entryTimeToLive.setExpirationAttributes(expirationAttributes);
+
+ if (maybeEntryTTLAttr == null) {
+ addAttribute(regionConfig, a -> a.setEntryTimeToLive(entryTimeToLive));
+ }
+ }
+
+ if (args.getDiskStore() != null) {
+ addAttribute(regionConfig, a -> a.setDiskStoreName(args.getDiskStore()));
+ } else if (regionAttributes != null) {
+ addAttribute(regionConfig, a -> a.setDiskStoreName(regionAttributes.getDiskStoreName()));
+ }
+
+ if (args.getDiskSynchronous() != null) {
+ addAttribute(regionConfig, a -> a.setDiskSynchronous(args.getDiskSynchronous()));
+ } else if (regionAttributes != null) {
+ addAttribute(regionConfig, a -> a.setDiskSynchronous(regionAttributes.isDiskSynchronous()));
+ }
+
+ if (args.getEnableAsyncConflation() != null) {
+ addAttribute(regionConfig, a -> a.setEnableAsyncConflation(args.getEnableAsyncConflation()));
+ } else if (regionAttributes != null) {
+ addAttribute(regionConfig, a -> a.setEnableAsyncConflation(regionAttributes
+ .getEnableAsyncConflation()));
+ }
+
+ if (args.getEnableSubscriptionConflation() != null) {
+ addAttribute(regionConfig,
+ a -> a.setEnableSubscriptionConflation(args.getEnableSubscriptionConflation()));
+ } else if (regionAttributes != null) {
+ addAttribute(regionConfig, a -> a.setEnableSubscriptionConflation(regionAttributes
+ .getEnableSubscriptionConflation()));
+ }
+
+ if (args.getConcurrencyChecksEnabled() != null) {
+ addAttribute(regionConfig, a -> a.setConcurrencyChecksEnabled(
+ args.getConcurrencyChecksEnabled()));
+ } else if (regionAttributes != null) {
+ addAttribute(regionConfig, a -> a.setConcurrencyChecksEnabled(regionAttributes
+ .getConcurrencyChecksEnabled()));
+ }
+
+ if (args.getCloningEnabled() != null) {
+ addAttribute(regionConfig, a -> a.setCloningEnabled(args.getCloningEnabled()));
+ } else if (regionAttributes != null) {
+ addAttribute(regionConfig, a -> a.setCloningEnabled(regionAttributes
+ .getCloningEnabled()));
+ }
+
+ if (args.getOffHeap() != null) {
+ addAttribute(regionConfig, a -> a.setOffHeap(args.getOffHeap()));
+ } else if (regionAttributes != null) {
+ addAttribute(regionConfig, a -> a.setOffHeap(regionAttributes.getOffHeap()));
+ }
+
+ if (args.getMcastEnabled() != null) {
+ addAttribute(regionConfig, a -> a.setMulticastEnabled(args.getMcastEnabled()));
+ } else if (regionAttributes != null) {
+ addAttribute(regionConfig, a -> a.setMulticastEnabled(regionAttributes
+ .getMulticastEnabled()));
+ }
+
+ if (args.getPartitionArgs() != null) {
+ RegionAttributesType.PartitionAttributes partitionAttributes =
+ new RegionAttributesType.PartitionAttributes();
+ RegionFunctionArgs.PartitionArgs partitionArgs = args.getPartitionArgs();
+ partitionAttributes.setColocatedWith(partitionArgs.getPrColocatedWith());
+ partitionAttributes.setLocalMaxMemory(int2string(partitionArgs.getPrLocalMaxMemory()));
+ partitionAttributes.setRecoveryDelay(long2string(partitionArgs.getPrRecoveryDelay()));
+ partitionAttributes.setRedundantCopies(int2string(partitionArgs.getPrRedundantCopies()));
+ partitionAttributes
+ .setStartupRecoveryDelay(long2string(partitionArgs.getPrStartupRecoveryDelay()));
+ partitionAttributes.setTotalMaxMemory(long2string(partitionArgs.getPrTotalMaxMemory()));
+ partitionAttributes.setTotalNumBuckets(int2string(partitionArgs.getPrTotalNumBuckets()));
+
+ if (partitionArgs.getPartitionResolver() != null) {
+ DeclarableType partitionResolverType = new DeclarableType();
+ partitionResolverType.setClassName(partitionArgs.getPartitionResolver());
+ partitionAttributes.setPartitionResolver(partitionResolverType);
+ }
+
+ addAttribute(regionConfig, a -> a.setPartitionAttributes(partitionAttributes));
+ } else if (regionAttributes != null && regionAttributes.getPartitionAttributes() != null) {
+ addAttribute(regionConfig, a -> a.setPartitionAttributes(
+ regionAttributes.getPartitionAttributes().convertToConfigPartitionAttributes()));
+ }
+
+ if (args.getGatewaySenderIds() != null && !args.getGatewaySenderIds().isEmpty()) {
+ addAttribute(regionConfig, a -> a.setGatewaySenderIds(String.join(",",
+ args.getGatewaySenderIds())));
+ }
+
+ if (args.getEvictionAttributes() != null) {
+ addAttribute(regionConfig, a -> a.setEvictionAttributes(
+ args.getEvictionAttributes().convertToConfigEvictionAttributes()));
+ } else if (regionAttributes != null &&
+ regionAttributes.getEvictionAttributes() != null &&
+ !regionAttributes.getEvictionAttributes().isEmpty()) {
+ addAttribute(regionConfig, a -> a.setEvictionAttributes(
+ regionAttributes.getEvictionAttributes().convertToConfigEvictionAttributes()));
+ }
+
+ if (args.getAsyncEventQueueIds() != null && !args.getAsyncEventQueueIds().isEmpty()) {
+ addAttribute(regionConfig,
+ a -> a.setAsyncEventQueueIds(String.join(",", args.getAsyncEventQueueIds())));
+ }
+
+ if (args.getCacheListeners() != null && !args.getCacheListeners().isEmpty()) {
+ addAttribute(regionConfig, a -> a.getCacheListeners().addAll(
+ args.getCacheListeners().stream().map(l -> {
+ DeclarableType declarableType = new DeclarableType();
+ declarableType.setClassName(l.getClassName());
+ return declarableType;
+ }).collect(Collectors.toList())));
+ }
+
+ if (args.getCacheLoader() != null) {
+ DeclarableType declarableType = new DeclarableType();
+ declarableType.setClassName(args.getCacheLoader().getClassName());
+ addAttribute(regionConfig, a -> a.setCacheLoader(declarableType));
+ }
+
+ if (args.getCacheWriter() != null) {
+ DeclarableType declarableType = new DeclarableType();
+ declarableType.setClassName(args.getCacheWriter().getClassName());
+ addAttribute(regionConfig, a -> a.setCacheWriter(declarableType));
+ }
+
+ if (args.getCompressor() != null) {
+ addAttribute(regionConfig, a -> a.setCompressor(new ClassNameType(args.getCompressor())));
+ addAttribute(regionConfig, a -> a.setCloningEnabled(true));
+ }
+
+ if (args.getConcurrencyLevel() != null) {
+ addAttribute(regionConfig, a -> a.setConcurrencyLevel(args.getConcurrencyLevel().toString()));
+ } else if (regionAttributes != null) {
+ addAttribute(regionConfig, a -> a.setConcurrencyLevel(Integer.toString(
+ regionAttributes.getConcurrencyLevel())));
+ }
+
+ if (regionAttributes != null && regionAttributes.getDataPolicy() != null) {
+ addAttribute(regionConfig,
+ a -> a.setDataPolicy(regionAttributes.getDataPolicy().toConfigType()));
+ }
+
+ return regionConfig;
+ }
+
+ private String int2string(Integer i) {
+ return Optional.ofNullable(i).map(j -> j.toString()).orElse(null);
+ }
+
+ private String long2string(Long i) {
+ return Optional.ofNullable(i).map(j -> j.toString()).orElse(null);
+ }
+
+ private String getLeafRegion(String fullPath) {
+ String regionPath = fullPath;
+ String[] regions = regionPath.split("/");
+
+ return regions[regions.length - 1];
+ }
+
+ private void addAttribute(RegionConfig config, RegionAttributeSetFunction func) {
+ final List<RegionAttributesType> regionAttributes = config.getRegionAttributes();
+ if (regionAttributes.isEmpty()) {
+ regionAttributes.add(new RegionAttributesType());
+ }
+
+ func.setAttributeValue(regionAttributes.get(0));
+ }
+
+ private Object getRegionAttributeValue(RegionConfig config, RegionAttributeGetFunction function) {
+ return config.getRegionAttributes().stream()
+ .findFirst()
+ .map(a -> function.getValue(a))
+ .orElse(null);
+ }
+}
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/RegionAlterFunction.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/RegionAlterFunction.java
index fe53185..d568041 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/RegionAlterFunction.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/RegionAlterFunction.java
@@ -111,8 +111,8 @@ public class RegionAlterFunction implements InternalFunction {
AttributesMutator mutator = region.getAttributesMutator();
- if (regionAlterArgs.isCloningEnabled() != null) {
- mutator.setCloningEnabled(regionAlterArgs.isCloningEnabled());
+ if (regionAlterArgs.getCloningEnabled() != null) {
+ mutator.setCloningEnabled(regionAlterArgs.getCloningEnabled());
if (logger.isDebugEnabled()) {
logger.debug("Region successfully altered - cloning");
}
@@ -128,7 +128,7 @@ public class RegionAlterFunction implements InternalFunction {
// Alter expiration attributes
final RegionFunctionArgs.ExpirationAttrs newEntryExpirationIdleTime =
regionAlterArgs.getEntryExpirationIdleTime();
- if (newEntryExpirationIdleTime.isTimeOrActionSet()) {
+ if (newEntryExpirationIdleTime != null && newEntryExpirationIdleTime.isTimeOrActionSet()) {
mutator.setEntryIdleTimeout(
newEntryExpirationIdleTime.getExpirationAttributes(region.getEntryIdleTimeout()));
if (logger.isDebugEnabled()) {
@@ -138,7 +138,7 @@ public class RegionAlterFunction implements InternalFunction {
final RegionFunctionArgs.ExpirationAttrs newEntryExpirationTTL =
regionAlterArgs.getEntryExpirationTTL();
- if (newEntryExpirationTTL.isTimeOrActionSet()) {
+ if (newEntryExpirationTTL != null && newEntryExpirationTTL.isTimeOrActionSet()) {
mutator.setEntryTimeToLive(
newEntryExpirationTTL.getExpirationAttributes(region.getEntryTimeToLive()));
if (logger.isDebugEnabled()) {
@@ -167,7 +167,7 @@ public class RegionAlterFunction implements InternalFunction {
final RegionFunctionArgs.ExpirationAttrs newRegionExpirationIdleTime =
regionAlterArgs.getRegionExpirationIdleTime();
- if (newRegionExpirationIdleTime.isTimeOrActionSet()) {
+ if (newRegionExpirationIdleTime != null && newRegionExpirationIdleTime.isTimeOrActionSet()) {
mutator.setRegionIdleTimeout(
newRegionExpirationIdleTime.getExpirationAttributes(region.getRegionIdleTimeout()));
if (logger.isDebugEnabled()) {
@@ -177,7 +177,7 @@ public class RegionAlterFunction implements InternalFunction {
final RegionFunctionArgs.ExpirationAttrs newRegionExpirationTTL =
regionAlterArgs.getRegionExpirationTTL();
- if (newRegionExpirationTTL.isTimeOrActionSet()) {
+ if (newRegionExpirationTTL != null && newRegionExpirationTTL.isTimeOrActionSet()) {
mutator.setRegionTimeToLive(
newRegionExpirationTTL.getExpirationAttributes(region.getRegionTimeToLive()));
if (logger.isDebugEnabled()) {
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/RegionCreateFunction.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/RegionCreateFunction.java
index 26ca760..353ee30 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/RegionCreateFunction.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/RegionCreateFunction.java
@@ -16,6 +16,7 @@ package org.apache.geode.management.internal.cli.functions;
import java.util.ArrayList;
import java.util.List;
+import java.util.Optional;
import java.util.Set;
import org.apache.commons.lang3.StringUtils;
@@ -84,21 +85,22 @@ public class RegionCreateFunction implements InternalFunction {
if (regionCreateArgs.isIfNotExists()) {
Region<Object, Object> region = cache.getRegion(regionCreateArgs.getRegionPath());
if (region != null) {
- resultSender.lastResult(new CliFunctionResult(memberNameOrId, true,
- CliStrings.format(
- CliStrings.CREATE_REGION__MSG__SKIPPING_0_REGION_PATH_1_ALREADY_EXISTS,
- memberNameOrId, regionCreateArgs.getRegionPath())));
+ resultSender
+ .lastResult(new CliFunctionResult(memberNameOrId, CliFunctionResult.StatusState.OK,
+ CliStrings.format(
+ CliStrings.CREATE_REGION__MSG__SKIPPING_0_REGION_PATH_1_ALREADY_EXISTS,
+ memberNameOrId, regionCreateArgs.getRegionPath())));
return;
}
}
try {
Region<?, ?> createdRegion = createRegion(cache, regionCreateArgs);
- XmlEntity xmlEntity = getXmlEntityForRegion(createdRegion);
- resultSender.lastResult(new CliFunctionResult(memberNameOrId, xmlEntity,
- CliStrings.format(CliStrings.CREATE_REGION__MSG__REGION_0_CREATED_ON_1,
- createdRegion.getFullPath(), memberNameOrId)));
+ resultSender
+ .lastResult(new CliFunctionResult(memberNameOrId, CliFunctionResult.StatusState.OK,
+ CliStrings.format(CliStrings.CREATE_REGION__MSG__REGION_0_CREATED_ON_1,
+ createdRegion.getFullPath(), memberNameOrId)));
} catch (IllegalStateException e) {
String exceptionMsg = e.getMessage();
String localizedString =
@@ -154,18 +156,9 @@ public class RegionCreateFunction implements InternalFunction {
final RegionShortcut regionShortcut = regionCreateArgs.getRegionShortcut();
// create the region factory using the arguments
- boolean isPartitioned = false;
- RegionFactory<K, V> factory = null;
- RegionAttributes<K, V> regionAttributes = null;
- if (regionShortcut != null) {
- regionAttributes = cache.getRegionAttributes(regionShortcut.toString());
- regionCreateArgs.setRegionAttributes(regionAttributes);
- } else {
- regionAttributes = regionCreateArgs.getRegionAttributes();
- }
-
- isPartitioned = regionAttributes.getPartitionAttributes() != null;
- factory = cache.createRegionFactory(regionAttributes);
+ RegionAttributes<K, V> regionAttributes = regionCreateArgs.getRegionAttributes();
+ boolean isPartitioned = regionAttributes.getPartitionAttributes() != null;
+ RegionFactory<K, V> factory = cache.createRegionFactory(regionAttributes);
if (isPartitioned) {
PartitionAttributes<K, V> partitionAttributes =
@@ -197,7 +190,7 @@ public class RegionCreateFunction implements InternalFunction {
// Expiration attributes
final RegionFunctionArgs.ExpirationAttrs entryExpirationIdleTime =
regionCreateArgs.getEntryExpirationIdleTime();
- if (entryExpirationIdleTime.isTimeOrActionSet()) {
+ if (entryExpirationIdleTime != null && entryExpirationIdleTime.isTimeOrActionSet()) {
factory.setEntryIdleTimeout(entryExpirationIdleTime.getExpirationAttributes());
}
@@ -213,21 +206,23 @@ public class RegionCreateFunction implements InternalFunction {
final RegionFunctionArgs.ExpirationAttrs entryExpirationTTL =
regionCreateArgs.getEntryExpirationTTL();
- if (entryExpirationTTL.isTimeOrActionSet()) {
+ if (entryExpirationTTL != null && entryExpirationTTL.isTimeOrActionSet()) {
factory.setEntryTimeToLive(entryExpirationTTL.getExpirationAttributes());
}
final RegionFunctionArgs.ExpirationAttrs regionExpirationIdleTime =
regionCreateArgs.getRegionExpirationIdleTime();
- if (regionExpirationIdleTime.isTimeOrActionSet()) {
+ if (regionExpirationIdleTime != null && regionExpirationIdleTime.isTimeOrActionSet()) {
factory.setRegionIdleTimeout(regionExpirationIdleTime.getExpirationAttributes());
}
final RegionFunctionArgs.ExpirationAttrs regionExpirationTTL =
regionCreateArgs.getRegionExpirationTTL();
- if (regionExpirationTTL.isTimeOrActionSet()) {
+ if (regionExpirationTTL != null && regionExpirationTTL.isTimeOrActionSet()) {
factory.setRegionTimeToLive(regionExpirationTTL.getExpirationAttributes());
}
- EvictionAttributes evictionAttributes = regionCreateArgs.getEvictionAttributes();
+ EvictionAttributes evictionAttributes = Optional
+ .ofNullable(regionCreateArgs.getEvictionAttributes())
+ .map(a -> a.convertToEvictionAttributes()).orElse(null);
if (evictionAttributes != null) {
ObjectSizer sizer = evictionAttributes.getObjectSizer();
if (sizer != null && !(sizer instanceof Declarable)) {
@@ -243,24 +238,24 @@ public class RegionCreateFunction implements InternalFunction {
factory.setDiskStoreName(diskStore);
}
- if (regionCreateArgs.isDiskSynchronous() != null) {
- factory.setDiskSynchronous(regionCreateArgs.isDiskSynchronous());
+ if (regionCreateArgs.getDiskSynchronous() != null) {
+ factory.setDiskSynchronous(regionCreateArgs.getDiskSynchronous());
}
- if (regionCreateArgs.isOffHeap() != null) {
- factory.setOffHeap(regionCreateArgs.isOffHeap());
+ if (regionCreateArgs.getOffHeap() != null) {
+ factory.setOffHeap(regionCreateArgs.getOffHeap());
}
- if (regionCreateArgs.isStatisticsEnabled() != null) {
- factory.setStatisticsEnabled(regionCreateArgs.isStatisticsEnabled());
+ if (regionCreateArgs.getStatisticsEnabled() != null) {
+ factory.setStatisticsEnabled(regionCreateArgs.getStatisticsEnabled());
}
- if (regionCreateArgs.isEnableAsyncConflation() != null) {
- factory.setEnableAsyncConflation(regionCreateArgs.isEnableAsyncConflation());
+ if (regionCreateArgs.getEnableAsyncConflation() != null) {
+ factory.setEnableAsyncConflation(regionCreateArgs.getEnableAsyncConflation());
}
- if (regionCreateArgs.isEnableSubscriptionConflation() != null) {
- factory.setEnableSubscriptionConflation(regionCreateArgs.isEnableSubscriptionConflation());
+ if (regionCreateArgs.getEnableSubscriptionConflation() != null) {
+ factory.setEnableSubscriptionConflation(regionCreateArgs.getEnableSubscriptionConflation());
}
// Gateway Sender Ids
@@ -279,20 +274,20 @@ public class RegionCreateFunction implements InternalFunction {
}
}
- if (regionCreateArgs.isConcurrencyChecksEnabled() != null) {
- factory.setConcurrencyChecksEnabled(regionCreateArgs.isConcurrencyChecksEnabled());
+ if (regionCreateArgs.getConcurrencyChecksEnabled() != null) {
+ factory.setConcurrencyChecksEnabled(regionCreateArgs.getConcurrencyChecksEnabled());
}
if (regionCreateArgs.getConcurrencyLevel() != null) {
factory.setConcurrencyLevel(regionCreateArgs.getConcurrencyLevel());
}
- if (regionCreateArgs.isCloningEnabled() != null) {
- factory.setCloningEnabled(regionCreateArgs.isCloningEnabled());
+ if (regionCreateArgs.getCloningEnabled() != null) {
+ factory.setCloningEnabled(regionCreateArgs.getCloningEnabled());
}
- if (regionCreateArgs.isMcastEnabled() != null) {
- factory.setMulticastEnabled(regionCreateArgs.isMcastEnabled());
+ if (regionCreateArgs.getMcastEnabled() != null) {
+ factory.setMulticastEnabled(regionCreateArgs.getMcastEnabled());
}
// Set plugins
@@ -341,9 +336,8 @@ public class RegionCreateFunction implements InternalFunction {
@SuppressWarnings("unchecked")
private static <K, V> PartitionAttributes<K, V> extractPartitionAttributes(Cache cache,
RegionAttributes<K, V> regionAttributes, RegionFunctionArgs regionCreateArgs) {
- RegionFunctionArgs.PartitionArgs partitionArgs = regionCreateArgs.getPartitionArgs();
- PartitionAttributesFactory<K, V> prAttrFactory = null;
+ PartitionAttributesFactory<K, V> prAttrFactory;
PartitionAttributes<K, V> partitionAttributes = regionAttributes.getPartitionAttributes();
if (partitionAttributes != null) {
@@ -352,46 +346,49 @@ public class RegionCreateFunction implements InternalFunction {
prAttrFactory = new PartitionAttributesFactory<>();
}
- String colocatedWith = partitionArgs.getPrColocatedWith();
- if (colocatedWith != null) {
- Region<Object, Object> colocatedWithRegion = cache.getRegion(colocatedWith);
- if (colocatedWithRegion == null) {
- throw new IllegalArgumentException(CliStrings.format(
- CliStrings.CREATE_REGION__MSG__COLOCATEDWITH_REGION_0_DOES_NOT_EXIST, colocatedWith));
+ if (regionCreateArgs.hasPartitionAttributes()) {
+ RegionFunctionArgs.PartitionArgs partitionArgs = regionCreateArgs.getPartitionArgs();
+ String colocatedWith = partitionArgs.getPrColocatedWith();
+ if (colocatedWith != null) {
+ Region<Object, Object> colocatedWithRegion = cache.getRegion(colocatedWith);
+ if (colocatedWithRegion == null) {
+ throw new IllegalArgumentException(CliStrings.format(
+ CliStrings.CREATE_REGION__MSG__COLOCATEDWITH_REGION_0_DOES_NOT_EXIST, colocatedWith));
+ }
+ if (!colocatedWithRegion.getAttributes().getDataPolicy().withPartitioning()) {
+ throw new IllegalArgumentException(CliStrings.format(
+ CliStrings.CREATE_REGION__MSG__COLOCATEDWITH_REGION_0_IS_NOT_PARTITIONEDREGION,
+ colocatedWith));
+ }
+ prAttrFactory.setColocatedWith(colocatedWith);
}
- if (!colocatedWithRegion.getAttributes().getDataPolicy().withPartitioning()) {
- throw new IllegalArgumentException(CliStrings.format(
- CliStrings.CREATE_REGION__MSG__COLOCATEDWITH_REGION_0_IS_NOT_PARTITIONEDREGION,
- colocatedWith));
+ if (partitionArgs.getPrLocalMaxMemory() != null) {
+ prAttrFactory.setLocalMaxMemory(partitionArgs.getPrLocalMaxMemory());
+ }
+ if (partitionArgs.getPrTotalMaxMemory() != null) {
+ prAttrFactory.setTotalMaxMemory(partitionArgs.getPrTotalMaxMemory());
+ }
+ if (partitionArgs.getPrTotalNumBuckets() != null) {
+ prAttrFactory.setTotalNumBuckets(partitionArgs.getPrTotalNumBuckets());
+ }
+ if (partitionArgs.getPrRedundantCopies() != null) {
+ prAttrFactory.setRedundantCopies(partitionArgs.getPrRedundantCopies());
+ }
+ if (partitionArgs.getPrRecoveryDelay() != null) {
+ prAttrFactory.setRecoveryDelay(partitionArgs.getPrRecoveryDelay());
+ }
+ if (partitionArgs.getPrStartupRecoveryDelay() != null) {
+ prAttrFactory.setStartupRecoveryDelay(partitionArgs.getPrStartupRecoveryDelay());
}
- prAttrFactory.setColocatedWith(colocatedWith);
- }
- if (partitionArgs.getPrLocalMaxMemory() != null) {
- prAttrFactory.setLocalMaxMemory(partitionArgs.getPrLocalMaxMemory());
- }
- if (partitionArgs.getPrTotalMaxMemory() != null) {
- prAttrFactory.setTotalMaxMemory(partitionArgs.getPrTotalMaxMemory());
- }
- if (partitionArgs.getPrTotalNumBuckets() != null) {
- prAttrFactory.setTotalNumBuckets(partitionArgs.getPrTotalNumBuckets());
- }
- if (partitionArgs.getPrRedundantCopies() != null) {
- prAttrFactory.setRedundantCopies(partitionArgs.getPrRedundantCopies());
- }
- if (partitionArgs.getPrRecoveryDelay() != null) {
- prAttrFactory.setRecoveryDelay(partitionArgs.getPrRecoveryDelay());
- }
- if (partitionArgs.getPrStartupRecoveryDelay() != null) {
- prAttrFactory.setStartupRecoveryDelay(partitionArgs.getPrStartupRecoveryDelay());
- }
- if (regionCreateArgs.getPartitionArgs().getPartitionResolver() != null) {
- Class<PartitionResolver> partitionResolverClass =
- forName(regionCreateArgs.getPartitionArgs().getPartitionResolver(),
- CliStrings.CREATE_REGION__PARTITION_RESOLVER);
- prAttrFactory
- .setPartitionResolver((PartitionResolver<K, V>) newInstance(partitionResolverClass,
- CliStrings.CREATE_REGION__PARTITION_RESOLVER));
+ if (regionCreateArgs.getPartitionArgs().getPartitionResolver() != null) {
+ Class<PartitionResolver> partitionResolverClass =
+ forName(regionCreateArgs.getPartitionArgs().getPartitionResolver(),
+ CliStrings.CREATE_REGION__PARTITION_RESOLVER);
+ prAttrFactory
+ .setPartitionResolver((PartitionResolver<K, V>) newInstance(partitionResolverClass,
+ CliStrings.CREATE_REGION__PARTITION_RESOLVER));
+ }
}
return prAttrFactory.create();
}
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/RegionFunctionArgs.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/RegionFunctionArgs.java
index 948ba29..21d975d 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/RegionFunctionArgs.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/RegionFunctionArgs.java
@@ -33,6 +33,8 @@ import org.apache.geode.cache.ExpirationAction;
import org.apache.geode.cache.ExpirationAttributes;
import org.apache.geode.cache.RegionAttributes;
import org.apache.geode.cache.RegionShortcut;
+import org.apache.geode.cache.configuration.EnumActionDestroyOverflow;
+import org.apache.geode.cache.configuration.RegionAttributesType;
import org.apache.geode.cache.util.ObjectSizer;
import org.apache.geode.internal.ClassPathLoader;
import org.apache.geode.management.internal.cli.domain.ClassName;
@@ -80,9 +82,7 @@ public class RegionFunctionArgs implements Serializable {
private Boolean offHeap;
private RegionAttributes<?, ?> regionAttributes;
- public RegionFunctionArgs() {
- this.partitionArgs = new PartitionArgs();
- }
+ public RegionFunctionArgs() {}
public void setRegionPath(String regionPath) {
this.regionPath = regionPath;
@@ -114,18 +114,34 @@ public class RegionFunctionArgs implements Serializable {
}
public void setEntryExpirationIdleTime(Integer timeout, ExpirationAction action) {
+ if (timeout == null && action == null) {
+ return;
+ }
+
this.entryExpirationIdleTime = new ExpirationAttrs(timeout, action);
}
public void setEntryExpirationTTL(Integer timeout, ExpirationAction action) {
+ if (timeout == null && action == null) {
+ return;
+ }
+
this.entryExpirationTTL = new ExpirationAttrs(timeout, action);
}
public void setRegionExpirationIdleTime(Integer timeout, ExpirationAction action) {
+ if (timeout == null && action == null) {
+ return;
+ }
+
this.regionExpirationIdleTime = new ExpirationAttrs(timeout, action);
}
public void setRegionExpirationTTL(Integer timeout, ExpirationAction action) {
+ if (timeout == null && action == null) {
+ return;
+ }
+
this.regionExpirationTTL = new ExpirationAttrs(timeout, action);
}
@@ -199,6 +215,19 @@ public class RegionFunctionArgs implements Serializable {
public void setPartitionArgs(String prColocatedWith, Integer prLocalMaxMemory,
Long prRecoveryDelay, Integer prRedundantCopies, Long prStartupRecoveryDelay,
Long prTotalMaxMemory, Integer prTotalNumBuckets, String partitionResolver) {
+ if (prColocatedWith == null &&
+ prLocalMaxMemory == null &&
+ prRecoveryDelay == null &&
+ prRedundantCopies == null &&
+ prStartupRecoveryDelay == null &&
+ prTotalMaxMemory == null &&
+ prTotalNumBuckets == null &&
+ partitionResolver == null) {
+ return;
+ }
+ if (partitionArgs == null) {
+ partitionArgs = new PartitionArgs();
+ }
partitionArgs.setPrColocatedWith(prColocatedWith);
partitionArgs.setPrLocalMaxMemory(prLocalMaxMemory);
partitionArgs.setPrRecoveryDelay(prRecoveryDelay);
@@ -270,7 +299,7 @@ public class RegionFunctionArgs implements Serializable {
/**
* @return the statisticsEnabled
*/
- public Boolean isStatisticsEnabled() {
+ public Boolean getStatisticsEnabled() {
return this.statisticsEnabled;
}
@@ -312,25 +341,25 @@ public class RegionFunctionArgs implements Serializable {
/**
* @return the diskSynchronous
*/
- public Boolean isDiskSynchronous() {
+ public Boolean getDiskSynchronous() {
return this.diskSynchronous;
}
- public Boolean isOffHeap() {
+ public Boolean getOffHeap() {
return this.offHeap;
}
/**
* @return the enableAsyncConflation
*/
- public Boolean isEnableAsyncConflation() {
+ public Boolean getEnableAsyncConflation() {
return this.enableAsyncConflation;
}
/**
* @return the enableSubscriptionConflation
*/
- public Boolean isEnableSubscriptionConflation() {
+ public Boolean getEnableSubscriptionConflation() {
return this.enableSubscriptionConflation;
}
@@ -381,21 +410,21 @@ public class RegionFunctionArgs implements Serializable {
/**
* @return the concurrencyChecksEnabled
*/
- public Boolean isConcurrencyChecksEnabled() {
+ public Boolean getConcurrencyChecksEnabled() {
return this.concurrencyChecksEnabled;
}
/**
* @return the cloningEnabled
*/
- public Boolean isCloningEnabled() {
+ public Boolean getCloningEnabled() {
return this.cloningEnabled;
}
/**
* @return the mcastEnabled setting
*/
- public Boolean isMcastEnabled() {
+ public Boolean getMcastEnabled() {
return this.mcastEnabled;
}
@@ -415,7 +444,7 @@ public class RegionFunctionArgs implements Serializable {
* @return the partitionArgs
*/
public boolean hasPartitionAttributes() {
- return this.partitionArgs.hasPartitionAttributes();
+ return this.partitionArgs != null && this.partitionArgs.hasPartitionAttributes();
}
/**
@@ -439,8 +468,8 @@ public class RegionFunctionArgs implements Serializable {
return this.compressor;
}
- public EvictionAttributes getEvictionAttributes() {
- return evictionAttributes != null ? evictionAttributes.convertToEvictionAttributes() : null;
+ public EvictionAttrs getEvictionAttributes() {
+ return this.evictionAttributes;
}
/**
@@ -601,6 +630,35 @@ public class RegionFunctionArgs implements Serializable {
return EvictionAttributes.createLRUEntryAttributes(maxEntryCount, action);
}
}
+
+ public RegionAttributesType.EvictionAttributes convertToConfigEvictionAttributes() {
+ 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;
+ }
}
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/i18n/CliStrings.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/i18n/CliStrings.java
index a7cbd16..bd96248 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/i18n/CliStrings.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/i18n/CliStrings.java
@@ -946,6 +946,8 @@ public class CliStrings {
public static final String CREATE_REGION__TOTALNUMBUCKETS__HELP =
"Sets the total number of hash buckets to be used by the region in all processes. (Default: "
+ PartitionAttributesFactory.GLOBAL_MAX_BUCKETS_DEFAULT + ").";
+ public static final String CREATE_REGION__MSG__CANNOT_DISABLE_CLONING_WITH_COMPRESSOR =
+ "Cannot set enable-cloning to false when compressor is provided";
public static final String CREATE_REGION__MSG__SPECIFY_VALID_REGION_PATH =
"Specify a valid " + CliStrings.CREATE_REGION__REGION;
public static final String CREATE_REGION__MSG__PARENT_REGION_FOR_0_DOES_NOT_EXIST =
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/util/RegionPath.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/util/RegionPath.java
index aac49bf..3bd548b 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/util/RegionPath.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/util/RegionPath.java
@@ -14,7 +14,9 @@
*/
package org.apache.geode.management.internal.cli.util;
+import java.util.ArrayList;
import java.util.LinkedList;
+import java.util.List;
import org.apache.geode.cache.Cache;
import org.apache.geode.cache.Region;
@@ -67,6 +69,20 @@ public class RegionPath {
return regionParentPath;
}
+ public String[] getRegionsOnParentPath() {
+ String[] regionsOnPath = getParent().split(Region.SEPARATOR);
+
+ // Ignore preceding separator if there is one
+ int start = regionsOnPath[0] == null || regionsOnPath[0].isEmpty() ? 1 : 0;
+
+ List<String> regions = new ArrayList<>();
+ for (int i = start; i < regionsOnPath.length; i++) {
+ regions.add(regionsOnPath[i]);
+ }
+
+ return regions.toArray(new String[] {});
+ }
+
/**
* @return Parent RegionPath of this RegionPath. null if this is a root region
*/
diff --git a/geode-core/src/main/java/org/apache/geode/redis/internal/RegionProvider.java b/geode-core/src/main/java/org/apache/geode/redis/internal/RegionProvider.java
index 8d38c49..d3649f1 100644
--- a/geode-core/src/main/java/org/apache/geode/redis/internal/RegionProvider.java
+++ b/geode-core/src/main/java/org/apache/geode/redis/internal/RegionProvider.java
@@ -41,9 +41,9 @@ import org.apache.geode.cache.query.QueryService;
import org.apache.geode.cache.query.RegionNotFoundException;
import org.apache.geode.internal.cache.GemFireCacheImpl;
import org.apache.geode.internal.hll.HyperLogLogPlus;
-import org.apache.geode.management.cli.Result;
import org.apache.geode.management.cli.Result.Status;
import org.apache.geode.management.internal.cli.commands.CreateRegionCommand;
+import org.apache.geode.management.internal.cli.result.model.ResultModel;
import org.apache.geode.redis.GeodeRedisServer;
import org.apache.geode.redis.internal.executor.ExpirationExecutor;
import org.apache.geode.redis.internal.executor.ListQuery;
@@ -399,17 +399,19 @@ public class RegionProvider implements Closeable {
return r;
do {
createRegionCmd.setCache(cache);
- Result result = createRegionCmd.createRegion(regionPath, defaultRegionType, null, null, true,
- null, null, null, null, null, null, null, null, false, false, true, false, false, false,
- true, null, null, null, null, null, null, null, null, null, null, null, null, null, false,
- null, null, null, null, null, null, null, null, null, null, null);
+ ResultModel resultModel =
+ createRegionCmd.createRegion(regionPath, defaultRegionType, null, null, true,
+ null, null, null, null, null, null, null, null, false, false, true, false, false,
+ false,
+ true, null, null, null, null, null, null, null, null, null, null, null, null, null,
+ false,
+ null, null, null, null, null, null, null, null, null, null, null);
r = cache.getRegion(regionPath);
- if (result.getStatus() == Status.ERROR && r == null) {
+ if (resultModel.getStatus() == Status.ERROR && r == null) {
String err = "Unable to create region named \"" + regionPath + "\":\n";
- while (result.hasNextLine())
- err += result.nextLine();
- throw new RegionCreationException(err);
+ // TODO: check this
+ throw new RegionCreationException(err + resultModel.toJson());
}
} while (r == null); // The region can be null in the case that it is concurrently destroyed by
// a remote even triggered internally by Geode
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 4d68704..83ea16b 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
@@ -172,31 +172,31 @@ public class CreateRegionCommandTest {
assertThat(args.isIfNotExists()).isFalse();
assertThat(args.getKeyConstraint()).isNull();
assertThat(args.getValueConstraint()).isNull();
- assertThat(args.isStatisticsEnabled()).isNull();
+ assertThat(args.getStatisticsEnabled()).isNull();
ExpirationAttrs empty = new ExpirationAttrs(null, null);
- assertThat(args.getEntryExpirationIdleTime()).isEqualTo(empty);
- assertThat(args.getEntryExpirationTTL()).isEqualTo(empty);
- assertThat(args.getRegionExpirationIdleTime()).isEqualTo(empty);
- assertThat(args.getRegionExpirationTTL()).isEqualTo(empty);
+ assertThat(args.getEntryExpirationIdleTime()).isNull();
+ assertThat(args.getEntryExpirationTTL()).isNull();
+ assertThat(args.getRegionExpirationIdleTime()).isNull();
+ assertThat(args.getRegionExpirationTTL()).isNull();
assertThat(args.getDiskStore()).isNull();
- assertThat(args.isDiskSynchronous()).isNull();
- assertThat(args.isEnableAsyncConflation()).isNull();
- assertThat(args.isEnableSubscriptionConflation()).isNull();
+ assertThat(args.getDiskSynchronous()).isNull();
+ assertThat(args.getEnableAsyncConflation()).isNull();
+ assertThat(args.getEnableSubscriptionConflation()).isNull();
assertThat(args.getCacheListeners()).isEmpty();
assertThat(args.getCacheLoader()).isNull();
assertThat(args.getCacheWriter()).isNull();
assertThat(args.getAsyncEventQueueIds()).isEmpty();
assertThat(args.getGatewaySenderIds()).isEmpty();
- assertThat(args.isConcurrencyChecksEnabled()).isNull();
- assertThat(args.isCloningEnabled()).isNull();
- assertThat(args.isMcastEnabled()).isNull();
+ assertThat(args.getConcurrencyChecksEnabled()).isNull();
+ assertThat(args.getCloningEnabled()).isNull();
+ assertThat(args.getMcastEnabled()).isNull();
assertThat(args.getConcurrencyLevel()).isNull();
- assertThat(args.getPartitionArgs()).isNotNull();
+ assertThat(args.getPartitionArgs()).isNull();
assertThat(args.getEvictionMax()).isNull();
assertThat(args.getCompressor()).isNull();
- assertThat(args.isOffHeap()).isNull();
+ assertThat(args.getOffHeap()).isNull();
assertThat(args.getRegionAttributes()).isNull();
}
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
new file mode 100644
index 0000000..31b5bd9
--- /dev/null
+++ b/geode-core/src/test/java/org/apache/geode/management/internal/cli/domain/RegionConfigFactoryTest.java
@@ -0,0 +1,273 @@
+/*
+ * 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.List;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import org.apache.geode.cache.EvictionAction;
+import org.apache.geode.cache.ExpirationAction;
+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.RegionAttributesType;
+import org.apache.geode.cache.configuration.RegionConfig;
+import org.apache.geode.management.internal.cli.functions.RegionFunctionArgs;
+
+public class RegionConfigFactoryTest {
+
+ RegionConfigFactory subject;
+ RegionFunctionArgs args;
+
+ @Before
+ public void setup() {
+ subject = new RegionConfigFactory();
+ args = new RegionFunctionArgs();
+ args.setRegionPath("region-name");
+ }
+
+ @Test
+ public void generatesConfigForRegion() {
+ RegionConfig config = subject.generate(args);
+ assertThat(config.getName()).isEqualTo("region-name");
+ }
+
+ @Test
+ public void generatesConfigForSubRegion() {
+ args.setRegionPath("region-name/subregion");
+
+ RegionConfig config = subject.generate(args);
+ assertThat(config.getName()).isEqualTo("subregion");
+ }
+
+ @Test
+ public void generatesWithNoAttributes() {
+ RegionConfig config = subject.generate(args);
+ assertThat(config.getRegionAttributes()).isEmpty();
+ }
+
+ @Test
+ public void generatesWithConstraintAttributes() {
+ args.setKeyConstraint("key-const");
+ args.setValueConstraint("value-const");
+
+ RegionConfig config = subject.generate(args);
+ assertThat(getRegionAttributeValue(config, t -> t.getKeyConstraint())).isEqualTo("key-const");
+ assertThat(getRegionAttributeValue(config, t -> t.getValueConstraint()))
+ .isEqualTo("value-const");
+ }
+
+ @Test
+ public void generatesWithExpirationIdleTimeAttributes() {
+ args.setRegionExpirationTTL(10, ExpirationAction.DESTROY);
+ args.setRegionExpirationIdleTime(3, ExpirationAction.INVALIDATE);
+ args.setEntryExpirationTTL(1, ExpirationAction.LOCAL_DESTROY);
+ args.setEntryExpirationIdleTime(12, ExpirationAction.LOCAL_DESTROY);
+ args.setEntryIdleTimeCustomExpiry(new ClassName<>("java.lang.String"));
+
+ RegionConfig config = subject.generate(args);
+ RegionAttributesType.RegionTimeToLive regionTimeToLive =
+ (RegionAttributesType.RegionTimeToLive) getRegionAttributeValue(config,
+ t -> t.getRegionTimeToLive());
+ assertThat(regionTimeToLive.getExpirationAttributes().getTimeout()).isEqualTo("10");
+
+ RegionAttributesType.EntryTimeToLive entryTimeToLive =
+ (RegionAttributesType.EntryTimeToLive) getRegionAttributeValue(config,
+ t -> t.getEntryTimeToLive());
+ assertThat(entryTimeToLive.getExpirationAttributes().getAction())
+ .isEqualTo(ExpirationAction.LOCAL_DESTROY.toXmlString());
+
+ RegionAttributesType.EntryIdleTime entryIdleTime =
+ (RegionAttributesType.EntryIdleTime) getRegionAttributeValue(config,
+ t -> t.getEntryIdleTime());
+ DeclarableType customExpiry = entryIdleTime.getExpirationAttributes().getCustomExpiry();
+ assertThat(customExpiry.getClassName()).isEqualTo("java.lang.String");
+ assertThat(entryIdleTime.getExpirationAttributes().getAction())
+ .isEqualTo(ExpirationAction.LOCAL_DESTROY.toXmlString());
+ assertThat(entryIdleTime.getExpirationAttributes().getTimeout())
+ .isEqualTo("12");
+ }
+
+ @Test
+ public void generatesWithDiskAttributes() {
+ args.setDiskStore("disk-store");
+ args.setDiskSynchronous(false);
+
+ RegionConfig config = subject.generate(args);
+ assertThat(getRegionAttributeValue(config, t -> t.getDiskStoreName())).isEqualTo("disk-store");
+ assertThat(getRegionAttributeValue(config, t -> t.isDiskSynchronous())).isEqualTo(false);
+ }
+
+ @Test
+ public void generatesWithPrAttributes() {
+ args.setPartitionArgs("colo-with", 100,
+ 100L, 100, 100L,
+ 100L, 100, "java.lang.String");
+
+ RegionConfig config = subject.generate(args);
+ RegionAttributesType.PartitionAttributes partitionAttributes =
+ (RegionAttributesType.PartitionAttributes) getRegionAttributeValue(config,
+ t -> t.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() {
+ args.setStatisticsEnabled(false);
+ args.setEnableAsyncConflation(false);
+ args.setConcurrencyChecksEnabled(true);
+ args.setEnableSubscriptionConflation(true);
+ args.setMcastEnabled(false);
+ args.setCloningEnabled(false);
+ args.setOffHeap(true);
+ RegionConfig config = subject.generate(args);
+
+ assertThat(getRegionAttributeValue(config, t -> t.isStatisticsEnabled())).isEqualTo(false);
+ assertThat(getRegionAttributeValue(config, t -> t.isEnableSubscriptionConflation()))
+ .isEqualTo(true);
+ assertThat(getRegionAttributeValue(config, t -> t.isConcurrencyChecksEnabled()))
+ .isEqualTo(true);
+ assertThat(getRegionAttributeValue(config, t -> t.isEnableSubscriptionConflation()))
+ .isEqualTo(true);
+ assertThat(getRegionAttributeValue(config, t -> t.isMulticastEnabled()))
+ .isEqualTo(false);
+ assertThat(getRegionAttributeValue(config, t -> t.isCloningEnabled())).isEqualTo(false);
+ assertThat(getRegionAttributeValue(config, t -> t.isOffHeap())).isEqualTo(true);
+ }
+
+ @Test
+ public void generatesWithGatewayFlags() {
+ args.setGatewaySenderIds(new String[] {"some-id", "some-other-id"});
+ RegionConfig config = subject.generate(args);
+
+ assertThat((String) getRegionAttributeValue(config, t -> t.getGatewaySenderIds()))
+ .contains("some-id");
+ assertThat((String) getRegionAttributeValue(config, t -> t.getGatewaySenderIds()))
+ .contains("some-other-id");
+ }
+
+ @Test
+ public void generatesWithEvictionHeapPercentageFlags() {
+ args.setEvictionAttributes(EvictionAction.LOCAL_DESTROY.toString(), null, null,
+ "java.lang.String");
+ RegionConfig config = subject.generate(args);
+
+ RegionAttributesType.EvictionAttributes evictionAttributes =
+ (RegionAttributesType.EvictionAttributes) getRegionAttributeValue(config,
+ t -> t.getEvictionAttributes());
+ assertThat(evictionAttributes).isNotNull();
+ assertThat(evictionAttributes.getLruHeapPercentage().getAction())
+ .isSameAs(EnumActionDestroyOverflow.LOCAL_DESTROY);
+ assertThat(evictionAttributes.getLruHeapPercentage().getClassName())
+ .isEqualTo("java.lang.String");
+ }
+
+ @Test
+ public void generatesWithEvictionMaxMemory() {
+ args.setEvictionAttributes(EvictionAction.LOCAL_DESTROY.toString(), 100, null,
+ null);
+ RegionConfig config = subject.generate(args);
+
+ RegionAttributesType.EvictionAttributes evictionAttributes =
+ (RegionAttributesType.EvictionAttributes) getRegionAttributeValue(config,
+ t -> t.getEvictionAttributes());
+ assertThat(evictionAttributes).isNotNull();
+ assertThat(evictionAttributes.getLruMemorySize().getAction())
+ .isSameAs(EnumActionDestroyOverflow.LOCAL_DESTROY);
+ assertThat(evictionAttributes.getLruMemorySize().getMaximum()).isEqualTo("100");
+ }
+
+ @Test
+ public void generatesWithEvictionMaxEntry() {
+ args.setEvictionAttributes(EvictionAction.OVERFLOW_TO_DISK.toString(), null, 1,
+ null);
+ RegionConfig config = subject.generate(args);
+ RegionAttributesType.EvictionAttributes evictionAttributes =
+ (RegionAttributesType.EvictionAttributes) getRegionAttributeValue(config,
+ t -> t.getEvictionAttributes());
+ assertThat(evictionAttributes).isNotNull();
+ assertThat(evictionAttributes.getLruEntryCount().getAction())
+ .isSameAs(EnumActionDestroyOverflow.OVERFLOW_TO_DISK);
+ assertThat(evictionAttributes.getLruEntryCount().getMaximum()).isEqualTo("1");
+ }
+
+ @Test
+ public void generatesWithAsyncEventQueueIds() {
+ args.setAsyncEventQueueIds(new String[] {"id-1", "id-2"});
+ RegionConfig config = subject.generate(args);
+
+ assertThat((String) getRegionAttributeValue(config, t -> t.getAsyncEventQueueIds()))
+ .contains("id-1");
+ assertThat((String) getRegionAttributeValue(config, t -> t.getAsyncEventQueueIds()))
+ .contains("id-2");
+ }
+
+ @Test
+ public void generatesWithCacheClasses() {
+ args.setCacheListeners(new ClassName[] {new ClassName("java.lang.String")});
+ args.setCacheLoader(new ClassName("java.lang.String"));
+ args.setCacheWriter(new ClassName("java.lang.String"));
+ RegionConfig config = subject.generate(args);
+
+ List<DeclarableType> cacheListeners = config.getRegionAttributes().stream()
+ .filter(a -> !a.getCacheListeners().isEmpty())
+ .findFirst()
+ .map(a -> a.getCacheListeners())
+ .orElse(null);
+
+ assertThat(cacheListeners).isNotNull();
+ assertThat(cacheListeners.get(0).getClassName()).isEqualTo("java.lang.String");
+ assertThat(
+ ((DeclarableType) getRegionAttributeValue(config, t -> t.getCacheLoader())).getClassName())
+ .isEqualTo("java.lang.String");
+ assertThat(
+ ((DeclarableType) getRegionAttributeValue(config, t -> t.getCacheWriter())).getClassName())
+ .isEqualTo("java.lang.String");
+ }
+
+ @Test
+ public void generatesWithOtherMiscSimpleFlags() {
+ args.setCompressor("java.lang.String");
+ args.setConcurrencyLevel(1);
+
+ RegionConfig config = subject.generate(args);
+
+ assertThat(
+ ((ClassNameType) getRegionAttributeValue(config, t -> t.getCompressor())).getClassName())
+ .isEqualTo("java.lang.String");
+ assertThat(getRegionAttributeValue(config, t -> t.getConcurrencyLevel())).isEqualTo("1");
+ }
+
+ private Object getRegionAttributeValue(RegionConfig config, RegionAttributeGetFunction function) {
+ return config.getRegionAttributes().stream()
+ .findFirst()
+ .map(a -> function.getValue(a))
+ .orElse(null);
+ }
+}
diff --git a/geode-core/src/test/java/org/apache/geode/management/internal/cli/functions/RegionFunctionArgsTest.java b/geode-core/src/test/java/org/apache/geode/management/internal/cli/functions/RegionFunctionArgsTest.java
index de22efb..12d6dd5 100644
--- a/geode-core/src/test/java/org/apache/geode/management/internal/cli/functions/RegionFunctionArgsTest.java
+++ b/geode-core/src/test/java/org/apache/geode/management/internal/cli/functions/RegionFunctionArgsTest.java
@@ -37,16 +37,40 @@ public class RegionFunctionArgsTest {
@Test
public void defaultRegionFunctionArgs() throws Exception {
- assertThat(args.isDiskSynchronous()).isNull();
- assertThat(args.isCloningEnabled()).isNull();
- assertThat(args.isConcurrencyChecksEnabled()).isNull();
+ assertThat(args.getDiskSynchronous()).isNull();
+ assertThat(args.getCloningEnabled()).isNull();
+ assertThat(args.getConcurrencyChecksEnabled()).isNull();
assertThat(args.getConcurrencyLevel()).isNull();
- assertThat(args.getPartitionArgs()).isNotNull();
- assertThat(args.getPartitionArgs().hasPartitionAttributes()).isFalse();
+ assertThat(args.getPartitionArgs()).isNull();
+ assertThat(args.hasPartitionAttributes()).isFalse();
assertThat(args.getEvictionAttributes()).isNull();
}
@Test
+ public void emptyPartitionArgsShouldBeNull() throws Exception {
+ args.setPartitionArgs(null, null, null,
+ null, null, null,
+ null, null);
+ assertThat(args.getPartitionArgs()).isNull();
+ assertThat(args.hasPartitionAttributes()).isFalse();
+ }
+
+ @Test
+ public void emptyExpirationAttributesShouldBeNull() throws Exception {
+ args.setEntryExpirationIdleTime(null, null);
+ assertThat(args.getEntryExpirationIdleTime()).isNull();
+
+ args.setEntryExpirationTTL(null, null);
+ assertThat(args.getEntryExpirationTTL()).isNull();
+
+ args.setRegionExpirationIdleTime(null, null);
+ assertThat(args.getRegionExpirationIdleTime()).isNull();
+
+ args.setRegionExpirationTTL(null, null);
+ assertThat(args.getRegionExpirationTTL()).isNull();
+ }
+
+ @Test
public void defaultPartitionArgs() throws Exception {
assertThat(partitionArgs.hasPartitionAttributes()).isFalse();
@@ -64,19 +88,22 @@ public class RegionFunctionArgsTest {
assertThat(args.getEvictionAttributes()).isNull();
args.setEvictionAttributes("local-destroy", null, null, null);
- EvictionAttributes attributes = args.getEvictionAttributes();
+ EvictionAttributes attributes = args.getEvictionAttributes()
+ .convertToEvictionAttributes();
assertThat(attributes.getAlgorithm()).isEqualTo(EvictionAlgorithm.LRU_HEAP);
assertThat(attributes.getAction()).isEqualTo(EvictionAction.LOCAL_DESTROY);
assertThat(attributes.getMaximum()).isEqualTo(0);
args.setEvictionAttributes("overflow-to-disk", 1000, null, null);
- EvictionAttributes attributes1 = args.getEvictionAttributes();
+ EvictionAttributes attributes1 = args.getEvictionAttributes()
+ .convertToEvictionAttributes();
assertThat(attributes1.getAlgorithm()).isEqualTo(EvictionAlgorithm.LRU_MEMORY);
assertThat(attributes1.getAction()).isEqualTo(EvictionAction.OVERFLOW_TO_DISK);
assertThat(attributes1.getMaximum()).isEqualTo(1000);
args.setEvictionAttributes("local-destroy", null, 1000, null);
- EvictionAttributes attributes2 = args.getEvictionAttributes();
+ EvictionAttributes attributes2 = args.getEvictionAttributes()
+ .convertToEvictionAttributes();
assertThat(attributes2.getAlgorithm()).isEqualTo(EvictionAlgorithm.LRU_ENTRY);
assertThat(attributes2.getAction()).isEqualTo(EvictionAction.LOCAL_DESTROY);
assertThat(attributes2.getMaximum()).isEqualTo(1000);
@@ -85,7 +112,7 @@ public class RegionFunctionArgsTest {
@Test
public void evictionAttributesWithNullAction() throws Exception {
args.setEvictionAttributes(null, null, 1000, null);
- EvictionAttributes attributes3 = args.getEvictionAttributes();
+ RegionFunctionArgs.EvictionAttrs attributes3 = args.getEvictionAttributes();
assertThat(attributes3).isNull();
}
}
diff --git a/geode-wan/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/CreateRegionCommandDUnitTest.java b/geode-wan/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/CreateRegionCommandDUnitTest.java
index 365eb73..57d91a3 100644
--- a/geode-wan/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/CreateRegionCommandDUnitTest.java
+++ b/geode-wan/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/CreateRegionCommandDUnitTest.java
@@ -14,13 +14,17 @@
*/
package org.apache.geode.management.internal.cli.commands;
+import static org.assertj.core.api.Assertions.assertThat;
+
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;
import org.junit.rules.TestName;
+import org.apache.geode.cache.Region;
import org.apache.geode.test.dunit.IgnoredException;
import org.apache.geode.test.dunit.rules.ClusterStartupRule;
import org.apache.geode.test.dunit.rules.MemberVM;
@@ -65,9 +69,9 @@ public class CreateRegionCommandDUnitTest {
+ " --async-event-queue-id=" + asyncQueueName)
.statusIsError()
.containsOutput("server-1",
- "ERROR: Parallel Async Event Queue " + asyncQueueName
+ "Parallel Async Event Queue " + asyncQueueName
+ " can not be used with replicated region /" + regionName)
- .containsOutput("server-2", "ERROR: Parallel Async Event Queue " + asyncQueueName
+ .containsOutput("server-2", "Parallel Async Event Queue " + asyncQueueName
+ " can not be used with replicated region /" + regionName);
// The exception must be thrown early in the initialization, so the region itself shouldn't be
@@ -91,13 +95,56 @@ public class CreateRegionCommandDUnitTest {
+ " --gateway-sender-id=" + gatewaySenderName)
.statusIsError()
.containsOutput("server-1",
- "ERROR: Parallel gateway sender " + gatewaySenderName
+ "Parallel gateway sender " + gatewaySenderName
+ " can not be used with replicated region /" + regionName)
- .containsOutput("server-2", "ERROR: Parallel gateway sender " + gatewaySenderName
+ .containsOutput("server-2", "Parallel gateway sender " + gatewaySenderName
+ " can not be used with replicated region /" + regionName);
// The exception must be thrown early in the initialization, so the region itself shouldn't be
// added to the root regions.
gfsh.executeAndAssertThat("list regions").statusIsSuccess().doesNotContainOutput(regionName);
}
+
+ /**
+ * 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-6103
+ */
+ @Ignore
+ @Test
+ public void createRegionFromTemplateWithGatewaySender() throws Exception {
+ String regionName = testName.getMethodName();
+ String sender = "sender1";
+ String remoteDS = "2";
+ IgnoredException.addIgnoredException("could not get remote locator information");
+
+ gfsh.executeAndAssertThat("create gateway-sender"
+ + " --id=" + sender
+ + " --remote-distributed-system-id=" + remoteDS).statusIsSuccess();
+
+ // Give gateway sender time to get created
+ Thread.sleep(2000);
+
+ gfsh.executeAndAssertThat("create region"
+ + " --name=" + regionName
+ + " --type=REPLICATE_PERSISTENT"
+ + " --gateway-sender-id=" + sender).statusIsSuccess();
+
+ String regionNameFromTemplate = regionName + "-from-template";
+ gfsh.executeAndAssertThat("create region --name=" + regionNameFromTemplate
+ + " --template-region=" + regionName)
+ .statusIsSuccess();
+
+ server1.invoke(() -> {
+ Region region1 = ClusterStartupRule.getCache().getRegion(regionNameFromTemplate);
+ assertThat(region1.getAttributes().getGatewaySenderIds())
+ .describedAs("region1 contains gateway sender")
+ .contains(sender);
+
+ Region region2 = ClusterStartupRule.getCache().getRegion(regionNameFromTemplate);
+ assertThat(region2.getAttributes().getGatewaySenderIds())
+ .describedAs("region2 contains gateway sender")
+ .contains(sender);
+ });
+ }
}