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);
}
}