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

jchen21 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 1f364dd  GEODE-6102: add gfsh destroy data-source (#2918)
1f364dd is described below

commit 1f364dd157c185b8394cc97be0613b80248613bc
Author: BenjaminPerryRoss <[email protected]>
AuthorDate: Tue Dec 11 09:49:07 2018 -0800

    GEODE-6102: add gfsh destroy data-source (#2918)
    
    * Adding DestroyDataSourceCommand
    
    - Refactored DestroyJndiBindingFunction class to provide accurate output
      based on command invoking it
    - Added unit test class for DestroyDataSourceCommand Class
    - Completed Unit test and added DUnit test for DestroyDataSourceCommand
    
    Co-authored-by: Ben Ross <[email protected]>
    Co-authored-by: Darrel Schneider <[email protected]>
    Co-authored-by: Scott Jewell <[email protected]>
---
 .../cli/DestroyDataSourceCommandDUnitTest.java     |  38 ++---
 .../internal/cli/DestroyDataSourceCommand.java     |  79 ++++++++---
 .../org.springframework.shell.core.CommandMarker   |   1 +
 .../internal/cli/DestroyDataSourceCommandTest.java | 154 +++++++++++++++++----
 .../DestroyJndiBindingCommandDUnitTest.java        |   3 -
 .../functions/DestroyJndiBindingFunctionTest.java  |  56 +++++++-
 .../apache/geode/internal/jndi/JNDIInvoker.java    |  12 ++
 .../cli/commands/DestroyJndiBindingCommand.java    |   3 +-
 .../cli/functions/DestroyJndiBindingFunction.java  |  37 +++--
 .../commands/DestroyJndiBindingCommandTest.java    |  24 ++--
 10 files changed, 317 insertions(+), 90 deletions(-)

diff --git 
a/geode-core/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/DestroyJndiBindingCommandDUnitTest.java
 
b/geode-connectors/src/distributedTest/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyDataSourceCommandDUnitTest.java
similarity index 75%
copy from 
geode-core/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/DestroyJndiBindingCommandDUnitTest.java
copy to 
geode-connectors/src/distributedTest/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyDataSourceCommandDUnitTest.java
index 97f0170..ff7af83 100644
--- 
a/geode-core/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/DestroyJndiBindingCommandDUnitTest.java
+++ 
b/geode-connectors/src/distributedTest/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyDataSourceCommandDUnitTest.java
@@ -12,15 +12,14 @@
  * or implied. See the License for the specific language governing permissions 
and limitations under
  * the License.
  */
-
-package org.apache.geode.management.internal.cli.commands;
+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.Test;
-import org.junit.experimental.categories.Category;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.NodeList;
@@ -32,13 +31,10 @@ import 
org.apache.geode.management.internal.configuration.domain.Configuration;
 import org.apache.geode.management.internal.configuration.utils.XmlUtils;
 import org.apache.geode.test.dunit.rules.ClusterStartupRule;
 import org.apache.geode.test.dunit.rules.MemberVM;
-import org.apache.geode.test.junit.categories.GfshTest;
 import org.apache.geode.test.junit.rules.GfshCommandRule;
 import org.apache.geode.test.junit.rules.VMProvider;
 
-@Category(GfshTest.class)
-public class DestroyJndiBindingCommandDUnitTest {
-
+public class DestroyDataSourceCommandDUnitTest {
   private static MemberVM locator, server1, server2;
 
   @ClassRule
@@ -55,50 +51,54 @@ public class DestroyJndiBindingCommandDUnitTest {
 
     gfsh.connectAndVerify(locator);
 
-    // create the binding
     gfsh.execute(
-        "create jndi-binding --name=jndi1 --type=SIMPLE 
--jdbc-driver-class=org.apache.derby.jdbc.EmbeddedDriver 
--connection-url=\"jdbc:derby:newDB;create=true\"");
+        "create data-source --name=datasource1 
--url=\"jdbc:derby:newDB;create=true\"");
   }
 
   @Test
-  public void testDestroyJndiBinding() {
+  public void testDestroyDataSource() {
     // assert that there is a datasource
     VMProvider
         .invokeInEveryMember(
             () -> 
assertThat(JNDIInvoker.getBindingNamesRecursively(JNDIInvoker.getJNDIContext()))
-                .containsKey("java:jndi1").containsValue(
+                .containsKey("java:datasource1").containsValue(
                     
"org.apache.geode.internal.datasource.GemFireBasicDataSource"),
             server1, server2);
 
-    gfsh.executeAndAssertThat("destroy jndi-binding 
--name=jndi1").statusIsSuccess()
-        .tableHasColumnOnlyWithValues("Member", "server-1", "server-2");
+    gfsh.executeAndAssertThat("destroy data-source 
--name=datasource1").statusIsSuccess()
+        .tableHasColumnOnlyWithValues("Member", "server-1", "server-2")
+        .tableHasColumnOnlyWithValues("Message",
+            "Data source \"datasource1\" destroyed on \"server-1\"",
+            "Data source \"datasource1\" destroyed on \"server-2\"");
 
     // verify cluster config is updated
     locator.invoke(() -> {
       InternalLocator internalLocator = ClusterStartupRule.getLocator();
-      assertThat(internalLocator).isNotNull();
+      AssertionsForClassTypes.assertThat(internalLocator).isNotNull();
       InternalConfigurationPersistenceService ccService =
           internalLocator.getConfigurationPersistenceService();
       Configuration configuration = ccService.getConfiguration("cluster");
       Document document = 
XmlUtils.createDocumentFromXml(configuration.getCacheXmlContent());
       NodeList jndiBindings = document.getElementsByTagName("jndi-binding");
 
-      assertThat(jndiBindings.getLength()).isEqualTo(0);
+      
AssertionsForClassTypes.assertThat(jndiBindings.getLength()).isEqualTo(0);
 
       boolean found = false;
       for (int i = 0; i < jndiBindings.getLength(); i++) {
         Element eachBinding = (Element) jndiBindings.item(i);
-        if (eachBinding.getAttribute("jndi-name").equals("jndi1")) {
+        if (eachBinding.getAttribute("jndi-name").equals("datasource1")) {
           found = true;
           break;
         }
       }
-      assertThat(found).isFalse();
+      AssertionsForClassTypes.assertThat(found).isFalse();
     });
 
     // verify datasource does not exists
     VMProvider.invokeInEveryMember(
-        () -> 
assertThat(JNDIInvoker.getNoOfAvailableDataSources()).isEqualTo(0), server1, 
server2);
+        () -> 
AssertionsForClassTypes.assertThat(JNDIInvoker.getNoOfAvailableDataSources())
+            .isEqualTo(0),
+        server1, server2);
 
     // bounce server1 and assert that there is still no datasource received 
from cluster config
     server1.stop(false);
@@ -106,7 +106,7 @@ public class DestroyJndiBindingCommandDUnitTest {
 
     // verify no datasource from cluster config
     server1.invoke(() -> {
-      assertThat(JNDIInvoker.getNoOfAvailableDataSources()).isEqualTo(0);
+      
AssertionsForClassTypes.assertThat(JNDIInvoker.getNoOfAvailableDataSources()).isEqualTo(0);
     });
   }
 }
diff --git 
a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/DestroyJndiBindingCommand.java
 
b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyDataSourceCommand.java
similarity index 56%
copy from 
geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/DestroyJndiBindingCommand.java
copy to 
geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyDataSourceCommand.java
index 9ba0b92..fcd1ec4 100644
--- 
a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/DestroyJndiBindingCommand.java
+++ 
b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyDataSourceCommand.java
@@ -12,8 +12,7 @@
  * or implied. See the License for the specific language governing permissions 
and limitations under
  * the License.
  */
-package org.apache.geode.management.internal.cli.commands;
-
+package org.apache.geode.connectors.jdbc.internal.cli;
 
 import java.util.List;
 import java.util.Set;
@@ -28,6 +27,7 @@ import org.apache.geode.distributed.DistributedMember;
 import 
org.apache.geode.distributed.internal.InternalConfigurationPersistenceService;
 import org.apache.geode.management.cli.CliMetaData;
 import org.apache.geode.management.cli.SingleGfshCommand;
+import 
org.apache.geode.management.internal.cli.commands.CreateJndiBindingCommand;
 import 
org.apache.geode.management.internal.cli.exceptions.EntityNotFoundException;
 import org.apache.geode.management.internal.cli.functions.CliFunctionResult;
 import 
org.apache.geode.management.internal.cli.functions.DestroyJndiBindingFunction;
@@ -36,23 +36,24 @@ import 
org.apache.geode.management.internal.cli.result.model.ResultModel;
 import org.apache.geode.management.internal.security.ResourceOperation;
 import org.apache.geode.security.ResourcePermission;
 
-public class DestroyJndiBindingCommand extends SingleGfshCommand {
-  static final String DESTROY_JNDIBINDING = "destroy jndi-binding";
-  static final String DESTROY_JNDIBINDING__HELP =
-      "Destroy a JNDI binding that holds the configuration for an XA 
datasource.";
-  static final String JNDI_NAME = "name";
-  static final String JNDI_NAME__HELP = "Name of the binding to be destroyed.";
+public class DestroyDataSourceCommand extends SingleGfshCommand {
+  static final String DESTROY_DATA_SOURCE = "destroy data-source";
+  static final String DESTROY_DATA_SOURCE_HELP =
+      "Destroy a data source that holds a jdbc configuration.";
+  static final String DATA_SOURCE_NAME = "name";
+  static final String DATA_SOURCE_NAME_HELP = "Name of the data source to be 
destroyed.";
   static final String IFEXISTS_HELP =
-      "Skip the destroy operation when the specified JNDI binding does "
+      "Skip the destroy operation when the specified data source does "
           + "not exist. Without this option, an error results from the 
specification "
-          + "of a JNDI binding that does not exist.";
+          + "of a data source that does not exist.";
 
-  @CliCommand(value = DESTROY_JNDIBINDING, help = DESTROY_JNDIBINDING__HELP)
+  @CliCommand(value = DESTROY_DATA_SOURCE, help = DESTROY_DATA_SOURCE_HELP)
   @CliMetaData(relatedTopic = CliStrings.TOPIC_GEODE_REGION)
   @ResourceOperation(resource = ResourcePermission.Resource.CLUSTER,
       operation = ResourcePermission.Operation.MANAGE)
-  public ResultModel destroyJDNIBinding(
-      @CliOption(key = JNDI_NAME, mandatory = true, help = JNDI_NAME__HELP) 
String jndiName,
+  public ResultModel destroyDataSource(
+      @CliOption(key = DATA_SOURCE_NAME, mandatory = true,
+          help = DATA_SOURCE_NAME_HELP) String dataSourceName,
       @CliOption(key = CliStrings.IFEXISTS, help = IFEXISTS_HELP, 
specifiedDefaultValue = "true",
           unspecifiedDefaultValue = "false") boolean ifExists) {
 
@@ -61,28 +62,62 @@ public class DestroyJndiBindingCommand extends 
SingleGfshCommand {
     if (service != null) {
       List<JndiBindingsType.JndiBinding> bindings =
           service.getCacheConfig("cluster").getJndiBindings();
-      JndiBindingsType.JndiBinding binding = 
CacheElement.findElement(bindings, jndiName);
-      // fail fast when CC is running and if required binding not found 
assuming that
-      // when CC is running then every configuration goes through CC
+      JndiBindingsType.JndiBinding binding = 
CacheElement.findElement(bindings, dataSourceName);
       if (binding == null) {
         throw new EntityNotFoundException(
-            CliStrings.format("Jndi binding with jndi-name \"{0}\" does not 
exist.", jndiName),
+            CliStrings.format("Data source named \"{0}\" does not exist.", 
dataSourceName),
             ifExists);
       }
+
+      if (!isDataSource(binding)) {
+        return ResultModel.createError(CliStrings.format(
+            "Data source named \"{0}\" does not exist. A jndi-binding was 
found with that name.",
+            dataSourceName));
+      }
     }
 
     Set<DistributedMember> targetMembers = findMembers(null, null);
     if (targetMembers.size() > 0) {
-      List<CliFunctionResult> jndiCreationResult =
-          executeAndGetFunctionResult(new DestroyJndiBindingFunction(), 
jndiName, targetMembers);
-      ResultModel result = 
ResultModel.createMemberStatusResult(jndiCreationResult);
-      result.setConfigObject(jndiName);
+      List<CliFunctionResult> dataSourceDestroyResult =
+          executeAndGetFunctionResult(new DestroyJndiBindingFunction(),
+              new Object[] {dataSourceName, true}, targetMembers);
+
+      if (!ifExists) {
+        int resultsNotFound = 0;
+        for (CliFunctionResult result : dataSourceDestroyResult) {
+          if (result.getStatusMessage().contains("not found")) {
+            resultsNotFound++;
+          }
+        }
+        if (resultsNotFound == dataSourceDestroyResult.size()) {
+          throw new EntityNotFoundException(
+              CliStrings.format("Data source named \"{0}\" does not exist.", 
dataSourceName),
+              ifExists);
+        }
+      }
+
+      ResultModel result = 
ResultModel.createMemberStatusResult(dataSourceDestroyResult);
+      result.setConfigObject(dataSourceName);
+
       return result;
     } else {
-      return ResultModel.createInfo("No members found.");
+      if (service != null) {
+        ResultModel result =
+            ResultModel
+                .createInfo("No members found, data source removed from 
cluster configuration.");
+        result.setConfigObject(dataSourceName);
+        return result;
+      } else {
+        return ResultModel.createError("No members found and cluster 
configuration disabled.");
+      }
     }
   }
 
+  private boolean isDataSource(JndiBindingsType.JndiBinding binding) {
+    return 
CreateJndiBindingCommand.DATASOURCE_TYPE.SIMPLE.getType().equals(binding.getType())
+        || 
CreateJndiBindingCommand.DATASOURCE_TYPE.POOLED.getType().equals(binding.getType());
+  }
+
   @Override
   public boolean updateConfigForGroup(String group, CacheConfig config, Object 
element) {
     CacheElement.removeElement(config.getJndiBindings(), (String) element);
diff --git 
a/geode-connectors/src/main/resources/META-INF/services/org.springframework.shell.core.CommandMarker
 
b/geode-connectors/src/main/resources/META-INF/services/org.springframework.shell.core.CommandMarker
index ca6df1b..93adaef 100644
--- 
a/geode-connectors/src/main/resources/META-INF/services/org.springframework.shell.core.CommandMarker
+++ 
b/geode-connectors/src/main/resources/META-INF/services/org.springframework.shell.core.CommandMarker
@@ -22,3 +22,4 @@ 
org.apache.geode.connectors.jdbc.internal.cli.DestroyMappingCommand
 org.apache.geode.connectors.jdbc.internal.cli.DescribeMappingCommand
 org.apache.geode.connectors.jdbc.internal.cli.ListDataSourceCommand
 org.apache.geode.connectors.jdbc.internal.cli.ListMappingCommand
+org.apache.geode.connectors.jdbc.internal.cli.DestroyDataSourceCommand
\ No newline at end of file
diff --git 
a/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/DestroyJndiBindingCommandTest.java
 
b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyDataSourceCommandTest.java
similarity index 55%
copy from 
geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/DestroyJndiBindingCommandTest.java
copy to 
geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyDataSourceCommandTest.java
index 9de3810..c839428 100644
--- 
a/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/DestroyJndiBindingCommandTest.java
+++ 
b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyDataSourceCommandTest.java
@@ -12,11 +12,12 @@
  * or implied. See the License for the specific language governing permissions 
and limitations under
  * the License.
  */
-package org.apache.geode.management.internal.cli.commands;
+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.ArgumentMatchers.isNotNull;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
@@ -43,27 +44,27 @@ import 
org.apache.geode.cache.configuration.JndiBindingsType;
 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.commands.CreateJndiBindingCommand;
 import org.apache.geode.management.internal.cli.functions.CliFunctionResult;
 import 
org.apache.geode.management.internal.cli.functions.DestroyJndiBindingFunction;
 import org.apache.geode.management.internal.configuration.domain.Configuration;
 import org.apache.geode.test.junit.rules.GfshParserRule;
 
-public class DestroyJndiBindingCommandTest {
-
+public class DestroyDataSourceCommandTest {
   @ClassRule
   public static GfshParserRule gfsh = new GfshParserRule();
 
-  private DestroyJndiBindingCommand command;
+  private DestroyDataSourceCommand command;
   private InternalCache cache;
   private CacheConfig cacheConfig;
   private InternalConfigurationPersistenceService ccService;
 
-  private static String COMMAND = "destroy jndi-binding ";
+  private static String COMMAND = "destroy data-source ";
 
   @Before
-  public void setUp() throws Exception {
+  public void setUp() {
     cache = mock(InternalCache.class);
-    command = spy(DestroyJndiBindingCommand.class);
+    command = spy(DestroyDataSourceCommand.class);
     doReturn(cache).when(command).getCache();
     cacheConfig = mock(CacheConfig.class);
     ccService = mock(InternalConfigurationPersistenceService.class);
@@ -115,25 +116,121 @@ public class DestroyJndiBindingCommandTest {
     doReturn(Collections.emptySet()).when(command).findMembers(any(), any());
     doReturn(null).when(command).getConfigurationPersistenceService();
 
-    gfsh.executeAndAssertThat(command, COMMAND + " 
--name=name").statusIsSuccess()
-        .containsOutput("No members found").containsOutput(
-            "Cluster configuration service is not running. Configuration 
change is not persisted.");
+    gfsh.executeAndAssertThat(command, COMMAND + " 
--name=name").statusIsError()
+        .containsOutput("No members found and cluster configuration 
disabled.");
+  }
+
+  @Test
+  public void whenClusterConfigRunningAndJndiBindingFoundThenError() {
+    List<JndiBindingsType.JndiBinding> bindings = new ArrayList<>();
+    JndiBindingsType.JndiBinding jndiBinding = new 
JndiBindingsType.JndiBinding();
+    jndiBinding.setJndiName("name");
+    
jndiBinding.setType(CreateJndiBindingCommand.DATASOURCE_TYPE.MANAGED.getType());
+    bindings.add(jndiBinding);
+    doReturn(bindings).when(cacheConfig).getJndiBindings();
+
+    gfsh.executeAndAssertThat(command, COMMAND + " 
--name=name").statusIsError()
+        .containsOutput(
+            "Data source named \\\"name\\\" does not exist. A jndi-binding was 
found with that name.");
   }
 
+
+
   @Test
   public void 
whenNoMembersFoundAndClusterConfigRunningThenUpdateClusterConfig() {
     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();
 
     gfsh.executeAndAssertThat(command, COMMAND + " 
--name=name").statusIsSuccess()
-        .containsOutput("No members found.")
+        .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), 
any());
+    verify(command).updateConfigForGroup(eq("cluster"), eq(cacheConfig), 
isNotNull());
+  }
+
+  @Test
+  public void 
whenNoMembersFoundAndClusterConfigRunningWithPooledTypeThenUpdateClusterConfig()
 {
+    List<JndiBindingsType.JndiBinding> bindings = new ArrayList<>();
+    JndiBindingsType.JndiBinding jndiBinding = new 
JndiBindingsType.JndiBinding();
+    jndiBinding.setJndiName("name");
+    
jndiBinding.setType(CreateJndiBindingCommand.DATASOURCE_TYPE.POOLED.getType());
+    bindings.add(jndiBinding);
+    doReturn(bindings).when(cacheConfig).getJndiBindings();
+
+    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 whenMembersFoundAllReturnErrorAndIfExistsFalseThenError() {
+    Set<DistributedMember> members = new HashSet<>();
+    members.add(mock(DistributedMember.class));
+
+    CliFunctionResult result =
+        new CliFunctionResult("server1", true, "Data source \"name\" not found 
on \"server1\"");
+    List<CliFunctionResult> results = new ArrayList<>();
+    results.add(result);
+
+    doReturn(members).when(command).findMembers(any(), any());
+    doReturn(null).when(command).getConfigurationPersistenceService();
+    doReturn(results).when(command).executeAndGetFunctionResult(any(), any(), 
any());
+
+    gfsh.executeAndAssertThat(command, COMMAND + " --name=name 
--if-exists=false").statusIsError()
+        .containsOutput("Data source named \\\"name\\\" does not exist.");
+  }
+
+  @Test
+  public void whenMembersFoundAllReturnErrorAndIfExistsTrueThenSuccess() {
+    Set<DistributedMember> members = new HashSet<>();
+    members.add(mock(DistributedMember.class));
+
+    CliFunctionResult result =
+        new CliFunctionResult("server1", true, "Data source \"name\" not found 
on \"server1\"");
+    List<CliFunctionResult> results = new ArrayList<>();
+    results.add(result);
+
+    doReturn(members).when(command).findMembers(any(), any());
+    doReturn(null).when(command).getConfigurationPersistenceService();
+    doReturn(results).when(command).executeAndGetFunctionResult(any(), any(), 
any());
+
+    gfsh.executeAndAssertThat(command, COMMAND + " --name=name 
--if-exists=true").statusIsSuccess()
+        .tableHasColumnOnlyWithValues("Member", "server1")
+        .tableHasColumnOnlyWithValues("Status", "OK")
+        .tableHasColumnOnlyWithValues("Message", "Data source \"name\" not 
found on \"server1\"");
+  }
+
+  @Test
+  public void whenMembersFoundPartialReturnErrorAndIfExistsFalseThenSuccess() {
+    Set<DistributedMember> members = new HashSet<>();
+    members.add(mock(DistributedMember.class));
+    members.add(mock(DistributedMember.class));
+
+    CliFunctionResult result =
+        new CliFunctionResult("server1", true, "Data source \"name\" not found 
on \"server1\"");
+    CliFunctionResult result2 =
+        new CliFunctionResult("server2", true, "Data source \"name\" destroyed 
on \"server2\"");
+    List<CliFunctionResult> results = new ArrayList<>();
+    results.add(result);
+    results.add(result2);
+
+    doReturn(members).when(command).findMembers(any(), any());
+    doReturn(null).when(command).getConfigurationPersistenceService();
+    doReturn(results).when(command).executeAndGetFunctionResult(any(), any(), 
any());
+
+    gfsh.executeAndAssertThat(command, COMMAND + " --name=name 
--if-exists=false").statusIsSuccess()
+        .tableHasColumnOnlyWithValues("Member", "server1", "server2")
+        .tableHasColumnOnlyWithValues("Status", "OK", "OK")
+        .tableHasColumnOnlyWithValues("Message", "Data source \"name\" not 
found on \"server1\"",
+            "Data source \"name\" destroyed on \"server2\"");
   }
 
   @Test
@@ -142,7 +239,7 @@ public class DestroyJndiBindingCommandTest {
     members.add(mock(DistributedMember.class));
 
     CliFunctionResult result =
-        new CliFunctionResult("server1", true, "Jndi binding \"name\" 
destroyed on \"server1\"");
+        new CliFunctionResult("server1", true, "Data source \"name\" destroyed 
on \"server1\"");
     List<CliFunctionResult> results = new ArrayList<>();
     results.add(result);
 
@@ -153,20 +250,24 @@ public class DestroyJndiBindingCommandTest {
     gfsh.executeAndAssertThat(command, COMMAND + " 
--name=name").statusIsSuccess()
         .tableHasColumnOnlyWithValues("Member", "server1")
         .tableHasColumnOnlyWithValues("Status", "OK")
-        .tableHasColumnOnlyWithValues("Message", "Jndi binding \"name\" 
destroyed on \"server1\"");
+        .tableHasColumnOnlyWithValues("Message", "Data source \"name\" 
destroyed on \"server1\"");
 
     verify(ccService, times(0)).updateCacheConfig(any(), any());
 
     ArgumentCaptor<DestroyJndiBindingFunction> function =
         ArgumentCaptor.forClass(DestroyJndiBindingFunction.class);
-    ArgumentCaptor<String> jndiName = ArgumentCaptor.forClass(String.class);
+    ArgumentCaptor<Object[]> arguments = 
ArgumentCaptor.forClass(Object[].class);
+
     ArgumentCaptor<Set<DistributedMember>> targetMembers = 
ArgumentCaptor.forClass(Set.class);
-    verify(command, times(1)).executeAndGetFunctionResult(function.capture(), 
jndiName.capture(),
+    verify(command, times(1)).executeAndGetFunctionResult(function.capture(), 
arguments.capture(),
         targetMembers.capture());
 
+    String jndiName = (String) arguments.getValue()[0];
+    boolean destroyingDataSource = (boolean) arguments.getValue()[1];
+
     
assertThat(function.getValue()).isInstanceOf(DestroyJndiBindingFunction.class);
-    assertThat(jndiName.getValue()).isNotNull();
-    assertThat(jndiName.getValue()).isEqualTo("name");
+    assertThat(jndiName).isEqualTo("name");
+    assertThat(destroyingDataSource).isEqualTo(true);
     assertThat(targetMembers.getValue()).isEqualTo(members);
   }
 
@@ -175,6 +276,7 @@ public class DestroyJndiBindingCommandTest {
     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();
 
@@ -182,7 +284,7 @@ public class DestroyJndiBindingCommandTest {
     members.add(mock(DistributedMember.class));
 
     CliFunctionResult result =
-        new CliFunctionResult("server1", true, "Jndi binding \"name\" 
destroyed on \"server1\"");
+        new CliFunctionResult("server1", true, "Data source \"name\" destroyed 
on \"server1\"");
     List<CliFunctionResult> results = new ArrayList<>();
     results.add(result);
 
@@ -192,21 +294,25 @@ public class DestroyJndiBindingCommandTest {
     gfsh.executeAndAssertThat(command, COMMAND + " 
--name=name").statusIsSuccess()
         .tableHasColumnOnlyWithValues("Member", "server1")
         .tableHasColumnOnlyWithValues("Status", "OK")
-        .tableHasColumnOnlyWithValues("Message", "Jndi binding \"name\" 
destroyed on \"server1\"");
+        .tableHasColumnOnlyWithValues("Message", "Data source \"name\" 
destroyed on \"server1\"");
 
     assertThat(cacheConfig.getJndiBindings().isEmpty()).isTrue();
     verify(command).updateConfigForGroup(eq("cluster"), eq(cacheConfig), 
any());
 
     ArgumentCaptor<DestroyJndiBindingFunction> function =
         ArgumentCaptor.forClass(DestroyJndiBindingFunction.class);
-    ArgumentCaptor<String> jndiName = ArgumentCaptor.forClass(String.class);
+    ArgumentCaptor<Object[]> arguments = 
ArgumentCaptor.forClass(Object[].class);
+
     ArgumentCaptor<Set<DistributedMember>> targetMembers = 
ArgumentCaptor.forClass(Set.class);
-    verify(command, times(1)).executeAndGetFunctionResult(function.capture(), 
jndiName.capture(),
+    verify(command, times(1)).executeAndGetFunctionResult(function.capture(), 
arguments.capture(),
         targetMembers.capture());
 
+    String jndiName = (String) arguments.getValue()[0];
+    boolean destroyingDataSource = (boolean) arguments.getValue()[1];
+
     
assertThat(function.getValue()).isInstanceOf(DestroyJndiBindingFunction.class);
-    assertThat(jndiName.getValue()).isNotNull();
-    assertThat(jndiName.getValue()).isEqualTo("name");
+    assertThat(jndiName).isEqualTo("name");
+    assertThat(destroyingDataSource).isEqualTo(true);
     assertThat(targetMembers.getValue()).isEqualTo(members);
   }
 }
diff --git 
a/geode-core/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/DestroyJndiBindingCommandDUnitTest.java
 
b/geode-core/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/DestroyJndiBindingCommandDUnitTest.java
index 97f0170..bb61474 100644
--- 
a/geode-core/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/DestroyJndiBindingCommandDUnitTest.java
+++ 
b/geode-core/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/DestroyJndiBindingCommandDUnitTest.java
@@ -20,7 +20,6 @@ import static 
org.assertj.core.api.AssertionsForInterfaceTypes.assertThat;
 import org.junit.BeforeClass;
 import org.junit.ClassRule;
 import org.junit.Test;
-import org.junit.experimental.categories.Category;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.NodeList;
@@ -32,11 +31,9 @@ import 
org.apache.geode.management.internal.configuration.domain.Configuration;
 import org.apache.geode.management.internal.configuration.utils.XmlUtils;
 import org.apache.geode.test.dunit.rules.ClusterStartupRule;
 import org.apache.geode.test.dunit.rules.MemberVM;
-import org.apache.geode.test.junit.categories.GfshTest;
 import org.apache.geode.test.junit.rules.GfshCommandRule;
 import org.apache.geode.test.junit.rules.VMProvider;
 
-@Category(GfshTest.class)
 public class DestroyJndiBindingCommandDUnitTest {
 
   private static MemberVM locator, server1, server2;
diff --git 
a/geode-core/src/integrationTest/java/org/apache/geode/management/internal/cli/functions/DestroyJndiBindingFunctionTest.java
 
b/geode-core/src/integrationTest/java/org/apache/geode/management/internal/cli/functions/DestroyJndiBindingFunctionTest.java
index cf9cbbd..3717fdc 100644
--- 
a/geode-core/src/integrationTest/java/org/apache/geode/management/internal/cli/functions/DestroyJndiBindingFunctionTest.java
+++ 
b/geode-core/src/integrationTest/java/org/apache/geode/management/internal/cli/functions/DestroyJndiBindingFunctionTest.java
@@ -16,6 +16,8 @@
 package org.apache.geode.management.internal.cli.functions;
 
 import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
@@ -70,7 +72,7 @@ public class DestroyJndiBindingFunctionTest {
 
   @Test
   public void destroyJndiBindingIsSuccessfulWhenBindingFound() throws 
Exception {
-    when(context.getArguments()).thenReturn("jndi1");
+    when(context.getArguments()).thenReturn(new Object[] {"jndi1", false});
     when(context.getMemberName()).thenReturn("server-1");
     when(context.getResultSender()).thenReturn(resultSender);
 
@@ -85,7 +87,7 @@ public class DestroyJndiBindingFunctionTest {
 
   @Test
   public void destroyJndiBindingIsSuccessfulWhenNoBindingFound() throws 
Exception {
-    when(context.getArguments()).thenReturn("somectx/unknownjndi");
+    when(context.getArguments()).thenReturn(new Object[] 
{"\"somectx/unknownjndi\"", false});
     when(context.getResultSender()).thenReturn(resultSender);
 
     destroyJndiBindingFunction.execute(context);
@@ -94,6 +96,54 @@ public class DestroyJndiBindingFunctionTest {
     CliFunctionResult result = resultCaptor.getValue();
 
     assertThat(result.isSuccessful()).isTrue();
-    assertThat(result.getMessage()).contains("not found");
+    assertThat(result.getMessage()).contains("not found").contains("Jndi 
binding");
+  }
+
+  @Test
+  public void destroyDataSourceIsSuccessfulWhenBindingFound() throws Exception 
{
+    when(context.getArguments()).thenReturn(new Object[] {"jndi1", true});
+    when(context.getMemberName()).thenReturn("server-1");
+    when(context.getResultSender()).thenReturn(resultSender);
+
+    destroyJndiBindingFunction.execute(context);
+
+    verify(resultSender).lastResult(resultCaptor.capture());
+    CliFunctionResult result = resultCaptor.getValue();
+
+    assertThat(result.isSuccessful()).isTrue();
+    assertThat(result.getMessage()).contains("Data source \"jndi1\" destroyed 
on \"server-1\"");
+  }
+
+  @Test
+  public void destroyDataSourceIsSuccessfulWhenNoBindingFound() throws 
Exception {
+    when(context.getArguments()).thenReturn(new Object[] 
{"\"somectx/unknownjndi\"", true});
+    when(context.getResultSender()).thenReturn(resultSender);
+
+    destroyJndiBindingFunction.execute(context);
+
+    verify(resultSender).lastResult(resultCaptor.capture());
+    CliFunctionResult result = resultCaptor.getValue();
+
+    assertThat(result.isSuccessful()).isTrue();
+    assertThat(result.getMessage()).contains("not found").contains("Data 
source");
+  }
+
+  @Test
+  public void destroyDataSourceFailsWhenBindingHasInvalidType() throws 
Exception {
+
+    when(context.getArguments()).thenReturn(new Object[] {"jndi1", true});
+    when(context.getResultSender()).thenReturn(resultSender);
+    DestroyJndiBindingFunction destroyFunctionSpy = 
spy(destroyJndiBindingFunction);
+    doReturn(true).when(destroyFunctionSpy).checkForInvalidDataSource(any());
+
+    destroyFunctionSpy.execute(context);
+    verify(resultSender).lastResult(resultCaptor.capture());
+
+
+    CliFunctionResult result = resultCaptor.getValue();
+
+    assertThat(result.isSuccessful()).isEqualTo(false);
+    assertThat(result.getMessage()).contains(
+        "Data Source jndi1 has invalid type for destroy data-source, destroy 
jndi-binding command should be used.");
   }
 }
diff --git 
a/geode-core/src/main/java/org/apache/geode/internal/jndi/JNDIInvoker.java 
b/geode-core/src/main/java/org/apache/geode/internal/jndi/JNDIInvoker.java
index 1fcd032..3c47c85 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/jndi/JNDIInvoker.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/jndi/JNDIInvoker.java
@@ -45,6 +45,8 @@ import 
org.apache.geode.internal.datasource.ClientConnectionFactoryWrapper;
 import org.apache.geode.internal.datasource.ConfigProperty;
 import org.apache.geode.internal.datasource.DataSourceCreateException;
 import org.apache.geode.internal.datasource.DataSourceFactory;
+import org.apache.geode.internal.datasource.GemFireBasicDataSource;
+import org.apache.geode.internal.datasource.GemFireConnPooledDataSource;
 import org.apache.geode.internal.jta.TransactionManagerImpl;
 import org.apache.geode.internal.jta.TransactionUtils;
 import org.apache.geode.internal.jta.UserTransactionImpl;
@@ -396,6 +398,16 @@ public class JNDIInvoker {
     }
   }
 
+  public static boolean checkForInvalidDataSource(String name) {
+    Object dataSource = dataSourceMap.get(name);
+
+    if (dataSource == null || dataSource instanceof GemFireBasicDataSource
+        || dataSource instanceof GemFireConnPooledDataSource) {
+      return false;
+    }
+    return true;
+  }
+
   /**
    * @return Context the existing JNDI Context. If there is no pre-esisting 
JNDI Context, the
    *         GemFire JNDI Context is returned.
diff --git 
a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/DestroyJndiBindingCommand.java
 
b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/DestroyJndiBindingCommand.java
index 9ba0b92..4540121 100644
--- 
a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/DestroyJndiBindingCommand.java
+++ 
b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/DestroyJndiBindingCommand.java
@@ -74,7 +74,8 @@ public class DestroyJndiBindingCommand extends 
SingleGfshCommand {
     Set<DistributedMember> targetMembers = findMembers(null, null);
     if (targetMembers.size() > 0) {
       List<CliFunctionResult> jndiCreationResult =
-          executeAndGetFunctionResult(new DestroyJndiBindingFunction(), 
jndiName, targetMembers);
+          executeAndGetFunctionResult(new DestroyJndiBindingFunction(),
+              new Object[] {jndiName, false}, targetMembers);
       ResultModel result = 
ResultModel.createMemberStatusResult(jndiCreationResult);
       result.setConfigObject(jndiName);
       return result;
diff --git 
a/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/DestroyJndiBindingFunction.java
 
b/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/DestroyJndiBindingFunction.java
index 51bb130..a31d8bd 100644
--- 
a/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/DestroyJndiBindingFunction.java
+++ 
b/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/DestroyJndiBindingFunction.java
@@ -21,22 +21,39 @@ import org.apache.geode.internal.jndi.JNDIInvoker;
 import org.apache.geode.management.cli.CliFunction;
 import org.apache.geode.management.internal.cli.i18n.CliStrings;
 
-public class DestroyJndiBindingFunction extends CliFunction<String> {
-
-  static final String RESULT_MESSAGE = "Jndi binding \"{0}\" destroyed on 
\"{1}\"";
-  static final String EXCEPTION_RESULT_MESSAGE = "Jndi binding \"{0}\" not 
found on \"{1}\"";
+public class DestroyJndiBindingFunction extends CliFunction<Object[]> {
 
   @Override
-  public CliFunctionResult executeFunction(FunctionContext context) {
-    String jndiName = (String) context.getArguments();
+  public CliFunctionResult executeFunction(FunctionContext<Object[]> context) {
+    String jndiName = (String) context.getArguments()[0];
+    boolean destroyingDataSource = (boolean) context.getArguments()[1];
+
+    String typeName = "Jndi binding";
+
+    if (destroyingDataSource) {
+      typeName = "Data source";
+      if (checkForInvalidDataSource(jndiName)) {
+        return new CliFunctionResult(context.getMemberName(), 
CliFunctionResult.StatusState.ERROR,
+            CliStrings.format(
+                "Data Source {0} has invalid type for destroy data-source, 
destroy jndi-binding command should be used.",
+                jndiName));
+      }
+    }
+
+    final String RESULT_MESSAGE = "{0} \"{1}\" destroyed on \"{2}\"";
+    final String EXCEPTION_RESULT_MESSAGE = "{0} \"{1}\" not found on \"{2}\"";
 
     try {
       JNDIInvoker.unMapDatasource(jndiName);
-      return new CliFunctionResult(context.getMemberName(), true,
-          CliStrings.format(RESULT_MESSAGE, jndiName, 
context.getMemberName()));
+      return new CliFunctionResult(context.getMemberName(), 
CliFunctionResult.StatusState.OK,
+          CliStrings.format(RESULT_MESSAGE, typeName, jndiName, 
context.getMemberName()));
     } catch (NamingException e) {
-      return new CliFunctionResult(context.getMemberName(), true,
-          CliStrings.format(EXCEPTION_RESULT_MESSAGE, jndiName, 
context.getMemberName()));
+      return new CliFunctionResult(context.getMemberName(), 
CliFunctionResult.StatusState.OK,
+          CliStrings.format(EXCEPTION_RESULT_MESSAGE, typeName, jndiName, 
context.getMemberName()));
     }
   }
+
+  boolean checkForInvalidDataSource(String jndiName) {
+    return JNDIInvoker.checkForInvalidDataSource(jndiName);
+  }
 }
diff --git 
a/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/DestroyJndiBindingCommandTest.java
 
b/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/DestroyJndiBindingCommandTest.java
index 9de3810..e61805a 100644
--- 
a/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/DestroyJndiBindingCommandTest.java
+++ 
b/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/DestroyJndiBindingCommandTest.java
@@ -159,14 +159,18 @@ public class DestroyJndiBindingCommandTest {
 
     ArgumentCaptor<DestroyJndiBindingFunction> function =
         ArgumentCaptor.forClass(DestroyJndiBindingFunction.class);
-    ArgumentCaptor<String> jndiName = ArgumentCaptor.forClass(String.class);
+    ArgumentCaptor<Object[]> arguments = 
ArgumentCaptor.forClass(Object[].class);
+
     ArgumentCaptor<Set<DistributedMember>> targetMembers = 
ArgumentCaptor.forClass(Set.class);
-    verify(command, times(1)).executeAndGetFunctionResult(function.capture(), 
jndiName.capture(),
+    verify(command, times(1)).executeAndGetFunctionResult(function.capture(), 
arguments.capture(),
         targetMembers.capture());
 
+    String jndiName = (String) arguments.getValue()[0];
+    boolean destroyingDataSource = (boolean) arguments.getValue()[1];
+
     
assertThat(function.getValue()).isInstanceOf(DestroyJndiBindingFunction.class);
-    assertThat(jndiName.getValue()).isNotNull();
-    assertThat(jndiName.getValue()).isEqualTo("name");
+    assertThat(jndiName).isEqualTo("name");
+    assertThat(destroyingDataSource).isEqualTo(false);
     assertThat(targetMembers.getValue()).isEqualTo(members);
   }
 
@@ -199,14 +203,18 @@ public class DestroyJndiBindingCommandTest {
 
     ArgumentCaptor<DestroyJndiBindingFunction> function =
         ArgumentCaptor.forClass(DestroyJndiBindingFunction.class);
-    ArgumentCaptor<String> jndiName = ArgumentCaptor.forClass(String.class);
+    ArgumentCaptor<Object[]> arguments = 
ArgumentCaptor.forClass(Object[].class);
+
     ArgumentCaptor<Set<DistributedMember>> targetMembers = 
ArgumentCaptor.forClass(Set.class);
-    verify(command, times(1)).executeAndGetFunctionResult(function.capture(), 
jndiName.capture(),
+    verify(command, times(1)).executeAndGetFunctionResult(function.capture(), 
arguments.capture(),
         targetMembers.capture());
 
+    String jndiName = (String) arguments.getValue()[0];
+    boolean destroyingDataSource = (boolean) arguments.getValue()[1];
+
     
assertThat(function.getValue()).isInstanceOf(DestroyJndiBindingFunction.class);
-    assertThat(jndiName.getValue()).isNotNull();
-    assertThat(jndiName.getValue()).isEqualTo("name");
+    assertThat(jndiName).isEqualTo("name");
+    assertThat(destroyingDataSource).isEqualTo(false);
     assertThat(targetMembers.getValue()).isEqualTo(members);
   }
 }

Reply via email to