This is an automated email from the ASF dual-hosted git repository. jchen21 pushed a commit to branch feature/GEODE-6118 in repository https://gitbox.apache.org/repos/asf/geode.git
commit 193db1b09d2f65b028c0162f316fd6649b7bed0d Author: Darrel Schneider <dschnei...@pivotal.io> AuthorDate: Fri Nov 30 13:25:06 2018 -0800 GEODE-6118: Support slash on region name for jdbc-mapping commands Co-authored-by: Darrel Schneider <dschnei...@pivotal.io> Co-authored-by: Jianxia Chen <jche...@apache.org> --- geode-connectors/build.gradle | 4 +- .../cli/CreateMappingCommandDUnitTest.java | 179 ++++++++++++--------- .../cli/DescribeMappingCommandDUnitTest.java | 23 ++- .../cli/DestroyMappingCommandDunitTest.java | 46 +++++- .../jdbc/internal/cli/CreateMappingCommand.java | 7 + .../jdbc/internal/cli/DescribeMappingCommand.java | 4 + .../jdbc/internal/cli/DestroyMappingCommand.java | 4 + .../internal/cli/CreateMappingCommandTest.java | 35 ++++ .../internal/cli/DescribeMappingCommandTest.java | 18 +++ .../internal/cli/DestroyMappingCommandTest.java | 17 +- 10 files changed, 249 insertions(+), 88 deletions(-) diff --git a/geode-connectors/build.gradle b/geode-connectors/build.gradle index 9795dfe..bd05614 100644 --- a/geode-connectors/build.gradle +++ b/geode-connectors/build.gradle @@ -72,10 +72,12 @@ dependencies { integrationTestCompile('junit:junit:' + project.'junit.version') integrationTestCompile('junit:junit:4.12') integrationTestCompile('org.assertj:assertj-core:' + project.'assertj-core.version') + integrationTestCompile('pl.pragmatists:JUnitParams:' + project.'JUnitParams.version') distributedTestCompile('junit:junit:' + project.'junit.version') distributedTestCompile('org.assertj:assertj-core:' + project.'assertj-core.version') distributedTestCompile('org.mockito:mockito-core:2.19.1') + distributedTestCompile('pl.pragmatists:JUnitParams:' + project.'JUnitParams.version') distributedTestRuntime('org.apache.derby:derby:' + project.'derby.version') acceptanceTestCompile('com.github.stefanbirkner:system-rules:' + project.'system-rules.version') { @@ -86,7 +88,7 @@ dependencies { acceptanceTestCompile('org.awaitility:awaitility:' + project.'awaitility.version') acceptanceTestCompile('org.mockito:mockito-core:' + project.'mockito-core.version') acceptanceTestCompile(group: 'com.palantir.docker.compose', name: 'docker-compose-rule-core', version: '0.31.1') - + acceptanceTestCompile('pl.pragmatists:JUnitParams:' + project.'JUnitParams.version') acceptanceTestCompile(group: 'com.palantir.docker.compose', name: 'docker-compose-rule-junit4', version: '0.31.1') acceptanceTestRuntime(group: 'mysql', name: 'mysql-connector-java', version: '5.1.46') diff --git a/geode-connectors/src/distributedTest/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingCommandDUnitTest.java b/geode-connectors/src/distributedTest/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingCommandDUnitTest.java index d9f8e94..6856fc7 100644 --- a/geode-connectors/src/distributedTest/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingCommandDUnitTest.java +++ b/geode-connectors/src/distributedTest/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingCommandDUnitTest.java @@ -24,10 +24,13 @@ import static org.assertj.core.api.Assertions.assertThat; import java.util.List; +import junitparams.JUnitParamsRunner; +import junitparams.Parameters; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; +import org.junit.runner.RunWith; import org.apache.geode.cache.Region; import org.apache.geode.cache.asyncqueue.AsyncEventQueue; @@ -49,6 +52,7 @@ import org.apache.geode.test.junit.rules.GfshCommandRule; import org.apache.geode.test.junit.rules.serializable.SerializableTestName; @Category({JDBCConnectorTest.class}) +@RunWith(JUnitParamsRunner.class) public class CreateMappingCommandDUnitTest { private static final String REGION_NAME = "testRegion"; @@ -74,96 +78,108 @@ public class CreateMappingCommandDUnitTest { } - private void setupReplicate() { - setupReplicate(false); + private void setupReplicate(String regionName) { + setupReplicate(regionName, false); } - private void setupReplicate(boolean addLoader) { - gfsh.executeAndAssertThat("create region --name=" + REGION_NAME + " --type=REPLICATE" + private void setupReplicate(String regionName, boolean addLoader) { + gfsh.executeAndAssertThat("create region --name=" + regionName + " --type=REPLICATE" + (addLoader ? " --cache-loader=" + JdbcLoader.class.getName() : "")) .statusIsSuccess(); } - private void setupPartition() { - gfsh.executeAndAssertThat("create region --name=" + REGION_NAME + " --type=PARTITION") + private void setupPartition(String regionName) { + gfsh.executeAndAssertThat("create region --name=" + regionName + " --type=PARTITION") .statusIsSuccess(); } - private void setupAsyncEventQueue() { + private void setupAsyncEventQueue(String regionName) { gfsh.executeAndAssertThat( "create async-event-queue --id=" - + CreateMappingCommand.createAsyncEventQueueName(REGION_NAME) + + CreateMappingCommand.createAsyncEventQueueName(regionName) + " --listener=" + JdbcAsyncWriter.class.getName()) .statusIsSuccess(); } - private static RegionMapping getRegionMappingFromClusterConfig() { + private static RegionMapping getRegionMappingFromClusterConfig(String regionName) { CacheConfig cacheConfig = InternalLocator.getLocator().getConfigurationPersistenceService().getCacheConfig(null); RegionConfig regionConfig = cacheConfig.getRegions().stream() - .filter(region -> region.getName().equals(REGION_NAME)).findFirst().orElse(null); + .filter(region -> region.getName().equals(convertRegionPathToName(regionName))).findFirst() + .orElse(null); return (RegionMapping) regionConfig.getCustomRegionElements().stream() .filter(element -> element instanceof RegionMapping).findFirst().orElse(null); } - private static RegionMapping getRegionMappingFromService() { + private static RegionMapping getRegionMappingFromService(String regionName) { return ClusterStartupRule.getCache().getService(JdbcConnectorService.class) - .getMappingForRegion(REGION_NAME); + .getMappingForRegion(convertRegionPathToName(regionName)); } - private static void validateAsyncEventQueueCreatedInClusterConfig(boolean isParallel) { + private static void validateAsyncEventQueueCreatedInClusterConfig(String regionName, + boolean isParallel) { CacheConfig cacheConfig = InternalLocator.getLocator().getConfigurationPersistenceService().getCacheConfig(null); List<CacheConfig.AsyncEventQueue> queueList = cacheConfig.getAsyncEventQueues(); CacheConfig.AsyncEventQueue queue = queueList.get(0); - String queueName = CreateMappingCommand.createAsyncEventQueueName(REGION_NAME); + String queueName = CreateMappingCommand.createAsyncEventQueueName(regionName); assertThat(queue.getId()).isEqualTo(queueName); assertThat(queue.getAsyncEventListener().getClassName()) .isEqualTo(JdbcAsyncWriter.class.getName()); assertThat(queue.isParallel()).isEqualTo(isParallel); } - private static void validateRegionAlteredInClusterConfig(boolean synchronous) { + private static String convertRegionPathToName(String regionPath) { + if (regionPath.startsWith("/")) { + return regionPath.substring(1); + } + return regionPath; + } + + private static void validateRegionAlteredInClusterConfig(String regionName, boolean synchronous) { CacheConfig cacheConfig = InternalLocator.getLocator().getConfigurationPersistenceService().getCacheConfig(null); RegionConfig regionConfig = cacheConfig.getRegions().stream() - .filter(region -> region.getName().equals(REGION_NAME)).findFirst().orElse(null); + .filter(region -> region.getName().equals(convertRegionPathToName(regionName))).findFirst() + .orElse(null); RegionAttributesType attributes = regionConfig.getRegionAttributes().get(0); assertThat(attributes.getCacheLoader().getClassName()).isEqualTo(JdbcLoader.class.getName()); if (synchronous) { assertThat(attributes.getCacheWriter().getClassName()).isEqualTo(JdbcWriter.class.getName()); } else { - String queueName = CreateMappingCommand.createAsyncEventQueueName(REGION_NAME); + String queueName = CreateMappingCommand.createAsyncEventQueueName(regionName); assertThat(attributes.getAsyncEventQueueIds()).isEqualTo(queueName); } } - private static void validateAsyncEventQueueCreatedOnServer(boolean isParallel) { + private static void validateAsyncEventQueueCreatedOnServer(String regionName, + boolean isParallel) { InternalCache cache = ClusterStartupRule.getCache(); - String queueName = CreateMappingCommand.createAsyncEventQueueName(REGION_NAME); + String queueName = CreateMappingCommand.createAsyncEventQueueName(regionName); AsyncEventQueue queue = cache.getAsyncEventQueue(queueName); assertThat(queue).isNotNull(); assertThat(queue.getAsyncEventListener()).isInstanceOf(JdbcAsyncWriter.class); assertThat(queue.isParallel()).isEqualTo(isParallel); } - private static void validateRegionAlteredOnServer(boolean synchronous) { + private static void validateRegionAlteredOnServer(String regionName, boolean synchronous) { InternalCache cache = ClusterStartupRule.getCache(); - Region<?, ?> region = cache.getRegion(REGION_NAME); + Region<?, ?> region = cache.getRegion(regionName); assertThat(region.getAttributes().getCacheLoader()).isInstanceOf(JdbcLoader.class); if (synchronous) { assertThat(region.getAttributes().getCacheWriter()).isInstanceOf(JdbcWriter.class); } else { - String queueName = CreateMappingCommand.createAsyncEventQueueName(REGION_NAME); + String queueName = CreateMappingCommand.createAsyncEventQueueName(regionName); assertThat(region.getAttributes().getAsyncEventQueueIds()).contains(queueName); } } @Test - public void createMappingUpdatesServiceAndClusterConfig() { - setupReplicate(); + @Parameters({REGION_NAME, "/" + REGION_NAME}) + public void createMappingUpdatesServiceAndClusterConfig(String regionName) { + setupReplicate(regionName); CommandStringBuilder csb = new CommandStringBuilder(CREATE_MAPPING); - csb.addOption(CREATE_MAPPING__REGION_NAME, REGION_NAME); + csb.addOption(CREATE_MAPPING__REGION_NAME, regionName); csb.addOption(CREATE_MAPPING__DATA_SOURCE_NAME, "connection"); csb.addOption(CREATE_MAPPING__TABLE_NAME, "myTable"); csb.addOption(CREATE_MAPPING__PDX_NAME, "myPdxClass"); @@ -171,29 +187,30 @@ public class CreateMappingCommandDUnitTest { gfsh.executeAndAssertThat(csb.toString()).statusIsSuccess(); server.invoke(() -> { - RegionMapping mapping = getRegionMappingFromService(); + RegionMapping mapping = getRegionMappingFromService(regionName); assertThat(mapping.getDataSourceName()).isEqualTo("connection"); assertThat(mapping.getTableName()).isEqualTo("myTable"); assertThat(mapping.getPdxName()).isEqualTo("myPdxClass"); - validateRegionAlteredOnServer(false); - validateAsyncEventQueueCreatedOnServer(false); + validateRegionAlteredOnServer(regionName, false); + validateAsyncEventQueueCreatedOnServer(regionName, false); }); locator.invoke(() -> { - RegionMapping regionMapping = getRegionMappingFromClusterConfig(); + RegionMapping regionMapping = getRegionMappingFromClusterConfig(regionName); assertThat(regionMapping.getDataSourceName()).isEqualTo("connection"); assertThat(regionMapping.getTableName()).isEqualTo("myTable"); assertThat(regionMapping.getPdxName()).isEqualTo("myPdxClass"); - validateRegionAlteredInClusterConfig(false); - validateAsyncEventQueueCreatedInClusterConfig(false); + validateRegionAlteredInClusterConfig(regionName, false); + validateAsyncEventQueueCreatedInClusterConfig(regionName, false); }); } @Test - public void createSynchronousMappingUpdatesServiceAndClusterConfig() { - setupReplicate(); + @Parameters({REGION_NAME, "/" + REGION_NAME}) + public void createSynchronousMappingUpdatesServiceAndClusterConfig(String regionName) { + setupReplicate(regionName); CommandStringBuilder csb = new CommandStringBuilder(CREATE_MAPPING); - csb.addOption(CREATE_MAPPING__REGION_NAME, REGION_NAME); + csb.addOption(CREATE_MAPPING__REGION_NAME, regionName); csb.addOption(CREATE_MAPPING__DATA_SOURCE_NAME, "connection"); csb.addOption(CREATE_MAPPING__TABLE_NAME, "myTable"); csb.addOption(CREATE_MAPPING__PDX_NAME, "myPdxClass"); @@ -202,27 +219,28 @@ public class CreateMappingCommandDUnitTest { gfsh.executeAndAssertThat(csb.toString()).statusIsSuccess(); server.invoke(() -> { - RegionMapping mapping = getRegionMappingFromService(); + RegionMapping mapping = getRegionMappingFromService(regionName); assertThat(mapping.getDataSourceName()).isEqualTo("connection"); assertThat(mapping.getTableName()).isEqualTo("myTable"); assertThat(mapping.getPdxName()).isEqualTo("myPdxClass"); - validateRegionAlteredOnServer(true); + validateRegionAlteredOnServer(regionName, true); }); locator.invoke(() -> { - RegionMapping regionMapping = getRegionMappingFromClusterConfig(); + RegionMapping regionMapping = getRegionMappingFromClusterConfig(regionName); assertThat(regionMapping.getDataSourceName()).isEqualTo("connection"); assertThat(regionMapping.getTableName()).isEqualTo("myTable"); assertThat(regionMapping.getPdxName()).isEqualTo("myPdxClass"); - validateRegionAlteredInClusterConfig(true); + validateRegionAlteredInClusterConfig(regionName, true); }); } @Test - public void createMappingWithPartitionUpdatesServiceAndClusterConfig() { - setupPartition(); + @Parameters({REGION_NAME, "/" + REGION_NAME}) + public void createMappingWithPartitionUpdatesServiceAndClusterConfig(String regionName) { + setupPartition(regionName); CommandStringBuilder csb = new CommandStringBuilder(CREATE_MAPPING); - csb.addOption(CREATE_MAPPING__REGION_NAME, REGION_NAME); + csb.addOption(CREATE_MAPPING__REGION_NAME, regionName); csb.addOption(CREATE_MAPPING__DATA_SOURCE_NAME, "connection"); csb.addOption(CREATE_MAPPING__TABLE_NAME, "myTable"); csb.addOption(CREATE_MAPPING__PDX_NAME, "myPdxClass"); @@ -230,80 +248,83 @@ public class CreateMappingCommandDUnitTest { gfsh.executeAndAssertThat(csb.toString()).statusIsSuccess(); server.invoke(() -> { - RegionMapping mapping = getRegionMappingFromService(); + RegionMapping mapping = getRegionMappingFromService(regionName); assertThat(mapping.getDataSourceName()).isEqualTo("connection"); assertThat(mapping.getTableName()).isEqualTo("myTable"); assertThat(mapping.getPdxName()).isEqualTo("myPdxClass"); - validateRegionAlteredOnServer(false); - validateAsyncEventQueueCreatedOnServer(true); + validateRegionAlteredOnServer(regionName, false); + validateAsyncEventQueueCreatedOnServer(regionName, true); }); locator.invoke(() -> { - RegionMapping regionMapping = getRegionMappingFromClusterConfig(); + RegionMapping regionMapping = getRegionMappingFromClusterConfig(regionName); assertThat(regionMapping.getDataSourceName()).isEqualTo("connection"); assertThat(regionMapping.getTableName()).isEqualTo("myTable"); assertThat(regionMapping.getPdxName()).isEqualTo("myPdxClass"); - validateRegionAlteredInClusterConfig(false); - validateAsyncEventQueueCreatedInClusterConfig(true); + validateRegionAlteredInClusterConfig(regionName, false); + validateAsyncEventQueueCreatedInClusterConfig(regionName, true); }); } @Test - public void createMappingWithNoTable() { - setupReplicate(); + @Parameters({REGION_NAME, "/" + REGION_NAME}) + public void createMappingWithNoTable(String regionName) { + setupReplicate(regionName); CommandStringBuilder csb = new CommandStringBuilder(CREATE_MAPPING); - csb.addOption(CREATE_MAPPING__REGION_NAME, REGION_NAME); + csb.addOption(CREATE_MAPPING__REGION_NAME, regionName); csb.addOption(CREATE_MAPPING__DATA_SOURCE_NAME, "connection"); csb.addOption(CREATE_MAPPING__PDX_NAME, "myPdxClass"); gfsh.executeAndAssertThat(csb.toString()).statusIsSuccess(); server.invoke(() -> { - RegionMapping mapping = getRegionMappingFromService(); + RegionMapping mapping = getRegionMappingFromService(regionName); assertThat(mapping.getDataSourceName()).isEqualTo("connection"); assertThat(mapping.getTableName()).isNull(); assertThat(mapping.getPdxName()).isEqualTo("myPdxClass"); - validateRegionAlteredOnServer(false); - validateAsyncEventQueueCreatedOnServer(false); + validateRegionAlteredOnServer(regionName, false); + validateAsyncEventQueueCreatedOnServer(regionName, false); }); locator.invoke(() -> { - RegionMapping regionMapping = getRegionMappingFromClusterConfig(); + RegionMapping regionMapping = getRegionMappingFromClusterConfig(regionName); assertThat(regionMapping.getDataSourceName()).isEqualTo("connection"); assertThat(regionMapping.getTableName()).isNull(); assertThat(regionMapping.getPdxName()).isEqualTo("myPdxClass"); - validateRegionAlteredInClusterConfig(false); - validateAsyncEventQueueCreatedInClusterConfig(false); + validateRegionAlteredInClusterConfig(regionName, false); + validateAsyncEventQueueCreatedInClusterConfig(regionName, false); }); } @Test - public void createExistingRegionMappingFails() { - setupReplicate(); + @Parameters({REGION_NAME, "/" + REGION_NAME}) + public void createExistingRegionMappingFails(String regionName) { + setupReplicate(regionName); CommandStringBuilder csb = new CommandStringBuilder(CREATE_MAPPING); - csb.addOption(CREATE_MAPPING__REGION_NAME, REGION_NAME); + csb.addOption(CREATE_MAPPING__REGION_NAME, regionName); csb.addOption(CREATE_MAPPING__DATA_SOURCE_NAME, "connection"); csb.addOption(CREATE_MAPPING__PDX_NAME, "myPdxClass"); csb.addOption(CREATE_MAPPING__TABLE_NAME, "myTable"); gfsh.executeAndAssertThat(csb.toString()).statusIsSuccess(); csb = new CommandStringBuilder(CREATE_MAPPING); - csb.addOption(CREATE_MAPPING__REGION_NAME, REGION_NAME); + csb.addOption(CREATE_MAPPING__REGION_NAME, regionName); csb.addOption(CREATE_MAPPING__DATA_SOURCE_NAME, "bogusConnection"); csb.addOption(CREATE_MAPPING__PDX_NAME, "bogusPdxClass"); csb.addOption(CREATE_MAPPING__TABLE_NAME, "bogusTable"); gfsh.executeAndAssertThat(csb.toString()).statusIsError() - .containsOutput("A jdbc-mapping for " + REGION_NAME + " already exists"); + .containsOutput( + "A jdbc-mapping for " + convertRegionPathToName(regionName) + " already exists"); server.invoke(() -> { - RegionMapping mapping = getRegionMappingFromService(); + RegionMapping mapping = getRegionMappingFromService(regionName); assertThat(mapping.getDataSourceName()).isEqualTo("connection"); assertThat(mapping.getTableName()).isEqualTo("myTable"); assertThat(mapping.getPdxName()).isEqualTo("myPdxClass"); }); locator.invoke(() -> { - RegionMapping regionMapping = getRegionMappingFromClusterConfig(); + RegionMapping regionMapping = getRegionMappingFromClusterConfig(regionName); assertThat(regionMapping.getDataSourceName()).isEqualTo("connection"); assertThat(regionMapping.getTableName()).isEqualTo("myTable"); assertThat(regionMapping.getPdxName()).isEqualTo("myPdxClass"); @@ -311,10 +332,11 @@ public class CreateMappingCommandDUnitTest { } @Test - public void createMappingWithoutPdxNameFails() { - setupReplicate(); + @Parameters({REGION_NAME, "/" + REGION_NAME}) + public void createMappingWithoutPdxNameFails(String regionName) { + setupReplicate(regionName); CommandStringBuilder csb = new CommandStringBuilder(CREATE_MAPPING); - csb.addOption(CREATE_MAPPING__REGION_NAME, REGION_NAME); + csb.addOption(CREATE_MAPPING__REGION_NAME, regionName); csb.addOption(CREATE_MAPPING__DATA_SOURCE_NAME, "connection"); // NOTE: --table is optional so it should not be in the output but it is. See GEODE-3468. @@ -324,8 +346,9 @@ public class CreateMappingCommandDUnitTest { } @Test - public void createMappingWithNonExistentRegionFails() { - setupReplicate(); + @Parameters({REGION_NAME, "/" + REGION_NAME}) + public void createMappingWithNonExistentRegionFails(String regionName) { + setupReplicate(regionName); CommandStringBuilder csb = new CommandStringBuilder(CREATE_MAPPING); csb.addOption(CREATE_MAPPING__REGION_NAME, "bogusRegion"); csb.addOption(CREATE_MAPPING__DATA_SOURCE_NAME, "connection"); @@ -336,30 +359,32 @@ public class CreateMappingCommandDUnitTest { } @Test - public void createMappingWithRegionThatHasALoaderFails() { - setupReplicate(true); + @Parameters({REGION_NAME, "/" + REGION_NAME}) + public void createMappingWithRegionThatHasALoaderFails(String regionName) { + setupReplicate(regionName, true); CommandStringBuilder csb = new CommandStringBuilder(CREATE_MAPPING); - csb.addOption(CREATE_MAPPING__REGION_NAME, REGION_NAME); + csb.addOption(CREATE_MAPPING__REGION_NAME, regionName); csb.addOption(CREATE_MAPPING__DATA_SOURCE_NAME, "connection"); csb.addOption(CREATE_MAPPING__PDX_NAME, "myPdxClass"); gfsh.executeAndAssertThat(csb.toString()).statusIsError() - .containsOutput("The existing region " + REGION_NAME + .containsOutput("The existing region " + convertRegionPathToName(regionName) + " must not already have a cache-loader, but it has " + JdbcLoader.class.getName()); } @Test - public void createMappingWithExistingQueueFails() { - setupReplicate(); - setupAsyncEventQueue(); + @Parameters({REGION_NAME, "/" + REGION_NAME}) + public void createMappingWithExistingQueueFails(String regionName) { + setupReplicate(regionName); + setupAsyncEventQueue(regionName); CommandStringBuilder csb = new CommandStringBuilder(CREATE_MAPPING); - csb.addOption(CREATE_MAPPING__REGION_NAME, REGION_NAME); + csb.addOption(CREATE_MAPPING__REGION_NAME, regionName); csb.addOption(CREATE_MAPPING__DATA_SOURCE_NAME, "connection"); csb.addOption(CREATE_MAPPING__PDX_NAME, "myPdxClass"); gfsh.executeAndAssertThat(csb.toString()).statusIsError() .containsOutput("An async-event-queue named " - + CreateMappingCommand.createAsyncEventQueueName(REGION_NAME) + + CreateMappingCommand.createAsyncEventQueueName(regionName) + " must not already exist."); } diff --git a/geode-connectors/src/distributedTest/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeMappingCommandDUnitTest.java b/geode-connectors/src/distributedTest/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeMappingCommandDUnitTest.java index 06896f7..a79a9ba 100644 --- a/geode-connectors/src/distributedTest/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeMappingCommandDUnitTest.java +++ b/geode-connectors/src/distributedTest/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeMappingCommandDUnitTest.java @@ -26,9 +26,12 @@ import static org.assertj.core.api.Assertions.assertThat; import java.io.Serializable; import java.util.Properties; +import junitparams.JUnitParamsRunner; +import junitparams.Parameters; import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; +import org.junit.runner.RunWith; import org.apache.geode.connectors.jdbc.internal.JdbcConnectorService; import org.apache.geode.connectors.jdbc.internal.RegionMappingExistsException; @@ -44,6 +47,7 @@ import org.apache.geode.test.junit.rules.GfshCommandRule; import org.apache.geode.test.junit.rules.serializable.SerializableTestName; @Category({JDBCConnectorTest.class}) +@RunWith(JUnitParamsRunner.class) public class DescribeMappingCommandDUnitTest implements Serializable { private static final String REGION_NAME = "testRegion"; @@ -59,17 +63,25 @@ public class DescribeMappingCommandDUnitTest implements Serializable { private MemberVM locator, server; + private static String convertRegionPathToName(String regionPath) { + if (regionPath.startsWith("/")) { + return regionPath.substring(1); + } + return regionPath; + } + @Test - public void describesExistingMapping() throws Exception { + @Parameters({REGION_NAME, "/" + REGION_NAME}) + public void describesExistingMapping(String regionName) throws Exception { locator = startupRule.startLocatorVM(0); server = startupRule.startServerVM(1, locator.getPort()); gfsh.connectAndVerify(locator); - gfsh.executeAndAssertThat("create region --name=" + REGION_NAME + " --type=REPLICATE") + gfsh.executeAndAssertThat("create region --name=" + regionName + " --type=REPLICATE") .statusIsSuccess(); CommandStringBuilder csb = new CommandStringBuilder(CREATE_MAPPING); - csb.addOption(CREATE_MAPPING__REGION_NAME, REGION_NAME); + csb.addOption(CREATE_MAPPING__REGION_NAME, regionName); csb.addOption(CREATE_MAPPING__DATA_SOURCE_NAME, "connection"); csb.addOption(CREATE_MAPPING__TABLE_NAME, "testTable"); csb.addOption(CREATE_MAPPING__PDX_NAME, "myPdxClass"); @@ -77,12 +89,13 @@ public class DescribeMappingCommandDUnitTest implements Serializable { gfsh.executeAndAssertThat(csb.toString()).statusIsSuccess(); csb = new CommandStringBuilder(DESCRIBE_MAPPING).addOption(DESCRIBE_MAPPING__REGION_NAME, - REGION_NAME); + regionName); CommandResultAssert commandResultAssert = gfsh.executeAndAssertThat(csb.toString()); commandResultAssert.statusIsSuccess(); - commandResultAssert.containsKeyValuePair(CREATE_MAPPING__REGION_NAME, REGION_NAME); + commandResultAssert.containsKeyValuePair(CREATE_MAPPING__REGION_NAME, + convertRegionPathToName(regionName)); commandResultAssert.containsKeyValuePair(CREATE_MAPPING__DATA_SOURCE_NAME, "connection"); commandResultAssert.containsKeyValuePair(CREATE_MAPPING__TABLE_NAME, "testTable"); commandResultAssert.containsKeyValuePair(CREATE_MAPPING__PDX_NAME, "myPdxClass"); 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 cda69dc..a7b8d38 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,7 +95,7 @@ public class DestroyMappingCommandDunitTest implements Serializable { } @Test - public void destroysAsyncMapping() throws Exception { + public void destroysAsyncMapping() { setupAsyncMapping(); CommandStringBuilder csb = new CommandStringBuilder(DESTROY_MAPPING); csb.addOption(DESTROY_MAPPING__REGION_NAME, REGION_NAME); @@ -117,6 +117,28 @@ public class DestroyMappingCommandDunitTest implements Serializable { } @Test + public void destroysAsyncMappingWithRegionPath() { + setupAsyncMapping(); + CommandStringBuilder csb = new CommandStringBuilder(DESTROY_MAPPING); + csb.addOption(DESTROY_MAPPING__REGION_NAME, "/" + REGION_NAME); + + gfsh.executeAndAssertThat(csb.toString()).statusIsSuccess(); + + locator.invoke(() -> { + assertThat(getRegionMappingFromClusterConfig()).isNull(); + validateAsyncEventQueueRemovedFromClusterConfig(); + validateRegionAlteredInClusterConfig(false); + }); + + server.invoke(() -> { + InternalCache cache = ClusterStartupRule.getCache(); + verifyMappingRemovedFromService(cache); + verifyRegionAltered(cache); + verifyQueueRemoved(cache); + }); + } + + @Test public void destroysSynchronousMapping() throws Exception { setupSynchronousMapping(); CommandStringBuilder csb = new CommandStringBuilder(DESTROY_MAPPING); @@ -138,6 +160,28 @@ public class DestroyMappingCommandDunitTest implements Serializable { }); } + @Test + public void destroysSynchronousMappingWithRegionPath() throws Exception { + setupSynchronousMapping(); + CommandStringBuilder csb = new CommandStringBuilder(DESTROY_MAPPING); + csb.addOption(DESTROY_MAPPING__REGION_NAME, "/" + REGION_NAME); + + gfsh.executeAndAssertThat(csb.toString()).statusIsSuccess(); + + locator.invoke(() -> { + assertThat(getRegionMappingFromClusterConfig()).isNull(); + validateAsyncEventQueueRemovedFromClusterConfig(); + validateRegionAlteredInClusterConfig(true); + }); + + server.invoke(() -> { + InternalCache cache = ClusterStartupRule.getCache(); + verifyMappingRemovedFromService(cache); + verifyRegionAltered(cache); + verifyQueueRemoved(cache); + }); + } + private static RegionMapping getRegionMappingFromClusterConfig() { CacheConfig cacheConfig = InternalLocator.getLocator().getConfigurationPersistenceService().getCacheConfig(null); diff --git a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingCommand.java b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingCommand.java index 4137f42..8c70df9 100644 --- a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingCommand.java +++ b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingCommand.java @@ -65,6 +65,9 @@ public class CreateMappingCommand extends SingleGfshCommand { "By default, writes will be asynchronous. If true, writes will be synchronous."; public static String createAsyncEventQueueName(String regionPath) { + if (regionPath.startsWith("/")) { + regionPath = regionPath.substring(1); + } return "JDBC#" + regionPath.replace('/', '_'); } @@ -84,6 +87,10 @@ public class CreateMappingCommand extends SingleGfshCommand { @CliOption(key = CREATE_MAPPING__SYNCHRONOUS_NAME, help = CREATE_MAPPING__SYNCHRONOUS_NAME__HELP, specifiedDefaultValue = "true", unspecifiedDefaultValue = "false") boolean synchronous) { + if (regionName.startsWith("/")) { + regionName = regionName.substring(1); + } + // input Set<DistributedMember> targetMembers = getMembers(null, null); RegionMapping mapping = new RegionMapping(regionName, pdxName, table, dataSourceName); diff --git a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeMappingCommand.java b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeMappingCommand.java index 18d7121..6d6f310 100644 --- a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeMappingCommand.java +++ b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeMappingCommand.java @@ -54,6 +54,10 @@ public class DescribeMappingCommand extends GfshCommand { operation = ResourcePermission.Operation.MANAGE) public ResultModel describeMapping(@CliOption(key = DESCRIBE_MAPPING__REGION_NAME, mandatory = true, help = DESCRIBE_MAPPING__REGION_NAME__HELP) String regionName) { + if (regionName.startsWith("/")) { + regionName = regionName.substring(1); + } + RegionMapping mapping = null; Set<DistributedMember> members = findMembers(null, null); diff --git a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyMappingCommand.java b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyMappingCommand.java index d797c49..3de83b0 100644 --- a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyMappingCommand.java +++ b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyMappingCommand.java @@ -56,6 +56,10 @@ public class DestroyMappingCommand extends SingleGfshCommand { operation = ResourcePermission.Operation.MANAGE) public ResultModel destroyMapping(@CliOption(key = DESTROY_MAPPING__REGION_NAME, mandatory = true, help = DESTROY_MAPPING__REGION_NAME__HELP) String regionName) { + if (regionName.startsWith("/")) { + regionName = regionName.substring(1); + } + // input Set<DistributedMember> targetMembers = getMembers(null, null); diff --git a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingCommandTest.java b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingCommandTest.java index 7fb820a..6038853 100644 --- a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingCommandTest.java +++ b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingCommandTest.java @@ -139,6 +139,21 @@ public class CreateMappingCommandTest { } @Test + public void createsMappingWithRegionPathCreatesMappingWithSlashRemoved() { + setupRequiredPreconditions(); + results.add(successFunctionResult); + + ResultModel result = createRegionMappingCommand.createMapping("/" + regionName, dataSourceName, + tableName, pdxClass, false); + + assertThat(result.getStatus()).isSameAs(Result.Status.OK); + Object[] results = (Object[]) result.getConfigObject(); + RegionMapping regionMapping = (RegionMapping) results[0]; + assertThat(regionMapping).isNotNull(); + assertThat(regionMapping.getRegionName()).isEqualTo(regionName); + } + + @Test public void createsMappingReturnsStatusERRORWhenFunctionResultIsEmpty() { setupRequiredPreconditions(); results.clear(); @@ -534,4 +549,24 @@ public class CreateMappingCommandTest { assertThat(queueList).isEmpty(); } + + @Test + public void createAsyncEventQueueNameWithRegionPathReturnsQueueNameThatIsTheSameAsRegionWithNoSlash() { + String queueName1 = CreateMappingCommand.createAsyncEventQueueName("regionName"); + String queueName2 = CreateMappingCommand.createAsyncEventQueueName("/regionName"); + assertThat(queueName1).isEqualTo(queueName2); + } + + @Test + public void createAsyncEventQueueNameWithEmptyStringReturnsQueueName() { + String queueName = CreateMappingCommand.createAsyncEventQueueName(""); + assertThat(queueName).isEqualTo("JDBC#"); + } + + @Test + public void createAsyncEventQueueNameWithSubregionNameReturnsQueueNameWithNoSlashes() { + String queueName = CreateMappingCommand.createAsyncEventQueueName("/parent/child/grandchild"); + assertThat(queueName).isEqualTo("JDBC#parent_child_grandchild"); + } + } diff --git a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeMappingCommandTest.java b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeMappingCommandTest.java index 01bcc35..d317982 100644 --- a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeMappingCommandTest.java +++ b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeMappingCommandTest.java @@ -15,9 +15,12 @@ package org.apache.geode.connectors.jdbc.internal.cli; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.util.Collections; @@ -79,6 +82,21 @@ public class DescribeMappingCommandTest { } @Test + public void whenMemberExistsWithRegionPathFunctionIsCalledWithNoSlashRegionName() { + doReturn(Collections.singleton(mock(DistributedMember.class))).when(command).findMembers(null, + null); + ResultCollector rc = mock(ResultCollector.class); + doReturn(rc).when(command).executeFunction(any(), any(), any(Set.class)); + when(rc.getResult()).thenReturn( + Collections.singletonList( + new CliFunctionResult("server-1", mock(RegionMapping.class), "success"))); + + command.describeMapping("/regionName"); + + verify(command, times(1)).executeFunctionAndGetFunctionResult(any(), eq("regionName"), any()); + } + + @Test public void whenNoMappingFoundOnMember() { doReturn(Collections.singleton(mock(DistributedMember.class))).when(command).findMembers(null, null); diff --git a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyMappingCommandTest.java b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyMappingCommandTest.java index 210f19f..9018055 100644 --- a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyMappingCommandTest.java +++ b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyMappingCommandTest.java @@ -16,6 +16,7 @@ package org.apache.geode.connectors.jdbc.internal.cli; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; @@ -59,7 +60,6 @@ public class DestroyMappingCommandTest { private Set<InternalDistributedMember> members; private List<CliFunctionResult> results; private CliFunctionResult successFunctionResult; - private RegionMapping mapping; private CacheConfig cacheConfig; RegionConfig matchingRegion; RegionAttributesType matchingRegionAttributes; @@ -82,9 +82,6 @@ public class DestroyMappingCommandTest { doReturn(results).when(destroyRegionMappingCommand).executeAndGetFunctionResult(any(), any(), any()); - mapping = mock(RegionMapping.class); - when(mapping.getRegionName()).thenReturn(regionName); - cacheConfig = mock(CacheConfig.class); matchingRegion = mock(RegionConfig.class); @@ -107,6 +104,18 @@ public class DestroyMappingCommandTest { } @Test + public void destroyMappingGivenARegionPathReturnsTheNoSlashRegionNameAsTheConfigObject() { + results.add(successFunctionResult); + + ResultModel result = destroyRegionMappingCommand.destroyMapping("/" + regionName); + + verify(destroyRegionMappingCommand, times(1)).executeAndGetFunctionResult(any(), eq(regionName), + any()); + assertThat(result.getStatus()).isSameAs(Result.Status.OK); + assertThat(result.getConfigObject()).isEqualTo(regionName); + } + + @Test public void updateClusterConfigWithNoRegionsDoesNotThrowException() { when(cacheConfig.getRegions()).thenReturn(Collections.emptyList());