This is an automated email from the ASF dual-hosted git repository.

dschneider pushed a commit to branch feature/GEODE-6102
in repository https://gitbox.apache.org/repos/asf/geode.git


The following commit(s) were added to refs/heads/feature/GEODE-6102 by this 
push:
     new 01cf715  destroy data-source now fails if used by a jdbc-mapping
01cf715 is described below

commit 01cf71547dd4a14c87d25717fe4cd83e21c1d5c0
Author: Darrel Schneider <[email protected]>
AuthorDate: Wed Dec 12 16:48:59 2018 -0800

    destroy data-source now fails if used by a jdbc-mapping
---
 .../cli/DestroyDataSourceCommandDUnitTest.java     | 31 ++++++++++----
 .../internal/cli/DestroyDataSourceCommand.java     | 30 +++++++++++++
 .../internal/cli/DestroyDataSourceCommandTest.java | 49 ++++++++++++++++++++++
 3 files changed, 101 insertions(+), 9 deletions(-)

diff --git 
a/geode-connectors/src/distributedTest/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyDataSourceCommandDUnitTest.java
 
b/geode-connectors/src/distributedTest/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyDataSourceCommandDUnitTest.java
index ff7af83..1f6c3b0 100644
--- 
a/geode-connectors/src/distributedTest/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyDataSourceCommandDUnitTest.java
+++ 
b/geode-connectors/src/distributedTest/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyDataSourceCommandDUnitTest.java
@@ -17,8 +17,8 @@ package org.apache.geode.connectors.jdbc.internal.cli;
 import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat;
 
 import org.assertj.core.api.AssertionsForClassTypes;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
+import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
@@ -35,16 +35,16 @@ import org.apache.geode.test.junit.rules.GfshCommandRule;
 import org.apache.geode.test.junit.rules.VMProvider;
 
 public class DestroyDataSourceCommandDUnitTest {
-  private static MemberVM locator, server1, server2;
+  private MemberVM locator, server1, server2;
 
-  @ClassRule
-  public static ClusterStartupRule cluster = new ClusterStartupRule();
+  @Rule
+  public ClusterStartupRule cluster = new ClusterStartupRule();
 
-  @ClassRule
-  public static GfshCommandRule gfsh = new GfshCommandRule();
+  @Rule
+  public GfshCommandRule gfsh = new GfshCommandRule();
 
-  @BeforeClass
-  public static void before() throws Exception {
+  @Before
+  public void before() throws Exception {
     locator = cluster.startLocatorVM(0);
     server1 = cluster.startServerVM(1, locator.getPort());
     server2 = cluster.startServerVM(2, locator.getPort());
@@ -109,4 +109,17 @@ public class DestroyDataSourceCommandDUnitTest {
       
AssertionsForClassTypes.assertThat(JNDIInvoker.getNoOfAvailableDataSources()).isEqualTo(0);
     });
   }
+
+  @Test
+  public void destroyDataSourceFailsIfInUseByJdbcMapping() {
+    gfsh.executeAndAssertThat("create region --name=myRegion 
--type=REPLICATE").statusIsSuccess();
+    gfsh.executeAndAssertThat(
+        "create jdbc-mapping --data-source=datasource1 --pdx-name=myPdxClass 
--region=myRegion")
+        .statusIsSuccess();
+
+    gfsh.executeAndAssertThat("destroy data-source 
--name=datasource1").statusIsError()
+        .containsOutput(
+            "Data source named \"datasource1\" is still being used by region 
\"myRegion\"."
+                + " Use destroy jdbc-mapping --name=myRegion and then try 
again.");
+  }
 }
diff --git 
a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyDataSourceCommand.java
 
b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyDataSourceCommand.java
index 3d1a2ec..c66c8aa 100644
--- 
a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyDataSourceCommand.java
+++ 
b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyDataSourceCommand.java
@@ -24,6 +24,8 @@ 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.JndiBindingsType;
+import org.apache.geode.cache.configuration.RegionConfig;
+import org.apache.geode.connectors.jdbc.internal.configuration.RegionMapping;
 import org.apache.geode.distributed.DistributedMember;
 import 
org.apache.geode.distributed.internal.InternalConfigurationPersistenceService;
 import org.apache.geode.management.cli.CliMetaData;
@@ -75,6 +77,15 @@ public class DestroyDataSourceCommand extends 
SingleGfshCommand {
             "Data source named \"{0}\" does not exist. A jndi-binding was 
found with that name.",
             dataSourceName));
       }
+
+      try {
+        checkIfDataSourceIsInUse(service, dataSourceName);
+      } catch (IllegalStateException ex) {
+        return ResultModel.createError(CliStrings.format(
+            "Data source named \"{0}\" is still being used by region \"{1}\". 
Use destroy jdbc-mapping --name={1} and then try again.",
+            dataSourceName, ex.getMessage()));
+
+      }
     }
 
     Set<DistributedMember> targetMembers = findMembers(null, null);
@@ -114,6 +125,25 @@ public class DestroyDataSourceCommand extends 
SingleGfshCommand {
     }
   }
 
+  /**
+   * @throws IllegalStateException if the data source is used by a 
jdbc-mapping. The exception
+   *         message names the region using this data source
+   */
+  private void 
checkIfDataSourceIsInUse(InternalConfigurationPersistenceService service,
+      String dataSourceName) {
+    CacheConfig cacheConfig = service.getCacheConfig(null);
+    for (RegionConfig regionConfig : cacheConfig.getRegions()) {
+      for (CacheElement cacheElement : regionConfig.getCustomRegionElements()) 
{
+        if (cacheElement instanceof RegionMapping) {
+          RegionMapping regionMapping = (RegionMapping) cacheElement;
+          if (dataSourceName.equals(regionMapping.getDataSourceName())) {
+            throw new IllegalStateException(regionConfig.getName());
+          }
+        }
+      }
+    }
+  }
+
   private boolean isDataSource(JndiBindingsType.JndiBinding binding) {
     return 
CreateJndiBindingCommand.DATASOURCE_TYPE.SIMPLE.getType().equals(binding.getType())
         || 
CreateJndiBindingCommand.DATASOURCE_TYPE.POOLED.getType().equals(binding.getType());
diff --git 
a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyDataSourceCommandTest.java
 
b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyDataSourceCommandTest.java
index c839428..67f9a96 100644
--- 
a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyDataSourceCommandTest.java
+++ 
b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyDataSourceCommandTest.java
@@ -40,7 +40,10 @@ import org.mockito.ArgumentCaptor;
 
 import org.apache.geode.cache.Region;
 import org.apache.geode.cache.configuration.CacheConfig;
+import org.apache.geode.cache.configuration.CacheElement;
 import org.apache.geode.cache.configuration.JndiBindingsType;
+import org.apache.geode.cache.configuration.RegionConfig;
+import org.apache.geode.connectors.jdbc.internal.configuration.RegionMapping;
 import org.apache.geode.distributed.DistributedMember;
 import 
org.apache.geode.distributed.internal.InternalConfigurationPersistenceService;
 import org.apache.geode.internal.cache.InternalCache;
@@ -134,7 +137,53 @@ public class DestroyDataSourceCommandTest {
             "Data source named \\\"name\\\" does not exist. A jndi-binding was 
found with that name.");
   }
 
+  @Test
+  public void whenClusterConfigRunningAndDataSourceInUseByRegionThenError() {
+    String DATA_SOURCE_NAME = "myDataSourceName";
+    List<JndiBindingsType.JndiBinding> bindings = new ArrayList<>();
+    JndiBindingsType.JndiBinding jndiBinding = new 
JndiBindingsType.JndiBinding();
+    jndiBinding.setJndiName(DATA_SOURCE_NAME);
+    
jndiBinding.setType(CreateJndiBindingCommand.DATASOURCE_TYPE.SIMPLE.getType());
+    bindings.add(jndiBinding);
+    doReturn(bindings).when(cacheConfig).getJndiBindings();
+    setupRegionConfigToUseDataSource(DATA_SOURCE_NAME);
 
+    gfsh.executeAndAssertThat(command, COMMAND + " --name=" + 
DATA_SOURCE_NAME).statusIsError()
+        .containsOutput("Data source named \\\"" + DATA_SOURCE_NAME
+            + "\\\" is still being used by region 
\\\"regionUsingDataSource\\\"."
+            + " Use destroy jdbc-mapping --name=regionUsingDataSource and then 
try again.");
+  }
+
+  private void setupRegionConfigToUseDataSource(String dataSourceName) {
+    RegionConfig regionConfig = mock(RegionConfig.class);
+    when(regionConfig.getName()).thenReturn("regionUsingDataSource");
+    List<RegionConfig> regionConfigList = new ArrayList<>();
+    regionConfigList.add(regionConfig);
+    when(cacheConfig.getRegions()).thenReturn(regionConfigList);
+    RegionMapping regionMapping = mock(RegionMapping.class);
+    when(regionMapping.getDataSourceName()).thenReturn(dataSourceName);
+    List<CacheElement> cacheElementList = new ArrayList<>();
+    cacheElementList.add(regionMapping);
+    when(regionConfig.getCustomRegionElements()).thenReturn(cacheElementList);
+  }
+
+  @Test
+  public void 
whenNoMembersFoundAndClusterConfigRunningAndRegionUsingOtherDataSourceThenUpdateClusterConfig()
 {
+    List<JndiBindingsType.JndiBinding> bindings = new ArrayList<>();
+    JndiBindingsType.JndiBinding jndiBinding = new 
JndiBindingsType.JndiBinding();
+    jndiBinding.setJndiName("name");
+    
jndiBinding.setType(CreateJndiBindingCommand.DATASOURCE_TYPE.SIMPLE.getType());
+    bindings.add(jndiBinding);
+    doReturn(bindings).when(cacheConfig).getJndiBindings();
+    setupRegionConfigToUseDataSource("otherDataSource");
+
+    gfsh.executeAndAssertThat(command, COMMAND + " 
--name=name").statusIsSuccess()
+        .containsOutput("No members found, data source removed from cluster 
configuration.")
+        .containsOutput("Changes to configuration for group 'cluster' are 
persisted.");
+
+    verify(ccService).updateCacheConfig(any(), any());
+    verify(command).updateConfigForGroup(eq("cluster"), eq(cacheConfig), 
isNotNull());
+  }
 
   @Test
   public void 
whenNoMembersFoundAndClusterConfigRunningThenUpdateClusterConfig() {

Reply via email to