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/16 21:01:16 UTC
[geode] 02/02: DestroyMappingFunction now cleans up the region and
the async event queue. Verified with unit test
This is an automated email from the ASF dual-hosted git repository.
dschneider pushed a commit to branch feature/GEODE-6068
in repository https://gitbox.apache.org/repos/asf/geode.git
commit f7eabd153fded118344e52d5f1e36c7060009d0d
Author: Darrel Schneider <ds...@pivotal.io>
AuthorDate: Fri Nov 16 13:00:34 2018 -0800
DestroyMappingFunction now cleans up the region and the async event queue. Verified with unit test
---
.../jdbc/internal/cli/DestroyMappingCommand.java | 2 -
.../jdbc/internal/cli/DestroyMappingFunction.java | 45 +++++++-
.../cli/DestroyMappingCommandFunctionTest.java | 116 ++++++++++++++++++++-
3 files changed, 154 insertions(+), 9 deletions(-)
diff --git a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyMappingCommand.java b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyMappingCommand.java
index f85bf44..4bf12fb 100644
--- a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyMappingCommand.java
+++ b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyMappingCommand.java
@@ -39,8 +39,6 @@ public class DestroyMappingCommand extends SingleGfshCommand {
static final String DESTROY_MAPPING__REGION_NAME = "region";
static final String DESTROY_MAPPING__REGION_NAME__HELP = "Name of the region mapping to destroy.";
- private static final String ERROR_PREFIX = "ERROR: ";
-
@CliCommand(value = DESTROY_MAPPING, help = DESTROY_MAPPING__HELP)
@CliMetaData(relatedTopic = CliStrings.DEFAULT_TOPIC_GEODE)
@ResourceOperation(resource = ResourcePermission.Resource.CLUSTER,
diff --git a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyMappingFunction.java b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyMappingFunction.java
index 2204596..5a0a255 100644
--- a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyMappingFunction.java
+++ b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyMappingFunction.java
@@ -14,12 +14,22 @@
*/
package org.apache.geode.connectors.jdbc.internal.cli;
+import java.util.Set;
+
import org.apache.geode.annotations.Experimental;
+import org.apache.geode.cache.Cache;
+import org.apache.geode.cache.CacheLoader;
+import org.apache.geode.cache.CacheWriter;
+import org.apache.geode.cache.Region;
+import org.apache.geode.cache.asyncqueue.internal.InternalAsyncEventQueue;
import org.apache.geode.cache.execute.FunctionContext;
+import org.apache.geode.connectors.jdbc.JdbcLoader;
+import org.apache.geode.connectors.jdbc.JdbcWriter;
import org.apache.geode.connectors.jdbc.internal.JdbcConnectorService;
import org.apache.geode.connectors.jdbc.internal.configuration.RegionMapping;
import org.apache.geode.management.cli.CliFunction;
import org.apache.geode.management.internal.cli.functions.CliFunctionResult;
+import org.apache.geode.management.internal.cli.functions.CliFunctionResult.StatusState;
@Experimental
@@ -27,17 +37,48 @@ public class DestroyMappingFunction extends CliFunction<String> {
@Override
public CliFunctionResult executeFunction(FunctionContext<String> context) {
+ Cache cache = context.getCache();
JdbcConnectorService service = FunctionContextArgumentProvider.getJdbcConnectorService(context);
String regionName = context.getArguments();
String member = context.getMemberName();
RegionMapping mapping = service.getMappingForRegion(regionName);
if (mapping != null) {
+ cleanupRegionAndQueue(cache, regionName);
service.destroyRegionMapping(regionName);
String message = "Destroyed region mapping for region " + regionName + " on " + member;
- return new CliFunctionResult(member, true, message);
+ return new CliFunctionResult(member, StatusState.OK, message);
} else {
String message = "Region mapping for region \"" + regionName + "\" not found";
- return new CliFunctionResult(member, false, message);
+ return new CliFunctionResult(member, StatusState.ERROR, message);
+ }
+ }
+
+ private void cleanupRegionAndQueue(Cache cache, String regionName) {
+ String queueName = CreateMappingCommand.createAsyncEventQueueName(regionName);
+ InternalAsyncEventQueue queue = (InternalAsyncEventQueue) cache.getAsyncEventQueue(queueName);
+
+ if (queue != null) {
+ queue.stop();
+ }
+
+ Region<?, ?> region = cache.getRegion(regionName);
+ if (region != null) {
+ CacheLoader<?, ?> loader = region.getAttributes().getCacheLoader();
+ if (loader instanceof JdbcLoader) {
+ region.getAttributesMutator().setCacheLoader(null);
+ }
+ CacheWriter<?, ?> writer = region.getAttributes().getCacheWriter();
+ if (writer instanceof JdbcWriter) {
+ region.getAttributesMutator().setCacheWriter(null);
+ }
+ Set<String> queueIds = region.getAttributes().getAsyncEventQueueIds();
+ if (queueIds.contains(queueName)) {
+ region.getAttributesMutator().removeAsyncEventQueueId(queueName);
+ }
+ }
+
+ if (queue != null) {
+ queue.destroy();
}
}
}
diff --git a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyMappingCommandFunctionTest.java b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyMappingCommandFunctionTest.java
index 8525280..4913eb8 100644
--- a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyMappingCommandFunctionTest.java
+++ b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyMappingCommandFunctionTest.java
@@ -16,20 +16,31 @@ package org.apache.geode.connectors.jdbc.internal.cli;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.any;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.io.Serializable;
+import java.util.Collections;
import org.apache.commons.lang3.SerializationUtils;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
+import org.apache.geode.cache.AttributesMutator;
+import org.apache.geode.cache.CacheLoader;
+import org.apache.geode.cache.CacheWriter;
+import org.apache.geode.cache.Region;
+import org.apache.geode.cache.RegionAttributes;
+import org.apache.geode.cache.asyncqueue.internal.InternalAsyncEventQueue;
import org.apache.geode.cache.execute.FunctionContext;
import org.apache.geode.cache.execute.ResultSender;
+import org.apache.geode.connectors.jdbc.JdbcLoader;
+import org.apache.geode.connectors.jdbc.JdbcWriter;
import org.apache.geode.connectors.jdbc.internal.JdbcConnectorService;
import org.apache.geode.connectors.jdbc.internal.configuration.RegionMapping;
import org.apache.geode.distributed.DistributedMember;
@@ -46,11 +57,23 @@ public class DestroyMappingCommandFunctionTest {
private ResultSender<Object> resultSender;
private RegionMapping mapping;
private JdbcConnectorService service;
+ private InternalCache cache;
+ private Region region;
+ private RegionAttributes regionAttributes;
+ private AttributesMutator regionMutator;
@Before
public void setUp() {
- InternalCache cache = mock(InternalCache.class);
+ cache = mock(InternalCache.class);
+ region = mock(Region.class);
+ when(region.getName()).thenReturn(regionName);
+ regionAttributes = mock(RegionAttributes.class);
+ regionMutator = mock(AttributesMutator.class);
+ when(region.getAttributes()).thenReturn(regionAttributes);
+ when(region.getAttributesMutator()).thenReturn(regionMutator);
+ when(cache.getRegion(regionName)).thenReturn(region);
context = mock(FunctionContext.class);
+ when(context.getMemberName()).thenReturn("myMemberName");
DistributedMember member = mock(DistributedMember.class);
resultSender = mock(ResultSender.class);
service = mock(JdbcConnectorService.class);
@@ -88,23 +111,106 @@ public class DestroyMappingCommandFunctionTest {
}
@Test
- public void destroyRegionMappingReturnsTrueIfConnectionDestroyed() {
+ public void executeFunctionGivenExistingMappingReturnsTrue() {
when(service.getMappingForRegion(eq(regionName))).thenReturn(mapping);
+
CliFunctionResult result = function.executeFunction(context);
+
assertThat(result.isSuccessful()).isTrue();
+ assertThat(result.toString())
+ .contains("Destroyed region mapping for region " + regionName + " on myMemberName");
}
@Test
- public void destroyRegionMappingReturnsFalseIfMappingDoesNotExist() {
+ public void executeFunctionGivenNoExistingMappingReturnsFalse() {
CliFunctionResult result = function.executeFunction(context);
+
assertThat(result.isSuccessful()).isFalse();
+ assertThat(result.toString())
+ .contains("Region mapping for region \"" + regionName + "\" not found");
}
@Test
- public void executeDestroysIfMappingFound() {
+ public void executeFunctionGivenARegionWithJdbcLoaderRemovesTheLoader() {
+ when(regionAttributes.getCacheLoader()).thenReturn(mock(JdbcLoader.class));
when(service.getMappingForRegion(eq(regionName))).thenReturn(mapping);
- function.execute(context);
+ function.executeFunction(context);
+
+ verify(regionMutator, times(1)).setCacheLoader(null);
+ }
+
+ @Test
+ public void executeFunctionGivenARegionWithNonJdbcLoaderDoesNotRemoveTheLoader() {
+ when(regionAttributes.getCacheLoader()).thenReturn(mock(CacheLoader.class));
+ when(service.getMappingForRegion(eq(regionName))).thenReturn(mapping);
+
+ function.executeFunction(context);
+
+ verify(regionMutator, never()).setCacheLoader(null);
+ }
+
+ @Test
+ public void executeFunctionGivenARegionWithJdbcWriterRemovesTheWriter() {
+ when(regionAttributes.getCacheWriter()).thenReturn(mock(JdbcWriter.class));
+ when(service.getMappingForRegion(eq(regionName))).thenReturn(mapping);
+
+ function.executeFunction(context);
+
+ verify(regionMutator, times(1)).setCacheWriter(null);
+ }
+
+ @Test
+ public void executeFunctionGivenARegionWithNonJdbcWriterDoesNotRemoveTheWriter() {
+ when(regionAttributes.getCacheWriter()).thenReturn(mock(CacheWriter.class));
+ when(service.getMappingForRegion(eq(regionName))).thenReturn(mapping);
+
+ function.executeFunction(context);
+
+ verify(regionMutator, never()).setCacheWriter(null);
+ }
+
+ @Test
+ public void executeFunctionGivenARegionWithJdbcAsyncEventQueueRemovesTheQueueName() {
+ String queueName = CreateMappingCommand.createAsyncEventQueueName(regionName);
+ when(regionAttributes.getAsyncEventQueueIds()).thenReturn(Collections.singleton(queueName));
+ when(service.getMappingForRegion(eq(regionName))).thenReturn(mapping);
+
+ function.executeFunction(context);
+
+ verify(regionMutator, times(1)).removeAsyncEventQueueId(queueName);
+ }
+
+ @Test
+ public void executeFunctionGivenARegionWithNonJdbcAsyncEventQueueDoesNotRemoveTheQueueName() {
+ when(regionAttributes.getAsyncEventQueueIds())
+ .thenReturn(Collections.singleton("nonJdbcQueue"));
+ when(service.getMappingForRegion(eq(regionName))).thenReturn(mapping);
+
+ function.executeFunction(context);
+
+ verify(regionMutator, never()).removeAsyncEventQueueId(any());
+ }
+
+ @Test
+ public void executeFunctionGivenAJdbcAsyncWriterQueueRemovesTheQueue() {
+ String queueName = CreateMappingCommand.createAsyncEventQueueName(regionName);
+ InternalAsyncEventQueue myQueue = mock(InternalAsyncEventQueue.class);
+ when(cache.getAsyncEventQueue(queueName)).thenReturn(myQueue);
+
+ when(service.getMappingForRegion(eq(regionName))).thenReturn(mapping);
+
+ function.executeFunction(context);
+
+ verify(myQueue, times(1)).stop();
+ verify(myQueue, times(1)).destroy();
+ }
+
+ @Test
+ public void executeFunctionGivenExistingMappingCallsDestroyRegionMapping() {
+ when(service.getMappingForRegion(eq(regionName))).thenReturn(mapping);
+
+ function.executeFunction(context);
verify(service, times(1)).destroyRegionMapping(eq(regionName));
}