You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by ji...@apache.org on 2019/04/18 18:15:15 UTC
[geode] branch develop updated: GEODE-6612: add entry count for
list Region and rework filtering by groups (#3465)
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 6a177ec GEODE-6612: add entry count for list Region and rework filtering by groups (#3465)
6a177ec is described below
commit 6a177ecfebc443affda84bea33f3c6cfa26f7c00
Author: jinmeiliao <ji...@pivotal.io>
AuthorDate: Thu Apr 18 11:15:04 2019 -0700
GEODE-6612: add entry count for list Region and rework filtering by groups (#3465)
Co-authored-by: Owen Nichols <on...@pivotal.io>
Co-authored-by: Jens Deppe jdeppe@pivotal.io
* Create a RuntimeCacheElement interface to hold multiple groups
* Using RegionConfig can only set/get one group
---
.../rest/ListRegionManagementDunitTest.java | 140 +++++++++++++++++----
.../integrationTest/resources/assembly_content.txt | 2 +
.../RegionConfigMutatorIntegrationTest.java | 2 +-
.../api/LocatorClusterManagementService.java | 77 ++++++++----
.../mutators/ConfigurationManager.java | 3 +-
.../mutators/RegionConfigManager.java | 39 +++++-
.../validators/CacheElementValidator.java | 37 ++++++
.../validators/RegionConfigValidator.java | 5 -
.../api/LocatorClusterManagementServiceTest.java | 111 +++++++++++-----
.../validators/CacheElementValidatorTest.java} | 32 ++---
.../validators/RegionConfigValidatorTest.java | 9 --
.../assertions/ClusterManagementResultAssert.java | 4 +-
.../geode/cache/configuration/CacheElement.java | 40 ++++--
.../geode/cache/configuration/RegionConfig.java | 24 ++++
.../management/api/ClusterManagementResult.java | 8 +-
.../management/configuration/MemberConfig.java | 6 +-
.../configuration/RuntimeCacheElement.java | 36 ++++++
.../configuration/RuntimeRegionConfig.java | 45 +++++++
.../configuration/CacheElementJsonMappingTest.java | 54 +++++++-
.../cache/configuration/CacheElementTest.java | 102 +++++++++++++++
.../ClientClusterManagementServiceDUnitTest.java | 15 +--
.../rest/RegionManagementIntegrationTest.java | 13 ++
22 files changed, 656 insertions(+), 148 deletions(-)
diff --git a/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/rest/ListRegionManagementDunitTest.java b/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/rest/ListRegionManagementDunitTest.java
index 6dd1135..b0bca71 100644
--- a/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/rest/ListRegionManagementDunitTest.java
+++ b/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/rest/ListRegionManagementDunitTest.java
@@ -15,6 +15,7 @@
package org.apache.geode.management.internal.rest;
+import static org.apache.geode.test.awaitility.GeodeAwaitility.await;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.List;
@@ -25,10 +26,14 @@ import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Test;
+import org.apache.geode.cache.Region;
import org.apache.geode.cache.configuration.CacheElement;
import org.apache.geode.cache.configuration.RegionConfig;
+import org.apache.geode.cache.configuration.RegionType;
import org.apache.geode.management.api.ClusterManagementService;
import org.apache.geode.management.client.ClusterManagementServiceProvider;
+import org.apache.geode.management.configuration.RuntimeCacheElement;
+import org.apache.geode.management.configuration.RuntimeRegionConfig;
import org.apache.geode.test.dunit.rules.ClusterStartupRule;
import org.apache.geode.test.dunit.rules.MemberVM;
import org.apache.geode.test.junit.rules.GfshCommandRule;
@@ -61,15 +66,34 @@ public class ListRegionManagementDunitTest {
regionConfig.setName("customers1");
regionConfig.setGroup("group1");
client.create(regionConfig);
+ locator.waitUntilRegionIsReadyOnExactlyThisManyServers("/customers1", 1);
+
+ // create a region that has different type on different group
+ regionConfig = new RegionConfig();
+ regionConfig.setName("customers2");
+ regionConfig.setGroup("group1");
+ regionConfig.setType(RegionType.PARTITION_PROXY);
+ client.create(regionConfig);
regionConfig = new RegionConfig();
regionConfig.setName("customers2");
regionConfig.setGroup("group2");
client.create(regionConfig);
+ locator.waitUntilRegionIsReadyOnExactlyThisManyServers("/customers2", 2);
regionConfig = new RegionConfig();
regionConfig.setName("customers");
client.create(regionConfig);
+ locator.waitUntilRegionIsReadyOnExactlyThisManyServers("/customers", 2);
+
+ // create a region that belongs to multiple groups
+ regionConfig = new RegionConfig();
+ regionConfig.setName("customers3");
+ regionConfig.setGroup("group1");
+ client.create(regionConfig);
+ regionConfig.setGroup("group2");
+ client.create(regionConfig);
+ locator.waitUntilRegionIsReadyOnExactlyThisManyServers("/customers3", 2);
}
@Before
@@ -80,69 +104,141 @@ public class ListRegionManagementDunitTest {
@Test
public void listAll() throws Exception {
// list all
- List<CacheElement> regions = client.list(filter).getResult();
- assertThat(regions.stream().map(CacheElement::getId).collect(Collectors.toList()))
- .containsExactlyInAnyOrder("customers", "customers1", "customers2");
- assertThat(regions.stream().map(CacheElement::getConfigGroup).collect(Collectors.toList()))
- .containsExactlyInAnyOrder("cluster", "group1", "group2");
+ List<RuntimeCacheElement> regions = client.list(filter).getResult();
+ assertThat(regions).hasSize(5);
+ RuntimeCacheElement element = CacheElement.findElement(regions, "customers");
+ assertThat(element.getGroup()).isNull();
+
+ element = CacheElement.findElement(regions, "customers1");
+ assertThat(element.getGroup()).isEqualTo("group1");
+
+ RegionConfig region = (RegionConfig) CacheElement.findElement(regions, "customers2");
+ assertThat(region.getGroup()).isIn("group1", "group2");
+ assertThat(region.getType()).isIn("PARTITION", "PARTITION_PROXY");
+
+ element = CacheElement.findElement(regions, "customers3");
+ assertThat(element.getGroups()).containsExactlyInAnyOrder("group1", "group2");
}
@Test
public void listClusterLevel() throws Exception {
// list cluster level only
filter.setGroup("cluster");
- List<CacheElement> regions = client.list(filter).getResult();
+ List<RuntimeCacheElement> regions = client.list(filter).getResult();
assertThat(regions).hasSize(1);
assertThat(regions.get(0).getId()).isEqualTo("customers");
- assertThat(regions.get(0).getConfigGroup()).isEqualTo("cluster");
assertThat(regions.get(0).getGroup()).isNull();
}
@Test
+ public void testEntryCount() throws Exception {
+ server1.invoke(() -> {
+ Region region = ClusterStartupRule.getCache().getRegion("/customers");
+ region.put("k1", "v1");
+ region.put("k2", "v2");
+ });
+
+ // wait till entry size are correctly gathered by the mbean
+ locator.invoke(() -> {
+ await().untilAsserted(
+ () -> assertThat(ClusterStartupRule.memberStarter.getRegionMBean("/customers")
+ .getSystemRegionEntryCount()).isEqualTo(2));
+ });
+
+ filter.setName("customers");
+ List<RuntimeCacheElement> regions = client.list(filter).getResult();
+ assertThat(regions).hasSize(1);
+ RuntimeRegionConfig regionConfig = (RuntimeRegionConfig) regions.get(0);
+ assertThat(regionConfig.getName()).isEqualTo("customers");
+ assertThat(regionConfig).isInstanceOf(RuntimeRegionConfig.class);
+ assertThat(regionConfig.getEntryCount()).isEqualTo(2);
+ }
+
+ @Test
public void listGroup1() throws Exception {
// list group1
filter.setGroup("group1");
- List<CacheElement> regions = client.list(filter).getResult();
- assertThat(regions).hasSize(1);
- assertThat(regions.get(0).getId()).isEqualTo("customers1");
- assertThat(regions.get(0).getConfigGroup()).isEqualTo("group1");
- assertThat(regions.get(0).getGroup()).isEqualTo("group1");
+ List<RuntimeCacheElement> regions = client.list(filter).getResult();
+ assertThat(regions).hasSize(3);
+ // when filtering by group, the returned list should not have group info
+ RuntimeCacheElement region =
+ (RuntimeCacheElement) CacheElement.findElement(regions, "customers1");
+ assertThat(region.getGroup()).isEqualTo("group1");
+
+ region = (RuntimeCacheElement) CacheElement.findElement(regions, "customers2");
+ assertThat(region.getGroup()).isEqualTo("group1");
+
+ region = (RuntimeCacheElement) CacheElement.findElement(regions, "customers3");
+ assertThat(region.getGroups()).containsExactlyInAnyOrder("group1", "group2");
}
@Test
public void listGroup2() throws Exception {
// list group1
filter.setGroup("group2");
- List<CacheElement> regions = client.list(filter).getResult();
- assertThat(regions).hasSize(1);
- assertThat(regions.get(0).getId()).isEqualTo("customers2");
- assertThat(regions.get(0).getConfigGroup()).isEqualTo("group2");
- assertThat(regions.get(0).getGroup()).isEqualTo("group2");
+ List<RuntimeCacheElement> regions = client.list(filter).getResult();
+ assertThat(regions).hasSize(2);
+
+ RuntimeCacheElement region = CacheElement.findElement(regions, "customers2");
+ assertThat(region.getGroup()).isEqualTo("group2");
+
+ region = CacheElement.findElement(regions, "customers3");
+ assertThat(region.getGroups()).containsExactlyInAnyOrder("group1", "group2");
}
@Test
public void listNonExistentGroup() throws Exception {
// list non-existent group
filter.setGroup("group3");
- List<CacheElement> regions = client.list(filter).getResult();
+ List<RuntimeCacheElement> regions = client.list(filter).getResult();
assertThat(regions).hasSize(0);
}
@Test
public void listRegionByName() throws Exception {
filter.setName("customers");
- List<CacheElement> regions = client.list(filter).getResult();
+ List<RuntimeCacheElement> regions = client.list(filter).getResult();
assertThat(regions).hasSize(1);
assertThat(regions.get(0).getId()).isEqualTo("customers");
- assertThat(regions.get(0).getConfigGroup()).isEqualTo("cluster");
assertThat(regions.get(0).getGroup()).isNull();
}
@Test
+ public void listRegionByName1() throws Exception {
+ filter.setName("customers1");
+ List<RuntimeCacheElement> regions = client.list(filter).getResult();
+ assertThat(regions).hasSize(1);
+ assertThat(regions.get(0).getId()).isEqualTo("customers1");
+ assertThat(regions.get(0).getGroup()).isEqualTo("group1");
+ }
+
+ @Test
+ public void listRegionByName2() throws Exception {
+ filter.setName("customers2");
+ List<RuntimeCacheElement> regions = client.list(filter).getResult();
+ assertThat(regions).hasSize(2);
+ assertThat(regions.stream().map(RuntimeCacheElement::getGroup).collect(Collectors.toList()))
+ .containsExactlyInAnyOrder("group1", "group2");
+ assertThat(regions.stream().map(RegionConfig.class::cast)
+ .map(RegionConfig::getType)
+ .collect(Collectors.toList()))
+ .containsExactlyInAnyOrder("PARTITION", "PARTITION_PROXY");
+ }
+
+ @Test
+ public void listRegionByName3() throws Exception {
+ filter.setName("customers3");
+ List<RuntimeCacheElement> regions = client.list(filter).getResult();
+ assertThat(regions).hasSize(1);
+ assertThat(regions.get(0).getId()).isEqualTo("customers3");
+ assertThat(regions.get(0).getGroups()).containsExactlyInAnyOrder("group1", "group2");
+ }
+
+ @Test
public void listNonExistentRegion() throws Exception {
// list non-existent region
- filter.setName("customer3");
- List<CacheElement> regions = client.list(filter).getResult();
+ filter.setName("customer4");
+ List<RuntimeCacheElement> regions = client.list(filter).getResult();
assertThat(regions).hasSize(0);
}
}
diff --git a/geode-assembly/src/integrationTest/resources/assembly_content.txt b/geode-assembly/src/integrationTest/resources/assembly_content.txt
index bb3200b..5cc2a63 100644
--- a/geode-assembly/src/integrationTest/resources/assembly_content.txt
+++ b/geode-assembly/src/integrationTest/resources/assembly_content.txt
@@ -707,6 +707,8 @@ javadoc/org/apache/geode/management/client/package-frame.html
javadoc/org/apache/geode/management/client/package-summary.html
javadoc/org/apache/geode/management/client/package-tree.html
javadoc/org/apache/geode/management/configuration/MemberConfig.html
+javadoc/org/apache/geode/management/configuration/RuntimeCacheElement.html
+javadoc/org/apache/geode/management/configuration/RuntimeRegionConfig.html
javadoc/org/apache/geode/management/configuration/package-frame.html
javadoc/org/apache/geode/management/configuration/package-summary.html
javadoc/org/apache/geode/management/configuration/package-tree.html
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/management/internal/configuration/mutators/RegionConfigMutatorIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/management/internal/configuration/mutators/RegionConfigMutatorIntegrationTest.java
index 30d4140..c3b84aa 100644
--- a/geode-core/src/integrationTest/java/org/apache/geode/management/internal/configuration/mutators/RegionConfigMutatorIntegrationTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/management/internal/configuration/mutators/RegionConfigMutatorIntegrationTest.java
@@ -37,7 +37,7 @@ public class RegionConfigMutatorIntegrationTest {
@Before
public void before() throws Exception {
config = new RegionConfig();
- mutator = new RegionConfigManager();
+ mutator = new RegionConfigManager(locator.getCache());
}
@Test
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/api/LocatorClusterManagementService.java b/geode-core/src/main/java/org/apache/geode/management/internal/api/LocatorClusterManagementService.java
index 5d79e29..ffa9342 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/api/LocatorClusterManagementService.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/api/LocatorClusterManagementService.java
@@ -21,6 +21,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -42,12 +43,14 @@ import org.apache.geode.internal.logging.LogService;
import org.apache.geode.management.api.ClusterManagementResult;
import org.apache.geode.management.api.ClusterManagementService;
import org.apache.geode.management.configuration.MemberConfig;
+import org.apache.geode.management.configuration.RuntimeCacheElement;
import org.apache.geode.management.internal.cli.CliUtil;
import org.apache.geode.management.internal.cli.functions.CliFunctionResult;
import org.apache.geode.management.internal.cli.functions.UpdateCacheFunction;
import org.apache.geode.management.internal.configuration.mutators.ConfigurationManager;
import org.apache.geode.management.internal.configuration.mutators.MemberConfigManager;
import org.apache.geode.management.internal.configuration.mutators.RegionConfigManager;
+import org.apache.geode.management.internal.configuration.validators.CacheElementValidator;
import org.apache.geode.management.internal.configuration.validators.ConfigurationValidator;
import org.apache.geode.management.internal.configuration.validators.RegionConfigValidator;
import org.apache.geode.management.internal.exceptions.EntityExistsException;
@@ -56,23 +59,24 @@ public class LocatorClusterManagementService implements ClusterManagementService
private static final Logger logger = LogService.getLogger();
private InternalCache cache;
private ConfigurationPersistenceService persistenceService;
- private HashMap<Class, ConfigurationManager> managers;
- private HashMap<Class, ConfigurationValidator> validators;
+ private Map<Class, ConfigurationManager> managers;
+ private Map<Class, ConfigurationValidator> validators;
public LocatorClusterManagementService(InternalCache cache,
ConfigurationPersistenceService persistenceService) {
this(cache, persistenceService, new HashMap(), new HashMap());
// initialize the list of managers
- managers.put(RegionConfig.class, new RegionConfigManager());
+ managers.put(RegionConfig.class, new RegionConfigManager(cache));
managers.put(MemberConfig.class, new MemberConfigManager(cache));
// initialize the list of validators
+ validators.put(CacheElement.class, new CacheElementValidator());
validators.put(RegionConfig.class, new RegionConfigValidator(cache));
}
@VisibleForTesting
public LocatorClusterManagementService(InternalCache cache,
- ConfigurationPersistenceService persistenceService, HashMap managers, HashMap validators) {
+ ConfigurationPersistenceService persistenceService, Map managers, Map validators) {
this.cache = cache;
this.persistenceService = persistenceService;
this.managers = managers;
@@ -88,18 +92,24 @@ public class LocatorClusterManagementService implements ClusterManagementService
"Cluster configuration service needs to be enabled");
}
- ClusterManagementResult result = new ClusterManagementResult();
- ConfigurationManager configurationMutator = managers.get(config.getClass());
+ // first validate common attributes of all configuration object
+ validators.get(CacheElement.class).validate(config);
ConfigurationValidator validator = validators.get(config.getClass());
if (validator != null) {
validator.validate(config);
+ // exit early if config element already exists in cache config
+ CacheConfig currentPersistedConfig = persistenceService.getCacheConfig(group, true);
+ if (validator.exists(config, currentPersistedConfig)) {
+ throw new EntityExistsException("cache element " + config.getId() + " already exists.");
+ }
}
- // exit early if config element already exists in cache config
- CacheConfig currentPersistedConfig = persistenceService.getCacheConfig(group, true);
- if (validator.exists(config, currentPersistedConfig)) {
- throw new EntityExistsException("cache element " + config.getId() + " already exists.");
+ // validate that user used the correct config object type
+ ConfigurationManager configurationManager = managers.get(config.getClass());
+ if (configurationManager == null) {
+ throw new IllegalArgumentException(String.format("Configuration type %s is not supported.",
+ config.getClass().getSimpleName()));
}
// execute function on all members
@@ -110,6 +120,8 @@ public class LocatorClusterManagementService implements ClusterManagementService
"no members found in " + group + " to create cache element");
}
+ ClusterManagementResult result = new ClusterManagementResult();
+
List<CliFunctionResult> functionResults = executeAndGetFunctionResult(
new UpdateCacheFunction(),
Arrays.asList(config, UpdateCacheFunction.CacheElementOperation.ADD),
@@ -129,7 +141,7 @@ public class LocatorClusterManagementService implements ClusterManagementService
final String finalGroup = group; // the below lambda requires a reference that is final
persistenceService.updateCacheConfig(finalGroup, cacheConfigForGroup -> {
try {
- configurationMutator.add(config, cacheConfigForGroup);
+ configurationManager.add(config, cacheConfigForGroup);
result.setStatus(true,
"successfully persisted config for " + finalGroup);
} catch (Exception e) {
@@ -159,7 +171,7 @@ public class LocatorClusterManagementService implements ClusterManagementService
ClusterManagementResult result = new ClusterManagementResult();
if (filter instanceof MemberConfig) {
- List<CacheElement> listResults = manager.list(filter, null);
+ List<RuntimeCacheElement> listResults = manager.list(filter, null);
result.setResult(listResults);
return result;
}
@@ -169,23 +181,46 @@ public class LocatorClusterManagementService implements ClusterManagementService
"Cluster configuration service needs to be enabled");
}
- List<CacheElement> elements = new ArrayList<>();
+ List<RuntimeCacheElement> resultList = new ArrayList<>();
+
+ // get a list of all the resultList from all groups that satisfy the filter criteria (all
+ // filters
+ // have been applied except the group)
for (String group : persistenceService.getGroups()) {
- if (StringUtils.isBlank(filter.getGroup()) || group.equals(filter.getConfigGroup())) {
- CacheConfig currentPersistedConfig = persistenceService.getCacheConfig(group, true);
- List<CacheElement> listInGroup = manager.list(filter, currentPersistedConfig);
- // only set the group attribute when the config level is not in the cluster level
- if (!group.equals("cluster")) {
- listInGroup.stream().forEach(e -> e.setGroup(group));
+ CacheConfig currentPersistedConfig = persistenceService.getCacheConfig(group, true);
+ List<RuntimeCacheElement> listInGroup = manager.list(filter, currentPersistedConfig);
+ for (RuntimeCacheElement element : listInGroup) {
+ element.getGroups().add(group);
+ int index = resultList.indexOf(element);
+ if (index >= 0) {
+ RuntimeCacheElement exist = resultList.get(index);
+ exist.getGroups().add(group);
+ } else {
+ resultList.add(element);
}
- elements.addAll(listInGroup);
}
}
- result.setResult(elements);
+ // filtering by group. Do this after iterating through all the groups because some region might
+ // belong to multiple groups and we want the "group" field to show that.
+ if (StringUtils.isNotBlank(filter.getGroup())) {
+ resultList =
+ resultList.stream().filter(e -> e.getGroups().contains(filter.getConfigGroup()))
+ .collect(Collectors.toList());
+ }
+
+ // if "cluster" is the only group of the element, remove it
+ for (RuntimeCacheElement element : resultList) {
+ if (element.getGroups().size() == 1 && "cluster".equals(element.getGroup())) {
+ element.getGroups().clear();
+ }
+ }
+
+ result.setResult(resultList);
return result;
}
+
@Override
public boolean isConnected() {
return true;
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/configuration/mutators/ConfigurationManager.java b/geode-core/src/main/java/org/apache/geode/management/internal/configuration/mutators/ConfigurationManager.java
index 9862cff..83f31f9 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/configuration/mutators/ConfigurationManager.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/configuration/mutators/ConfigurationManager.java
@@ -22,6 +22,7 @@ import java.util.List;
import org.apache.geode.annotations.Experimental;
import org.apache.geode.cache.configuration.CacheConfig;
import org.apache.geode.cache.configuration.CacheElement;
+import org.apache.geode.management.configuration.RuntimeCacheElement;
/**
* Defines the behavior to mutate a configuration change into a pre-existing cache config from a
@@ -37,5 +38,5 @@ public interface ConfigurationManager<T extends CacheElement> {
void delete(T config, CacheConfig existing);
- List<? extends T> list(T filterConfig, CacheConfig existing);
+ List<? extends RuntimeCacheElement> list(T filterConfig, CacheConfig existing);
}
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/configuration/mutators/RegionConfigManager.java b/geode-core/src/main/java/org/apache/geode/management/internal/configuration/mutators/RegionConfigManager.java
index 87e239e..de44010 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/configuration/mutators/RegionConfigManager.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/configuration/mutators/RegionConfigManager.java
@@ -17,6 +17,7 @@
package org.apache.geode.management.internal.configuration.mutators;
+import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@@ -25,10 +26,20 @@ import org.apache.commons.lang3.StringUtils;
import org.apache.geode.cache.configuration.CacheConfig;
import org.apache.geode.cache.configuration.RegionConfig;
+import org.apache.geode.internal.cache.InternalCache;
+import org.apache.geode.management.DistributedRegionMXBean;
+import org.apache.geode.management.ManagementService;
+import org.apache.geode.management.configuration.RuntimeRegionConfig;
-public class RegionConfigManager implements ConfigurationManager<RegionConfig> {
+public class RegionConfigManager
+ implements ConfigurationManager<RegionConfig> {
+ private InternalCache cache;
+ private ManagementService managementService;
- public RegionConfigManager() {}
+ public RegionConfigManager(InternalCache cache) {
+ this.cache = cache;
+ this.managementService = ManagementService.getExistingManagementService(cache);
+ }
@Override
public void add(RegionConfig configElement, CacheConfig existingConfig) {
@@ -46,11 +57,27 @@ public class RegionConfigManager implements ConfigurationManager<RegionConfig> {
}
@Override
- public List<RegionConfig> list(RegionConfig filter, CacheConfig existing) {
+ public List<RuntimeRegionConfig> list(RegionConfig filter, CacheConfig existing) {
+ List<RegionConfig> staticRegionConfigs;
if (StringUtils.isBlank(filter.getName())) {
- return existing.getRegions();
+ staticRegionConfigs = existing.getRegions();
+ } else {
+ staticRegionConfigs =
+ existing.getRegions().stream().filter(r -> filter.getName().equals(r.getName())).collect(
+ Collectors.toList());
+ }
+
+ List<RuntimeRegionConfig> results = new ArrayList<>();
+ for (RegionConfig config : staticRegionConfigs) {
+ DistributedRegionMXBean distributedRegionMXBean =
+ managementService.getDistributedRegionMXBean("/" + config.getName());
+ if (distributedRegionMXBean == null) {
+ throw new IllegalStateException("Can't get the region mbean info for " + config.getName());
+ }
+ RuntimeRegionConfig runtimeConfig = new RuntimeRegionConfig(config);
+ runtimeConfig.setEntryCount(distributedRegionMXBean.getSystemRegionEntryCount());
+ results.add(runtimeConfig);
}
- return existing.getRegions().stream().filter(r -> filter.getName().equals(r.getName())).collect(
- Collectors.toList());
+ return results;
}
}
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/configuration/validators/CacheElementValidator.java b/geode-core/src/main/java/org/apache/geode/management/internal/configuration/validators/CacheElementValidator.java
new file mode 100644
index 0000000..085fce3
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/configuration/validators/CacheElementValidator.java
@@ -0,0 +1,37 @@
+/*
+ * 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.configuration.validators;
+
+import org.apache.geode.cache.configuration.CacheConfig;
+import org.apache.geode.cache.configuration.CacheElement;
+
+/**
+ * this is used to validate all the common attributes of CacheElement, eg. group
+ */
+public class CacheElementValidator implements ConfigurationValidator<CacheElement> {
+ @Override
+ public void validate(CacheElement config) throws IllegalArgumentException {
+ if ("cluster".equalsIgnoreCase(config.getGroup())) {
+ throw new IllegalArgumentException(
+ "cluster is a reserved group name. Do not use it for member groups.");
+ }
+ }
+
+ @Override
+ public boolean exists(CacheElement config, CacheConfig persistedConfig) {
+ return false;
+ }
+}
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 79084fe..f794e4a 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
@@ -40,11 +40,6 @@ public class RegionConfigValidator implements ConfigurationValidator<RegionConfi
RegionNameValidation.validate(config.getName());
- if ("cluster".equalsIgnoreCase(config.getGroup())) {
- throw new IllegalArgumentException(
- "cluster is a reserved group name. Do not use it for member groups.");
- }
-
if (config.getType() == null) {
RegionType defaultRegion = RegionType.PARTITION;
config.setType(defaultRegion);
diff --git a/geode-core/src/test/java/org/apache/geode/management/internal/api/LocatorClusterManagementServiceTest.java b/geode-core/src/test/java/org/apache/geode/management/internal/api/LocatorClusterManagementServiceTest.java
index ff5a79b..7bf79c8 100644
--- a/geode-core/src/test/java/org/apache/geode/management/internal/api/LocatorClusterManagementServiceTest.java
+++ b/geode-core/src/test/java/org/apache/geode/management/internal/api/LocatorClusterManagementServiceTest.java
@@ -15,29 +15,45 @@
package org.apache.geode.management.internal.api;
+import static org.apache.geode.test.junit.assertions.ClusterManagementResultAssert.assertManagementResult;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
+import com.google.common.collect.Sets;
import org.junit.Before;
import org.junit.Test;
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.distributed.ConfigurationPersistenceService;
import org.apache.geode.distributed.DistributedMember;
import org.apache.geode.internal.cache.InternalCache;
import org.apache.geode.management.api.ClusterManagementResult;
+import org.apache.geode.management.configuration.MemberConfig;
+import org.apache.geode.management.configuration.RuntimeCacheElement;
+import org.apache.geode.management.configuration.RuntimeRegionConfig;
import org.apache.geode.management.internal.cli.functions.CliFunctionResult;
-import org.apache.geode.management.internal.exceptions.EntityExistsException;
+import org.apache.geode.management.internal.configuration.mutators.ConfigurationManager;
+import org.apache.geode.management.internal.configuration.validators.CacheElementValidator;
+import org.apache.geode.management.internal.configuration.validators.ConfigurationValidator;
+import org.apache.geode.management.internal.configuration.validators.RegionConfigValidator;
public class LocatorClusterManagementServiceTest {
@@ -46,12 +62,25 @@ public class LocatorClusterManagementServiceTest {
private ConfigurationPersistenceService persistenceService;
private RegionConfig regionConfig;
private ClusterManagementResult result;
+ private Map<Class, ConfigurationValidator> validators = new HashMap<>();
+ private Map<Class, ConfigurationManager> managers = new HashMap<>();
+ private ConfigurationValidator<RegionConfig> regionValidator;
+ private ConfigurationValidator<CacheElement> cacheElementValidator;
+ private ConfigurationManager<RegionConfig> regionManager;
@Before
public void before() throws Exception {
+ regionValidator = mock(RegionConfigValidator.class);
+ regionManager = mock(ConfigurationManager.class);
+ cacheElementValidator = mock(CacheElementValidator.class);
+ validators.put(RegionConfig.class, regionValidator);
+ validators.put(CacheElement.class, cacheElementValidator);
+ managers.put(RegionConfig.class, regionManager);
+
cache = mock(InternalCache.class);
persistenceService = mock(ConfigurationPersistenceService.class);
- service = spy(new LocatorClusterManagementService(cache, persistenceService));
+ service =
+ spy(new LocatorClusterManagementService(cache, persistenceService, managers, validators));
regionConfig = new RegionConfig();
}
@@ -65,33 +94,14 @@ public class LocatorClusterManagementServiceTest {
}
@Test
- public void elementAlreadyExist() throws Exception {
- regionConfig.setName("test");
- CacheConfig cacheConfig = new CacheConfig();
- cacheConfig.getRegions().add(regionConfig);
- when(persistenceService.getCacheConfig("cluster", true)).thenReturn(cacheConfig);
-
- assertThatThrownBy(() -> service.create(regionConfig))
- .isInstanceOf(EntityExistsException.class)
- .hasMessageContaining("cache element test already exists");
- }
-
- @Test
- public void validationFailed() throws Exception {
- assertThatThrownBy(() -> service.create(regionConfig))
- .isInstanceOf(IllegalArgumentException.class)
- .hasMessageContaining("Name of the region has to be specified");
- }
-
- @Test
- public void noMemberFound() throws Exception {
- regionConfig.setName("test");
- when(persistenceService.getCacheConfig("cluster", true)).thenReturn(new CacheConfig());
- doReturn(Collections.emptySet()).when(service).findMembers(any());
- result = service.create(regionConfig);
- assertThat(result.isSuccessful()).isFalse();
- assertThat(result.getStatusMessage())
- .contains("no members found in cluster to create cache element");
+ public void validatorIsCalledCorrectly() throws Exception {
+ doReturn(Collections.emptySet()).when(service).findMembers(anyString());
+ assertManagementResult(service.create(regionConfig))
+ .failed().hasStatusCode(ClusterManagementResult.StatusCode.ERROR)
+ .containsStatusMessage("no members found");
+ verify(cacheElementValidator).validate(regionConfig);
+ verify(regionValidator).validate(regionConfig);
+ verify(regionValidator).exists(eq(regionConfig), any());
}
@Test
@@ -110,4 +120,47 @@ public class LocatorClusterManagementServiceTest {
assertThat(result.getStatusMessage())
.contains("Failed to apply the update on all members");
}
+
+ @Test
+ public void non_supportedConfigObject() throws Exception {
+ MemberConfig config = new MemberConfig();
+ assertThatThrownBy(() -> service.create(config)).isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("Configuration type MemberConfig is not supported");
+ }
+
+ @Test
+ public void listOneGroup() throws Exception {
+ regionConfig.setGroup("cluster");
+ when(persistenceService.getGroups()).thenReturn(Sets.newHashSet("cluster", "group1"));
+
+ service.list(regionConfig);
+ // even we are listing regions in one group, we still need to go through all the groups
+ verify(persistenceService).getCacheConfig("cluster", true);
+ verify(persistenceService).getCacheConfig("group1", true);
+ verify(regionManager, times(2)).list(any(), any());
+ }
+
+ @Test
+ public void aRegionInClusterAndGroup1() throws Exception {
+ when(persistenceService.getGroups()).thenReturn(Sets.newHashSet("cluster", "group1"));
+ RuntimeRegionConfig region1 = new RuntimeRegionConfig();
+ region1.setName("region1");
+ region1.setType("REPLICATE");
+ RuntimeRegionConfig region2 = new RuntimeRegionConfig();
+ region2.setName("region1");
+ region2.setType("REPLICATE");
+
+ List clusterRegions = Arrays.asList(region1);
+ List group1Regions = Arrays.asList(region2);
+ when(regionManager.list(any(), any())).thenReturn(clusterRegions)
+ .thenReturn(group1Regions);
+
+ // this is to make sure when 'cluster" is in one of the group, it will show
+ // the cluster and the other group name
+ List<RuntimeCacheElement> results = service.list(new RegionConfig()).getResult();
+ assertThat(results).hasSize(1);
+ RuntimeRegionConfig result = (RuntimeRegionConfig) results.get(0);
+ assertThat(result.getName()).isEqualTo("region1");
+ assertThat(result.getGroups()).containsExactlyInAnyOrder("cluster", "group1");
+ }
}
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/management/internal/configuration/mutators/RegionConfigMutatorIntegrationTest.java b/geode-core/src/test/java/org/apache/geode/management/internal/configuration/validators/CacheElementValidatorTest.java
similarity index 52%
copy from geode-core/src/integrationTest/java/org/apache/geode/management/internal/configuration/mutators/RegionConfigMutatorIntegrationTest.java
copy to geode-core/src/test/java/org/apache/geode/management/internal/configuration/validators/CacheElementValidatorTest.java
index 30d4140..1be5265 100644
--- a/geode-core/src/integrationTest/java/org/apache/geode/management/internal/configuration/mutators/RegionConfigMutatorIntegrationTest.java
+++ b/geode-core/src/test/java/org/apache/geode/management/internal/configuration/validators/CacheElementValidatorTest.java
@@ -12,42 +12,34 @@
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
-package org.apache.geode.management.internal.configuration.mutators;
-import static org.assertj.core.api.Assertions.assertThat;
+package org.apache.geode.management.internal.configuration.validators;
+
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
import org.junit.Before;
-import org.junit.Rule;
import org.junit.Test;
-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.configuration.RegionType;
-import org.apache.geode.test.junit.rules.LocatorStarterRule;
-
-public class RegionConfigMutatorIntegrationTest {
- @Rule
- public LocatorStarterRule locator = new LocatorStarterRule().withAutoStart();
+public class CacheElementValidatorTest {
- private RegionConfigManager mutator;
+ private CacheElementValidator validator;
private RegionConfig config;
@Before
public void before() throws Exception {
+ validator = new CacheElementValidator();
config = new RegionConfig();
- mutator = new RegionConfigManager();
}
@Test
- public void sanity() throws Exception {
- config.setType(RegionType.REPLICATE);
+ public void invalidGroup_cluster() throws Exception {
config.setName("test");
- CacheConfig cacheConfig =
- locator.getLocator().getConfigurationPersistenceService().getCacheConfig("cluster", true);
-
- mutator.add(config, cacheConfig);
- assertThat(CacheElement.findElement(cacheConfig.getRegions(), config.getId())).isNotNull();
+ config.setGroup("cluster");
+ assertThatThrownBy(() -> validator.validate(config)).isInstanceOf(
+ IllegalArgumentException.class)
+ .hasMessageContaining(
+ "cluster is a reserved group name");
}
}
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 8c70c00..38dbf58 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
@@ -113,13 +113,4 @@ public class RegionConfigValidatorTest {
"Region names may only be alphanumeric and may contain hyphens or underscores");
}
- @Test
- public void invalidGroup() throws Exception {
- config.setName("test");
- config.setGroup("cluster");
- assertThatThrownBy(() -> validator.validate(config)).isInstanceOf(
- IllegalArgumentException.class)
- .hasMessageContaining(
- "cluster is a reserved group name");
- }
}
diff --git a/geode-junit/src/main/java/org/apache/geode/test/junit/assertions/ClusterManagementResultAssert.java b/geode-junit/src/main/java/org/apache/geode/test/junit/assertions/ClusterManagementResultAssert.java
index f66acbe..fa3a7a8 100644
--- a/geode-junit/src/main/java/org/apache/geode/test/junit/assertions/ClusterManagementResultAssert.java
+++ b/geode-junit/src/main/java/org/apache/geode/test/junit/assertions/ClusterManagementResultAssert.java
@@ -20,8 +20,8 @@ import static org.assertj.core.api.Assertions.assertThat;
import org.assertj.core.api.AbstractAssert;
import org.assertj.core.api.ListAssert;
-import org.apache.geode.cache.configuration.CacheElement;
import org.apache.geode.management.api.ClusterManagementResult;
+import org.apache.geode.management.configuration.RuntimeCacheElement;
public class ClusterManagementResultAssert
extends AbstractAssert<ClusterManagementResultAssert, ClusterManagementResult> {
@@ -50,7 +50,7 @@ public class ClusterManagementResultAssert
return this;
}
- public ListAssert<CacheElement> hasListResult() {
+ public ListAssert<RuntimeCacheElement> hasListResult() {
return assertThat(actual.getResult());
}
diff --git a/geode-management/src/main/java/org/apache/geode/cache/configuration/CacheElement.java b/geode-management/src/main/java/org/apache/geode/cache/configuration/CacheElement.java
index 4462f57..268ae1d 100644
--- a/geode-management/src/main/java/org/apache/geode/cache/configuration/CacheElement.java
+++ b/geode-management/src/main/java/org/apache/geode/cache/configuration/CacheElement.java
@@ -18,11 +18,13 @@
package org.apache.geode.cache.configuration;
import java.io.Serializable;
+import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlTransient;
import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonSetter;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import org.apache.commons.lang3.StringUtils;
@@ -32,35 +34,53 @@ import org.apache.geode.lang.Identifiable;
@Experimental
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, property = "class")
public abstract class CacheElement implements Identifiable<String>, Serializable {
- private String group;
+ protected List<String> groups = new ArrayList<>();
- public static <T extends CacheElement> boolean exists(List<T> list, String id) {
+ public static <T extends Identifiable> boolean exists(List<T> list, String id) {
return list.stream().anyMatch(o -> o.getId().equals(id));
}
- public static <T extends CacheElement> T findElement(List<T> list, String id) {
+ public static <T extends Identifiable> T findElement(List<T> list, String id) {
return list.stream().filter(o -> o.getId().equals(id)).findFirst().orElse(null);
}
- public static <T extends CacheElement> void removeElement(List<T> list, String id) {
+ public static <T extends Identifiable> void removeElement(List<T> list, String id) {
list.removeIf(t -> t.getId().equals(id));
}
- @XmlTransient
- public String getGroup() {
- return group;
- }
-
+ /**
+ * this returns a non-null value
+ * for cluster level element, it will return "cluster" for sure.
+ */
@XmlTransient
@JsonIgnore
public String getConfigGroup() {
+ String group = getGroup();
if (StringUtils.isBlank(group)) {
return "cluster";
}
return group;
}
+ /**
+ * this returns the first group set by the user
+ * if no group is set, this returns null
+ */
+ @XmlTransient
+ public String getGroup() {
+ if (groups.size() == 0) {
+ return null;
+ }
+ return groups.get(0);
+ }
+
+ @JsonSetter
public void setGroup(String group) {
- this.group = group;
+ groups.clear();
+
+ if (StringUtils.isBlank(group)) {
+ return;
+ }
+ groups.add(group);
}
}
diff --git a/geode-management/src/main/java/org/apache/geode/cache/configuration/RegionConfig.java b/geode-management/src/main/java/org/apache/geode/cache/configuration/RegionConfig.java
index b3d43e4..610233e 100644
--- a/geode-management/src/main/java/org/apache/geode/cache/configuration/RegionConfig.java
+++ b/geode-management/src/main/java/org/apache/geode/cache/configuration/RegionConfig.java
@@ -30,6 +30,7 @@ import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;
import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.google.common.base.Objects;
import org.apache.geode.annotations.Experimental;
import org.apache.geode.management.api.RestfulEndpoint;
@@ -178,6 +179,17 @@ public class RegionConfig extends CacheElement implements RestfulEndpoint {
this.type = refid;
}
+ public RegionConfig(RegionConfig config) {
+ this.regionAttributes = config.getRegionAttributes();
+ this.type = config.getType();
+ this.entries = config.getEntries();
+ this.indexes = config.getIndexes();
+ this.name = config.getName();
+ this.regionElements = config.getCustomRegionElements();
+ this.regions = config.getRegions();
+ this.setGroup(config.getGroup());
+ }
+
@Override
public String getEndpoint() {
return REGION_CONFIG_ENDPOINT;
@@ -467,6 +479,18 @@ public class RegionConfig extends CacheElement implements RestfulEndpoint {
return getName();
}
+ @Override
+ public boolean equals(Object that) {
+ if (this == that) {
+ return true;
+ }
+ if (that == null || getClass() != that.getClass()) {
+ return false;
+ }
+ RegionConfig config = (RegionConfig) that;
+ return Objects.equal(getName(), config.getName()) &&
+ Objects.equal(getType(), config.getType());
+ }
/**
* <p>
diff --git a/geode-management/src/main/java/org/apache/geode/management/api/ClusterManagementResult.java b/geode-management/src/main/java/org/apache/geode/management/api/ClusterManagementResult.java
index 0f825f2..17fc775 100644
--- a/geode-management/src/main/java/org/apache/geode/management/api/ClusterManagementResult.java
+++ b/geode-management/src/main/java/org/apache/geode/management/api/ClusterManagementResult.java
@@ -22,7 +22,7 @@ import java.util.Map;
import com.fasterxml.jackson.annotation.JsonIgnore;
import org.apache.geode.annotations.Experimental;
-import org.apache.geode.cache.configuration.CacheElement;
+import org.apache.geode.management.configuration.RuntimeCacheElement;
@Experimental
public class ClusterManagementResult {
@@ -59,7 +59,7 @@ public class ClusterManagementResult {
private StatusCode statusCode = StatusCode.OK;
private String statusMessage;
- private List<CacheElement> result = new ArrayList<>();
+ private List<RuntimeCacheElement> result = new ArrayList<>();
public ClusterManagementResult() {}
@@ -109,11 +109,11 @@ public class ClusterManagementResult {
return statusCode;
}
- public List<CacheElement> getResult() {
+ public List<RuntimeCacheElement> getResult() {
return result;
}
- public void setResult(List<CacheElement> result) {
+ public void setResult(List<RuntimeCacheElement> result) {
this.result = result;
}
}
diff --git a/geode-management/src/main/java/org/apache/geode/management/configuration/MemberConfig.java b/geode-management/src/main/java/org/apache/geode/management/configuration/MemberConfig.java
index 4f488db..f4697f5 100644
--- a/geode-management/src/main/java/org/apache/geode/management/configuration/MemberConfig.java
+++ b/geode-management/src/main/java/org/apache/geode/management/configuration/MemberConfig.java
@@ -22,7 +22,7 @@ import org.apache.geode.cache.configuration.CacheElement;
import org.apache.geode.management.api.RestfulEndpoint;
@Experimental
-public class MemberConfig extends CacheElement implements RestfulEndpoint {
+public class MemberConfig extends CacheElement implements RuntimeCacheElement, RestfulEndpoint {
private static final long serialVersionUID = -6262538068604902018L;
@@ -92,4 +92,8 @@ public class MemberConfig extends CacheElement implements RestfulEndpoint {
public String getId() {
return id;
}
+
+ public List<String> getGroups() {
+ return groups;
+ }
}
diff --git a/geode-management/src/main/java/org/apache/geode/management/configuration/RuntimeCacheElement.java b/geode-management/src/main/java/org/apache/geode/management/configuration/RuntimeCacheElement.java
new file mode 100644
index 0000000..b15e199
--- /dev/null
+++ b/geode-management/src/main/java/org/apache/geode/management/configuration/RuntimeCacheElement.java
@@ -0,0 +1,36 @@
+/*
+ * 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.configuration;
+
+import java.io.Serializable;
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlTransient;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonTypeInfo;
+
+import org.apache.geode.lang.Identifiable;
+
+@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, property = "class")
+public interface RuntimeCacheElement extends Identifiable<String>, Serializable {
+ @XmlTransient
+ List<String> getGroups();
+
+ @XmlTransient
+ @JsonIgnore
+ String getGroup();
+}
diff --git a/geode-management/src/main/java/org/apache/geode/management/configuration/RuntimeRegionConfig.java b/geode-management/src/main/java/org/apache/geode/management/configuration/RuntimeRegionConfig.java
new file mode 100644
index 0000000..da4367e
--- /dev/null
+++ b/geode-management/src/main/java/org/apache/geode/management/configuration/RuntimeRegionConfig.java
@@ -0,0 +1,45 @@
+/*
+ * 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.configuration;
+
+
+import java.util.List;
+
+import org.apache.geode.annotations.Experimental;
+import org.apache.geode.cache.configuration.RegionConfig;
+
+@Experimental
+public class RuntimeRegionConfig extends RegionConfig implements RuntimeCacheElement {
+ private long entryCount;
+
+ public RuntimeRegionConfig() {}
+
+ public RuntimeRegionConfig(RegionConfig config) {
+ super(config);
+ }
+
+ public long getEntryCount() {
+ return entryCount;
+ }
+
+ public void setEntryCount(long entrySize) {
+ this.entryCount = entrySize;
+ }
+
+ public List<String> getGroups() {
+ return groups;
+ }
+}
diff --git a/geode-management/src/test/java/org/apache/geode/cache/configuration/CacheElementJsonMappingTest.java b/geode-management/src/test/java/org/apache/geode/cache/configuration/CacheElementJsonMappingTest.java
index c244e00..2d2be4f 100644
--- a/geode-management/src/test/java/org/apache/geode/cache/configuration/CacheElementJsonMappingTest.java
+++ b/geode-management/src/test/java/org/apache/geode/cache/configuration/CacheElementJsonMappingTest.java
@@ -26,13 +26,15 @@ import org.junit.Test;
import org.apache.geode.management.api.ClusterManagementResult;
import org.apache.geode.management.configuration.MemberConfig;
+import org.apache.geode.management.configuration.RuntimeCacheElement;
+import org.apache.geode.management.configuration.RuntimeRegionConfig;
import org.apache.geode.util.internal.GeodeJsonMapper;
public class CacheElementJsonMappingTest {
private static ObjectMapper mapper = GeodeJsonMapper.getMapper();
private static MemberConfig member;
- private static RegionConfig region;
+ private static RuntimeRegionConfig region;
@BeforeClass
public static void beforeClass() throws Exception {
@@ -40,7 +42,7 @@ public class CacheElementJsonMappingTest {
member.setId("server");
member.setPid("123");
- region = new RegionConfig();
+ region = new RuntimeRegionConfig();
region.setName("test");
}
@@ -79,7 +81,7 @@ public class CacheElementJsonMappingTest {
@Test
public void serializeResult() throws Exception {
ClusterManagementResult result = new ClusterManagementResult();
- List<CacheElement> elements = new ArrayList<>();
+ List<RuntimeCacheElement> elements = new ArrayList<>();
elements.add(region);
elements.add(member);
result.setResult(elements);
@@ -108,4 +110,50 @@ public class CacheElementJsonMappingTest {
String json = mapper.writeValueAsString(region);
assertThat(json).doesNotContain("\"group\"");
}
+
+ @Test
+ public void group() throws Exception {
+ String json = "{'name':'test','group':'group1'}";
+ RegionConfig regionConfig = mapper.readValue(json, RegionConfig.class);
+ assertThat(regionConfig.getGroup()).isEqualTo("group1");
+ }
+
+ @Test
+ public void groups() throws Exception {
+ String json = "{'name':'test','groups':['group1','group2']}";
+ RuntimeRegionConfig regionConfig = mapper.readValue(json, RuntimeRegionConfig.class);
+ assertThat(regionConfig.getGroups()).containsExactlyInAnyOrder("group1", "group2");
+ }
+
+ @Test
+ public void serializeGroup() throws Exception {
+ RegionConfig config = new RegionConfig();
+ config.setName("test");
+ config.setGroup("group1");
+ String json = mapper.writeValueAsString(config);
+ System.out.println(json);
+ assertThat(json)
+ .contains("\"group\":\"group1\"");
+ }
+
+ @Test
+ public void serializeMultipleGroup() throws Exception {
+ RuntimeRegionConfig config = new RuntimeRegionConfig();
+ config.setName("test");
+ config.getGroups().add("group1");
+ config.getGroups().add("group2");
+ String json = mapper.writeValueAsString(config);
+ System.out.println(json);
+ assertThat(json).contains("\"groups\":[\"group1\",\"group2\"]").doesNotContain("\"group\"");
+ }
+
+ @Test
+ public void serializeGroupCluster() throws Exception {
+ RegionConfig config = new RegionConfig();
+ config.setName("test");
+ config.setGroup("cluster");
+ String json = mapper.writeValueAsString(config);
+ System.out.println(json);
+ assertThat(json).contains("\"group\":\"cluster\"");
+ }
}
diff --git a/geode-management/src/test/java/org/apache/geode/cache/configuration/CacheElementTest.java b/geode-management/src/test/java/org/apache/geode/cache/configuration/CacheElementTest.java
new file mode 100644
index 0000000..b3d075b
--- /dev/null
+++ b/geode-management/src/test/java/org/apache/geode/cache/configuration/CacheElementTest.java
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.apache.geode.cache.configuration;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import org.apache.geode.management.configuration.RuntimeCacheElement;
+import org.apache.geode.management.configuration.RuntimeRegionConfig;
+import org.apache.geode.util.internal.GeodeJsonMapper;
+
+public class CacheElementTest {
+
+ private CacheElement element;
+ private RuntimeCacheElement runtime;
+
+ private static ObjectMapper mapper;
+ private String json;
+
+ @BeforeClass
+ public static void beforeClass() {
+ mapper = GeodeJsonMapper.getMapper();
+ }
+
+ @Before
+ public void before() throws Exception {
+ element = new RegionConfig();
+ runtime = new RuntimeRegionConfig();
+ }
+
+ @Test
+ public void plainRegionConfig() throws Exception {
+ assertThat(element.getGroup()).isNull();
+ assertThat(element.getConfigGroup()).isEqualTo("cluster");
+ json = mapper.writeValueAsString(element);
+ System.out.println(json);
+ assertThat(json).doesNotContain("group").doesNotContain("groups");
+ }
+
+ @Test
+ public void plainRuntimeRegionConfig() throws Exception {
+ assertThat(runtime.getGroup()).isNull();
+ assertThat(runtime.getGroups()).isNotNull().isEmpty();
+ json = mapper.writeValueAsString(runtime);
+ System.out.println(json);
+ assertThat(json).doesNotContain("group").doesNotContain("groups");
+ }
+
+
+ @Test
+ public void setterRegionConfigGroup() throws Exception {
+ element.setGroup("group1");
+ assertThat(element.getGroup()).isEqualTo("group1");
+ assertThat(element.getConfigGroup()).isEqualTo("group1");
+ json = mapper.writeValueAsString(element);
+ System.out.println(json);
+ assertThat(json).contains("\"group\":\"group1\"").doesNotContain("groups");
+ }
+
+ @Test
+ public void setterRuntimeRegionConfig() throws Exception {
+ runtime.getGroups().add("group1");
+ assertThat(runtime.getGroup()).isEqualTo("group1");
+ json = mapper.writeValueAsString(runtime);
+ System.out.println(json);
+ assertThat(json).contains("\"groups\":[\"group1\"]").doesNotContain("\"group\"");
+ }
+
+ @Test
+ public void copy() throws Exception {
+ RegionConfig config = new RegionConfig();
+ config.setName("test");
+ runtime = new RuntimeRegionConfig(config);
+ assertThat(runtime.getGroup()).isNull();
+ assertThat(runtime.getGroups()).hasSize(0);
+ }
+
+ @Test
+ public void setGroup() throws Exception {
+ element.setGroup("group1");
+ assertThat(element.getGroup()).isEqualTo("group1");
+ element.setGroup("");
+ assertThat(element.getGroup()).isNull();
+ }
+}
diff --git a/geode-web-management/src/distributedTest/java/org/apache/geode/management/client/ClientClusterManagementServiceDUnitTest.java b/geode-web-management/src/distributedTest/java/org/apache/geode/management/client/ClientClusterManagementServiceDUnitTest.java
index c98b445..2d14160 100644
--- a/geode-web-management/src/distributedTest/java/org/apache/geode/management/client/ClientClusterManagementServiceDUnitTest.java
+++ b/geode-web-management/src/distributedTest/java/org/apache/geode/management/client/ClientClusterManagementServiceDUnitTest.java
@@ -19,8 +19,6 @@ package org.apache.geode.management.client;
import static org.apache.geode.test.junit.assertions.ClusterManagementResultAssert.assertManagementResult;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
-import java.util.List;
-
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -32,7 +30,6 @@ import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.web.context.WebApplicationContext;
-import org.apache.geode.cache.configuration.CacheElement;
import org.apache.geode.cache.configuration.RegionConfig;
import org.apache.geode.cache.configuration.RegionType;
import org.apache.geode.management.api.ClusterManagementResult;
@@ -68,7 +65,7 @@ public class ClientClusterManagementServiceDUnitTest {
@Test
@WithMockUser
- public void createAndListRegion() {
+ public void createRegion() {
RegionConfig region = new RegionConfig();
region.setName("customer");
region.setType(RegionType.REPLICATE);
@@ -78,16 +75,6 @@ public class ClientClusterManagementServiceDUnitTest {
// in StressNewTest, this will be run multiple times without restarting the locator
assertManagementResult(result).hasStatusCode(ClusterManagementResult.StatusCode.OK,
ClusterManagementResult.StatusCode.ENTITY_EXISTS);
-
- // list region when regions are not created in a group
- RegionConfig noFilter = new RegionConfig();
- ClusterManagementResult list = client.list(noFilter);
- List<CacheElement> regions = list.getResult();
- assertThat(regions.size()).isEqualTo(1);
- RegionConfig cacheElement = (RegionConfig) regions.get(0);
- assertThat(cacheElement.getId()).isEqualTo("customer");
- assertThat(cacheElement.getType()).isEqualTo("REPLICATE");
- assertThat(cacheElement.getConfigGroup()).isEqualTo("cluster");
}
diff --git a/geode-web-management/src/integrationTest/java/org/apache/geode/management/internal/rest/RegionManagementIntegrationTest.java b/geode-web-management/src/integrationTest/java/org/apache/geode/management/internal/rest/RegionManagementIntegrationTest.java
index 35c81d3..b193e1a 100644
--- a/geode-web-management/src/integrationTest/java/org/apache/geode/management/internal/rest/RegionManagementIntegrationTest.java
+++ b/geode-web-management/src/integrationTest/java/org/apache/geode/management/internal/rest/RegionManagementIntegrationTest.java
@@ -34,6 +34,7 @@ import org.apache.geode.cache.configuration.RegionType;
import org.apache.geode.management.api.ClusterManagementResult;
import org.apache.geode.management.api.ClusterManagementService;
import org.apache.geode.management.client.ClusterManagementServiceProvider;
+import org.apache.geode.management.configuration.RuntimeRegionConfig;
@RunWith(SpringRunner.class)
@ContextConfiguration(locations = {"classpath*:WEB-INF/geode-management-servlet.xml"},
@@ -94,6 +95,18 @@ public class RegionManagementIntegrationTest {
}
@Test
+ public void invalidConfigObject() throws Exception {
+ RuntimeRegionConfig regionConfig = new RuntimeRegionConfig();
+ regionConfig.setName("customers");
+ regionConfig.setGroup("group1");
+
+ assertManagementResult(client.create(regionConfig))
+ .failed()
+ .hasStatusCode(ClusterManagementResult.StatusCode.ILLEGAL_ARGUMENT)
+ .containsStatusMessage("Configuration type RuntimeRegionConfig is not supported");
+ }
+
+ @Test
@WithMockUser
public void ping() throws Exception {
context.perform(get("/v2/ping"))