You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by ds...@apache.org on 2018/11/28 00:55:20 UTC

[geode] branch feature/GEODE-6067 created (now 7c826fd)

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

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


      at 7c826fd  added dunit test

This branch includes the following new commits:

     new d72b7a6  added list data-source and unit test
     new 7c826fd  added dunit test

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[geode] 02/02: added dunit test

Posted by ds...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 7c826fd25b154d5b358168ae023baa9317ba7d8e
Author: Darrel Schneider <ds...@pivotal.io>
AuthorDate: Tue Nov 27 16:55:00 2018 -0800

    added dunit test
---
 .../cli/ListDataSourceCommandDUnitTest.java        | 111 +++++++++++++++++++++
 1 file changed, 111 insertions(+)

diff --git a/geode-connectors/src/distributedTest/java/org/apache/geode/connectors/jdbc/internal/cli/ListDataSourceCommandDUnitTest.java b/geode-connectors/src/distributedTest/java/org/apache/geode/connectors/jdbc/internal/cli/ListDataSourceCommandDUnitTest.java
new file mode 100644
index 0000000..197c32b
--- /dev/null
+++ b/geode-connectors/src/distributedTest/java/org/apache/geode/connectors/jdbc/internal/cli/ListDataSourceCommandDUnitTest.java
@@ -0,0 +1,111 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.apache.geode.connectors.jdbc.internal.cli;
+
+import java.util.Properties;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import org.apache.geode.test.dunit.rules.ClusterStartupRule;
+import org.apache.geode.test.dunit.rules.MemberVM;
+import org.apache.geode.test.junit.assertions.CommandResultAssert;
+import org.apache.geode.test.junit.rules.GfshCommandRule;
+
+public class ListDataSourceCommandDUnitTest {
+
+  private MemberVM locator, server;
+
+  @Rule
+  public ClusterStartupRule cluster = new ClusterStartupRule();
+
+  @Rule
+  public GfshCommandRule gfsh = new GfshCommandRule();
+
+  @Before
+  public void before() throws Exception {
+    locator = cluster.startLocatorVM(0);
+    server = cluster.startServerVM(1, new Properties(), locator.getPort());
+
+    gfsh.connectAndVerify(locator);
+  }
+
+  @Test
+  public void listDataSourceForSimpleDataSource() {
+    gfsh.executeAndAssertThat(
+        "create data-source --name=simple --url=\"jdbc:derby:newDB;create=true\" --username=joe --password=myPassword")
+        .statusIsSuccess().tableHasColumnOnlyWithValues("Member", "server-1");
+
+    CommandResultAssert result = gfsh.executeAndAssertThat("list data-source");
+
+    result.statusIsSuccess()
+        .tableHasRowWithValues("name", "pooled", "in use", "url", "simple", "false", "false",
+            "jdbc:derby:newDB;create=true");
+  }
+
+  @Test
+  public void listDataSourceUsedByRegionsHasCorrectOutput() {
+    gfsh.executeAndAssertThat(
+        "create data-source --name=simple --url=\"jdbc:derby:newDB;create=true\"")
+        .statusIsSuccess().tableHasColumnOnlyWithValues("Member", "server-1");
+    gfsh.executeAndAssertThat("create region --name=region1 --type=REPLICATE").statusIsSuccess();
+    gfsh.executeAndAssertThat("create region --name=region2 --type=PARTITION").statusIsSuccess();
+    gfsh.executeAndAssertThat(
+        "create jdbc-mapping --region=region1 --data-source=simple --pdx-name=myPdx");
+    gfsh.executeAndAssertThat(
+        "create jdbc-mapping --region=region2 --data-source=simple --pdx-name=myPdx");
+
+    CommandResultAssert result = gfsh.executeAndAssertThat("list data-source");
+
+    result.statusIsSuccess()
+        .tableHasRowWithValues("name", "pooled", "in use", "url", "simple", "false", "true",
+            "jdbc:derby:newDB;create=true");
+  }
+
+  @Test
+  public void listDataSourceForPooledDataSource() {
+    gfsh.executeAndAssertThat(
+        "create data-source --name=pooled --pooled --url=\"jdbc:derby:newDB;create=true\" --pooled-data-source-factory-class=org.apache.geode.internal.jta.CacheJTAPooledDataSourceFactory --pool-properties={'name':'prop1','value':'value1'},{'name':'pool.prop2','value':'value2'}")
+        .statusIsSuccess().tableHasColumnOnlyWithValues("Member", "server-1");
+
+    gfsh.executeAndAssertThat("list data-source").statusIsSuccess()
+        .tableHasRowWithValues("name", "pooled", "in use", "url", "pooled", "true", "false",
+            "jdbc:derby:newDB;create=true");
+  }
+
+  @Test
+  public void listDataSourceWithMultipleDataSourcesListsAll() {
+    gfsh.executeAndAssertThat(
+        "create data-source --name=simple --url=\"jdbc:derby:newDB;create=true\" --username=joe --password=myPassword")
+        .statusIsSuccess().tableHasColumnOnlyWithValues("Member", "server-1");
+    gfsh.executeAndAssertThat(
+        "create data-source --name=pooled --pooled --url=\"jdbc:derby:newDB;create=true\" --pooled-data-source-factory-class=org.apache.geode.internal.jta.CacheJTAPooledDataSourceFactory --pool-properties={'name':'prop1','value':'value1'},{'name':'pool.prop2','value':'value2'}")
+        .statusIsSuccess().tableHasColumnOnlyWithValues("Member", "server-1");
+
+    gfsh.executeAndAssertThat("list data-source").statusIsSuccess()
+        .tableHasRowWithValues("name", "pooled", "in use", "url", "pooled", "true", "false",
+            "jdbc:derby:newDB;create=true")
+        .tableHasRowWithValues("name", "pooled", "in use", "url", "simple", "false", "false",
+            "jdbc:derby:newDB;create=true");
+  }
+
+  @Test
+  public void listDataSourceWithNoDataSources() {
+    gfsh.executeAndAssertThat("list data-source").statusIsSuccess()
+        .containsOutput("No data sources found");
+  }
+}


[geode] 01/02: added list data-source and unit test

Posted by ds...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit d72b7a62092834a72484d8be502bf417d96cbdd0
Author: Darrel Schneider <ds...@pivotal.io>
AuthorDate: Tue Nov 27 16:22:56 2018 -0800

    added list data-source and unit test
---
 .../jdbc/internal/cli/ListDataSourceCommand.java   | 114 +++++++++++
 .../org.springframework.shell.core.CommandMarker   |   1 +
 .../cli/DescribeDataSourceCommandTest.java         |   2 +-
 ...andTest.java => ListDataSourceCommandTest.java} | 215 +++++++--------------
 4 files changed, 191 insertions(+), 141 deletions(-)

diff --git a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/ListDataSourceCommand.java b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/ListDataSourceCommand.java
new file mode 100644
index 0000000..b2c4e68
--- /dev/null
+++ b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/ListDataSourceCommand.java
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.apache.geode.connectors.jdbc.internal.cli;
+
+import org.springframework.shell.core.annotation.CliAvailabilityIndicator;
+import org.springframework.shell.core.annotation.CliCommand;
+
+import org.apache.geode.annotations.Experimental;
+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.internal.InternalConfigurationPersistenceService;
+import org.apache.geode.management.cli.CliMetaData;
+import org.apache.geode.management.internal.cli.commands.CreateJndiBindingCommand.DATASOURCE_TYPE;
+import org.apache.geode.management.internal.cli.commands.InternalGfshCommand;
+import org.apache.geode.management.internal.cli.result.model.ResultModel;
+import org.apache.geode.management.internal.cli.result.model.TabularResultModel;
+import org.apache.geode.management.internal.security.ResourceOperation;
+import org.apache.geode.security.ResourcePermission;
+
+@Experimental
+public class ListDataSourceCommand extends InternalGfshCommand {
+  static final String LIST_DATA_SOURCE = "list data-source";
+  private static final String LIST_DATA_SOURCE__HELP = EXPERIMENTAL +
+      "List each existing data source.";
+
+  static final String DATA_SOURCE_PROPERTIES_SECTION = "data-source-properties";
+
+  @CliCommand(value = LIST_DATA_SOURCE, help = LIST_DATA_SOURCE__HELP)
+  @CliMetaData
+  @ResourceOperation(resource = ResourcePermission.Resource.CLUSTER,
+      operation = ResourcePermission.Operation.READ)
+  public ResultModel listDataSources() {
+
+    ResultModel resultModel = new ResultModel();
+    resultModel.setHeader(EXPERIMENTAL);
+    TabularResultModel tabularData = resultModel.addTable(DATA_SOURCE_PROPERTIES_SECTION);
+    tabularData.setColumnHeader("name", "pooled", "in use", "url");
+
+    InternalConfigurationPersistenceService ccService = getConfigurationPersistenceService();
+    if (ccService == null) {
+      return ResultModel.createError("Cluster configuration service must be enabled.");
+    }
+    CacheConfig cacheConfig = ccService.getCacheConfig(null);
+    if (cacheConfig == null) {
+      return ResultModel.createInfo("No data sources found");
+    }
+
+    cacheConfig.getJndiBindings().stream()
+        .forEach(dataSource -> addDataSourceToResult(dataSource, cacheConfig, tabularData));
+
+    return resultModel;
+  }
+
+  private void addDataSourceToResult(JndiBindingsType.JndiBinding binding, CacheConfig cacheConfig,
+      TabularResultModel tabularData) {
+    boolean pooled;
+    String type = binding.getType();
+    if (DATASOURCE_TYPE.SIMPLE.getType().equals(type)) {
+      pooled = false;
+    } else if (DATASOURCE_TYPE.POOLED.getType().equals(type)) {
+      pooled = true;
+    } else {
+      // skip this binding since it was not created as a data-source
+      return;
+    }
+
+    String dataSourceName = binding.getJndiName();
+    tabularData.addRow(dataSourceName, Boolean.toString(pooled),
+        Boolean.toString(isDataSourceUsedByRegion(cacheConfig, dataSourceName)),
+        binding.getConnectionUrl());
+
+  }
+
+  boolean isDataSourceUsedByRegion(CacheConfig cacheConfig, String dataSourceName) {
+    return cacheConfig.getRegions().stream()
+        .anyMatch(regionConfig -> hasJdbcMappingThatUsesDataSource(regionConfig, dataSourceName));
+  }
+
+  private boolean hasJdbcMappingThatUsesDataSource(RegionConfig regionConfig,
+      String dataSourceName) {
+    return regionConfig.getCustomRegionElements()
+        .stream()
+        .anyMatch(cacheElement -> isRegionMappingUsingDataSource(cacheElement, dataSourceName));
+  }
+
+  private boolean isRegionMappingUsingDataSource(CacheElement cacheElement, String dataSourceName) {
+    if (!(cacheElement instanceof RegionMapping)) {
+      return false;
+    }
+    RegionMapping regionMapping = (RegionMapping) cacheElement;
+    return dataSourceName.equals(regionMapping.getDataSourceName());
+  }
+
+  @CliAvailabilityIndicator({LIST_DATA_SOURCE})
+  public boolean commandAvailable() {
+    return isOnlineCommandAvailable();
+  }
+}
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 a6ae8aa..ca6df1b 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
@@ -20,4 +20,5 @@ org.apache.geode.connectors.jdbc.internal.cli.CreateMappingCommand
 org.apache.geode.connectors.jdbc.internal.cli.DescribeDataSourceCommand
 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
diff --git a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeDataSourceCommandTest.java b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeDataSourceCommandTest.java
index abba7a2..6276f40 100644
--- a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeDataSourceCommandTest.java
+++ b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeDataSourceCommandTest.java
@@ -327,7 +327,7 @@ public class DescribeDataSourceCommandTest {
   }
 
   @Test
-  public void describeDataSourceWithRegionsUsingItReturnsResultWithNoRegionsUsingIt() {
+  public void describeDataSourceWithNoRegionsUsingItReturnsResultWithNoRegionsUsingIt() {
     RegionConfig regionConfig = mock(RegionConfig.class);
     when(regionConfig.getCustomRegionElements())
         .thenReturn(Collections.singletonList(mock(RegionMapping.class)));
diff --git a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeDataSourceCommandTest.java b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/ListDataSourceCommandTest.java
similarity index 51%
copy from geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeDataSourceCommandTest.java
copy to geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/ListDataSourceCommandTest.java
index abba7a2..3b2ed59 100644
--- a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeDataSourceCommandTest.java
+++ b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/ListDataSourceCommandTest.java
@@ -33,23 +33,22 @@ import org.junit.Test;
 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.JndiBindingsType.JndiBinding.ConfigProperty;
+import org.apache.geode.cache.configuration.JndiBindingsType.JndiBinding;
 import org.apache.geode.cache.configuration.RegionConfig;
 import org.apache.geode.connectors.jdbc.internal.configuration.RegionMapping;
 import org.apache.geode.distributed.internal.InternalConfigurationPersistenceService;
 import org.apache.geode.management.cli.Result.Status;
 import org.apache.geode.management.internal.cli.commands.CreateJndiBindingCommand.DATASOURCE_TYPE;
-import org.apache.geode.management.internal.cli.result.model.InfoResultModel;
 import org.apache.geode.management.internal.cli.result.model.ResultModel;
 import org.apache.geode.management.internal.cli.result.model.TabularResultModel;
 import org.apache.geode.test.junit.rules.GfshParserRule;
 
-public class DescribeDataSourceCommandTest {
+public class ListDataSourceCommandTest {
 
   @ClassRule
   public static GfshParserRule gfsh = new GfshParserRule();
 
-  private DescribeDataSourceCommand command;
+  private ListDataSourceCommand command;
 
   private JndiBindingsType.JndiBinding binding;
   private List<JndiBindingsType.JndiBinding> bindings;
@@ -57,16 +56,17 @@ public class DescribeDataSourceCommandTest {
   private CacheConfig cacheConfig;
   private List<RegionConfig> regionConfigs;
 
-  private static String COMMAND = "describe data-source";
+  private static String COMMAND = "list data-source";
   private static String DATA_SOURCE_NAME = "myDataSource";
 
   @Before
   public void setUp() {
-    command = spy(DescribeDataSourceCommand.class);
+    command = spy(ListDataSourceCommand.class);
 
     binding = new JndiBindingsType.JndiBinding();
     binding.setJndiName(DATA_SOURCE_NAME);
     binding.setType(DATASOURCE_TYPE.POOLED.getType());
+    binding.setConnectionUrl("myURL");
     bindings = new ArrayList<>();
     clusterConfigService = mock(InternalConfigurationPersistenceService.class);
     cacheConfig = mock(CacheConfig.class);
@@ -80,203 +80,138 @@ public class DescribeDataSourceCommandTest {
   }
 
   @Test
-  public void missingMandatory() {
-    gfsh.executeAndAssertThat(command, COMMAND).statusIsError()
-        .containsOutput("Invalid command: describe data-source");
+  public void noArgsReturnsSuccess() {
+    gfsh.executeAndAssertThat(command, COMMAND).statusIsSuccess();
   }
 
   @Test
-  public void nameWorks() {
-    gfsh.executeAndAssertThat(command, COMMAND + " --name=" + DATA_SOURCE_NAME).statusIsSuccess();
-  }
-
-  @Test
-  public void describeDataSourceWithNoClusterConfigurationServerFails() {
+  public void listDataSourceWithNoClusterConfigurationServerFails() {
     doReturn(null).when(command).getConfigurationPersistenceService();
 
-    ResultModel result = command.describeDataSource(DATA_SOURCE_NAME);
+    ResultModel result = command.listDataSources();
 
     assertThat(result.getStatus()).isEqualTo(Status.ERROR);
     assertThat(result.toString()).contains("Cluster configuration service must be enabled.");
   }
 
   @Test
-  public void describeDataSourceWithNoClusterConfigFails() {
+  public void listDataSourceWithNoClusterConfigIsOkWithNoDataSources() {
     doReturn(null).when(clusterConfigService).getCacheConfig(any());
 
-    ResultModel result = command.describeDataSource(DATA_SOURCE_NAME);
+    ResultModel result = command.listDataSources();
 
-    assertThat(result.getStatus()).isEqualTo(Status.ERROR);
-    assertThat(result.toString()).contains("Data source: " + DATA_SOURCE_NAME + " not found");
+    assertThat(result.getStatus()).isEqualTo(Status.OK);
+    assertThat(result.toString()).contains("No data sources found");
   }
 
   @Test
-  public void describeDataSourceWithWrongNameFails() {
-    ResultModel result = command.describeDataSource("bogusName");
-
-    assertThat(result.getStatus()).isEqualTo(Status.ERROR);
-    assertThat(result.toString()).contains("Data source: bogusName not found");
-  }
-
-  @Test
-  public void describeDataSourceWithUnsupportedTypeFails() {
+  public void listDataSourceWithUnsupportedTypeIgnoresIt() {
     binding.setType(DATASOURCE_TYPE.MANAGED.getType());
 
-    ResultModel result = command.describeDataSource(DATA_SOURCE_NAME);
+    ResultModel result = command.listDataSources();
 
-    assertThat(result.getStatus()).isEqualTo(Status.ERROR);
-    assertThat(result.toString()).contains("Unknown data source type: ManagedDataSource");
+    assertThat(result.getStatus()).isEqualTo(Status.OK);
+    assertThat(result.toString()).doesNotContain(DATA_SOURCE_NAME);
   }
 
   @Test
-  public void describeDataSourceWithSimpleTypeReturnsPooledFalse() {
+  public void listDataSourceWithSimpleTypeReturnsPooledFalse() {
     binding.setType(DATASOURCE_TYPE.SIMPLE.getType());
 
-    ResultModel result = command.describeDataSource(DATA_SOURCE_NAME);
+    ResultModel result = command.listDataSources();
 
     TabularResultModel section =
-        result.getTableSection(DescribeDataSourceCommand.DATA_SOURCE_PROPERTIES_SECTION);
-    assertThat(section.getValuesInRow(3)).isEqualTo(Arrays.asList("pooled", "false"));
+        result.getTableSection(ListDataSourceCommand.DATA_SOURCE_PROPERTIES_SECTION);
+    assertThat(section.getValuesInRow(0))
+        .isEqualTo(Arrays.asList(DATA_SOURCE_NAME, "false", "false", "myURL"));
   }
 
   @Test
-  public void describeDataSourceWithPooledTypeReturnsPooledTrue() {
+  public void listDataSourceWithPooledTypeReturnsPooledTrue() {
     binding.setType(DATASOURCE_TYPE.POOLED.getType());
 
-    ResultModel result = command.describeDataSource(DATA_SOURCE_NAME);
-
-    TabularResultModel section =
-        result.getTableSection(DescribeDataSourceCommand.DATA_SOURCE_PROPERTIES_SECTION);
-    assertThat(section.getValuesInRow(3)).isEqualTo(Arrays.asList("pooled", "true"));
-  }
-
-  @Test
-  public void describeDataSourceTypeReturnsName() {
-    ResultModel result = command.describeDataSource(DATA_SOURCE_NAME);
-
-    TabularResultModel section =
-        result.getTableSection(DescribeDataSourceCommand.DATA_SOURCE_PROPERTIES_SECTION);
-    assertThat(section.getValuesInRow(0)).isEqualTo(Arrays.asList("name", DATA_SOURCE_NAME));
-  }
-
-  @Test
-  public void describeDataSourceWithUrlReturnsUrl() {
-    binding.setConnectionUrl("myUrl");
-
-    ResultModel result = command.describeDataSource(DATA_SOURCE_NAME);
-
-    TabularResultModel section =
-        result.getTableSection(DescribeDataSourceCommand.DATA_SOURCE_PROPERTIES_SECTION);
-    assertThat(section.getValuesInRow(1)).isEqualTo(Arrays.asList("url", "myUrl"));
-  }
-
-  @Test
-  public void describeDataSourceWithUsernameReturnsUsername() {
-    binding.setUserName("myUserName");
-
-    ResultModel result = command.describeDataSource(DATA_SOURCE_NAME);
+    ResultModel result = command.listDataSources();
 
     TabularResultModel section =
-        result.getTableSection(DescribeDataSourceCommand.DATA_SOURCE_PROPERTIES_SECTION);
-    assertThat(section.getValuesInRow(2)).isEqualTo(Arrays.asList("username", "myUserName"));
+        result.getTableSection(ListDataSourceCommand.DATA_SOURCE_PROPERTIES_SECTION);
+    assertThat(section.getValuesInRow(0))
+        .isEqualTo(Arrays.asList(DATA_SOURCE_NAME, "true", "false", "myURL"));
   }
 
   @Test
-  public void describeDataSourceWithPooledDataSourceFactoryClassShowsItInTheResult() {
-    binding.setType(DATASOURCE_TYPE.POOLED.getType());
-    binding.setConnPooledDatasourceClass("myPooledDataSourceFactoryClass");
-
-    ResultModel result = command.describeDataSource(DATA_SOURCE_NAME);
+  public void listDataSourcesReturnsInfoOnSingleDataSource() {
+    ResultModel result = command.listDataSources();
 
     TabularResultModel section =
-        result.getTableSection(DescribeDataSourceCommand.DATA_SOURCE_PROPERTIES_SECTION);
-    assertThat(section.getValuesInRow(4)).isEqualTo(
-        Arrays.asList("pooled-data-source-factory-class", "myPooledDataSourceFactoryClass"));
-  }
-
-  @Test
-  public void describeDataSourceWithPasswordDoesNotShowPasswordInResult() {
-    binding.setType(DATASOURCE_TYPE.POOLED.getType());
-    binding.setPassword("myPassword");
-
-    ResultModel result = command.describeDataSource(DATA_SOURCE_NAME);
-
-    assertThat(result.toString()).doesNotContain("myPassword");
+        result.getTableSection(ListDataSourceCommand.DATA_SOURCE_PROPERTIES_SECTION);
+    assertThat(section.getValuesInRow(0))
+        .isEqualTo(Arrays.asList(DATA_SOURCE_NAME, "true", "false", "myURL"));
   }
 
   @Test
-  public void describeDataSourceWithPoolPropertiesDoesNotShowsItInTheResult() {
-    binding.setType(DATASOURCE_TYPE.SIMPLE.getType());
-    List<ConfigProperty> configProperties = binding.getConfigProperties();
-    configProperties.add(new ConfigProperty("name1", "value1"));
+  public void listDataSourcesReturnsInfoOnMultipleDataSources() {
+    JndiBinding binding2 = new JndiBindingsType.JndiBinding();
+    binding2.setJndiName("myDataSource2");
+    binding2.setType(DATASOURCE_TYPE.SIMPLE.getType());
+    binding2.setConnectionUrl("myURL2");
+    bindings.add(binding2);
 
-    ResultModel result = command.describeDataSource(DATA_SOURCE_NAME);
-
-    assertThat(result.toString()).doesNotContain("name1");
-    assertThat(result.toString()).doesNotContain("value1");
-  }
-
-  @Test
-  public void describeDataSourceWithPoolPropertiesShowsItInTheResult() {
-    binding.setType(DATASOURCE_TYPE.POOLED.getType());
-    List<ConfigProperty> configProperties = binding.getConfigProperties();
-    configProperties.add(new ConfigProperty("name1", "value1"));
-    configProperties.add(new ConfigProperty("name2", "value2"));
-
-    ResultModel result = command.describeDataSource(DATA_SOURCE_NAME);
+    ResultModel result = command.listDataSources();
 
     TabularResultModel section =
-        result.getTableSection(DescribeDataSourceCommand.DATA_SOURCE_PROPERTIES_SECTION);
-    assertThat(section.getValuesInRow(5)).isEqualTo(Arrays.asList("name1", "value1"));
-    assertThat(section.getValuesInRow(6)).isEqualTo(Arrays.asList("name2", "value2"));
+        result.getTableSection(ListDataSourceCommand.DATA_SOURCE_PROPERTIES_SECTION);
+    assertThat(section.getValuesInRow(0))
+        .isEqualTo(Arrays.asList(DATA_SOURCE_NAME, "true", "false", "myURL"));
+    assertThat(section.getValuesInRow(1))
+        .isEqualTo(Arrays.asList("myDataSource2", "false", "false", "myURL2"));
   }
 
   @Test
-  public void getRegionsThatUseDataSourceGivenNoRegionsReturnsEmptyList() {
+  public void isDataSourceUsedByRegionGivenNoRegionsReturnsFalse() {
     regionConfigs.clear();
 
-    List<String> result = command.getRegionsThatUseDataSource(cacheConfig, "");
+    boolean result = command.isDataSourceUsedByRegion(cacheConfig, "");
 
-    assertThat(result).isEmpty();
+    assertThat(result).isFalse();
   }
 
   @Test
-  public void getRegionsThatUseDataSourceGivenRegionConfigWithNoCustomRegionElementsReturnsEmptyList() {
+  public void isDataSourceUsedByRegionGivenRegionConfigWithNoCustomRegionElementsReturnsFalse() {
     RegionConfig regionConfig = mock(RegionConfig.class);
     when(regionConfig.getCustomRegionElements()).thenReturn(Collections.emptyList());
     regionConfigs.add(regionConfig);
 
-    List<String> result = command.getRegionsThatUseDataSource(cacheConfig, "");
+    boolean result = command.isDataSourceUsedByRegion(cacheConfig, "");
 
-    assertThat(result).isEmpty();
+    assertThat(result).isFalse();
   }
 
   @Test
-  public void getRegionsThatUseDataSourceGivenRegionConfigWithNonRegionMappingElementReturnsEmptyList() {
+  public void isDataSourceUsedByRegionGivenRegionConfigWithNonRegionMappingElementReturnsFalse() {
     RegionConfig regionConfig = mock(RegionConfig.class);
     when(regionConfig.getCustomRegionElements())
         .thenReturn(Collections.singletonList(mock(CacheElement.class)));
     regionConfigs.add(regionConfig);
 
-    List<String> result = command.getRegionsThatUseDataSource(cacheConfig, "");
+    boolean result = command.isDataSourceUsedByRegion(cacheConfig, "");
 
-    assertThat(result).isEmpty();
+    assertThat(result).isFalse();
   }
 
   @Test
-  public void getRegionsThatUseDataSourceGivenRegionConfigWithRegionMappingForOtherDataSourceReturnsEmptyList() {
+  public void isDataSourceUsedByRegionGivenRegionConfigWithRegionMappingForOtherDataSourceReturnsFalse() {
     RegionConfig regionConfig = mock(RegionConfig.class);
     when(regionConfig.getCustomRegionElements())
         .thenReturn(Collections.singletonList(mock(RegionMapping.class)));
     regionConfigs.add(regionConfig);
 
-    List<String> result = command.getRegionsThatUseDataSource(cacheConfig, "bogusDataSource");
+    boolean result = command.isDataSourceUsedByRegion(cacheConfig, "bogusDataSource");
 
-    assertThat(result).isEmpty();
+    assertThat(result).isFalse();
   }
 
   @Test
-  public void getRegionsThatUseDataSourceGivenRegionConfigWithRegionMappingForDataSourceReturnsRegionName() {
+  public void isDataSourceUsedByRegionGivenRegionConfigWithRegionMappingForDataSourceReturnsTrue() {
     RegionConfig regionConfig = mock(RegionConfig.class);
     when(regionConfig.getName()).thenReturn("regionName");
     RegionMapping regionMapping = mock(RegionMapping.class);
@@ -285,13 +220,13 @@ public class DescribeDataSourceCommandTest {
         .thenReturn(Collections.singletonList(regionMapping));
     regionConfigs.add(regionConfig);
 
-    List<String> result = command.getRegionsThatUseDataSource(cacheConfig, "dataSourceName");
+    boolean result = command.isDataSourceUsedByRegion(cacheConfig, "dataSourceName");
 
-    assertThat(result).isEqualTo(Collections.singletonList("regionName"));
+    assertThat(result).isTrue();
   }
 
   @Test
-  public void getRegionsThatUseDataSourceGivenMultipleRegionConfigsReturnsAllRegionNames() {
+  public void isDataSourceUsedByRegionGivenMultipleRegionConfigsReturnsTrue() {
     RegionMapping regionMapping;
     {
       RegionConfig regionConfig1 = mock(RegionConfig.class, "regionConfig1");
@@ -321,28 +256,28 @@ public class DescribeDataSourceCommandTest {
       regionConfigs.add(regionConfig3);
     }
 
-    List<String> result = command.getRegionsThatUseDataSource(cacheConfig, "dataSourceName");
+    boolean result = command.isDataSourceUsedByRegion(cacheConfig, "dataSourceName");
 
-    assertThat(result).isEqualTo(Arrays.asList("regionName1", "regionName3"));
+    assertThat(result).isTrue();
   }
 
   @Test
-  public void describeDataSourceWithRegionsUsingItReturnsResultWithNoRegionsUsingIt() {
+  public void listDataSourcesWithNoRegionsUsingItReturnsResultWithInUseFalse() {
     RegionConfig regionConfig = mock(RegionConfig.class);
     when(regionConfig.getCustomRegionElements())
         .thenReturn(Collections.singletonList(mock(RegionMapping.class)));
     regionConfigs.add(regionConfig);
 
-    ResultModel result = command.describeDataSource(DATA_SOURCE_NAME);
+    ResultModel result = command.listDataSources();
 
-    InfoResultModel regionsUsingSection = (InfoResultModel) result
-        .getSection(DescribeDataSourceCommand.REGIONS_USING_DATA_SOURCE_SECTION);
-    assertThat(regionsUsingSection.getContent())
-        .isEqualTo(Arrays.asList("no regions are using " + DATA_SOURCE_NAME));
+    TabularResultModel section =
+        result.getTableSection(ListDataSourceCommand.DATA_SOURCE_PROPERTIES_SECTION);
+    assertThat(section.getValuesInRow(0))
+        .isEqualTo(Arrays.asList(DATA_SOURCE_NAME, "true", "false", "myURL"));
   }
 
   @Test
-  public void describeDataSourceWithRegionsUsingItReturnsResultWithRegionNames() {
+  public void listDataSourcesWithRegionsUsingItReturnsResultWithInUseTrue() {
     RegionMapping regionMapping;
     {
       RegionConfig regionConfig1 = mock(RegionConfig.class, "regionConfig1");
@@ -372,11 +307,11 @@ public class DescribeDataSourceCommandTest {
       regionConfigs.add(regionConfig3);
     }
 
-    ResultModel result = command.describeDataSource(DATA_SOURCE_NAME);
+    ResultModel result = command.listDataSources();
 
-    InfoResultModel regionsUsingSection = (InfoResultModel) result
-        .getSection(DescribeDataSourceCommand.REGIONS_USING_DATA_SOURCE_SECTION);
-    assertThat(regionsUsingSection.getContent())
-        .isEqualTo(Arrays.asList("regionName1", "regionName3"));
+    TabularResultModel section =
+        result.getTableSection(ListDataSourceCommand.DATA_SOURCE_PROPERTIES_SECTION);
+    assertThat(section.getValuesInRow(0))
+        .isEqualTo(Arrays.asList(DATA_SOURCE_NAME, "true", "true", "myURL"));
   }
 }