This is an automated email from the ASF dual-hosted git repository.
dschneider 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 c0a6508 GEODE-6142: Check JDBC mapping before destroy region (#2950)
c0a6508 is described below
commit c0a650832a237a2297c5ec7f783e729ff09a6a8a
Author: Jianxia Chen <[email protected]>
AuthorDate: Thu Dec 6 17:31:40 2018 -0800
GEODE-6142: Check JDBC mapping before destroy region (#2950)
gfsh destroy region will now fail if the region has a jdbc-mapping that
has not yet been destroyed.
Co-authored-by: Darrel Schneider <[email protected]>
Co-authored-by: Jianxia Chen <[email protected]>
---
.../cli/DestroyMappingCommandDunitTest.java | 20 ++++++
.../cli/commands/DestroyRegionCommand.java | 33 ++++++++++
.../cli/commands/DestroyRegionCommandTest.java | 77 +++++++++++++++++++---
3 files changed, 122 insertions(+), 8 deletions(-)
diff --git
a/geode-connectors/src/distributedTest/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyMappingCommandDunitTest.java
b/geode-connectors/src/distributedTest/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyMappingCommandDunitTest.java
index 2cfcc7e..6fc139a 100644
---
a/geode-connectors/src/distributedTest/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyMappingCommandDunitTest.java
+++
b/geode-connectors/src/distributedTest/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyMappingCommandDunitTest.java
@@ -95,6 +95,26 @@ public class DestroyMappingCommandDunitTest implements
Serializable {
}
@Test
+ public void destroyRegionThatHasSynchronousMappingFails() {
+ setupSynchronousMapping();
+
+ gfsh.executeAndAssertThat("destroy region --name=" +
REGION_NAME).statusIsError()
+ .containsOutput("Cannot destroy region \"" + REGION_NAME
+ + "\" because JDBC mapping exists. Use \"destroy jdbc-mapping\"
first.");
+ }
+
+ @Test
+ public void destroyRegionThatHadSynchronousMappingSucceeds() {
+ setupSynchronousMapping();
+ CommandStringBuilder csb = new CommandStringBuilder(DESTROY_MAPPING);
+ csb.addOption(DESTROY_MAPPING__REGION_NAME, REGION_NAME);
+ gfsh.executeAndAssertThat(csb.toString()).statusIsSuccess();
+
+ gfsh.executeAndAssertThat("destroy region --name=" +
REGION_NAME).statusIsSuccess();
+ }
+
+
+ @Test
public void destroysAsyncMapping() {
setupAsyncMapping();
CommandStringBuilder csb = new CommandStringBuilder(DESTROY_MAPPING);
diff --git
a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/DestroyRegionCommand.java
b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/DestroyRegionCommand.java
index ba84405..8aa147d 100644
---
a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/DestroyRegionCommand.java
+++
b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/DestroyRegionCommand.java
@@ -20,6 +20,9 @@ import java.util.Set;
import org.springframework.shell.core.annotation.CliCommand;
import org.springframework.shell.core.annotation.CliOption;
+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.DistributedMember;
import
org.apache.geode.distributed.internal.InternalConfigurationPersistenceService;
import org.apache.geode.management.cli.CliMetaData;
@@ -58,6 +61,12 @@ public class DestroyRegionCommand extends
InternalGfshCommand {
throw new EntityNotFoundException(message, ifExists);
}
+ try {
+ checkForJDBCMapping(regionPath);
+ } catch (IllegalStateException e) {
+ return ResultBuilder.createGemFireErrorResult(e.getMessage());
+ }
+
// destroy is called on each member. If the region destroy is successful
on one member, we
// deem the destroy action successful, since if one member destroy
successfully, the subsequent
// destroy on a another member would probably throw
RegionDestroyedException
@@ -77,4 +86,28 @@ public class DestroyRegionCommand extends
InternalGfshCommand {
return result;
}
+ void checkForJDBCMapping(String regionPath) {
+ String regionName = regionPath;
+ if (regionPath.startsWith("/")) {
+ regionName = regionPath.substring(1);
+ }
+ InternalConfigurationPersistenceService ccService =
getConfigurationPersistenceService();
+ if (ccService == null) {
+ return;
+ }
+ CacheConfig cacheConfig = ccService.getCacheConfig(null);
+ if (cacheConfig == null) {
+ return;
+ }
+ RegionConfig regionConfig =
CacheElement.findElement(cacheConfig.getRegions(), regionName);
+ if (regionConfig == null) {
+ return;
+ }
+ CacheElement element =
+ CacheElement.findElement(regionConfig.getCustomRegionElements(),
"jdbc-mapping");
+ if (element != null) {
+ throw new IllegalStateException("Cannot destroy region \"" + regionName
+ + "\" because JDBC mapping exists. Use \"destroy jdbc-mapping\"
first.");
+ }
+ }
}
diff --git
a/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/DestroyRegionCommandTest.java
b/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/DestroyRegionCommandTest.java
index b393275..374eba1 100644
---
a/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/DestroyRegionCommandTest.java
+++
b/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/DestroyRegionCommandTest.java
@@ -33,12 +33,14 @@ import org.junit.Before;
import org.junit.ClassRule;
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.DistributedMember;
import
org.apache.geode.distributed.internal.InternalConfigurationPersistenceService;
import org.apache.geode.internal.cache.InternalCache;
import org.apache.geode.management.internal.cli.GfshParseResult;
import org.apache.geode.management.internal.cli.functions.CliFunctionResult;
-import org.apache.geode.management.internal.cli.result.CommandResult;
import org.apache.geode.management.internal.configuration.domain.XmlEntity;
import org.apache.geode.test.junit.rules.GfshParserRule;
@@ -48,10 +50,14 @@ public class DestroyRegionCommandTest {
public static GfshParserRule parser = new GfshParserRule();
private DestroyRegionCommand command;
- private CommandResult result;
private CliFunctionResult result1, result2;
private InternalConfigurationPersistenceService ccService;
XmlEntity xmlEntity;
+ private CacheConfig cacheConfig = mock(CacheConfig.class);
+ private RegionConfig regionConfig = mock(RegionConfig.class);
+ private CacheElement cacheElement = mock(CacheElement.class);
+ private List<RegionConfig> regionConfigList =
Collections.singletonList(regionConfig);
+ private List<CacheElement> cacheElementList =
Collections.singletonList(cacheElement);
@Before
public void before() throws Exception {
@@ -73,7 +79,7 @@ public class DestroyRegionCommandTest {
}
@Test
- public void invalidRegion() throws Exception {
+ public void invalidRegion() {
parser.executeAndAssertThat(command, "destroy region").statusIsError()
.containsOutput("Invalid command");
@@ -91,7 +97,7 @@ public class DestroyRegionCommandTest {
}
@Test
- public void whenNoRegionIsFoundOnAnyMembers() throws Exception {
+ public void whenNoRegionIsFoundOnAnyMembers() {
doReturn(Collections.emptySet()).when(command).findMembersForRegion(any());
parser.executeAndAssertThat(command, "destroy region
--name=test").statusIsError()
.containsOutput("Could not find a Region with Region path");
@@ -101,7 +107,7 @@ public class DestroyRegionCommandTest {
}
@Test
- public void multipleResultReturned_oneSucess_oneFailed() throws Exception {
+ public void multipleResultReturned_oneSucess_oneFailed() {
// mock this to pass the member search call
doReturn(Collections.singleton(DistributedMember.class)).when(command)
.findMembersForRegion(any());
@@ -120,7 +126,7 @@ public class DestroyRegionCommandTest {
}
@Test
- public void multipleResultReturned_oneSuccess_oneException() throws
Exception {
+ public void multipleResultReturned_oneSuccess_oneException() {
// mock this to pass the member search call
doReturn(Collections.singleton(DistributedMember.class)).when(command)
.findMembersForRegion(any());
@@ -140,7 +146,7 @@ public class DestroyRegionCommandTest {
}
@Test
- public void multipleResultReturned_all_failed() throws Exception {
+ public void multipleResultReturned_all_failed() {
// mock this to pass the member search call
doReturn(Collections.singleton(DistributedMember.class)).when(command)
.findMembersForRegion(any());
@@ -154,7 +160,62 @@ public class DestroyRegionCommandTest {
.containsOutput("result1 message").containsOutput("something
happened");
- // verify that xmlEntiry returned by the result1 is saved to Cluster config
+ // verify that xmlEntry returned by the result1 is saved to Cluster config
verify(command, never()).persistClusterConfiguration(any(), any());
}
+
+ private void setupJDBCMappingOnRegion(String regionName) {
+ doReturn(cacheConfig).when(ccService).getCacheConfig(null);
+ doReturn(regionConfigList).when(cacheConfig).getRegions();
+ doReturn(regionName).when(regionConfig).getName();
+ doReturn(regionName).when(regionConfig).getId();
+ doReturn(cacheElementList).when(regionConfig).getCustomRegionElements();
+ doReturn("jdbc-mapping").when(cacheElement).getId();
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void checkForJDBCMappingWithRegionPathThrowsIllegalStateException() {
+ setupJDBCMappingOnRegion("regionName");
+
+ command.checkForJDBCMapping("/regionName");
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void checkForJDBCMappingWithRegionNameThrowsIllegalStateException() {
+ setupJDBCMappingOnRegion("regionName");
+
+ command.checkForJDBCMapping("regionName");
+ }
+
+ @Test
+ public void checkForJDBCMappingWithNoClusterConfigDoesNotThrowException() {
+ setupJDBCMappingOnRegion("regionName");
+ doReturn(null).when(command).getConfigurationPersistenceService();
+
+ command.checkForJDBCMapping("regionName");
+ }
+
+ @Test
+ public void checkForJDBCMappingWithNoCacheConfigDoesNotThrowException() {
+ setupJDBCMappingOnRegion("regionName");
+ doReturn(null).when(ccService).getCacheConfig(null);
+
+ command.checkForJDBCMapping("regionName");
+ }
+
+ @Test
+ public void checkForJDBCMappingWithNoRegionConfigDoesNotThrowException() {
+ setupJDBCMappingOnRegion("regionName");
+ doReturn(Collections.emptyList()).when(cacheConfig).getRegions();
+
+ command.checkForJDBCMapping("regionName");
+ }
+
+ @Test
+ public void checkForJDBCMappingWithNoJDBCMappingDoesNotThrowException() {
+ setupJDBCMappingOnRegion("regionName");
+ doReturn("something").when(cacheElement).getId();
+
+ command.checkForJDBCMapping("regionName");
+ }
}