This is an automated email from the ASF dual-hosted git repository.
jinmeiliao pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/geode.git
The following commit(s) were added to refs/heads/develop by this push:
new f286ec4 GEODE-6944: add support for *REDUNDANT* regionType (#3957)
f286ec4 is described below
commit f286ec451684b5d9047c661087a506281c587043
Author: Jinmei Liao <[email protected]>
AuthorDate: Mon Aug 26 19:01:56 2019 -0700
GEODE-6944: add support for *REDUNDANT* regionType (#3957)
Co-authored-by: Darrel Schneider <[email protected]>
---
.../configuration/converters/RegionConverter.java | 126 +++++++++++++++------
.../realizers/RegionConfigRealizer.java | 27 +----
.../validators/RegionConfigValidator.java | 16 +++
.../sanctioned-geode-management-serializables.txt | 2 +-
.../converters/RegionConverterTest.java | 78 +++++++++++--
.../mutators/RegionConfigManagerTest.java | 4 +-
.../realizers/RegionConfigRealizerTest.java | 40 +++++--
.../validators/RegionConfigValidatorTest.java | 57 ++++++++++
.../geode/cache/configuration/RegionType.java | 111 +++++++++++++++---
.../geode/management/configuration/Region.java | 26 ++++-
.../geode/management/configuration/RegionTest.java | 46 +++++++-
11 files changed, 428 insertions(+), 105 deletions(-)
diff --git
a/geode-core/src/main/java/org/apache/geode/management/internal/configuration/converters/RegionConverter.java
b/geode-core/src/main/java/org/apache/geode/management/internal/configuration/converters/RegionConverter.java
index 9bed6fd..77632af 100644
---
a/geode-core/src/main/java/org/apache/geode/management/internal/configuration/converters/RegionConverter.java
+++
b/geode-core/src/main/java/org/apache/geode/management/internal/configuration/converters/RegionConverter.java
@@ -15,6 +15,9 @@
package org.apache.geode.management.internal.configuration.converters;
+
+import java.util.Optional;
+
import org.apache.geode.cache.configuration.EnumActionDestroyOverflow;
import org.apache.geode.cache.configuration.RegionAttributesDataPolicy;
import org.apache.geode.cache.configuration.RegionAttributesScope;
@@ -28,25 +31,17 @@ public class RegionConverter extends
ConfigurationConverter<Region, RegionConfig
protected Region fromNonNullXmlObject(RegionConfig xmlObject) {
Region region = new Region();
region.setName(xmlObject.getName());
- if (xmlObject.getType() == null) {
- // older gfsh would generate the region xml without the refid/type. we
will not
- // support showing these regions in management rest api for now.
- region.setType(RegionType.UNSUPPORTED);
- } else {
- try {
- region.setType(RegionType.valueOf(xmlObject.getType()));
- } catch (IllegalArgumentException e) {
- // Management rest api will not support showing regions with "LOCAL*"
types or user defined
- // refids
- region.setType(RegionType.UNSUPPORTED);
- }
- }
RegionAttributesType regionAttributes = xmlObject.getRegionAttributes();
+ region.setType(getRegionType(xmlObject.getType(), regionAttributes));
if (regionAttributes != null) {
region.setDiskStoreName(regionAttributes.getDiskStoreName());
region.setKeyConstraint(regionAttributes.getKeyConstraint());
region.setValueConstraint(regionAttributes.getValueConstraint());
+ Optional.ofNullable(regionAttributes.getPartitionAttributes())
+ .flatMap(
+ partitionAttributes ->
Optional.ofNullable(partitionAttributes.getRedundantCopies()))
+ .ifPresent(copies ->
region.setRedundantCopies(Integer.parseInt(copies)));
}
return region;
}
@@ -65,30 +60,108 @@ public class RegionConverter extends
ConfigurationConverter<Region, RegionConfig
attributesType.setKeyConstraint(configObject.getKeyConstraint());
attributesType.setValueConstraint(configObject.getValueConstraint());
region.setRegionAttributes(attributesType);
+
+ if (configObject.getRedundantCopies() != null) {
+ RegionAttributesType.PartitionAttributes partitionAttributes =
+ new RegionAttributesType.PartitionAttributes();
+
partitionAttributes.setRedundantCopies(configObject.getRedundantCopies().toString());
+ attributesType.setPartitionAttributes(partitionAttributes);
+ }
return region;
}
+ /**
+ * Data policy to regionType is almost a 1-to-1 mapping, except in
+ * the case of DataPolicy.PARTITION, we will need to see the local max memory
+ * to determine if it's a PARTITION type or a PARTITION_PROXY type.
+ *
+ * we do our best to infer the type from the existing xml attributes. For
data
+ * policies not supported by management rest api (for example, NORMAL and
PRELOADED)
+ * it will show as UNSUPPORTED
+ */
+ public RegionType getRegionType(String refid, RegionAttributesType
regionAttributes) {
+ if (refid != null) {
+ try {
+ return RegionType.valueOf(refid);
+ } catch (Exception e) {
+ return RegionType.UNSUPPORTED;
+ }
+ }
+
+ // if refid is null, we will try to determine the type based on the region
attributes
+ if (regionAttributes == null) {
+ return RegionType.UNSUPPORTED;
+ }
+ RegionAttributesDataPolicy dataPolicy = regionAttributes.getDataPolicy();
+
+ if (dataPolicy == null) {
+ return RegionType.UNSUPPORTED;
+ }
+
+ switch (dataPolicy) {
+ case PARTITION: {
+ RegionAttributesType.PartitionAttributes partitionAttributes =
+ regionAttributes.getPartitionAttributes();
+ if (partitionAttributes != null &&
"0".equals(partitionAttributes.getLocalMaxMemory())) {
+ return RegionType.PARTITION_PROXY;
+ }
+ return RegionType.PARTITION;
+ }
+ case PERSISTENT_PARTITION: {
+ return RegionType.PARTITION_PERSISTENT;
+ }
+ case PERSISTENT_REPLICATE: {
+ return RegionType.REPLICATE_PERSISTENT;
+ }
+ case REPLICATE: {
+ return RegionType.REPLICATE;
+ }
+ case EMPTY: {
+ return RegionType.REPLICATE_PROXY;
+ }
+ }
+ return RegionType.UNSUPPORTED;
+ }
+
+
public RegionAttributesType createRegionAttributesByType(String type) {
RegionAttributesType regionAttributes = new RegionAttributesType();
switch (type) {
+ // these are supported by the management rest api
case "PARTITION": {
regionAttributes.setDataPolicy(RegionAttributesDataPolicy.PARTITION);
break;
}
+ case "PARTITION_PERSISTENT": {
+
regionAttributes.setDataPolicy(RegionAttributesDataPolicy.PERSISTENT_PARTITION);
+ break;
+ }
+ case "PARTITION_PROXY": {
+ regionAttributes.setDataPolicy(RegionAttributesDataPolicy.PARTITION);
+ regionAttributes.setLocalMaxMemory("0");
+ break;
+ }
case "REPLICATE": {
regionAttributes.setDataPolicy(RegionAttributesDataPolicy.REPLICATE);
regionAttributes.setScope(RegionAttributesScope.DISTRIBUTED_ACK);
break;
}
+ case "REPLICATE_PERSISTENT": {
+
regionAttributes.setDataPolicy(RegionAttributesDataPolicy.PERSISTENT_REPLICATE);
+ regionAttributes.setScope(RegionAttributesScope.DISTRIBUTED_ACK);
+ break;
+ }
+ case "REPLICATE_PROXY": {
+ regionAttributes.setDataPolicy(RegionAttributesDataPolicy.EMPTY);
+ regionAttributes.setScope(RegionAttributesScope.DISTRIBUTED_ACK);
+ break;
+ }
case "PARTITION_REDUNDANT": {
regionAttributes.setDataPolicy(RegionAttributesDataPolicy.PARTITION);
regionAttributes.setRedundantCopy("1");
break;
}
- case "PARTITION_PERSISTENT": {
-
regionAttributes.setDataPolicy(RegionAttributesDataPolicy.PERSISTENT_PARTITION);
- break;
- }
+
case "PARTITION_REDUNDANT_PERSISTENT": {
regionAttributes.setDataPolicy(RegionAttributesDataPolicy.PERSISTENT_PARTITION);
regionAttributes.setRedundantCopy("1");
@@ -134,19 +207,12 @@ public class RegionConverter extends
ConfigurationConverter<Region, RegionConfig
.setLruHeapPercentageEvictionAction(EnumActionDestroyOverflow.LOCAL_DESTROY);
break;
}
-
- case "REPLICATE_PERSISTENT": {
-
regionAttributes.setDataPolicy(RegionAttributesDataPolicy.PERSISTENT_REPLICATE);
- regionAttributes.setScope(RegionAttributesScope.DISTRIBUTED_ACK);
- break;
- }
case "REPLICATE_OVERFLOW": {
regionAttributes.setDataPolicy(RegionAttributesDataPolicy.REPLICATE);
regionAttributes.setScope(RegionAttributesScope.DISTRIBUTED_ACK);
regionAttributes
.setLruHeapPercentageEvictionAction(EnumActionDestroyOverflow.OVERFLOW_TO_DISK);
break;
-
}
case "REPLICATE_PERSISTENT_OVERFLOW": {
regionAttributes.setDataPolicy(RegionAttributesDataPolicy.PERSISTENT_REPLICATE);
@@ -194,22 +260,14 @@ public class RegionConverter extends
ConfigurationConverter<Region, RegionConfig
.setLruHeapPercentageEvictionAction(EnumActionDestroyOverflow.OVERFLOW_TO_DISK);
break;
}
- case "PARTITION_PROXY": {
- regionAttributes.setDataPolicy(RegionAttributesDataPolicy.PARTITION);
- regionAttributes.setLocalMaxMemory("0");
- break;
- }
+
case "PARTITION_PROXY_REDUNDANT": {
regionAttributes.setDataPolicy(RegionAttributesDataPolicy.PARTITION);
regionAttributes.setLocalMaxMemory("0");
regionAttributes.setRedundantCopy("1");
break;
}
- case "REPLICATE_PROXY": {
- regionAttributes.setDataPolicy(RegionAttributesDataPolicy.EMPTY);
- regionAttributes.setScope(RegionAttributesScope.DISTRIBUTED_ACK);
- break;
- }
+
default:
throw new IllegalArgumentException("invalid type " + type);
}
diff --git
a/geode-core/src/main/java/org/apache/geode/management/internal/configuration/realizers/RegionConfigRealizer.java
b/geode-core/src/main/java/org/apache/geode/management/internal/configuration/realizers/RegionConfigRealizer.java
index ec8b673..b946d56 100644
---
a/geode-core/src/main/java/org/apache/geode/management/internal/configuration/realizers/RegionConfigRealizer.java
+++
b/geode-core/src/main/java/org/apache/geode/management/internal/configuration/realizers/RegionConfigRealizer.java
@@ -57,9 +57,8 @@ public class RegionConfigRealizer
*/
@Override
public RealizationResult create(Region regionConfig, InternalCache cache) {
- RegionFactory factory = getRegionFactory(cache, regionConfig);
- factory.create(regionConfig.getName());
- return new RealizationResult().setMessage("Region successfully created.");
+ RegionConfig xmlConfig = converter.fromConfigObject(regionConfig);
+ return create(xmlConfig, regionConfig.getName(), cache);
}
/**
@@ -86,28 +85,6 @@ public class RegionConfigRealizer
return new RealizationResult().setMessage("Region successfully created.");
}
- RegionFactory getRegionFactory(Cache cache, Region regionConfig) {
- RegionFactory factory =
- cache.createRegionFactory(regionConfig.getType().name());
- if (regionConfig.getDiskStoreName() != null) {
- factory.setDiskStoreName(regionConfig.getDiskStoreName());
- }
- final String keyConstraint = regionConfig.getKeyConstraint();
- final String valueConstraint = regionConfig.getValueConstraint();
- if (keyConstraint != null && !keyConstraint.isEmpty()) {
- Class<Object> keyConstraintClass =
- CliUtil.forName(keyConstraint,
CliStrings.CREATE_REGION__KEYCONSTRAINT);
- factory.setKeyConstraint(keyConstraintClass);
- }
-
- if (valueConstraint != null && !valueConstraint.isEmpty()) {
- Class<Object> valueConstraintClass =
- CliUtil.forName(valueConstraint,
CliStrings.CREATE_REGION__VALUECONSTRAINT);
- factory.setValueConstraint(valueConstraintClass);
- }
- return factory;
- }
-
private RegionFactory getRegionFactory(Cache cache, RegionAttributesType
regionAttributes) {
RegionFactory factory = cache.createRegionFactory();
diff --git
a/geode-core/src/main/java/org/apache/geode/management/internal/configuration/validators/RegionConfigValidator.java
b/geode-core/src/main/java/org/apache/geode/management/internal/configuration/validators/RegionConfigValidator.java
index d16e056..32c82a9 100644
---
a/geode-core/src/main/java/org/apache/geode/management/internal/configuration/validators/RegionConfigValidator.java
+++
b/geode-core/src/main/java/org/apache/geode/management/internal/configuration/validators/RegionConfigValidator.java
@@ -62,6 +62,22 @@ public class RegionConfigValidator implements
ConfigurationValidator<Region> {
if (config.getType() == RegionType.UNSUPPORTED) {
throw new IllegalArgumentException(("Region type is unsupported."));
}
+
+ Integer redundantCopies = config.getRedundantCopies();
+ if (config.getType().withRedundant() && redundantCopies == 0) {
+ throw new IllegalArgumentException(
+ "redundantCopies cannot be 0 when the type has redundancy.");
+ }
+
+ if (redundantCopies != null && (redundantCopies < 0 || redundantCopies >
3)) {
+ throw new IllegalArgumentException(
+ "redundantCopies cannot be less than 0 or greater than 3.");
+ }
+
+ if (!config.getType().withPartition() && config.getRedundantCopies() !=
null) {
+ throw new IllegalArgumentException("redundantCopies can only be set with
PARTITION regions.");
+ }
+
RegionNameValidation.validate(config.getName());
// additional authorization
diff --git
a/geode-core/src/main/resources/org/apache/geode/internal/sanctioned-geode-management-serializables.txt
b/geode-core/src/main/resources/org/apache/geode/internal/sanctioned-geode-management-serializables.txt
index 0f63eba..14dd558 100644
---
a/geode-core/src/main/resources/org/apache/geode/internal/sanctioned-geode-management-serializables.txt
+++
b/geode-core/src/main/resources/org/apache/geode/internal/sanctioned-geode-management-serializables.txt
@@ -37,7 +37,7 @@
org/apache/geode/management/configuration/GatewayReceiver,false,endPort:java/lan
org/apache/geode/management/configuration/Index,false,expression:java/lang/String,keyIndex:java/lang/Boolean,name:java/lang/String,regionPath:java/lang/String
org/apache/geode/management/configuration/MemberConfig,false,id:java/lang/String
org/apache/geode/management/configuration/Pdx,false,diskStoreName:java/lang/String,ignoreUnreadFields:java/lang/Boolean,pdxSerializer:org/apache/geode/management/configuration/ClassName,persistent:java/lang/Boolean,readSerialized:java/lang/Boolean
-org/apache/geode/management/configuration/Region,false,diskStoreName:java/lang/String,keyConstraint:java/lang/String,name:java/lang/String,type:org/apache/geode/cache/configuration/RegionType,valueConstraint:java/lang/String
+org/apache/geode/management/configuration/Region,false,diskStoreName:java/lang/String,keyConstraint:java/lang/String,name:java/lang/String,redundantCopies:java/lang/Integer,type:org/apache/geode/cache/configuration/RegionType,valueConstraint:java/lang/String
org/apache/geode/management/runtime/CacheServerInfo,true,1,bindAddress:java/lang/String,isRunning:boolean,maxConnections:int,maxThreads:int,port:int
org/apache/geode/management/runtime/GatewayReceiverInfo,false,bindAddress:java/lang/String,connectedSenders:java/lang/String[],hostnameForSenders:java/lang/String,port:int,running:boolean,senderCount:int
org/apache/geode/management/runtime/MemberInformation,true,1,cacheServerList:java/util/List,cacheXmlFilePath:java/lang/String,clientCount:int,cpuUsage:double,groups:java/lang/String,heapUsage:long,host:java/lang/String,hostedRegions:java/util/Set,httpServiceBindAddress:java/lang/String,httpServicePort:int,id:java/lang/String,initHeapSize:long,isCoordinator:boolean,isSecured:boolean,isServer:boolean,locatorPort:int,locators:java/lang/String,logFilePath:java/lang/String,maxHeapSize:long,of
[...]
diff --git
a/geode-core/src/test/java/org/apache/geode/management/internal/configuration/converters/RegionConverterTest.java
b/geode-core/src/test/java/org/apache/geode/management/internal/configuration/converters/RegionConverterTest.java
index a43f686..2eeeaac 100644
---
a/geode-core/src/test/java/org/apache/geode/management/internal/configuration/converters/RegionConverterTest.java
+++
b/geode-core/src/test/java/org/apache/geode/management/internal/configuration/converters/RegionConverterTest.java
@@ -16,6 +16,7 @@
package org.apache.geode.management.internal.configuration.converters;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
import java.io.File;
import java.net.URL;
@@ -49,7 +50,7 @@ public class RegionConverterTest {
@Test
public void fromXmlWithNameType() throws Exception {
config.setName("test");
- config.setType("REPLICATE");
+
config.setRegionAttributes(converter.createRegionAttributesByType("REPLICATE"));
Region region = converter.fromXmlObject(config);
assertThat(region.getName()).isEqualTo("test");
@@ -59,26 +60,32 @@ public class RegionConverterTest {
@Test
public void fromXmlWithAll() throws Exception {
config.setName("test");
- config.setType("REPLICATE");
+
config.setRegionAttributes(converter.createRegionAttributesByType("PARTITION"));
- RegionAttributesType attributesType = new RegionAttributesType();
+ RegionAttributesType attributesType = config.getRegionAttributes();
attributesType.setValueConstraint("foo");
attributesType.setKeyConstraint("bar");
attributesType.setDiskStoreName("diskstore");
config.setRegionAttributes(attributesType);
+ RegionAttributesType.PartitionAttributes partitionAttributes =
+ new RegionAttributesType.PartitionAttributes();
+ partitionAttributes.setRedundantCopies("2");
+ attributesType.setPartitionAttributes(partitionAttributes);
+
Region region = converter.fromXmlObject(config);
assertThat(region.getName()).isEqualTo("test");
- assertThat(region.getType()).isEqualTo(RegionType.REPLICATE);
+ assertThat(region.getType()).isEqualTo(RegionType.PARTITION);
assertThat(region.getValueConstraint()).isEqualTo("foo");
assertThat(region.getKeyConstraint()).isEqualTo("bar");
assertThat(region.getDiskStoreName()).isEqualTo("diskstore");
+ assertThat(region.getRedundantCopies()).isEqualTo(2);
}
@Test
public void fromXmlWithLocalType() throws Exception {
config.setName("test");
- config.setType("LOCAL");
+
config.setRegionAttributes(converter.createRegionAttributesByType("LOCAL"));
assertThat(converter.fromXmlObject(config).getType()).isEqualTo(RegionType.UNSUPPORTED);
}
@@ -92,18 +99,20 @@ public class RegionConverterTest {
@Test
public void fromConfig() throws Exception {
region.setName("test");
- region.setType(RegionType.REPLICATE);
+ region.setType(RegionType.PARTITION);
region.setValueConstraint("foo");
region.setKeyConstraint("bar");
region.setDiskStoreName("diskstore");
+ region.setRedundantCopies(2);
RegionConfig config = converter.fromConfigObject(region);
assertThat(config.getName()).isEqualTo("test");
- assertThat(config.getType()).isEqualTo("REPLICATE");
+ assertThat(config.getType()).isEqualTo("PARTITION");
RegionAttributesType regionAttributes = config.getRegionAttributes();
-
assertThat(regionAttributes.getDataPolicy()).isEqualTo(RegionAttributesDataPolicy.REPLICATE);
+
assertThat(regionAttributes.getDataPolicy()).isEqualTo(RegionAttributesDataPolicy.PARTITION);
assertThat(regionAttributes.getKeyConstraint()).isEqualTo("bar");
assertThat(regionAttributes.getValueConstraint()).isEqualTo("foo");
assertThat(regionAttributes.getDiskStoreName()).isEqualTo("diskstore");
+
assertThat(regionAttributes.getPartitionAttributes().getRedundantCopies()).isEqualTo("2");
}
@Test
@@ -123,4 +132,57 @@ public class RegionConverterTest {
assertThat(config).isEqualToComparingFieldByFieldRecursively(masterRegion);
}
}
+
+ @Test
+ public void getRegionType() throws Exception {
+ assertThat(converter.getRegionType("ABC", null))
+ .isEqualTo(RegionType.UNSUPPORTED);
+
+ assertThat(converter.getRegionType("PARTITION_REDUNDANT", null))
+ .isEqualTo(RegionType.PARTITION_REDUNDANT);
+ assertThat(converter.getRegionType(null,
null)).isEqualTo(RegionType.UNSUPPORTED);
+
+ RegionAttributesType regionAttributes = new RegionAttributesType();
+ assertThat(converter.getRegionType(null,
regionAttributes)).isEqualTo(RegionType.UNSUPPORTED);
+
+ regionAttributes.setDataPolicy(RegionAttributesDataPolicy.PARTITION);
+ assertThat(converter.getRegionType(null,
regionAttributes)).isEqualTo(RegionType.PARTITION);
+
+ RegionAttributesType.PartitionAttributes pAttributes =
+ new RegionAttributesType.PartitionAttributes();
+ pAttributes.setLocalMaxMemory("20000");
+ regionAttributes.setPartitionAttributes(pAttributes);
+ assertThat(converter.getRegionType(null,
regionAttributes)).isEqualTo(RegionType.PARTITION);
+
+ pAttributes.setLocalMaxMemory("0");
+ assertThat(converter.getRegionType(null, regionAttributes))
+ .isEqualTo(RegionType.PARTITION_PROXY);
+
+
regionAttributes.setDataPolicy(RegionAttributesDataPolicy.PERSISTENT_PARTITION);
+ assertThat(converter.getRegionType(null, regionAttributes))
+ .isEqualTo(RegionType.PARTITION_PERSISTENT);
+
+ regionAttributes.setDataPolicy(RegionAttributesDataPolicy.REPLICATE);
+ assertThat(converter.getRegionType(null,
regionAttributes)).isEqualTo(RegionType.REPLICATE);
+
+
regionAttributes.setDataPolicy(RegionAttributesDataPolicy.PERSISTENT_REPLICATE);
+ assertThat(converter.getRegionType(null, regionAttributes))
+ .isEqualTo(RegionType.REPLICATE_PERSISTENT);
+
+ regionAttributes.setDataPolicy(RegionAttributesDataPolicy.EMPTY);
+ assertThat(converter.getRegionType(null, regionAttributes))
+ .isEqualTo(RegionType.REPLICATE_PROXY);
+
+ regionAttributes.setDataPolicy(RegionAttributesDataPolicy.NORMAL);
+ assertThat(converter.getRegionType(null,
regionAttributes)).isEqualTo(RegionType.UNSUPPORTED);
+
+ regionAttributes.setDataPolicy(RegionAttributesDataPolicy.PRELOADED);
+ assertThat(converter.getRegionType(null,
regionAttributes)).isEqualTo(RegionType.UNSUPPORTED);
+ }
+
+ @Test
+ public void createRegionAttributesByInvalidType() throws Exception {
+ assertThatThrownBy(() -> converter.createRegionAttributesByType("abc"))
+ .isInstanceOf(IllegalArgumentException.class);
+ }
}
diff --git
a/geode-core/src/test/java/org/apache/geode/management/internal/configuration/mutators/RegionConfigManagerTest.java
b/geode-core/src/test/java/org/apache/geode/management/internal/configuration/mutators/RegionConfigManagerTest.java
index d3ed2a1..6e56ff8 100644
---
a/geode-core/src/test/java/org/apache/geode/management/internal/configuration/mutators/RegionConfigManagerTest.java
+++
b/geode-core/src/test/java/org/apache/geode/management/internal/configuration/mutators/RegionConfigManagerTest.java
@@ -46,8 +46,8 @@ public class RegionConfigManagerTest {
@Test
public void compatibleWithSameType() throws Exception {
- config1.setType(RegionType.PARTITION_HEAP_LRU);
- config2.setType(RegionType.PARTITION_HEAP_LRU);
+ config1.setType(RegionType.PARTITION_PERSISTENT);
+ config2.setType(RegionType.PARTITION_PERSISTENT);
manager.checkCompatibility(config1, "group", config2);
}
diff --git
a/geode-core/src/test/java/org/apache/geode/management/internal/configuration/realizers/RegionConfigRealizerTest.java
b/geode-core/src/test/java/org/apache/geode/management/internal/configuration/realizers/RegionConfigRealizerTest.java
index c41f978..198f25b 100644
---
a/geode-core/src/test/java/org/apache/geode/management/internal/configuration/realizers/RegionConfigRealizerTest.java
+++
b/geode-core/src/test/java/org/apache/geode/management/internal/configuration/realizers/RegionConfigRealizerTest.java
@@ -16,8 +16,8 @@
*/
package org.apache.geode.management.internal.configuration.realizers;
+import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
@@ -25,7 +25,10 @@ import static org.powermock.api.mockito.PowerMockito.when;
import org.junit.Before;
import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.apache.geode.cache.DataPolicy;
+import org.apache.geode.cache.PartitionAttributes;
import org.apache.geode.cache.RegionFactory;
import org.apache.geode.cache.configuration.RegionType;
import org.apache.geode.internal.cache.InternalCache;
@@ -45,29 +48,28 @@ public class RegionConfigRealizerTest {
cache = mock(InternalCache.class);
validator = new RegionConfigValidator(cache);
regionFactory = mock(RegionFactory.class);
- when(cache.createRegionFactory(anyString())).thenReturn(regionFactory);
+ when(cache.createRegionFactory()).thenReturn(regionFactory);
realizer = new RegionConfigRealizer();
config = new Region();
+ config.setName("test");
}
@Test
public void createsPartitionedInCache() {
- config.setName("regionName");
config.setType(RegionType.PARTITION);
validator.validate(CacheElementOperation.CREATE, config);
realizer.create(config, cache);
- verify(cache).createRegionFactory("PARTITION");
- verify(regionFactory).create("regionName");
+ verify(regionFactory).create("test");
+ verify(regionFactory).setDataPolicy(DataPolicy.PARTITION);
}
@Test
public void createsReplicateInCache() {
- config.setName("regionName");
config.setType(RegionType.REPLICATE);
validator.validate(CacheElementOperation.CREATE, config);
realizer.create(config, cache);
- verify(cache).createRegionFactory("REPLICATE");
- verify(regionFactory).create("regionName");
+ verify(regionFactory).create("test");
+ verify(regionFactory).setDataPolicy(DataPolicy.REPLICATE);
}
@Test
@@ -77,11 +79,25 @@ public class RegionConfigRealizerTest {
config.setKeyConstraint("java.lang.String");
config.setValueConstraint("java.lang.Boolean");
- realizer.getRegionFactory(cache, config);
+ realizer.create(config, cache);
verify(regionFactory).setKeyConstraint(String.class);
verify(regionFactory).setValueConstraint(Boolean.class);
verify(regionFactory).setDiskStoreName("diskstore");
- verify(cache).createRegionFactory("REPLICATE");
+ verify(regionFactory).setDataPolicy(DataPolicy.REPLICATE);
+ }
+
+
+ @Test
+ public void createPartitionRegion() throws Exception {
+ config.setType(RegionType.PARTITION);
+ config.setRedundantCopies(2);
+
+ realizer.create(config, cache);
+ verify(regionFactory).setDataPolicy(DataPolicy.PARTITION);
+ ArgumentCaptor<PartitionAttributes> argumentCaptor =
+ ArgumentCaptor.forClass(PartitionAttributes.class);
+ verify(regionFactory).setPartitionAttributes(argumentCaptor.capture());
+ assertThat(argumentCaptor.getValue().getRedundantCopies()).isEqualTo(2);
}
@Test
@@ -91,10 +107,10 @@ public class RegionConfigRealizerTest {
config.setKeyConstraint(null);
config.setValueConstraint(null);
- realizer.getRegionFactory(cache, config);
+ realizer.create(config, cache);
verify(regionFactory, never()).setKeyConstraint(any());
verify(regionFactory, never()).setValueConstraint(any());
verify(regionFactory, never()).setDiskStoreName(any());
- verify(cache).createRegionFactory("REPLICATE");
+ verify(regionFactory).setDataPolicy(DataPolicy.REPLICATE);
}
}
diff --git
a/geode-core/src/test/java/org/apache/geode/management/internal/configuration/validators/RegionConfigValidatorTest.java
b/geode-core/src/test/java/org/apache/geode/management/internal/configuration/validators/RegionConfigValidatorTest.java
index cc4b3d0..3d0a9cd 100644
---
a/geode-core/src/test/java/org/apache/geode/management/internal/configuration/validators/RegionConfigValidatorTest.java
+++
b/geode-core/src/test/java/org/apache/geode/management/internal/configuration/validators/RegionConfigValidatorTest.java
@@ -110,4 +110,61 @@ public class RegionConfigValidatorTest {
.hasMessageContaining(
"Region type is unsupported.");
}
+
+ @Test
+ public void validateDefaultRedundancy() throws Exception {
+ config.setName("test");
+ config.setType(RegionType.PARTITION_REDUNDANT);
+ // the config without the explicit redundancy is valid
+ validator.validate(CacheElementOperation.CREATE, config);
+ }
+
+ @Test
+ public void invalidRedundancy() throws Exception {
+ config.setName("test");
+ config.setType(RegionType.PARTITION_REDUNDANT);
+ config.setRedundantCopies(0);
+ assertThatThrownBy(() -> validator.validate(CacheElementOperation.CREATE,
config)).isInstanceOf(
+ IllegalArgumentException.class)
+ .hasMessageContaining(
+ "redundantCopies cannot be 0");
+ }
+
+ @Test
+ public void invalidRedundancy1() throws Exception {
+ config.setName("test");
+ config.setRedundantCopies(0);
+ config.setType(RegionType.PARTITION_REDUNDANT);
+ assertThatThrownBy(() -> validator.validate(CacheElementOperation.CREATE,
config)).isInstanceOf(
+ IllegalArgumentException.class)
+ .hasMessageContaining(
+ "redundantCopies cannot be 0");
+
+ config.setRedundantCopies(-1);
+ config.setType(RegionType.PARTITION_REDUNDANT);
+ assertThatThrownBy(() -> validator.validate(CacheElementOperation.CREATE,
config)).isInstanceOf(
+ IllegalArgumentException.class)
+ .hasMessageContaining(
+ "redundantCopies cannot be less than 0 or greater than 3.");
+
+ config.setRedundantCopies(4);
+ config.setType(RegionType.PARTITION_REDUNDANT);
+ assertThatThrownBy(() -> validator.validate(CacheElementOperation.CREATE,
config)).isInstanceOf(
+ IllegalArgumentException.class)
+ .hasMessageContaining(
+ "redundantCopies cannot be less than 0 or greater than 3.");
+
+ }
+
+ @Test
+ public void replicateWithRedundancy() throws Exception {
+ config.setName("test");
+ config.setType(RegionType.REPLICATE);
+ config.setRedundantCopies(2);
+
+ assertThatThrownBy(() -> validator.validate(CacheElementOperation.CREATE,
config)).isInstanceOf(
+ IllegalArgumentException.class)
+ .hasMessageContaining(
+ "redundantCopies can only be set with PARTITION regions.");
+ }
}
diff --git
a/geode-management/src/main/java/org/apache/geode/cache/configuration/RegionType.java
b/geode-management/src/main/java/org/apache/geode/cache/configuration/RegionType.java
index 39d58b8..5df4348 100644
---
a/geode-management/src/main/java/org/apache/geode/cache/configuration/RegionType.java
+++
b/geode-management/src/main/java/org/apache/geode/cache/configuration/RegionType.java
@@ -18,34 +18,111 @@ package org.apache.geode.cache.configuration;
import org.apache.geode.annotations.Experimental;
/**
- * these are the region types supported by Cluster Management V2 API. The
attributes of these
- * region types are the same as their namesakes in RegionShortcut
+ * these are the region types supported by Cluster Management V2 API.
+ * these corresponds to a subset of data policies
*/
@Experimental
public enum RegionType {
PARTITION,
- PARTITION_REDUNDANT,
PARTITION_PERSISTENT,
- PARTITION_REDUNDANT_PERSISTENT,
- PARTITION_OVERFLOW,
- PARTITION_REDUNDANT_OVERFLOW,
- PARTITION_PERSISTENT_OVERFLOW,
- PARTITION_REDUNDANT_PERSISTENT_OVERFLOW,
- PARTITION_HEAP_LRU,
- PARTITION_REDUNDANT_HEAP_LRU,
-
PARTITION_PROXY,
- PARTITION_PROXY_REDUNDANT,
REPLICATE,
REPLICATE_PERSISTENT,
- REPLICATE_OVERFLOW,
- REPLICATE_PERSISTENT_OVERFLOW,
- REPLICATE_HEAP_LRU,
-
REPLICATE_PROXY,
// this is used to represent regions not supported by the management V2 API.
For example Gfsh can
// create regions with "LOCAL*" types
- UNSUPPORTED;
+ UNSUPPORTED,
+
+ /**
+ * @deprecated use PARTITION and set the redundancy level to 1
+ */
+ @Deprecated
+ PARTITION_REDUNDANT,
+ /**
+ * @deprecated use PARTITION_PERSISTENT and set the redundancy level to 1
+ */
+ @Deprecated
+ PARTITION_REDUNDANT_PERSISTENT,
+ /**
+ * @deprecated use PARTITION and set the evictionAction to OVERFLOW_TO_DISK
+ */
+ // PARTITION_OVERFLOW,
+ /**
+ * @deprecated use PARTITION and set the redundancy level to 1, and set the
evictionAction to
+ * OVERFLOW_TO_DISK
+ */
+
+ // PARTITION_REDUNDANT_OVERFLOW,
+ /**
+ * @deprecated use PARTITION_PERSISTENT and set the evictionAction to
OVERFLOW_TO_DISK
+ */
+ // PARTITION_PERSISTENT_OVERFLOW,
+ /**
+ * @deprecated use PARTITION_PERSISTENT and set the redundancy level to 1
and set the
+ * evictionAction to OVERFLOW_TO_DISK
+ */
+ // PARTITION_REDUNDANT_PERSISTENT_OVERFLOW,
+ /**
+ * @deprecated use PARTITION and set the evictionAction to LOCAL_DESTROY
+ */
+ // PARTITION_HEAP_LRU,
+ /**
+ * @deprecated use PARTITION and set the redundancy level to 1 and set the
evictionAction to
+ * LOCAL_DESTROY
+ */
+ // PARTITION_REDUNDANT_HEAP_LRU,
+ /**
+ * @deprecated use PARTITION_PROXY and set the redundancy level to 1
+ */
+ @Deprecated
+ PARTITION_PROXY_REDUNDANT;
+ /**
+ * @deprecated use REPLICATE and set the evictionAction to OVERFLOW_TO_DISK
+ */
+ // REPLICATE_OVERFLOW,
+ /**
+ * @deprecated use REPLICATE_PERSISTENT and set the evictionAction to
OVERFLOW_TO_DISK
+ */
+ // REPLICATE_PERSISTENT_OVERFLOW,
+ /**
+ * @deprecated use REPLICATE and set the evictionAction to LOCAL_DESTROY
+ */
+ // REPLICATE_HEAP_LRU;
+
+ /**
+ * @return if the type contains "PROXY"
+ */
+ public boolean withProxy() {
+ return name().contains("PROXY");
+ }
+
+ /**
+ * @return if the type contains "PERSISTENT"
+ */
+ public boolean withPersistent() {
+ return name().contains("PERSISTENT");
+ }
+
+ /**
+ * @return if the type contains "REPLICATE"
+ */
+ public boolean withReplicate() {
+ return name().contains("REPLICATE");
+ }
+
+ /**
+ * @return if the type contains "PARTITION"
+ */
+ public boolean withPartition() {
+ return name().contains("PARTITION");
+ }
+
+ /**
+ * @return if the type contains "REDUNDANT"
+ */
+ public boolean withRedundant() {
+ return name().contains("REDUNDANT");
+ }
}
diff --git
a/geode-management/src/main/java/org/apache/geode/management/configuration/Region.java
b/geode-management/src/main/java/org/apache/geode/management/configuration/Region.java
index 87920de..c5da2cd 100644
---
a/geode-management/src/main/java/org/apache/geode/management/configuration/Region.java
+++
b/geode-management/src/main/java/org/apache/geode/management/configuration/Region.java
@@ -25,6 +25,12 @@ import org.apache.geode.management.api.CorrespondWith;
import org.apache.geode.management.api.RestfulEndpoint;
import org.apache.geode.management.runtime.RuntimeRegionInfo;
+/**
+ * this holds the region attributes you can configure using management rest api
+ *
+ * for regions created using gfsh but listed using management rest api, the
attributes not supported
+ * by management rest api won't be shown.
+ */
public class Region extends CacheElement implements RestfulEndpoint,
CorrespondWith<RuntimeRegionInfo> {
public static final String REGION_CONFIG_ENDPOINT = "/regions";
@@ -35,14 +41,10 @@ public class Region extends CacheElement implements
RestfulEndpoint,
private String keyConstraint;
private String valueConstraint;
private String diskStoreName;
+ private Integer redundantCopies;
public Region() {}
- public Region(String name, RegionType type) {
- this.name = name;
- this.type = type;
- }
-
@Override
public boolean isGlobalRuntime() {
return true;
@@ -89,6 +91,20 @@ public class Region extends CacheElement implements
RestfulEndpoint,
this.type = type;
}
+ /**
+ * @return the redundant copies of a region
+ */
+ public Integer getRedundantCopies() {
+ if (type != null && type.withRedundant() && redundantCopies == null) {
+ return 1;
+ }
+ return redundantCopies;
+ }
+
+ public void setRedundantCopies(Integer redundantCopies) {
+ this.redundantCopies = redundantCopies;
+ }
+
public String getKeyConstraint() {
return keyConstraint;
}
diff --git
a/geode-management/src/test/java/org/apache/geode/management/configuration/RegionTest.java
b/geode-management/src/test/java/org/apache/geode/management/configuration/RegionTest.java
index 9215bbd..6e35fe1 100644
---
a/geode-management/src/test/java/org/apache/geode/management/configuration/RegionTest.java
+++
b/geode-management/src/test/java/org/apache/geode/management/configuration/RegionTest.java
@@ -30,6 +30,7 @@ import org.apache.geode.util.internal.GeodeJsonMapper;
public class RegionTest {
private Region regionConfig;
+ private static ObjectMapper mapper = GeodeJsonMapper.getMapper();
@Before
public void before() throws Exception {
@@ -54,7 +55,6 @@ public class RegionTest {
@Test
public void correctJson() throws Exception {
String json = "{\"name\":\"test\", \"type\":\"REPLICATE\"}";
- ObjectMapper mapper = GeodeJsonMapper.getMapper();
regionConfig = mapper.readValue(json, Region.class);
assertThat(regionConfig.getName()).isEqualTo("test");
assertThat(regionConfig.getType()).isEqualTo(RegionType.REPLICATE);
@@ -79,4 +79,48 @@ public class RegionTest {
assertThat(regionConfig.hasRuntimeInfo()).isTrue();
}
+ @Test
+ public void parseJsonWithDeprecatedType() throws Exception {
+ String json = "{\"name\":\"test\",
\"type\":\"PARTITION_REDUNDANT_PERSISTENT\"}";
+ regionConfig = mapper.readValue(json, Region.class);
+ assertThat(regionConfig.getName()).isEqualTo("test");
+ assertThat(regionConfig.getRedundantCopies()).isEqualTo(1);
+
assertThat(regionConfig.getType()).isEqualTo(RegionType.PARTITION_REDUNDANT_PERSISTENT);
+
+ String resultJson = mapper.writeValueAsString(regionConfig);
+
assertThat(resultJson).contains("\"type\":\"PARTITION_REDUNDANT_PERSISTENT\"")
+ .contains("\"redundantCopies\":1");
+
+ Region resultRegion = mapper.readValue(resultJson, Region.class);
+ assertThat(regionConfig.getName()).isEqualTo(resultRegion.getName());
+ assertThat(regionConfig.getType()).isEqualTo(resultRegion.getType());
+
assertThat(regionConfig.getRedundantCopies()).isEqualTo(resultRegion.getRedundantCopies());
+ }
+
+ @Test
+ public void parseWithShortcutAndOtherOverridingAttributes() throws Exception
{
+ String json =
+ "{\"name\":\"test\", \"redundantCopies\":0,
\"type\":\"PARTITION_REDUNDANT_PERSISTENT\"}";
+ regionConfig = mapper.readValue(json, Region.class);
+ assertThat(regionConfig.getName()).isEqualTo("test");
+ assertThat(regionConfig.getRedundantCopies()).isEqualTo(0);
+
assertThat(regionConfig.getType()).isEqualTo(RegionType.PARTITION_REDUNDANT_PERSISTENT);
+ }
+
+ @Test
+ public void redundancySetter() throws Exception {
+ regionConfig.setType(RegionType.PARTITION_REDUNDANT);
+ regionConfig.setRedundantCopies(3);
+ assertThat(regionConfig.getRedundantCopies()).isEqualTo(3);
+ }
+
+ @Test
+ public void redundant() throws Exception {
+ regionConfig.setType(RegionType.PARTITION_REDUNDANT);
+ assertThat(regionConfig.getRedundantCopies()).isEqualTo(1);
+
+ regionConfig.setType(RegionType.PARTITION);
+ assertThat(regionConfig.getRedundantCopies()).isNull();
+ }
+
}