From 8e3941dd07a96576ae44a65d08ef182cc163deb4 Mon Sep 17 00:00:00 2001 From: Kirk Lund Date: Thu, 10 Jan 2019 10:54:58 -0800 Subject: [PATCH 1/2] GEODE-6232: Extract ResourceEventNotifier from InternalDistributedSystem --- .../geode/cache30/TXDistributedDUnitTest.java | 17 ++- ...iOplogWithMissingCreateRegressionTest.java | 3 +- .../GiiDiskAccessExceptionRegressionTest.java | 3 +- .../java/org/apache/geode/TXJUnitTest.java | 3 + .../SerialAsyncEventQueueImplJUnitTest.java | 3 +- ...RUClearWithDiskRegionOpRegressionTest.java | 3 +- .../geode/internal/cache/PRTXJUnitTest.java | 9 +- .../internal/beans/ManagementAdapterTest.java | 16 +-- .../geode/cache/DynamicRegionFactory.java | 9 +- .../internal/AsyncEventQueueFactoryImpl.java | 24 +++-- .../internal/ParallelAsyncEventQueueImpl.java | 17 ++- .../internal/SerialAsyncEventQueueImpl.java | 18 ++-- .../internal/InternalDistributedSystem.java | 82 -------------- .../distributed/internal/InternalLocator.java | 4 +- .../internal/locks/DLockService.java | 17 ++- .../admin/remote/AlertListenerMessage.java | 5 +- .../cache/AbstractBucketRegionQueue.java | 6 +- .../geode/internal/cache/BucketRegion.java | 6 +- .../internal/cache/BucketRegionQueue.java | 6 +- .../geode/internal/cache/CacheServerImpl.java | 17 +-- .../internal/cache/DiskStoreFactoryImpl.java | 53 ++++++---- .../internal/cache/DistributedRegion.java | 6 +- .../internal/cache/GemFireCacheImpl.java | 100 +++++++++++------- .../apache/geode/internal/cache/HARegion.java | 11 +- .../geode/internal/cache/InternalCache.java | 5 +- .../cache/InternalCacheForClientAccess.java | 6 ++ .../geode/internal/cache/LocalRegion.java | 31 ++++-- .../internal/cache/PartitionedRegion.java | 7 +- .../cache/wan/AbstractGatewaySender.java | 92 ++++++++-------- .../AbstractGatewaySenderEventProcessor.java | 6 +- .../cache/wan/WANServiceProvider.java | 11 +- .../parallel/ParallelGatewaySenderQueue.java | 23 ++-- .../wan/serial/SerialGatewaySenderQueue.java | 16 +-- .../internal/cache/wan/spi/WANFactory.java | 7 +- .../cache/xmlcache/CacheCreation.java | 18 +++- .../ParallelAsyncEventQueueCreation.java | 19 +++- .../ParallelGatewaySenderCreation.java | 21 +++- .../SerialAsyncEventQueueCreation.java | 19 +++- .../xmlcache/SerialGatewaySenderCreation.java | 21 +++- .../internal/SystemManagementService.java | 19 ++-- .../internal/beans/ManagementListener.java | 6 +- .../ConcurrentResourceEventNotifier.java | 84 +++++++++++++++ .../resource/DummyResourceEventNotifier.java | 48 +++++++++ .../internal/resource}/ResourceEvent.java | 51 +++++---- .../resource/ResourceEventListener.java} | 11 +- .../resource/ResourceEventNotifier.java | 37 +++++++ .../ResourceEventNotifierFactory.java | 35 ++++++ .../AsyncEventQueueFactoryImplTest.java | 7 +- .../AbstractDistributedRegionJUnitTest.java | 8 +- .../internal/cache/BucketRegionJUnitTest.java | 6 +- .../cache/BucketRegionQueueJUnitTest.java | 11 +- .../internal/cache/BucketRegionTest.java | 35 +++--- .../cache/DistributedRegionJUnitTest.java | 7 +- .../DistributedRegionSearchLoadJUnitTest.java | 13 ++- .../internal/cache/PartitionedRegionTest.java | 4 +- .../parallel/ParallelGatewaySenderHelper.java | 5 +- .../ParallelGatewaySenderQueueJUnitTest.java | 3 +- .../ParallelQueueRemovalMessageJUnitTest.java | 11 +- .../beans/ManagementListenerTest.java | 8 +- .../ConcurrentResourceEventNotifierTest.java | 74 +++++++++++++ .../org/apache/geode/test/fake/Fakes.java | 3 + .../internal/locator/wan/WANFactoryImpl.java | 11 +- .../wan/AbstractRemoteGatewaySender.java | 11 +- .../cache/wan/GatewayReceiverFactoryImpl.java | 23 ++-- .../cache/wan/GatewayReceiverImpl.java | 20 ++-- .../cache/wan/GatewaySenderFactoryImpl.java | 51 +++++++-- .../parallel/ParallelGatewaySenderImpl.java | 16 ++- .../wan/serial/SerialGatewaySenderImpl.java | 16 ++- .../GatewayReceiverFactoryImplJUnitTest.java | 4 +- .../wan/GatewayReceiverImplJUnitTest.java | 37 +++++-- 70 files changed, 952 insertions(+), 463 deletions(-) create mode 100644 geode-core/src/main/java/org/apache/geode/management/internal/resource/ConcurrentResourceEventNotifier.java create mode 100644 geode-core/src/main/java/org/apache/geode/management/internal/resource/DummyResourceEventNotifier.java rename geode-core/src/main/java/org/apache/geode/{distributed/internal => management/internal/resource}/ResourceEvent.java (91%) rename geode-core/src/main/java/org/apache/geode/{distributed/internal/ResourceEventsListener.java => management/internal/resource/ResourceEventListener.java} (81%) create mode 100644 geode-core/src/main/java/org/apache/geode/management/internal/resource/ResourceEventNotifier.java create mode 100644 geode-core/src/main/java/org/apache/geode/management/internal/resource/ResourceEventNotifierFactory.java create mode 100644 geode-core/src/test/java/org/apache/geode/management/internal/resource/ConcurrentResourceEventNotifierTest.java diff --git a/geode-core/src/distributedTest/java/org/apache/geode/cache30/TXDistributedDUnitTest.java b/geode-core/src/distributedTest/java/org/apache/geode/cache30/TXDistributedDUnitTest.java index cc897979f48d..e7b5cea1940c 100644 --- a/geode-core/src/distributedTest/java/org/apache/geode/cache30/TXDistributedDUnitTest.java +++ b/geode-core/src/distributedTest/java/org/apache/geode/cache30/TXDistributedDUnitTest.java @@ -35,8 +35,8 @@ import java.io.IOException; import java.io.Serializable; +import java.util.Collection; import java.util.HashSet; -import java.util.List; import java.util.Properties; import java.util.concurrent.CountDownLatch; @@ -60,8 +60,6 @@ import org.apache.geode.cache.RegionAttributes; import org.apache.geode.cache.Scope; import org.apache.geode.cache.TimeoutException; -import org.apache.geode.distributed.internal.ResourceEvent; -import org.apache.geode.distributed.internal.ResourceEventsListener; import org.apache.geode.distributed.internal.locks.DLockBatch; import org.apache.geode.distributed.internal.locks.DLockService; import org.apache.geode.distributed.internal.membership.InternalDistributedMember; @@ -78,6 +76,8 @@ import org.apache.geode.internal.cache.locks.TXLockBatch; import org.apache.geode.internal.cache.locks.TXLockService; import org.apache.geode.internal.cache.locks.TXLockServiceImpl; +import org.apache.geode.management.internal.resource.ResourceEvent; +import org.apache.geode.management.internal.resource.ResourceEventListener; import org.apache.geode.test.awaitility.GeodeAwaitility; import org.apache.geode.test.dunit.Assert; import org.apache.geode.test.dunit.Host; @@ -1324,7 +1324,7 @@ public void call(LocalRegion r, Operation op, RegionEntry re) { } } - public static class ShutdownListener implements ResourceEventsListener { + public static class ShutdownListener implements ResourceEventListener { CountDownLatch latch = new CountDownLatch(1); @Override @@ -1389,7 +1389,7 @@ public void run2() { af.setDiskStoreName(diskStoreName); gfc.createVMRegion(rgnName1, af.create(), ira); gfc.createVMRegion(rgnName2, af.create(), ira); - gfc.getInternalDistributedSystem().addResourceListener(new ShutdownListener()); + gfc.getResourceEventNotifier().addResourceListener(new ShutdownListener()); } catch (IOException ioe) { fail(ioe.toString()); } catch (TimeoutException e) { @@ -1462,10 +1462,9 @@ public void run2() { SerializableCallable allowCacheToShutdown = new SerializableCallable() { @Override public Object call() throws Exception { - GemFireCacheImpl cache = (GemFireCacheImpl) getCache(); - List listeners = - cache.getInternalDistributedSystem().getResourceListeners(); - for (ResourceEventsListener l : listeners) { + Collection resourceListeners = + getCache().getResourceEventNotifier().getResourceListeners(); + for (ResourceEventListener l : resourceListeners) { if (l instanceof ShutdownListener) { ShutdownListener shutListener = (ShutdownListener) l; shutListener.unblockShutdown(); diff --git a/geode-core/src/distributedTest/java/org/apache/geode/internal/cache/ClearDuringGiiOplogWithMissingCreateRegressionTest.java b/geode-core/src/distributedTest/java/org/apache/geode/internal/cache/ClearDuringGiiOplogWithMissingCreateRegressionTest.java index 09109c2d808d..782e882eb9bb 100644 --- a/geode-core/src/distributedTest/java/org/apache/geode/internal/cache/ClearDuringGiiOplogWithMissingCreateRegressionTest.java +++ b/geode-core/src/distributedTest/java/org/apache/geode/internal/cache/ClearDuringGiiOplogWithMissingCreateRegressionTest.java @@ -147,7 +147,8 @@ private void createCacheForVM1() throws IOException, ClassNotFoundException { factory.setDiskStoreName(diskStore.getName()); DistributedRegion distRegion = new DistributedRegion(regionName, factory.create(), null, - getCache(), new InternalRegionArguments().setDestroyLockFlag(true).setRecreateFlag(false) + getCache(), getCache().getResourceEventNotifier(), + new InternalRegionArguments().setDestroyLockFlag(true).setRecreateFlag(false) .setSnapshotInputStream(null).setImageTarget(null)); distRegion.entries.setEntryFactory(new TestableDiskRegionEntryFactory()); diff --git a/geode-core/src/distributedTest/java/org/apache/geode/internal/cache/GiiDiskAccessExceptionRegressionTest.java b/geode-core/src/distributedTest/java/org/apache/geode/internal/cache/GiiDiskAccessExceptionRegressionTest.java index 2e56d84fcf9c..684515b2bf23 100644 --- a/geode-core/src/distributedTest/java/org/apache/geode/internal/cache/GiiDiskAccessExceptionRegressionTest.java +++ b/geode-core/src/distributedTest/java/org/apache/geode/internal/cache/GiiDiskAccessExceptionRegressionTest.java @@ -132,7 +132,8 @@ public void diskAccessExceptionDuringGiiShouldShutdown() throws Exception { // used is customized by us to throw exception while writing to disk DistributedRegion distributedRegion = new DistributedRegion(uniqueName, factory.create(), null, - getCache(), new InternalRegionArguments().setDestroyLockFlag(true).setRecreateFlag(false) + getCache(), getCache().getResourceEventNotifier(), + new InternalRegionArguments().setDestroyLockFlag(true).setRecreateFlag(false) .setSnapshotInputStream(null).setImageTarget(null)); distributedRegion.entries.setEntryFactory(new DiskRegionEntryThrowsFactory()); diff --git a/geode-core/src/integrationTest/java/org/apache/geode/TXJUnitTest.java b/geode-core/src/integrationTest/java/org/apache/geode/TXJUnitTest.java index 408cc6b77110..aa1a8e23aad6 100644 --- a/geode-core/src/integrationTest/java/org/apache/geode/TXJUnitTest.java +++ b/geode-core/src/integrationTest/java/org/apache/geode/TXJUnitTest.java @@ -100,6 +100,7 @@ import org.apache.geode.internal.cache.TXStateProxy; import org.apache.geode.internal.logging.LogService; import org.apache.geode.internal.util.StopWatch; +import org.apache.geode.management.internal.resource.ResourceEventNotifier; /** * Tests basic transaction functionality @@ -119,6 +120,7 @@ public class TXJUnitTest { protected CacheTransactionManager txMgr; protected GemFireCacheImpl cache; + protected ResourceEventNotifier resourceEventNotifier; protected Region region; @Rule @@ -133,6 +135,7 @@ protected void createCache() throws Exception { properties.setProperty(MCAST_PORT, "0"); // loner this.cache = (GemFireCacheImpl) CacheFactory.create(DistributedSystem.connect(properties)); + resourceEventNotifier = cache.getResourceEventNotifier(); createRegion(); this.txMgr = this.cache.getCacheTransactionManager(); diff --git a/geode-core/src/integrationTest/java/org/apache/geode/cache/asyncqueue/internal/SerialAsyncEventQueueImplJUnitTest.java b/geode-core/src/integrationTest/java/org/apache/geode/cache/asyncqueue/internal/SerialAsyncEventQueueImplJUnitTest.java index d701dc2e5b20..af104d481947 100644 --- a/geode-core/src/integrationTest/java/org/apache/geode/cache/asyncqueue/internal/SerialAsyncEventQueueImplJUnitTest.java +++ b/geode-core/src/integrationTest/java/org/apache/geode/cache/asyncqueue/internal/SerialAsyncEventQueueImplJUnitTest.java @@ -47,7 +47,8 @@ public void tearDown() { public void testStopClearsStats() { GatewaySenderAttributes attrs = new GatewaySenderAttributes(); attrs.id = AsyncEventQueueImpl.ASYNC_EVENT_QUEUE_PREFIX + "id"; - SerialAsyncEventQueueImpl queue = new SerialAsyncEventQueueImpl(cache, attrs); + SerialAsyncEventQueueImpl queue = + new SerialAsyncEventQueueImpl(cache, cache.getResourceEventNotifier(), attrs); queue.getStatistics().incQueueSize(5); queue.getStatistics().incSecondaryQueueSize(6); queue.getStatistics().incTempQueueSize(10); diff --git a/geode-core/src/integrationTest/java/org/apache/geode/internal/cache/LRUClearWithDiskRegionOpRegressionTest.java b/geode-core/src/integrationTest/java/org/apache/geode/internal/cache/LRUClearWithDiskRegionOpRegressionTest.java index e051d1edcb61..8f4791e53bed 100644 --- a/geode-core/src/integrationTest/java/org/apache/geode/internal/cache/LRUClearWithDiskRegionOpRegressionTest.java +++ b/geode-core/src/integrationTest/java/org/apache/geode/internal/cache/LRUClearWithDiskRegionOpRegressionTest.java @@ -87,7 +87,8 @@ public void setUp() throws Exception { .setRecreateFlag(false).setSnapshotInputStream(null).setImageTarget(null); DistributedRegion distributedRegion = - new DistributedRegion(regionName, regionAttributes, null, cache, args); + new DistributedRegion(regionName, regionAttributes, null, cache, + cache.getResourceEventNotifier(), args); region = cache.createVMRegion(regionName, regionAttributes, new InternalRegionArguments().setInternalMetaRegion(distributedRegion) diff --git a/geode-core/src/integrationTest/java/org/apache/geode/internal/cache/PRTXJUnitTest.java b/geode-core/src/integrationTest/java/org/apache/geode/internal/cache/PRTXJUnitTest.java index 9699ffdbdfe1..7acc5cf4e4a8 100644 --- a/geode-core/src/integrationTest/java/org/apache/geode/internal/cache/PRTXJUnitTest.java +++ b/geode-core/src/integrationTest/java/org/apache/geode/internal/cache/PRTXJUnitTest.java @@ -26,6 +26,7 @@ import org.apache.geode.cache.Region; import org.apache.geode.cache.RegionAttributes; import org.apache.geode.cache.query.QueryException; +import org.apache.geode.management.internal.resource.ResourceEventNotifier; public class PRTXJUnitTest extends TXJUnitTest { @@ -38,7 +39,8 @@ protected void createRegion() throws Exception { .setPartitionAttributes(new PartitionAttributesFactory().setTotalNumBuckets(3).create()); this.region = new PRWithLocalOps(getClass().getSimpleName(), attributesFactory.create(), null, - this.cache, new InternalRegionArguments().setDestroyLockFlag(true).setRecreateFlag(false) + this.cache, resourceEventNotifier, + new InternalRegionArguments().setDestroyLockFlag(true).setRecreateFlag(false) .setSnapshotInputStream(null).setImageTarget(null)); ((PartitionedRegion) this.region).initialize(null, null, null); @@ -87,8 +89,9 @@ public void testTxId() { private static class PRWithLocalOps extends PartitionedRegion { PRWithLocalOps(String regionName, RegionAttributes ra, LocalRegion parentRegion, - GemFireCacheImpl cache, InternalRegionArguments internalRegionArgs) { - super(regionName, ra, parentRegion, cache, internalRegionArgs); + GemFireCacheImpl cache, ResourceEventNotifier resourceEventNotifier, + InternalRegionArguments internalRegionArgs) { + super(regionName, ra, parentRegion, cache, resourceEventNotifier, internalRegionArgs); } @Override diff --git a/geode-core/src/integrationTest/java/org/apache/geode/management/internal/beans/ManagementAdapterTest.java b/geode-core/src/integrationTest/java/org/apache/geode/management/internal/beans/ManagementAdapterTest.java index aa1a066510fb..310ec95b18ae 100644 --- a/geode-core/src/integrationTest/java/org/apache/geode/management/internal/beans/ManagementAdapterTest.java +++ b/geode-core/src/integrationTest/java/org/apache/geode/management/internal/beans/ManagementAdapterTest.java @@ -28,17 +28,18 @@ import org.junit.Rule; import org.junit.Test; -import org.apache.geode.distributed.internal.InternalDistributedSystem; -import org.apache.geode.distributed.internal.ResourceEvent; import org.apache.geode.internal.cache.DiskStoreImpl; import org.apache.geode.internal.cache.DiskStoreStats; import org.apache.geode.internal.cache.InternalCache; +import org.apache.geode.management.internal.resource.ResourceEvent; +import org.apache.geode.management.internal.resource.ResourceEventNotifier; import org.apache.geode.test.junit.rules.ConcurrencyRule; import org.apache.geode.test.junit.rules.ServerStarterRule; public class ManagementAdapterTest { private InternalCache cache; + private ResourceEventNotifier resourceEventNotifier; private DiskStoreImpl diskStore = mock(DiskStoreImpl.class); private AtomicBoolean raceConditionFound = new AtomicBoolean(false); @@ -52,6 +53,7 @@ public class ManagementAdapterTest { @Before public void before() { cache = serverRule.getCache(); + resourceEventNotifier = cache.getResourceEventNotifier(); doReturn(new DiskStoreStats(cache.getInternalDistributedSystem(), "disk-stats")) .when(diskStore).getStats(); doReturn(new File[] {}).when(diskStore).getDiskDirs(); @@ -63,10 +65,9 @@ public void testHandlingNotificationsConcurrently() { Callable cacheNotifications = () -> { if (raceConditionFound.get() == Boolean.FALSE) { try { - InternalDistributedSystem ids = cache.getInternalDistributedSystem(); - ids.handleResourceEvent(ResourceEvent.CACHE_REMOVE, cache); + resourceEventNotifier.handleResourceEvent(ResourceEvent.CACHE_REMOVE, cache); Thread.sleep(10); - ids.handleResourceEvent(ResourceEvent.CACHE_CREATE, cache); + resourceEventNotifier.handleResourceEvent(ResourceEvent.CACHE_CREATE, cache); Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); @@ -79,10 +80,9 @@ public void testHandlingNotificationsConcurrently() { Callable diskNotifications = () -> { if (raceConditionFound.get() == Boolean.FALSE) { try { - InternalDistributedSystem ids = cache.getInternalDistributedSystem(); - ids.handleResourceEvent(ResourceEvent.DISKSTORE_CREATE, diskStore); + resourceEventNotifier.handleResourceEvent(ResourceEvent.DISKSTORE_CREATE, diskStore); Thread.sleep(5); - ids.handleResourceEvent(ResourceEvent.DISKSTORE_REMOVE, diskStore); + resourceEventNotifier.handleResourceEvent(ResourceEvent.DISKSTORE_REMOVE, diskStore); Thread.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); diff --git a/geode-core/src/main/java/org/apache/geode/cache/DynamicRegionFactory.java b/geode-core/src/main/java/org/apache/geode/cache/DynamicRegionFactory.java index bb401ff1bb31..27bc0ece9ed9 100644 --- a/geode-core/src/main/java/org/apache/geode/cache/DynamicRegionFactory.java +++ b/geode-core/src/main/java/org/apache/geode/cache/DynamicRegionFactory.java @@ -46,6 +46,7 @@ import org.apache.geode.internal.cache.LocalRegion; import org.apache.geode.internal.cache.RegionEntry; import org.apache.geode.internal.cache.RegionEventImpl; +import org.apache.geode.management.internal.resource.ResourceEventNotifier; import org.apache.geode.security.GemFireSecurityException; /** @@ -153,6 +154,8 @@ public abstract class DynamicRegionFactory { InternalCache cache = null; + private ResourceEventNotifier resourceEventNotifier; + private Config config = null; /** The region listeners registered on this DynamicRegionFactory */ @@ -240,6 +243,7 @@ protected void doInternalInit(InternalCache theCache) throws CacheException { try { this.cache = theCache; + resourceEventNotifier = cache.getResourceEventNotifier(); this.dynamicRegionList = theCache.getRegion(DYNAMIC_REGION_LIST_NAME); final boolean isClient = this.config.getPoolName() != null; if (this.dynamicRegionList == null) { @@ -876,7 +880,8 @@ protected void razeDynamicRegion(EntryEvent event) { // the meta data private class LocalMetaRegion extends LocalRegion { protected LocalMetaRegion(RegionAttributes attrs, InternalRegionArguments ira) { - super(DYNAMIC_REGION_LIST_NAME, attrs, null, DynamicRegionFactory.this.cache, ira); + super(DYNAMIC_REGION_LIST_NAME, attrs, null, DynamicRegionFactory.this.cache, + resourceEventNotifier, ira); Assert.assertTrue(attrs.getScope().isLocal()); } @@ -986,7 +991,7 @@ public void basicPutPart3(EntryEventImpl event, RegionEntry entry, boolean isIni private class DistributedMetaRegion extends DistributedRegion { protected DistributedMetaRegion(RegionAttributes attrs) { super(DYNAMIC_REGION_LIST_NAME, attrs, null, DynamicRegionFactory.this.cache, - new InternalRegionArguments()); + resourceEventNotifier, new InternalRegionArguments()); } // This is an internal uses only region diff --git a/geode-core/src/main/java/org/apache/geode/cache/asyncqueue/internal/AsyncEventQueueFactoryImpl.java b/geode-core/src/main/java/org/apache/geode/cache/asyncqueue/internal/AsyncEventQueueFactoryImpl.java index 70f0c2c73244..1ddae063a35b 100644 --- a/geode-core/src/main/java/org/apache/geode/cache/asyncqueue/internal/AsyncEventQueueFactoryImpl.java +++ b/geode-core/src/main/java/org/apache/geode/cache/asyncqueue/internal/AsyncEventQueueFactoryImpl.java @@ -34,6 +34,7 @@ import org.apache.geode.internal.cache.xmlcache.ParallelAsyncEventQueueCreation; import org.apache.geode.internal.cache.xmlcache.SerialAsyncEventQueueCreation; import org.apache.geode.internal.logging.LogService; +import org.apache.geode.management.internal.resource.ResourceEventNotifier; public class AsyncEventQueueFactoryImpl implements AsyncEventQueueFactory { @@ -46,19 +47,24 @@ public class AsyncEventQueueFactoryImpl implements AsyncEventQueueFactory { private final InternalCache cache; + private final ResourceEventNotifier resourceEventNotifier; + /** * Used internally to pass the attributes from this factory to the real GatewaySender it is * creating. */ private final GatewaySenderAttributes gatewaySenderAttributes; - public AsyncEventQueueFactoryImpl(InternalCache cache) { - this(cache, new GatewaySenderAttributes(), DEFAULT_BATCH_TIME_INTERVAL); + public AsyncEventQueueFactoryImpl(InternalCache cache, + ResourceEventNotifier resourceEventNotifier) { + this(cache, resourceEventNotifier, new GatewaySenderAttributes(), DEFAULT_BATCH_TIME_INTERVAL); } - AsyncEventQueueFactoryImpl(InternalCache cache, GatewaySenderAttributes gatewaySenderAttributes, + AsyncEventQueueFactoryImpl(InternalCache cache, ResourceEventNotifier resourceEventNotifier, + GatewaySenderAttributes gatewaySenderAttributes, int batchTimeInterval) { this.cache = cache; + this.resourceEventNotifier = resourceEventNotifier; this.gatewaySenderAttributes = gatewaySenderAttributes; // set a different default for batchTimeInterval for AsyncEventQueue this.gatewaySenderAttributes.batchTimeInterval = batchTimeInterval; @@ -202,9 +208,11 @@ private GatewaySender create(String id) { } if (cache instanceof CacheCreation) { - sender = new ParallelAsyncEventQueueCreation(cache, gatewaySenderAttributes); + sender = new ParallelAsyncEventQueueCreation(cache, resourceEventNotifier, + gatewaySenderAttributes); } else { - sender = new ParallelAsyncEventQueueImpl(cache, gatewaySenderAttributes); + sender = + new ParallelAsyncEventQueueImpl(cache, resourceEventNotifier, gatewaySenderAttributes); } cache.addGatewaySender(sender); @@ -215,9 +223,11 @@ private GatewaySender create(String id) { } if (cache instanceof CacheCreation) { - sender = new SerialAsyncEventQueueCreation(cache, gatewaySenderAttributes); + sender = new SerialAsyncEventQueueCreation(cache, resourceEventNotifier, + gatewaySenderAttributes); } else { - sender = new SerialAsyncEventQueueImpl(cache, gatewaySenderAttributes); + sender = + new SerialAsyncEventQueueImpl(cache, resourceEventNotifier, gatewaySenderAttributes); } cache.addGatewaySender(sender); } diff --git a/geode-core/src/main/java/org/apache/geode/cache/asyncqueue/internal/ParallelAsyncEventQueueImpl.java b/geode-core/src/main/java/org/apache/geode/cache/asyncqueue/internal/ParallelAsyncEventQueueImpl.java index 045ced6fee36..94a223a32238 100644 --- a/geode-core/src/main/java/org/apache/geode/cache/asyncqueue/internal/ParallelAsyncEventQueueImpl.java +++ b/geode-core/src/main/java/org/apache/geode/cache/asyncqueue/internal/ParallelAsyncEventQueueImpl.java @@ -21,8 +21,6 @@ import org.apache.geode.cache.wan.GatewayTransportFilter; import org.apache.geode.distributed.internal.DistributionAdvisor.Profile; import org.apache.geode.distributed.internal.DistributionManager; -import org.apache.geode.distributed.internal.InternalDistributedSystem; -import org.apache.geode.distributed.internal.ResourceEvent; import org.apache.geode.internal.cache.DistributedRegion; import org.apache.geode.internal.cache.EntryEventImpl; import org.apache.geode.internal.cache.EventID; @@ -38,13 +36,16 @@ import org.apache.geode.internal.cache.xmlcache.CacheCreation; import org.apache.geode.internal.logging.LogService; import org.apache.geode.internal.monitoring.ThreadsMonitoring; +import org.apache.geode.management.internal.resource.ResourceEvent; +import org.apache.geode.management.internal.resource.ResourceEventNotifier; public class ParallelAsyncEventQueueImpl extends AbstractGatewaySender { private static final Logger logger = LogService.getLogger(); - public ParallelAsyncEventQueueImpl(InternalCache cache, GatewaySenderAttributes attrs) { - super(cache, attrs); + public ParallelAsyncEventQueueImpl(InternalCache cache, + ResourceEventNotifier resourceEventNotifier, GatewaySenderAttributes attrs) { + super(cache, resourceEventNotifier, attrs); if (!(this.cache instanceof CacheCreation)) { // this sender lies underneath the AsyncEventQueue. Need to have // AsyncEventQueueStats @@ -87,9 +88,7 @@ public void start() { } new UpdateAttributesProcessor(this).distribute(false); - InternalDistributedSystem system = - (InternalDistributedSystem) this.cache.getDistributedSystem(); - system.handleResourceEvent(ResourceEvent.GATEWAYSENDER_START, this); + resourceEventNotifier.handleResourceEvent(ResourceEvent.GATEWAYSENDER_START, this); logger.info("Started {}", this); @@ -118,9 +117,7 @@ public void stop() { logger.info("Stopped {}", this); - InternalDistributedSystem system = - (InternalDistributedSystem) this.cache.getDistributedSystem(); - system.handleResourceEvent(ResourceEvent.GATEWAYSENDER_STOP, this); + resourceEventNotifier.handleResourceEvent(ResourceEvent.GATEWAYSENDER_STOP, this); clearTempEventsAfterSenderStopped(); } finally { diff --git a/geode-core/src/main/java/org/apache/geode/cache/asyncqueue/internal/SerialAsyncEventQueueImpl.java b/geode-core/src/main/java/org/apache/geode/cache/asyncqueue/internal/SerialAsyncEventQueueImpl.java index 259ae81c969f..d105b165fbcb 100644 --- a/geode-core/src/main/java/org/apache/geode/cache/asyncqueue/internal/SerialAsyncEventQueueImpl.java +++ b/geode-core/src/main/java/org/apache/geode/cache/asyncqueue/internal/SerialAsyncEventQueueImpl.java @@ -22,8 +22,6 @@ import org.apache.geode.distributed.DistributedLockService; import org.apache.geode.distributed.internal.DistributionAdvisor.Profile; import org.apache.geode.distributed.internal.DistributionManager; -import org.apache.geode.distributed.internal.InternalDistributedSystem; -import org.apache.geode.distributed.internal.ResourceEvent; import org.apache.geode.internal.cache.EntryEventImpl; import org.apache.geode.internal.cache.EventID; import org.apache.geode.internal.cache.InternalCache; @@ -40,13 +38,16 @@ import org.apache.geode.internal.cache.xmlcache.CacheCreation; import org.apache.geode.internal.logging.LogService; import org.apache.geode.internal.monitoring.ThreadsMonitoring; +import org.apache.geode.management.internal.resource.ResourceEvent; +import org.apache.geode.management.internal.resource.ResourceEventNotifier; public class SerialAsyncEventQueueImpl extends AbstractGatewaySender { private static final Logger logger = LogService.getLogger(); - public SerialAsyncEventQueueImpl(InternalCache cache, GatewaySenderAttributes attrs) { - super(cache, attrs); + public SerialAsyncEventQueueImpl(InternalCache cache, ResourceEventNotifier resourceEventNotifier, + GatewaySenderAttributes attrs) { + super(cache, resourceEventNotifier, attrs); if (!(this.cache instanceof CacheCreation)) { // this sender lies underneath the AsyncEventQueue. Need to have // AsyncEventQueueStats @@ -99,10 +100,7 @@ public void start() { } new UpdateAttributesProcessor(this).distribute(false); - - InternalDistributedSystem system = - (InternalDistributedSystem) this.cache.getDistributedSystem(); - system.handleResourceEvent(ResourceEvent.GATEWAYSENDER_START, this); + resourceEventNotifier.handleResourceEvent(ResourceEvent.GATEWAYSENDER_START, this); logger .info("Started {}", this); @@ -168,9 +166,7 @@ public void stop() { } } - InternalDistributedSystem system = - (InternalDistributedSystem) this.cache.getDistributedSystem(); - system.handleResourceEvent(ResourceEvent.GATEWAYSENDER_STOP, this); + resourceEventNotifier.handleResourceEvent(ResourceEvent.GATEWAYSENDER_STOP, this); } @Override diff --git a/geode-core/src/main/java/org/apache/geode/distributed/internal/InternalDistributedSystem.java b/geode-core/src/main/java/org/apache/geode/distributed/internal/InternalDistributedSystem.java index e2cc885a8f99..ef2759ffc0dc 100644 --- a/geode-core/src/main/java/org/apache/geode/distributed/internal/InternalDistributedSystem.java +++ b/geode-core/src/main/java/org/apache/geode/distributed/internal/InternalDistributedSystem.java @@ -118,7 +118,6 @@ import org.apache.geode.internal.statistics.platform.LinuxProcFsStatistics; import org.apache.geode.internal.statistics.platform.OsStatisticsFactory; import org.apache.geode.internal.tcp.ConnectionTable; -import org.apache.geode.management.ManagementException; import org.apache.geode.security.GemFireSecurityException; import org.apache.geode.security.PostProcessor; import org.apache.geode.security.SecurityManager; @@ -139,9 +138,6 @@ public class InternalDistributedSystem extends DistributedSystem Boolean.getBoolean(DistributionConfig.GEMFIRE_PREFIX + "Cache.ALLOW_MEMORY_OVERCOMMIT"); private static final Logger logger = LogService.getLogger(); - public static final String DISABLE_MANAGEMENT_PROPERTY = - DistributionConfig.GEMFIRE_PREFIX + "disableManagement"; - /** * Feature flag to enable multiple caches within a JVM. */ @@ -308,10 +304,6 @@ public GrantorRequestProcessor.GrantorRequestContext getGrantorRequestContext() */ private InternalLocator startedLocator; - private List resourceListeners; - - private final boolean disableManagement = Boolean.getBoolean(DISABLE_MANAGEMENT_PROPERTY); - /** * Stack trace showing the creation of this instance of InternalDistributedSystem. */ @@ -565,47 +557,6 @@ public void setSecurityService(SecurityService securityService) { this.securityService = securityService; } - /** - * Registers a listener to the system - * - * @param listener listener to be added - */ - public void addResourceListener(ResourceEventsListener listener) { - resourceListeners.add(listener); - } - - /** - * Un-Registers a listener to the system - * - * @param listener listener to be removed - */ - public void removeResourceListener(ResourceEventsListener listener) { - resourceListeners.remove(listener); - } - - /** - * @return the listeners registered with the system - */ - public List getResourceListeners() { - return resourceListeners; - } - - /** - * Handles a particular event associated with a resource - * - * @param event Resource event - * @param resource resource on which event is generated - */ - public void handleResourceEvent(ResourceEvent event, Object resource) { - if (disableManagement) { - return; - } - if (resourceListeners.size() == 0) { - return; - } - notifyResourceEventListeners(event, resource); - } - /** * Returns true if system is a loner (for testing) */ @@ -822,7 +773,6 @@ private void initialize(SecurityManager securityManager, PostProcessor postProce throw ex; } - resourceListeners = new CopyOnWriteArrayList<>(); this.reconnected = this.attemptingToReconnect; this.attemptingToReconnect = false; } @@ -2188,38 +2138,6 @@ private static void notifyReconnectListeners(InternalDistributedSystem oldsys, } } - /** - * Notifies all resource event listeners. All exceptions are caught here and only a warning - * message is printed in the log - * - * @param event Enumeration depicting particular resource event - * @param resource the actual resource object. - */ - private void notifyResourceEventListeners(ResourceEvent event, Object resource) { - for (ResourceEventsListener listener : resourceListeners) { - try { - listener.handleEvent(event, resource); - } catch (CancelException e) { - // ignore - logger.info("Skipping notifyResourceEventListeners for {} due to cancellation", event); - } catch (GemFireSecurityException | ManagementException ex) { - if (event == ResourceEvent.CACHE_CREATE) { - throw ex; - } else { - logger.warn(ex.getMessage(), ex); - } - } catch (Exception err) { - logger.warn(err.getMessage(), err); - } catch (VirtualMachineError e) { - SystemFailure.initiateFailure(e); - throw e; - } catch (Throwable t) { - SystemFailure.checkFailure(); - logger.warn(t.getMessage(), t); - } - } - } - /** * Makes note of a DisconnectListener whose onDisconnect method will be * invoked when this connection to the distributed system is disconnected. diff --git a/geode-core/src/main/java/org/apache/geode/distributed/internal/InternalLocator.java b/geode-core/src/main/java/org/apache/geode/distributed/internal/InternalLocator.java index 33494e249418..bc418e0741e4 100644 --- a/geode-core/src/main/java/org/apache/geode/distributed/internal/InternalLocator.java +++ b/geode-core/src/main/java/org/apache/geode/distributed/internal/InternalLocator.java @@ -84,6 +84,7 @@ import org.apache.geode.management.internal.configuration.handlers.SharedConfigurationStatusRequestHandler; import org.apache.geode.management.internal.configuration.messages.SharedConfigurationStatusRequest; import org.apache.geode.management.internal.configuration.messages.SharedConfigurationStatusResponse; +import org.apache.geode.management.internal.resource.ResourceEvent; /** * Provides the implementation of a distribution {@code Locator} as well as internal-only @@ -655,7 +656,8 @@ private void startCache(DistributedSystem ds) { internalCache = this.myCache; } else { logger.info("Using existing cache for locator."); - ((InternalDistributedSystem) ds).handleResourceEvent(ResourceEvent.LOCATOR_START, this); + internalCache.getResourceEventNotifier().handleResourceEvent(ResourceEvent.LOCATOR_START, + this); } startJmxManagerLocationService(internalCache); diff --git a/geode-core/src/main/java/org/apache/geode/distributed/internal/locks/DLockService.java b/geode-core/src/main/java/org/apache/geode/distributed/internal/locks/DLockService.java index 757662a7fca3..568150833b9d 100644 --- a/geode-core/src/main/java/org/apache/geode/distributed/internal/locks/DLockService.java +++ b/geode-core/src/main/java/org/apache/geode/distributed/internal/locks/DLockService.java @@ -47,7 +47,6 @@ import org.apache.geode.distributed.internal.DistributionConfig; import org.apache.geode.distributed.internal.DistributionManager; import org.apache.geode.distributed.internal.InternalDistributedSystem; -import org.apache.geode.distributed.internal.ResourceEvent; import org.apache.geode.distributed.internal.deadlock.UnsafeThreadLocal; import org.apache.geode.distributed.internal.locks.DLockQueryProcessor.DLockQueryReplyMessage; import org.apache.geode.distributed.internal.membership.InternalDistributedMember; @@ -55,10 +54,12 @@ import org.apache.geode.internal.DataSerializableFixedID; import org.apache.geode.internal.OSProcess; import org.apache.geode.internal.Version; +import org.apache.geode.internal.cache.InternalCache; import org.apache.geode.internal.logging.LogService; import org.apache.geode.internal.logging.log4j.LogMarker; import org.apache.geode.internal.util.StopWatch; import org.apache.geode.internal.util.concurrent.FutureResult; +import org.apache.geode.management.internal.resource.ResourceEvent; /** * Implements the distributed locking service with distributed lock grantors. @@ -1910,7 +1911,11 @@ protected boolean init() { } } - ds.handleResourceEvent(ResourceEvent.LOCKSERVICE_CREATE, this); + InternalCache cache = ds.getCache(); + System.out.println("cache = " + cache); + if (cache != null) { + cache.getResourceEventNotifier().handleResourceEvent(ResourceEvent.LOCKSERVICE_CREATE, this); + } return success; } @@ -2336,8 +2341,12 @@ private void basicDestroy(boolean isCurrentlyLockGrantor, boolean isMakingLockGr // } } - protected void postDestroyAction() { - ds.handleResourceEvent(ResourceEvent.LOCKSERVICE_REMOVE, this); + private void postDestroyAction() { + InternalCache cache = ds.getCache(); + if (cache != null) { + cache.getResourceEventNotifier().handleResourceEvent(ResourceEvent.LOCKSERVICE_REMOVE, + this); + } } // ------------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/internal/admin/remote/AlertListenerMessage.java b/geode-core/src/main/java/org/apache/geode/internal/admin/remote/AlertListenerMessage.java index 4cc23247931f..ef14ceba3614 100644 --- a/geode-core/src/main/java/org/apache/geode/internal/admin/remote/AlertListenerMessage.java +++ b/geode-core/src/main/java/org/apache/geode/internal/admin/remote/AlertListenerMessage.java @@ -27,10 +27,10 @@ import org.apache.geode.distributed.internal.AdminMessageType; import org.apache.geode.distributed.internal.ClusterDistributionManager; import org.apache.geode.distributed.internal.PooledDistributionMessage; -import org.apache.geode.distributed.internal.ResourceEvent; import org.apache.geode.distributed.internal.membership.InternalDistributedMember; import org.apache.geode.internal.admin.Alert; import org.apache.geode.management.internal.AlertDetails; +import org.apache.geode.management.internal.resource.ResourceEvent; /** * A message that is sent to an admin member or manager to notify it of an alert. @@ -113,7 +113,8 @@ public void process(ClusterDistributionManager dm) { listener.created(alertDetail); } - dm.getSystem().handleResourceEvent(ResourceEvent.SYSTEM_ALERT, alertDetail); + dm.getCache().getResourceEventNotifier().handleResourceEvent(ResourceEvent.SYSTEM_ALERT, + alertDetail); } } diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/AbstractBucketRegionQueue.java b/geode-core/src/main/java/org/apache/geode/internal/cache/AbstractBucketRegionQueue.java index 2bf304f5d034..cb59f5b8b474 100644 --- a/geode-core/src/main/java/org/apache/geode/internal/cache/AbstractBucketRegionQueue.java +++ b/geode-core/src/main/java/org/apache/geode/internal/cache/AbstractBucketRegionQueue.java @@ -42,6 +42,7 @@ import org.apache.geode.internal.concurrent.ConcurrentHashSet; import org.apache.geode.internal.logging.LogService; import org.apache.geode.internal.offheap.OffHeapRegionEntryHelper; +import org.apache.geode.management.internal.resource.ResourceEventNotifier; public abstract class AbstractBucketRegionQueue extends BucketRegion { protected static final Logger logger = LogService.getLogger(); @@ -68,8 +69,9 @@ public abstract class AbstractBucketRegionQueue extends BucketRegion { private final ConcurrentHashSet failedBatchRemovalMessageKeys = new ConcurrentHashSet<>(); AbstractBucketRegionQueue(String regionName, RegionAttributes attrs, LocalRegion parentRegion, - InternalCache cache, InternalRegionArguments internalRegionArgs) { - super(regionName, attrs, parentRegion, cache, internalRegionArgs); + InternalCache cache, ResourceEventNotifier resourceEventNotifier, + InternalRegionArguments internalRegionArgs) { + super(regionName, attrs, parentRegion, cache, resourceEventNotifier, internalRegionArgs); this.gatewaySenderStats = this.getPartitionedRegion().getParallelGatewaySender().getStatistics(); } diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/BucketRegion.java b/geode-core/src/main/java/org/apache/geode/internal/cache/BucketRegion.java index 62d4605aceb7..6e1dfbedc6a1 100644 --- a/geode-core/src/main/java/org/apache/geode/internal/cache/BucketRegion.java +++ b/geode-core/src/main/java/org/apache/geode/internal/cache/BucketRegion.java @@ -92,6 +92,7 @@ import org.apache.geode.internal.offheap.annotations.Released; import org.apache.geode.internal.offheap.annotations.Retained; import org.apache.geode.internal.offheap.annotations.Unretained; +import org.apache.geode.management.internal.resource.ResourceEventNotifier; /** @@ -222,8 +223,9 @@ public AtomicLong5 getEventSeqNum() { } public BucketRegion(String regionName, RegionAttributes attrs, LocalRegion parentRegion, - InternalCache cache, InternalRegionArguments internalRegionArgs) { - super(regionName, attrs, parentRegion, cache, internalRegionArgs); + InternalCache cache, ResourceEventNotifier resourceEventNotifier, + InternalRegionArguments internalRegionArgs) { + super(regionName, attrs, parentRegion, cache, resourceEventNotifier, internalRegionArgs); if (PartitionedRegion.DISABLE_SECONDARY_BUCKET_ACK) { Assert.assertTrue(attrs.getScope().isDistributedNoAck()); } else { diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/BucketRegionQueue.java b/geode-core/src/main/java/org/apache/geode/internal/cache/BucketRegionQueue.java index af7b1ade472f..5d498101dbb5 100644 --- a/geode-core/src/main/java/org/apache/geode/internal/cache/BucketRegionQueue.java +++ b/geode-core/src/main/java/org/apache/geode/internal/cache/BucketRegionQueue.java @@ -48,6 +48,7 @@ import org.apache.geode.internal.logging.LogService; import org.apache.geode.internal.offheap.OffHeapRegionEntryHelper; import org.apache.geode.internal.offheap.annotations.Released; +import org.apache.geode.management.internal.resource.ResourceEventNotifier; public class BucketRegionQueue extends AbstractBucketRegionQueue { @@ -73,8 +74,9 @@ public class BucketRegionQueue extends AbstractBucketRegionQueue { private final AtomicLong latestAcknowledgedKey = new AtomicLong(); public BucketRegionQueue(String regionName, RegionAttributes attrs, LocalRegion parentRegion, - InternalCache cache, InternalRegionArguments internalRegionArgs) { - super(regionName, attrs, parentRegion, cache, internalRegionArgs); + InternalCache cache, ResourceEventNotifier resourceEventNotifier, + InternalRegionArguments internalRegionArgs) { + super(regionName, attrs, parentRegion, cache, resourceEventNotifier, internalRegionArgs); this.keySet(); this.indexes = new ConcurrentHashMap(); } diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/CacheServerImpl.java b/geode-core/src/main/java/org/apache/geode/internal/cache/CacheServerImpl.java index b0f4b5120b5f..cbce54828b52 100644 --- a/geode-core/src/main/java/org/apache/geode/internal/cache/CacheServerImpl.java +++ b/geode-core/src/main/java/org/apache/geode/internal/cache/CacheServerImpl.java @@ -58,7 +58,6 @@ import org.apache.geode.distributed.internal.DistributionConfig; import org.apache.geode.distributed.internal.DistributionManager; import org.apache.geode.distributed.internal.InternalDistributedSystem; -import org.apache.geode.distributed.internal.ResourceEvent; import org.apache.geode.distributed.internal.ServerLocation; import org.apache.geode.distributed.internal.membership.MemberAttributes; import org.apache.geode.internal.Assert; @@ -75,6 +74,8 @@ import org.apache.geode.internal.cache.tier.sockets.ServerConnectionFactory; import org.apache.geode.internal.logging.LogService; import org.apache.geode.internal.security.SecurityService; +import org.apache.geode.management.internal.resource.ResourceEvent; +import org.apache.geode.management.internal.resource.ResourceEventNotifier; import org.apache.geode.management.membership.ClientMembership; import org.apache.geode.management.membership.ClientMembershipListener; @@ -91,6 +92,8 @@ public class CacheServerImpl extends AbstractCacheServer implements Distribution private static final int FORCE_LOAD_UPDATE_FREQUENCY = getInteger( DistributionConfig.GEMFIRE_PREFIX + "BridgeServer.FORCE_LOAD_UPDATE_FREQUENCY", 10); + private final ResourceEventNotifier resourceEventNotifier; + private final SecurityService securityService; /** @@ -119,7 +122,7 @@ public class CacheServerImpl extends AbstractCacheServer implements Distribution /** * boolean that represents whether this server is a GatewayReceiver or a simple BridgeServer */ - private boolean isGatewayReceiver; + private final boolean isGatewayReceiver; private List gatewayTransportFilters = Collections.emptyList(); @@ -143,8 +146,10 @@ public class CacheServerImpl extends AbstractCacheServer implements Distribution * Creates a new{@code BridgeServerImpl} that serves the contents of the give {@code Cache}. It * has the default configuration. */ - public CacheServerImpl(InternalCache cache, boolean isGatewayReceiver) { + public CacheServerImpl(InternalCache cache, ResourceEventNotifier resourceEventNotifier, + boolean isGatewayReceiver) { super(cache); + this.resourceEventNotifier = resourceEventNotifier; this.isGatewayReceiver = isGatewayReceiver; this.securityService = cache.getSecurityService(); } @@ -387,8 +392,7 @@ public synchronized void start() throws IOException { } if (!isGatewayReceiver) { - InternalDistributedSystem system = this.cache.getInternalDistributedSystem(); - system.handleResourceEvent(ResourceEvent.CACHE_SERVER_START, this); + resourceEventNotifier.handleResourceEvent(ResourceEvent.CACHE_SERVER_START, this); } } @@ -484,8 +488,7 @@ public synchronized void stop() { txMgr.removeHostedTXStatesForClients(); if (!isGatewayReceiver) { - InternalDistributedSystem system = this.cache.getInternalDistributedSystem(); - system.handleResourceEvent(ResourceEvent.CACHE_SERVER_STOP, this); + resourceEventNotifier.handleResourceEvent(ResourceEvent.CACHE_SERVER_STOP, this); } } diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/DiskStoreFactoryImpl.java b/geode-core/src/main/java/org/apache/geode/internal/cache/DiskStoreFactoryImpl.java index 6eb01b36f6e6..928624b4bcbc 100755 --- a/geode-core/src/main/java/org/apache/geode/internal/cache/DiskStoreFactoryImpl.java +++ b/geode-core/src/main/java/org/apache/geode/internal/cache/DiskStoreFactoryImpl.java @@ -20,11 +20,12 @@ import org.apache.geode.GemFireIOException; import org.apache.geode.cache.DiskStore; import org.apache.geode.cache.DiskStoreFactory; -import org.apache.geode.distributed.internal.ResourceEvent; import org.apache.geode.internal.cache.backup.BackupService; import org.apache.geode.internal.cache.xmlcache.CacheCreation; import org.apache.geode.internal.cache.xmlcache.CacheXml; import org.apache.geode.internal.cache.xmlcache.DiskStoreAttributesCreation; +import org.apache.geode.management.internal.resource.ResourceEvent; +import org.apache.geode.management.internal.resource.ResourceEventNotifier; import org.apache.geode.pdx.internal.TypeRegistry; /** @@ -35,26 +36,32 @@ public class DiskStoreFactoryImpl implements DiskStoreFactory { private final InternalCache cache; + private final ResourceEventNotifier resourceEventNotifier; private final DiskStoreAttributes attrs = new DiskStoreAttributes(); - public DiskStoreFactoryImpl(InternalCache cache) { - this.cache = cache; + public DiskStoreFactoryImpl(InternalCache cache, ResourceEventNotifier resourceEventNotifier) { + this(cache, resourceEventNotifier, null); } - public DiskStoreFactoryImpl(InternalCache cache, DiskStoreAttributes attrs) { - this.attrs.name = attrs.name; - setAutoCompact(attrs.getAutoCompact()); - setAllowForceCompaction(attrs.getAllowForceCompaction()); - setCompactionThreshold(attrs.getCompactionThreshold()); - setMaxOplogSizeInBytes(attrs.getMaxOplogSizeInBytes()); - setTimeInterval(attrs.getTimeInterval()); - setWriteBufferSize(attrs.getWriteBufferSize()); - setQueueSize(attrs.getQueueSize()); - setDiskDirs(cloneArray(attrs.getDiskDirs())); - setDiskDirsAndSizes(cloneArray(attrs.getDiskDirs()), cloneArray(attrs.getDiskDirSizes())); - setDiskUsageWarningPercentage(attrs.getDiskUsageWarningPercentage()); - setDiskUsageCriticalPercentage(attrs.getDiskUsageCriticalPercentage()); + public DiskStoreFactoryImpl(InternalCache cache, ResourceEventNotifier resourceEventNotifier, + DiskStoreAttributes attrs) { this.cache = cache; + this.resourceEventNotifier = resourceEventNotifier; + + if (attrs != null) { + this.attrs.name = attrs.name; + setAutoCompact(attrs.getAutoCompact()); + setAllowForceCompaction(attrs.getAllowForceCompaction()); + setCompactionThreshold(attrs.getCompactionThreshold()); + setMaxOplogSizeInBytes(attrs.getMaxOplogSizeInBytes()); + setTimeInterval(attrs.getTimeInterval()); + setWriteBufferSize(attrs.getWriteBufferSize()); + setQueueSize(attrs.getQueueSize()); + setDiskDirs(cloneArray(attrs.getDiskDirs())); + setDiskDirsAndSizes(cloneArray(attrs.getDiskDirs()), cloneArray(attrs.getDiskDirSizes())); + setDiskUsageWarningPercentage(attrs.getDiskUsageWarningPercentage()); + setDiskUsageCriticalPercentage(attrs.getDiskUsageCriticalPercentage()); + } } private static File[] cloneArray(File[] o) { @@ -75,16 +82,19 @@ private static int[] cloneArray(int[] o) { return result; } + @Override public DiskStoreFactory setAutoCompact(boolean autoCompact) { this.attrs.autoCompact = autoCompact; return this; } + @Override public DiskStoreFactory setAllowForceCompaction(boolean allowForceCompaction) { this.attrs.allowForceCompaction = allowForceCompaction; return this; } + @Override public DiskStoreFactory setCompactionThreshold(int compactionThreshold) { if (compactionThreshold < 0) { throw new IllegalArgumentException( @@ -102,6 +112,7 @@ public DiskStoreFactory setCompactionThreshold(int compactionThreshold) { return this; } + @Override public DiskStoreFactory setTimeInterval(long timeInterval) { if (timeInterval < 0) { throw new IllegalArgumentException( @@ -127,6 +138,7 @@ DiskStoreImpl createOwnedByRegion(String name, boolean isOwnedByPR, } } + @Override public DiskStore create(String name) { this.attrs.name = name; // As a simple fix for 41290, only allow one DiskStore to be created @@ -139,9 +151,7 @@ public DiskStore create(String name) { TypeRegistry registry = this.cache.getPdxRegistry(); DiskStoreImpl dsi = new DiskStoreImpl(this.cache, this.attrs); result = dsi; - // Added for M&M - this.cache.getInternalDistributedSystem() - .handleResourceEvent(ResourceEvent.DISKSTORE_CREATE, dsi); + resourceEventNotifier.handleResourceEvent(ResourceEvent.DISKSTORE_CREATE, dsi); initializeDiskStore(dsi); this.cache.addDiskStore(dsi); if (registry != null) { @@ -198,6 +208,7 @@ private DiskStore findExisting(String name) { return existing; } + @Override public DiskStoreFactory setDiskDirsAndSizes(File[] diskDirs, int[] diskDirSizes) { if (diskDirSizes.length != diskDirs.length) { throw new IllegalArgumentException( @@ -244,6 +255,7 @@ public static void verifyNonNegativeDirSize(int[] sizes) { } } + @Override public DiskStoreFactory setDiskDirs(File[] diskDirs) { checkIfDirectoriesExist(diskDirs); int[] diskSizes = new int[diskDirs.length]; @@ -251,6 +263,7 @@ public DiskStoreFactory setDiskDirs(File[] diskDirs) { return setDiskDirsAndSizes(diskDirs, diskSizes); } + @Override public DiskStoreFactory setMaxOplogSize(long maxOplogSize) { long MAX = Long.MAX_VALUE / (1024 * 1024); if (maxOplogSize > MAX) { @@ -282,6 +295,7 @@ public DiskStoreFactory setMaxOplogSizeInBytes(long maxOplogSizeInBytes) { return this; } + @Override public DiskStoreFactory setQueueSize(int queueSize) { if (queueSize < 0) { throw new IllegalArgumentException( @@ -293,6 +307,7 @@ public DiskStoreFactory setQueueSize(int queueSize) { return this; } + @Override public DiskStoreFactory setWriteBufferSize(int writeBufferSize) { if (writeBufferSize < 0) { // TODO add a message for WriteBufferSize diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/DistributedRegion.java b/geode-core/src/main/java/org/apache/geode/internal/cache/DistributedRegion.java index b848a1a05a5e..15db271a712a 100755 --- a/geode-core/src/main/java/org/apache/geode/internal/cache/DistributedRegion.java +++ b/geode-core/src/main/java/org/apache/geode/internal/cache/DistributedRegion.java @@ -124,6 +124,7 @@ import org.apache.geode.internal.offheap.annotations.Retained; import org.apache.geode.internal.sequencelog.RegionLogger; import org.apache.geode.internal.util.concurrent.StoppableCountDownLatch; +import org.apache.geode.management.internal.resource.ResourceEventNotifier; @SuppressWarnings("deprecation") public class DistributedRegion extends LocalRegion implements InternalDistributedRegion { @@ -186,8 +187,9 @@ public class DistributedRegion extends LocalRegion implements InternalDistribute /** Creates a new instance of DistributedRegion */ protected DistributedRegion(String regionName, RegionAttributes attrs, LocalRegion parentRegion, - InternalCache cache, InternalRegionArguments internalRegionArgs) { - super(regionName, attrs, parentRegion, cache, internalRegionArgs); + InternalCache cache, ResourceEventNotifier resourceEventNotifier, + InternalRegionArguments internalRegionArgs) { + super(regionName, attrs, parentRegion, cache, resourceEventNotifier, internalRegionArgs); this.initializationLatchAfterMemberTimeout = new StoppableCountDownLatch(getCancelCriterion(), 1); this.distAdvisor = createDistributionAdvisor(internalRegionArgs); diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/GemFireCacheImpl.java b/geode-core/src/main/java/org/apache/geode/internal/cache/GemFireCacheImpl.java index 63eb8c64fad5..20f5c2dcbace 100755 --- a/geode-core/src/main/java/org/apache/geode/internal/cache/GemFireCacheImpl.java +++ b/geode-core/src/main/java/org/apache/geode/internal/cache/GemFireCacheImpl.java @@ -163,8 +163,6 @@ import org.apache.geode.distributed.internal.InternalLocator; import org.apache.geode.distributed.internal.ReplyException; import org.apache.geode.distributed.internal.ReplyProcessor21; -import org.apache.geode.distributed.internal.ResourceEvent; -import org.apache.geode.distributed.internal.ResourceEventsListener; import org.apache.geode.distributed.internal.ServerLocation; import org.apache.geode.distributed.internal.locks.DLockService; import org.apache.geode.distributed.internal.membership.InternalDistributedMember; @@ -229,6 +227,9 @@ import org.apache.geode.management.internal.beans.ManagementListener; import org.apache.geode.management.internal.configuration.domain.Configuration; import org.apache.geode.management.internal.configuration.messages.ConfigurationResponse; +import org.apache.geode.management.internal.resource.ResourceEvent; +import org.apache.geode.management.internal.resource.ResourceEventNotifier; +import org.apache.geode.management.internal.resource.ResourceEventNotifierFactory; import org.apache.geode.memcached.GemFireMemcachedServer; import org.apache.geode.memcached.GemFireMemcachedServer.Protocol; import org.apache.geode.pdx.JSONFormatter; @@ -527,7 +528,7 @@ public class GemFireCacheImpl implements InternalCache, InternalClientCache, Has private final Object offHeapEvictorLock = new Object(); - private ResourceEventsListener resourceEventsListener; + private final ResourceEventNotifier resourceEventNotifier; /** * Enabled when CacheExistsException issues arise in debugging @@ -803,7 +804,7 @@ private static GemFireCacheImpl basicCreate(InternalDistributedSystem system, bo return instance; } } catch (CacheXmlException | IllegalArgumentException e) { - logger.error(e.getLocalizedMessage()); // TODO: log the full stack trace or not? + logger.error(e.getLocalizedMessage()); throw e; } catch (Error | RuntimeException e) { logger.error(e); @@ -873,17 +874,19 @@ private GemFireCacheImpl(boolean isClient, PoolFactory pf, InternalDistributedSy if (!this.isClient && PoolManager.getAll().isEmpty()) { // We only support management on members of a distributed system - // Should do this: if (!getSystem().isLoner()) { - // but it causes quickstart.CqClientTest to hang - this.resourceEventsListener = new ManagementListener(this.system); - this.system.addResourceListener(this.resourceEventsListener); + resourceEventNotifier = new ResourceEventNotifierFactory().createResourceEventNotifier(); + resourceEventNotifier.addResourceListener(new ManagementListener(this.system)); + } else { + resourceEventNotifier = + new ResourceEventNotifierFactory().createDummyResourceEventNotifier(); + } + + if (!this.isClient && PoolManager.getAll().isEmpty()) { if (this.system.isLoner()) { - this.system.getInternalLogWriter() - .info("Running in local mode since no locators were specified."); + logger.info("Running in local mode since no locators were specified."); } } else { logger.info("Running in client mode"); - this.resourceEventsListener = null; } // Don't let admin-only VMs create Cache's just yet. @@ -985,6 +988,11 @@ private GemFireCacheImpl(boolean isClient, PoolFactory pf, InternalDistributedSy } // synchronized } + @Override + public ResourceEventNotifier getResourceEventNotifier() { + return resourceEventNotifier; + } + @Override public void reLoadClusterConfiguration() throws IOException, ClassNotFoundException { this.configurationResponse = requestSharedConfiguration(); @@ -1211,7 +1219,7 @@ private void initialize() { this.jmxAdvisor.initializationGate(); // Entry to GemFire Management service // this starts up the ManagementService, register and federate the internal beans - this.system.handleResourceEvent(ResourceEvent.CACHE_CREATE, this); + resourceEventNotifier.handleResourceEvent(ResourceEvent.CACHE_CREATE, this); initializeServices(); @@ -1267,7 +1275,7 @@ private void initializeServices() { for (CacheService service : loader) { service.init(this); this.services.put(service.getInterface(), service); - this.system.handleResourceEvent(ResourceEvent.CACHE_SERVICE_CREATE, service); + resourceEventNotifier.handleResourceEvent(ResourceEvent.CACHE_SERVICE_CREATE, service); logger.info("Initialized cache service {}", service.getClass().getName()); } } @@ -1478,6 +1486,7 @@ private static void logCacheXML(URL url, String cacheXmlDescription) { } } + @Override public synchronized void initializePdxRegistry() { if (this.pdxRegistry == null) { // The member with locator is initialized with a NullTypePdxRegistration @@ -1494,6 +1503,7 @@ public synchronized void initializePdxRegistry() { * Call to make this vm's dynamic region factory ready. Public so it can be called from * CacheCreation during xml processing */ + @Override public void readyDynamicRegionFactory() { try { ((DynamicRegionFactoryImpl) DynamicRegionFactory.get()).internalInit(this); @@ -1511,7 +1521,7 @@ public void readyDynamicRegionFactory() { */ @Override public DiskStoreFactory createDiskStoreFactory() { - return new DiskStoreFactoryImpl(this); + return new DiskStoreFactoryImpl(this, resourceEventNotifier); } /** @@ -1519,8 +1529,9 @@ public DiskStoreFactory createDiskStoreFactory() { * * @since GemFire prPersistSprint2 */ + @Override public DiskStoreFactory createDiskStoreFactory(DiskStoreAttributes attrs) { - return new DiskStoreFactoryImpl(this, attrs); + return new DiskStoreFactoryImpl(this, resourceEventNotifier, attrs); } class Stopper extends CancelCriterion { @@ -1611,6 +1622,7 @@ public CacheClosedException getCacheClosedException(String reason, Throwable cau } /** if the cache was forcibly closed this exception will reflect the cause */ + @Override public Throwable getDisconnectCause() { return this.disconnectCause; } @@ -2102,6 +2114,7 @@ public ClientMetadataService getClientMetadataService() { private final boolean DISABLE_DISCONNECT_DS_ON_CACHE_CLOSE = Boolean .getBoolean(DistributionConfig.GEMFIRE_PREFIX + "DISABLE_DISCONNECT_DS_ON_CACHE_CLOSE"); + @Override public void close(String reason, Throwable systemFailureCause, boolean keepAlive, boolean keepDS) { securityService.close(); @@ -2124,11 +2137,8 @@ public void close(String reason, Throwable systemFailureCause, boolean keepAlive * First close the ManagementService as it uses a lot of infra which will be closed by * cache.close() */ - this.system.handleResourceEvent(ResourceEvent.CACHE_REMOVE, this); - if (this.resourceEventsListener != null) { - this.system.removeResourceListener(this.resourceEventsListener); - this.resourceEventsListener = null; - } + resourceEventNotifier.handleResourceEvent(ResourceEvent.CACHE_REMOVE, this); + resourceEventNotifier.close(); if (systemFailureCause != null) { this.forcedDisconnect = systemFailureCause instanceof ForcedDisconnectException; @@ -2510,9 +2520,8 @@ public void addDiskStore(DiskStoreImpl dsi) { public void removeDiskStore(DiskStoreImpl diskStore) { this.diskStores.remove(diskStore.getName()); this.regionOwnedDiskStores.remove(diskStore.getName()); - // Added for M&M if (!diskStore.getOwnedByRegion()) - this.system.handleResourceEvent(ResourceEvent.DISKSTORE_REMOVE, diskStore); + resourceEventNotifier.handleResourceEvent(ResourceEvent.DISKSTORE_REMOVE, diskStore); } @Override @@ -2533,8 +2542,7 @@ public void closeDiskStores() { logger.debug("closing {}", dsi); } dsi.close(); - // Added for M&M - this.system.handleResourceEvent(ResourceEvent.DISKSTORE_REMOVE, dsi); + resourceEventNotifier.handleResourceEvent(ResourceEvent.DISKSTORE_REMOVE, dsi); } catch (RuntimeException e) { logger.fatal("Cache close caught an exception during disk store close", e); } @@ -2807,6 +2815,7 @@ public Properties getDeclarableProperties(final Declarable declarable) { * * @since GemFire 3.5 */ + @Override public int getUpTime() { return (int) (System.currentTimeMillis() - this.creationDate.getTime()) / 1000; } @@ -2872,6 +2881,7 @@ private void addLocalHostAsServer(PoolFactory poolFactory) { /** * Used to set the default pool on a new GemFireCache. */ + @Override public synchronized void determineDefaultPool() { if (!isClient()) { throw new UnsupportedOperationException(); @@ -2930,6 +2940,7 @@ public synchronized void determineDefaultPool() { * @param poolFactory Prospective pool factory. * @throws IllegalStateException When the specified pool factory does not match. */ + @Override public void validatePoolFactory(PoolFactory poolFactory) { // If the specified pool factory is null, by definition there is no pool factory to validate. if (poolFactory != null && !Objects.equals(this.poolFactory, poolFactory)) { @@ -2944,6 +2955,7 @@ public Region createRegion(String name, RegionAttributes aReg return basicCreateRegion(name, aRegionAttributes); } + @Override public Region basicCreateRegion(String name, RegionAttributes attrs) throws RegionExistsException, TimeoutException { try { @@ -3012,7 +3024,8 @@ public Region createVMRegion(String name, RegionAttributes p_ if (internalRegionArgs.getInternalMetaRegion() != null) { region = internalRegionArgs.getInternalMetaRegion(); } else if (isPartitionedRegion) { - region = new PartitionedRegion(name, attrs, null, this, internalRegionArgs); + region = new PartitionedRegion(name, attrs, null, this, resourceEventNotifier, + internalRegionArgs); } else { // Abstract region depends on the default pool existing so lazily initialize it // if necessary. @@ -3020,9 +3033,11 @@ public Region createVMRegion(String name, RegionAttributes p_ determineDefaultPool(); } if (attrs.getScope().isLocal()) { - region = new LocalRegion(name, attrs, null, this, internalRegionArgs); + region = new LocalRegion(name, attrs, null, this, resourceEventNotifier, + internalRegionArgs); } else { - region = new DistributedRegion(name, attrs, null, this, internalRegionArgs); + region = new DistributedRegion(name, attrs, null, this, resourceEventNotifier, + internalRegionArgs); } } @@ -3108,9 +3123,8 @@ public Region createVMRegion(String name, RegionAttributes p_ invokeRegionAfter(region); - // Added for M&M . Putting the callback here to avoid creating RegionMBean in case of Exception if (!region.isInternalRegion()) { - this.system.handleResourceEvent(ResourceEvent.REGION_CREATE, region); + resourceEventNotifier.handleResourceEvent(ResourceEvent.REGION_CREATE, region); } return region; @@ -3157,6 +3171,7 @@ public Region getRegion(String path) { * * @since GemFire 6.0 */ + @Override public Set getAllRegions() { Set result = new HashSet<>(); synchronized (this.rootRegions) { @@ -3352,6 +3367,7 @@ private boolean isGlobalRegionInitializing(InternalRegion region) { return rootRegions(false); } + @Override public Set> rootRegions(boolean includePRAdminRegions) { return rootRegions(includePRAdminRegions, true); } @@ -3762,13 +3778,15 @@ public CacheServer addCacheServer(boolean isGatewayReceiver) { throwIfClient(); this.stopper.checkCancelInProgress(null); - CacheServerImpl cacheServer = new CacheServerImpl(this, isGatewayReceiver); + CacheServerImpl cacheServer = + new CacheServerImpl(this, resourceEventNotifier, isGatewayReceiver); this.allCacheServers.add(cacheServer); sendAddCacheServerProfileMessage(); return cacheServer; } + @Override public boolean removeCacheServer(CacheServer cacheServer) { boolean removed = this.allCacheServers.remove(cacheServer); sendRemoveCacheServerProfileMessage(); @@ -3818,7 +3836,7 @@ public void addGatewaySender(GatewaySender sender) { } } if (!(sender.getRemoteDSId() < 0)) { - this.system.handleResourceEvent(ResourceEvent.GATEWAYSENDER_CREATE, sender); + resourceEventNotifier.handleResourceEvent(ResourceEvent.GATEWAYSENDER_CREATE, sender); } } @@ -3840,7 +3858,7 @@ public void removeGatewaySender(GatewaySender sender) { } } if (!(sender.getRemoteDSId() < 0)) { - this.system.handleResourceEvent(ResourceEvent.GATEWAYSENDER_REMOVE, sender); + resourceEventNotifier.handleResourceEvent(ResourceEvent.GATEWAYSENDER_REMOVE, sender); } } @@ -3858,6 +3876,7 @@ public void addGatewayReceiver(GatewayReceiver receiver) { } } + @Override public void removeGatewayReceiver(GatewayReceiver receiver) { throwIfClient(); this.stopper.checkCancelInProgress(null); @@ -3877,7 +3896,7 @@ public void addAsyncEventQueue(AsyncEventQueueImpl asyncQueue) { if (!asyncQueue.isMetaQueue()) { this.allVisibleAsyncEventQueues.add(asyncQueue); } - this.system.handleResourceEvent(ResourceEvent.ASYNCEVENTQUEUE_CREATE, asyncQueue); + resourceEventNotifier.handleResourceEvent(ResourceEvent.ASYNCEVENTQUEUE_CREATE, asyncQueue); } /** @@ -3953,7 +3972,7 @@ public void removeAsyncEventQueue(AsyncEventQueue asyncQueue) { this.allAsyncEventQueues.remove(asyncQueue); this.allVisibleAsyncEventQueues.remove(asyncQueue); } - this.system.handleResourceEvent(ResourceEvent.ASYNCEVENTQUEUE_REMOVE, asyncQueue); + resourceEventNotifier.handleResourceEvent(ResourceEvent.ASYNCEVENTQUEUE_REMOVE, asyncQueue); } /** get the conflict resolver for WAN */ @@ -4001,6 +4020,7 @@ public List getCacheServersAndGatewayReceiver() { * add a partitioned region to the set of tracked partitioned regions. This is used to notify the * regions when this cache requires, or does not require notification of all region/entry events. */ + @Override public void addPartitionedRegion(PartitionedRegion region) { synchronized (this.partitionedRegions) { if (region.isDestroyed()) { @@ -4341,6 +4361,7 @@ public InternalResourceManager getInternalResourceManager(boolean checkCancellat return this.resourceManager; } + @Override public void setBackupFiles(List backups) { this.backupFiles = backups; } @@ -5026,6 +5047,7 @@ public boolean getPdxIgnoreUnreadFields() { * Returns true if any of the GemFire services prefers PdxInstance. And application has not * requested getObject() on the PdxInstance. */ + @Override public boolean getPdxReadSerializedByAnyGemFireServices() { TypeRegistry pdxRegistry = this.getPdxRegistry(); boolean pdxReadSerializedOverriden = false; @@ -5049,17 +5071,17 @@ public DistributionManager getDistributionManager() { @Override public GatewaySenderFactory createGatewaySenderFactory() { - return WANServiceProvider.createGatewaySenderFactory(this); + return WANServiceProvider.createGatewaySenderFactory(this, resourceEventNotifier); } @Override public GatewayReceiverFactory createGatewayReceiverFactory() { - return WANServiceProvider.createGatewayReceiverFactory(this); + return WANServiceProvider.createGatewayReceiverFactory(this, resourceEventNotifier); } @Override public AsyncEventQueueFactory createAsyncEventQueueFactory() { - return new AsyncEventQueueFactoryImpl(this); + return new AsyncEventQueueFactoryImpl(this, resourceEventNotifier); } @Override @@ -5136,6 +5158,7 @@ public void setReadSerializedForTest(boolean value) { this.cacheConfig.setPdxReadSerialized(value); } + @Override public void setDeclarativeCacheConfig(CacheConfig cacheConfig) { this.cacheConfig.setDeclarativeConfig(cacheConfig); basicSetPdxSerializer(this.cacheConfig.getPdxSerializer()); @@ -5147,6 +5170,7 @@ public void setDeclarativeCacheConfig(CacheConfig cacheConfig) { * * @param mapOfNewDeclarableProps Map of the declarable properties to add */ + @Override public void addDeclarableProperties(final Map mapOfNewDeclarableProps) { synchronized (this.declarablePropertiesMap) { for (Entry newEntry : mapOfNewDeclarableProps.entrySet()) { @@ -5195,6 +5219,7 @@ public Properties getInitializerProps() { return this.initializerProps; } + @Override public void setInitializer(Declarable initializer, Properties initializerProps) { this.initializer = initializer; this.initializerProps = initializerProps; @@ -5215,6 +5240,7 @@ public PdxInstance createPdxEnum(String className, String enumName, int enumOrdi return PdxInstanceFactoryImpl.createPdxEnum(className, enumName, enumOrdinal, this); } + @Override public JmxManagerAdvisor getJmxManagerAdvisor() { return this.jmxAdvisor; } diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/HARegion.java b/geode-core/src/main/java/org/apache/geode/internal/cache/HARegion.java index 83dee3fbb631..4ffaa99e25f7 100755 --- a/geode-core/src/main/java/org/apache/geode/internal/cache/HARegion.java +++ b/geode-core/src/main/java/org/apache/geode/internal/cache/HARegion.java @@ -46,6 +46,7 @@ import org.apache.geode.internal.cache.tier.sockets.HAEventWrapper; import org.apache.geode.internal.logging.LogService; import org.apache.geode.internal.offheap.annotations.Released; +import org.apache.geode.management.internal.resource.ResourceEventNotifier; /** * This region is being implemented to suppress distribution of puts and to allow localDestroys on @@ -83,15 +84,11 @@ protected StringBuilder getStringBuilder() { return buf; } - // protected Object conditionalCopy(Object o) { - // return o; - // } - private volatile HARegionQueue owningQueue; private HARegion(String regionName, RegionAttributes attrs, LocalRegion parentRegion, - InternalCache cache) { - super(regionName, attrs, parentRegion, cache, + InternalCache cache, ResourceEventNotifier resourceEventNotifier) { + super(regionName, attrs, parentRegion, cache, resourceEventNotifier, new InternalRegionArguments().setDestroyLockFlag(true).setRecreateFlag(false) .setSnapshotInputStream(null).setImageTarget(null)); this.haRegionStats = new DummyCachePerfStats(); @@ -247,7 +244,7 @@ public static HARegion getInstance(String regionName, InternalCache cache, HAReg RegionAttributes ra) throws TimeoutException, RegionExistsException, IOException, ClassNotFoundException { - HARegion haRegion = new HARegion(regionName, ra, null, cache); + HARegion haRegion = new HARegion(regionName, ra, null, cache, cache.getResourceEventNotifier()); haRegion.setOwner(hrq); Region region = cache.createVMRegion(regionName, ra, new InternalRegionArguments().setInternalMetaRegion(haRegion).setDestroyLockFlag(true) diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/InternalCache.java b/geode-core/src/main/java/org/apache/geode/internal/cache/InternalCache.java index d44f7ca51773..40b9fde469b7 100644 --- a/geode-core/src/main/java/org/apache/geode/internal/cache/InternalCache.java +++ b/geode-core/src/main/java/org/apache/geode/internal/cache/InternalCache.java @@ -65,6 +65,7 @@ import org.apache.geode.internal.security.SecurityService; import org.apache.geode.management.internal.JmxManagerAdvisor; import org.apache.geode.management.internal.RestAgent; +import org.apache.geode.management.internal.resource.ResourceEventNotifier; import org.apache.geode.pdx.PdxInstanceFactory; import org.apache.geode.pdx.internal.TypeRegistry; @@ -72,7 +73,7 @@ * The InternalCache interface is contract for implementing classes for defining internal cache * operations that should not be part of the "public" API of the implementing class. * - * @see org.apache.geode.cache.Cache + * @see Cache * @since GemFire 7.0 */ public interface InternalCache extends Cache, Extensible, CacheTime { @@ -368,4 +369,6 @@ void invokeRegionEntrySynchronizationListenersAfterSynchronization( * by Geode will not be accessible from the returned cache. */ InternalCacheForClientAccess getCacheForProcessingClientRequests(); + + ResourceEventNotifier getResourceEventNotifier(); } diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/InternalCacheForClientAccess.java b/geode-core/src/main/java/org/apache/geode/internal/cache/InternalCacheForClientAccess.java index 759aa1f40063..d8536f2ce218 100644 --- a/geode-core/src/main/java/org/apache/geode/internal/cache/InternalCacheForClientAccess.java +++ b/geode-core/src/main/java/org/apache/geode/internal/cache/InternalCacheForClientAccess.java @@ -88,6 +88,7 @@ import org.apache.geode.internal.security.SecurityService; import org.apache.geode.management.internal.JmxManagerAdvisor; import org.apache.geode.management.internal.RestAgent; +import org.apache.geode.management.internal.resource.ResourceEventNotifier; import org.apache.geode.pdx.JSONFormatter; import org.apache.geode.pdx.PdxInstance; import org.apache.geode.pdx.PdxInstanceFactory; @@ -1218,4 +1219,9 @@ public void setPdxReadSerializedOverride(boolean pdxReadSerialized) { public InternalCacheForClientAccess getCacheForProcessingClientRequests() { return this; } + + @Override + public ResourceEventNotifier getResourceEventNotifier() { + return delegate.getResourceEventNotifier(); + } } diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/LocalRegion.java b/geode-core/src/main/java/org/apache/geode/internal/cache/LocalRegion.java index 1f0288401397..1ee6ef3ba402 100644 --- a/geode-core/src/main/java/org/apache/geode/internal/cache/LocalRegion.java +++ b/geode-core/src/main/java/org/apache/geode/internal/cache/LocalRegion.java @@ -150,7 +150,6 @@ import org.apache.geode.distributed.internal.DistributionManager; import org.apache.geode.distributed.internal.DistributionStats; import org.apache.geode.distributed.internal.InternalDistributedSystem; -import org.apache.geode.distributed.internal.ResourceEvent; import org.apache.geode.distributed.internal.membership.InternalDistributedMember; import org.apache.geode.internal.Assert; import org.apache.geode.internal.ClassLoadUtil; @@ -218,6 +217,8 @@ import org.apache.geode.internal.util.concurrent.FutureResult; import org.apache.geode.internal.util.concurrent.StoppableCountDownLatch; import org.apache.geode.internal.util.concurrent.StoppableReadWriteLock; +import org.apache.geode.management.internal.resource.ResourceEvent; +import org.apache.geode.management.internal.resource.ResourceEventNotifier; import org.apache.geode.pdx.JSONFormatter; import org.apache.geode.pdx.PdxInstance; @@ -375,6 +376,7 @@ public enum IteratorType { * @since GemFire 5.0 */ final boolean EXPIRY_UNITS_MS; + private final ResourceEventNotifier resourceEventNotifier; // Indicates that the entries are in fact initialized. It turns out // you can't trust the assignment of a volatile (as indicated above) @@ -594,12 +596,14 @@ private static String calcFullPath(String regionName, LocalRegion parentRegion) * Creates new region */ protected LocalRegion(String regionName, RegionAttributes attrs, LocalRegion parentRegion, - InternalCache cache, InternalRegionArguments internalRegionArgs) throws DiskAccessException { + InternalCache cache, ResourceEventNotifier resourceEventNotifier, + InternalRegionArguments internalRegionArgs) throws DiskAccessException { super(cache, attrs, regionName, internalRegionArgs); // Initialized here (and defers to parent) to fix GEODE-128 this.EXPIRY_UNITS_MS = parentRegion != null ? parentRegion.EXPIRY_UNITS_MS : Boolean.getBoolean(EXPIRY_MS_PROPERTY); + this.resourceEventNotifier = resourceEventNotifier; Assert.assertTrue(regionName != null, "regionName must not be null"); this.sharedDataView = buildDataView(); @@ -793,6 +797,7 @@ boolean isCacheClosing() { return this.cache.isClosed(); } + @Override public RegionEntry getRegionEntry(Object key) { return this.entries.getEntry(key); } @@ -951,20 +956,22 @@ public Region createSubregion(String subregionName, RegionAttributes attrs, internalRegionArgs.setUserAttribute(pr.getUserAttribute()); if (pr.isShadowPR()) { newRegion = new BucketRegionQueue(subregionName, regionAttributes, this, this.cache, - internalRegionArgs); + resourceEventNotifier, internalRegionArgs); } else { newRegion = new BucketRegion(subregionName, regionAttributes, this, this.cache, - internalRegionArgs); + resourceEventNotifier, internalRegionArgs); } } else if (regionAttributes.getPartitionAttributes() != null) { newRegion = new PartitionedRegion(subregionName, regionAttributes, this, this.cache, - internalRegionArgs); + resourceEventNotifier, internalRegionArgs); } else { boolean local = regionAttributes.getScope().isLocal(); newRegion = local ? new LocalRegion(subregionName, regionAttributes, this, this.cache, + resourceEventNotifier, internalRegionArgs) : new DistributedRegion(subregionName, regionAttributes, this, this.cache, + resourceEventNotifier, internalRegionArgs); } Object previousValue = this.subregions.putIfAbsent(subregionName, newRegion); @@ -1033,8 +1040,8 @@ public Region createSubregion(String subregionName, RegionAttributes attrs, // instead of destroyLock in LocalRegion? ManagementAdapter is one // of the Resource Event listeners - InternalDistributedSystem system = this.cache.getInternalDistributedSystem(); - system.handleResourceEvent(ResourceEvent.REGION_CREATE, newRegion); + resourceEventNotifier.handleResourceEvent(ResourceEvent.REGION_CREATE, + newRegion); } } success = true; @@ -1967,6 +1974,7 @@ public boolean containsKey(Object key) { return getDataView().containsKey(getKeyInfo(key), this); } + @Override public boolean containsTombstone(Object key) { checkReadiness(); checkForNoAccess(); @@ -2083,6 +2091,7 @@ protected int entryCount(Set buckets, boolean estimate) { /** * @return size after considering imageState */ + @Override public int getRegionSize() { synchronized (getSizeGuard()) { int result = getRegionMap().size(); @@ -2641,8 +2650,7 @@ private void recursiveDestroyRegion(Set eventSet, RegionEventImpl regionEvent, b try { region.recursiveDestroyRegion(eventSet, regionEvent, cacheWrite); if (!region.isInternalRegion()) { - InternalDistributedSystem system = region.cache.getInternalDistributedSystem(); - system.handleResourceEvent(ResourceEvent.REGION_REMOVE, region); + resourceEventNotifier.handleResourceEvent(ResourceEvent.REGION_REMOVE, region); } } catch (CancelException e) { // I don't think this should ever happen: bulletproofing for bug 39454 @@ -3562,6 +3570,7 @@ public Object getValueInVMOrDiskWithoutFaultIn(Object key) throws EntryNotFoundE * * @since GemFire 5.1 */ + @Override public Object getValueOnDiskOrBuffer(Object key) throws EntryNotFoundException { // Ok for this to ignore tx state RegionEntry re = this.entries.getEntry(key); @@ -6324,8 +6333,7 @@ void basicDestroyRegion(RegionEventImpl event, boolean cacheWrite, boolean lock, // Added for M&M : At this point we can safely call ResourceEvent to remove the region // artifacts From Management Layer if (!isInternalRegion()) { - InternalDistributedSystem system = this.cache.getInternalDistributedSystem(); - system.handleResourceEvent(ResourceEvent.REGION_REMOVE, this); + resourceEventNotifier.handleResourceEvent(ResourceEvent.REGION_REMOVE, this); } try { @@ -10491,6 +10499,7 @@ public Map getCacheServiceProfiles() { return this.cacheServiceProfiles.getSnapshot(); } + @Override public void addCacheServiceProfile(CacheServiceProfile profile) { cacheServiceProfileUpdateLock.lock(); try { diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/PartitionedRegion.java b/geode-core/src/main/java/org/apache/geode/internal/cache/PartitionedRegion.java index 197a65a9252d..e7f449c4a2d7 100755 --- a/geode-core/src/main/java/org/apache/geode/internal/cache/PartitionedRegion.java +++ b/geode-core/src/main/java/org/apache/geode/internal/cache/PartitionedRegion.java @@ -242,6 +242,7 @@ import org.apache.geode.internal.size.Sizeable; import org.apache.geode.internal.util.TransformUtils; import org.apache.geode.internal.util.concurrent.StoppableCountDownLatch; +import org.apache.geode.management.internal.resource.ResourceEventNotifier; /** * A Region whose total storage is split into chunks of data (partitions) which are copied up to a @@ -726,8 +727,10 @@ public synchronized String dump() { * and also by invoking Cache.createRegion(). (Cache.xml etc to be added) */ public PartitionedRegion(String regionName, RegionAttributes regionAttributes, - LocalRegion parentRegion, InternalCache cache, InternalRegionArguments internalRegionArgs) { - super(regionName, regionAttributes, parentRegion, cache, internalRegionArgs); + LocalRegion parentRegion, InternalCache cache, ResourceEventNotifier resourceEventNotifier, + InternalRegionArguments internalRegionArgs) { + super(regionName, regionAttributes, parentRegion, cache, resourceEventNotifier, + internalRegionArgs); this.node = initializeNode(); this.prStats = new PartitionedRegionStats(cache.getDistributedSystem(), getFullPath()); diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/wan/AbstractGatewaySender.java b/geode-core/src/main/java/org/apache/geode/internal/cache/wan/AbstractGatewaySender.java index ef0ac519041a..0eb9a9efa2bb 100644 --- a/geode-core/src/main/java/org/apache/geode/internal/cache/wan/AbstractGatewaySender.java +++ b/geode-core/src/main/java/org/apache/geode/internal/cache/wan/AbstractGatewaySender.java @@ -51,7 +51,6 @@ import org.apache.geode.distributed.internal.DistributionAdvisor.Profile; import org.apache.geode.distributed.internal.DistributionManager; import org.apache.geode.distributed.internal.InternalDistributedSystem; -import org.apache.geode.distributed.internal.ResourceEvent; import org.apache.geode.distributed.internal.ServerLocation; import org.apache.geode.internal.cache.CachePerfStats; import org.apache.geode.internal.cache.EntryEventImpl; @@ -75,6 +74,8 @@ import org.apache.geode.internal.offheap.annotations.Released; import org.apache.geode.internal.offheap.annotations.Retained; import org.apache.geode.internal.offheap.annotations.Unretained; +import org.apache.geode.management.internal.resource.ResourceEvent; +import org.apache.geode.management.internal.resource.ResourceEventNotifier; /** * Abstract implementation of both Serial and Parallel GatewaySender. It handles common @@ -88,6 +89,8 @@ public abstract class AbstractGatewaySender implements InternalGatewaySender, Di protected InternalCache cache; + protected final ResourceEventNotifier resourceEventNotifier; + protected String id; protected long startTime; @@ -96,23 +99,21 @@ public abstract class AbstractGatewaySender implements InternalGatewaySender, Di protected int remoteDSId; - protected String locName; - protected int socketBufferSize; protected int socketReadTimeout; - protected int queueMemory; + private final int queueMemory; - protected int maxMemoryPerDispatcherQueue; + private final int maxMemoryPerDispatcherQueue; protected int batchSize; protected int batchTimeInterval; - protected boolean isConflation; + private boolean isConflation; - protected boolean isPersistence; + private final boolean isPersistence; protected int alertThreshold; @@ -126,53 +127,53 @@ public abstract class AbstractGatewaySender implements InternalGatewaySender, Di protected String diskStoreName; - protected List eventFilters; + private List eventFilters; - protected List transFilters; + private final List transFilters; protected List listeners; protected boolean forwardExpirationDestroy; - protected GatewayEventSubstitutionFilter substitutionFilter; + private final GatewayEventSubstitutionFilter substitutionFilter; - protected LocatorDiscoveryCallback locatorDiscoveryCallback; + LocatorDiscoveryCallback locatorDiscoveryCallback; private final ReentrantReadWriteLock lifeCycleLock = new ReentrantReadWriteLock(); - protected GatewaySenderAdvisor senderAdvisor; + private GatewaySenderAdvisor senderAdvisor; - private int serialNumber; + private final int serialNumber; protected GatewaySenderStats statistics; private Stopper stopper; - private OrderPolicy policy; + private final OrderPolicy policy; - private int dispatcherThreads; + private final int dispatcherThreads; - protected boolean isBucketSorted; + private final boolean isBucketSorted; - protected boolean isMetaQueue; + private final boolean isMetaQueue; - private int parallelismForReplicatedRegion; + private final int parallelismForReplicatedRegion; protected AbstractGatewaySenderEventProcessor eventProcessor; - private org.apache.geode.internal.cache.GatewayEventFilter filter = + private final org.apache.geode.internal.cache.GatewayEventFilter filter = DefaultGatewayEventFilter.getInstance(); private ServerLocation serverLocation; - protected Object queuedEventsSync = new Object(); + private final Object queuedEventsSync = new Object(); - protected volatile boolean enqueuedAllTempQueueEvents = false; + private volatile boolean enqueuedAllTempQueueEvents; - protected volatile ConcurrentLinkedQueue tmpQueuedEvents = + private final ConcurrentLinkedQueue tmpQueuedEvents = new ConcurrentLinkedQueue<>(); - protected volatile ConcurrentLinkedQueue tmpDroppedEvents = + private final ConcurrentLinkedQueue tmpDroppedEvents = new ConcurrentLinkedQueue<>(); /** * The number of seconds to wait before stopping the GatewaySender. Default is 0 seconds. @@ -201,11 +202,11 @@ public abstract class AbstractGatewaySender implements InternalGatewaySender, Di /** * The name of the GatewaySender's meta data region. */ - protected static final String META_DATA_REGION_NAME = "gatewayEventIdIndexMetaData"; + private static final String META_DATA_REGION_NAME = "gatewayEventIdIndexMetaData"; - protected int myDSId = DEFAULT_DISTRIBUTED_SYSTEM_ID; + private int myDSId = DEFAULT_DISTRIBUTED_SYSTEM_ID; - protected int connectionIdleTimeOut = GATEWAY_CONNECTION_IDLE_TIMEOUT; + int connectionIdleTimeOut = GATEWAY_CONNECTION_IDLE_TIMEOUT; private boolean removeFromQueueOnException = GatewaySender.REMOVE_FROM_QUEUE_ON_EXCEPTION; @@ -223,12 +224,12 @@ public abstract class AbstractGatewaySender implements InternalGatewaySender, Di */ private Region eventIdIndexMetaDataRegion; - final Object lockForConcurrentDispatcher = new Object(); + private final Object lockForConcurrentDispatcher = new Object(); - protected AbstractGatewaySender() {} - - public AbstractGatewaySender(InternalCache cache, GatewaySenderAttributes attrs) { + public AbstractGatewaySender(InternalCache cache, ResourceEventNotifier resourceEventNotifier, + GatewaySenderAttributes attrs) { this.cache = cache; + this.resourceEventNotifier = resourceEventNotifier; this.id = attrs.getId(); this.socketBufferSize = attrs.getSocketBufferSize(); this.socketReadTimeout = attrs.getSocketReadTimeout(); @@ -390,7 +391,7 @@ public boolean isBatchConflationEnabled() { return this.isConflation; } - public void test_setBatchConflationEnabled(boolean enableConflation) { + void test_setBatchConflationEnabled(boolean enableConflation) { this.isConflation = enableConflation; } @@ -409,7 +410,7 @@ public int getMaxParallelismForReplicatedRegion() { return this.parallelismForReplicatedRegion; } - public LocatorDiscoveryCallback getLocatorDiscoveryCallback() { + LocatorDiscoveryCallback getLocatorDiscoveryCallback() { return this.locatorDiscoveryCallback; } @@ -701,7 +702,7 @@ public void setRemoveFromQueueOnException(boolean removeFromQueueOnException) { /** * @return the removeFromQueueOnException */ - public boolean isRemoveFromQueueOnException() { + boolean isRemoveFromQueueOnException() { return removeFromQueueOnException; } @@ -718,7 +719,7 @@ public synchronized ServerLocation getServerLocation() { return serverLocation; } - public synchronized boolean setServerLocation(ServerLocation location) { + synchronized boolean setServerLocation(ServerLocation location) { this.serverLocation = location; return true; } @@ -796,9 +797,7 @@ public void pause() { } this.eventProcessor.pauseDispatching(); - InternalDistributedSystem system = - (InternalDistributedSystem) this.cache.getDistributedSystem(); - system.handleResourceEvent(ResourceEvent.GATEWAYSENDER_PAUSE, this); + resourceEventNotifier.handleResourceEvent(ResourceEvent.GATEWAYSENDER_PAUSE, this); logger.info("Paused {}", this); @@ -819,10 +818,7 @@ public void resume() { } this.eventProcessor.resumeDispatching(); - - InternalDistributedSystem system = - (InternalDistributedSystem) this.cache.getDistributedSystem(); - system.handleResourceEvent(ResourceEvent.GATEWAYSENDER_RESUME, this); + resourceEventNotifier.handleResourceEvent(ResourceEvent.GATEWAYSENDER_RESUME, this); logger.info("Resumed {}", this); @@ -1133,7 +1129,7 @@ public boolean removeFromTempQueueEvents(Object tailKey) { * will be stored in temp queue. Once sender is started, these event from tmp queue will be * cleared. */ - public void clearTempEventsAfterSenderStopped() { + protected void clearTempEventsAfterSenderStopped() { TmpQueueEvent nextEvent = null; while ((nextEvent = tmpQueuedEvents.poll()) != null) { nextEvent.release(); @@ -1151,7 +1147,7 @@ public void clearTempEventsAfterSenderStopped() { statistics.setTempQueueSize(0); } - public Object getSubstituteValue(EntryEventImpl clonedEvent, EnumListenerEvent operation) { + private Object getSubstituteValue(EntryEventImpl clonedEvent, EnumListenerEvent operation) { // Get substitution value to enqueue if necessary Object substituteValue = null; if (this.substitutionFilter != null) { @@ -1172,7 +1168,7 @@ public Object getSubstituteValue(EntryEventImpl clonedEvent, EnumListenerEvent o return substituteValue; } - protected void initializeEventIdIndex() { + private void initializeEventIdIndex() { final boolean isDebugEnabled = logger.isDebugEnabled(); boolean gotLock = false; @@ -1306,7 +1302,7 @@ public int getEventQueueSize() { return localProcessor == null ? 0 : localProcessor.eventQueueSize(); } - public int getSecondaryEventQueueSize() { + int getSecondaryEventQueueSize() { AbstractGatewaySenderEventProcessor localProcessor = this.eventProcessor; return localProcessor == null ? 0 : localProcessor.secondaryEventQueueSize(); } @@ -1319,7 +1315,7 @@ protected boolean isAsyncEventQueue() { return this.getAsyncEventListeners() != null && !this.getAsyncEventListeners().isEmpty(); } - public Object getLockForConcurrentDispatcher() { + Object getLockForConcurrentDispatcher() { return this.lockForConcurrentDispatcher; } @@ -1386,7 +1382,7 @@ public static class TmpQueueEvent implements Releasable { private final @Retained EntryEventImpl event; private final Object substituteValue; - public TmpQueueEvent(EnumListenerEvent op, @Retained EntryEventImpl e, Object subValue) { + TmpQueueEvent(EnumListenerEvent op, @Retained EntryEventImpl e, Object subValue) { this.operation = op; this.event = e; this.substituteValue = subValue; @@ -1400,7 +1396,7 @@ public EnumListenerEvent getOperation() { return this.event; } - public Object getSubstituteValue() { + Object getSubstituteValue() { return this.substituteValue; } diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/wan/AbstractGatewaySenderEventProcessor.java b/geode-core/src/main/java/org/apache/geode/internal/cache/wan/AbstractGatewaySenderEventProcessor.java index 7e8b38232da1..a08d83552b42 100644 --- a/geode-core/src/main/java/org/apache/geode/internal/cache/wan/AbstractGatewaySenderEventProcessor.java +++ b/geode-core/src/main/java/org/apache/geode/internal/cache/wan/AbstractGatewaySenderEventProcessor.java @@ -145,10 +145,10 @@ public abstract class AbstractGatewaySenderEventProcessor extends LoggingThread */ private int batchSize; - public AbstractGatewaySenderEventProcessor(String string, - GatewaySender sender, ThreadsMonitoring tMonitoring) { + public AbstractGatewaySenderEventProcessor(String string, AbstractGatewaySender sender, + ThreadsMonitoring tMonitoring) { super(string); - this.sender = (AbstractGatewaySender) sender; + this.sender = sender; this.batchSize = sender.getBatchSize(); this.threadMonitoring = tMonitoring; } diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/wan/WANServiceProvider.java b/geode-core/src/main/java/org/apache/geode/internal/cache/wan/WANServiceProvider.java index 229736a43830..970c83ef1f22 100644 --- a/geode-core/src/main/java/org/apache/geode/internal/cache/wan/WANServiceProvider.java +++ b/geode-core/src/main/java/org/apache/geode/internal/cache/wan/WANServiceProvider.java @@ -23,6 +23,7 @@ import org.apache.geode.distributed.internal.WanLocatorDiscoverer; import org.apache.geode.internal.cache.InternalCache; import org.apache.geode.internal.cache.wan.spi.WANFactory; +import org.apache.geode.management.internal.resource.ResourceEventNotifier; public class WANServiceProvider { private static final WANFactory factory; @@ -38,19 +39,21 @@ public class WANServiceProvider { } } - public static GatewaySenderFactory createGatewaySenderFactory(InternalCache cache) { + public static GatewaySenderFactory createGatewaySenderFactory(InternalCache cache, + ResourceEventNotifier resourceEventNotifier) { if (factory == null) { throw new IllegalStateException("WAN service is not available."); } - return factory.createGatewaySenderFactory(cache); + return factory.createGatewaySenderFactory(cache, resourceEventNotifier); } - public static GatewayReceiverFactory createGatewayReceiverFactory(InternalCache cache) { + public static GatewayReceiverFactory createGatewayReceiverFactory(InternalCache cache, + ResourceEventNotifier resourceEventNotifier) { if (factory == null) { throw new IllegalStateException("WAN service is not available."); } - return factory.createGatewayReceiverFactory(cache); + return factory.createGatewayReceiverFactory(cache, resourceEventNotifier); } public static WanLocatorDiscoverer createLocatorDiscoverer() { diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/wan/parallel/ParallelGatewaySenderQueue.java b/geode-core/src/main/java/org/apache/geode/internal/cache/wan/parallel/ParallelGatewaySenderQueue.java index bcf2f040430d..2fca001d9a9b 100644 --- a/geode-core/src/main/java/org/apache/geode/internal/cache/wan/parallel/ParallelGatewaySenderQueue.java +++ b/geode-core/src/main/java/org/apache/geode/internal/cache/wan/parallel/ParallelGatewaySenderQueue.java @@ -85,6 +85,7 @@ import org.apache.geode.management.ManagementService; import org.apache.geode.management.internal.beans.AsyncEventQueueMBean; import org.apache.geode.management.internal.beans.GatewaySenderMBean; +import org.apache.geode.management.internal.resource.ResourceEventNotifier; public class ParallelGatewaySenderQueue implements RegionQueue { @@ -308,6 +309,7 @@ public void addShadowPartitionedRegionForUserRR(DistributedRegion userRegion) { return; InternalCache cache = sender.getCache(); + ResourceEventNotifier resourceEventNotifier = cache.getResourceEventNotifier(); final String prQName = getQueueName(sender.getId(), userRegion.getFullPath()); prQ = (PartitionedRegion) cache.getRegion(prQName); if (prQ == null) { @@ -353,7 +355,8 @@ public void addShadowPartitionedRegionForUserRR(DistributedRegion userRegion) { } ParallelGatewaySenderQueueMetaRegion meta = - new ParallelGatewaySenderQueueMetaRegion(prQName, ra, null, cache, sender); + new ParallelGatewaySenderQueueMetaRegion(prQName, ra, null, cache, + resourceEventNotifier, sender); try { prQ = (PartitionedRegion) cache.createVMRegion(prQName, ra, @@ -454,6 +457,7 @@ public void addShadowPartitionedRegionForUserPR(PartitionedRegion userPR) { } InternalCache cache = sender.getCache(); + ResourceEventNotifier resourceEventNotifier = cache.getResourceEventNotifier(); boolean isAccessor = (userPR.getLocalMaxMemory() == 0); final String prQName = sender.getId() + QSTRING + convertPathToName(userPR.getFullPath()); @@ -504,7 +508,7 @@ public void addShadowPartitionedRegionForUserPR(PartitionedRegion userPR) { } ParallelGatewaySenderQueueMetaRegion meta = - metaRegionFactory.newMetataRegion(cache, prQName, ra, sender); + metaRegionFactory.newMetataRegion(cache, resourceEventNotifier, prQName, ra, sender); try { prQ = (PartitionedRegion) cache.createVMRegion(prQName, ra, @@ -1778,13 +1782,14 @@ protected static class ParallelGatewaySenderQueueMetaRegion extends PartitionedR AbstractGatewaySender sender = null; public ParallelGatewaySenderQueueMetaRegion(String regionName, RegionAttributes attrs, - LocalRegion parentRegion, InternalCache cache, AbstractGatewaySender pgSender) { - super(regionName, attrs, parentRegion, cache, + LocalRegion parentRegion, InternalCache cache, ResourceEventNotifier resourceEventNotifier, + AbstractGatewaySender pgSender) { + super(regionName, attrs, parentRegion, cache, resourceEventNotifier, new InternalRegionArguments().setDestroyLockFlag(true).setRecreateFlag(false) .setSnapshotInputStream(null).setImageTarget(null) .setIsUsedForParallelGatewaySenderQueue(true) - .setParallelGatewaySender((AbstractGatewaySender) pgSender)); - this.sender = (AbstractGatewaySender) pgSender; + .setParallelGatewaySender(pgSender)); + this.sender = pgSender; } @@ -1839,10 +1844,12 @@ public int size(PartitionedRegion pr, int bucketId) throws ForceReattemptExcepti } static class MetaRegionFactory { - ParallelGatewaySenderQueueMetaRegion newMetataRegion(InternalCache cache, final String prQName, + ParallelGatewaySenderQueueMetaRegion newMetataRegion(InternalCache cache, + ResourceEventNotifier resourceEventNotifier, final String prQName, final RegionAttributes ra, AbstractGatewaySender sender) { ParallelGatewaySenderQueueMetaRegion meta = - new ParallelGatewaySenderQueueMetaRegion(prQName, ra, null, cache, sender); + new ParallelGatewaySenderQueueMetaRegion(prQName, ra, null, cache, resourceEventNotifier, + sender); return meta; } } diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/wan/serial/SerialGatewaySenderQueue.java b/geode-core/src/main/java/org/apache/geode/internal/cache/wan/serial/SerialGatewaySenderQueue.java index e0f38a51ff38..fc45b4822f3e 100644 --- a/geode-core/src/main/java/org/apache/geode/internal/cache/wan/serial/SerialGatewaySenderQueue.java +++ b/geode-core/src/main/java/org/apache/geode/internal/cache/wan/serial/SerialGatewaySenderQueue.java @@ -71,6 +71,7 @@ import org.apache.geode.management.ManagementService; import org.apache.geode.management.internal.beans.AsyncEventQueueMBean; import org.apache.geode.management.internal.beans.GatewaySenderMBean; +import org.apache.geode.management.internal.resource.ResourceEventNotifier; import org.apache.geode.pdx.internal.PeerTypeRegistration; /** @@ -828,6 +829,7 @@ private void updateHeadKey(long destroyedKey) throws CacheException { @SuppressWarnings({"unchecked", "rawtypes"}) private void initializeRegion(AbstractGatewaySender sender, CacheListener listener) { final InternalCache gemCache = sender.getCache(); + final ResourceEventNotifier resourceEventNotifier = gemCache.getResourceEventNotifier(); this.region = gemCache.getRegion(this.regionName); if (this.region == null) { AttributesFactory factory = new AttributesFactory(); @@ -862,7 +864,8 @@ private void initializeRegion(AbstractGatewaySender sender, CacheListener listen final RegionAttributes ra = factory.create(); try { SerialGatewaySenderQueueMetaRegion meta = - new SerialGatewaySenderQueueMetaRegion(this.regionName, ra, null, gemCache, sender); + new SerialGatewaySenderQueueMetaRegion(this.regionName, ra, null, gemCache, + resourceEventNotifier, sender); try { this.region = gemCache.createVMRegion(this.regionName, ra, new InternalRegionArguments().setInternalMetaRegion(meta).setDestroyLockFlag(true) @@ -872,14 +875,10 @@ private void initializeRegion(AbstractGatewaySender sender, CacheListener listen // Add overflow statistics to the mbean addOverflowStatisticsToMBean(gemCache, sender); - } catch (IOException veryUnLikely) { + } catch (IOException | ClassNotFoundException veryUnLikely) { logger.fatal(String.format("Unexpected Exception during init of %s", this.getClass()), veryUnLikely); - } catch (ClassNotFoundException alsoUnlikely) { - logger.fatal(String.format("Unexpected Exception during init of %s", - this.getClass()), - alsoUnlikely); } if (logger.isDebugEnabled()) { logger.debug("{}: Created queue region: {}", this, this.region); @@ -1102,8 +1101,9 @@ public static class SerialGatewaySenderQueueMetaRegion extends DistributedRegion AbstractGatewaySender sender = null; protected SerialGatewaySenderQueueMetaRegion(String regionName, RegionAttributes attrs, - LocalRegion parentRegion, InternalCache cache, AbstractGatewaySender sender) { - super(regionName, attrs, parentRegion, cache, + LocalRegion parentRegion, InternalCache cache, ResourceEventNotifier resourceEventNotifier, + AbstractGatewaySender sender) { + super(regionName, attrs, parentRegion, cache, resourceEventNotifier, new InternalRegionArguments().setDestroyLockFlag(true).setRecreateFlag(false) .setSnapshotInputStream(null).setImageTarget(null) .setIsUsedForSerialGatewaySenderQueue(true).setSerialGatewaySender(sender)); diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/wan/spi/WANFactory.java b/geode-core/src/main/java/org/apache/geode/internal/cache/wan/spi/WANFactory.java index 3af9bf8b2807..740651cc9b51 100644 --- a/geode-core/src/main/java/org/apache/geode/internal/cache/wan/spi/WANFactory.java +++ b/geode-core/src/main/java/org/apache/geode/internal/cache/wan/spi/WANFactory.java @@ -19,12 +19,15 @@ import org.apache.geode.cache.wan.GatewaySenderFactory; import org.apache.geode.distributed.internal.WanLocatorDiscoverer; import org.apache.geode.internal.cache.InternalCache; +import org.apache.geode.management.internal.resource.ResourceEventNotifier; public interface WANFactory { - GatewaySenderFactory createGatewaySenderFactory(InternalCache cache); + GatewaySenderFactory createGatewaySenderFactory(InternalCache cache, + ResourceEventNotifier resourceEventNotifier); - GatewayReceiverFactory createGatewayReceiverFactory(InternalCache cache); + GatewayReceiverFactory createGatewayReceiverFactory(InternalCache cache, + ResourceEventNotifier resourceEventNotifier); WanLocatorDiscoverer createLocatorDiscoverer(); diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/xmlcache/CacheCreation.java b/geode-core/src/main/java/org/apache/geode/internal/cache/xmlcache/CacheCreation.java index d5719033afd7..3fb97abf3ce1 100755 --- a/geode-core/src/main/java/org/apache/geode/internal/cache/xmlcache/CacheCreation.java +++ b/geode-core/src/main/java/org/apache/geode/internal/cache/xmlcache/CacheCreation.java @@ -155,6 +155,8 @@ import org.apache.geode.internal.security.SecurityServiceFactory; import org.apache.geode.management.internal.JmxManagerAdvisor; import org.apache.geode.management.internal.RestAgent; +import org.apache.geode.management.internal.resource.ResourceEventNotifier; +import org.apache.geode.management.internal.resource.ResourceEventNotifierFactory; import org.apache.geode.pdx.JSONFormatter; import org.apache.geode.pdx.PdxInstance; import org.apache.geode.pdx.PdxInstanceFactory; @@ -291,6 +293,9 @@ public Properties getProperties() { */ private final SimpleExtensionPoint extensionPoint = new SimpleExtensionPoint<>(this, this); + private final ResourceEventNotifier resourceEventNotifier = + new ResourceEventNotifierFactory().createDummyResourceEventNotifier(); + /** * Creates a new {@code CacheCreation} with no root regions */ @@ -429,7 +434,7 @@ boolean hasMessageSyncInterval() { */ @Override public DiskStoreFactory createDiskStoreFactory() { - return new DiskStoreFactoryImpl(this); + return new DiskStoreFactoryImpl(this, resourceEventNotifier); } /** @@ -1640,17 +1645,17 @@ public Set getRegionListeners() { @Override public GatewaySenderFactory createGatewaySenderFactory() { - return WANServiceProvider.createGatewaySenderFactory(this); + return WANServiceProvider.createGatewaySenderFactory(this, resourceEventNotifier); } @Override public GatewayReceiverFactory createGatewayReceiverFactory() { - return WANServiceProvider.createGatewayReceiverFactory(this); + return WANServiceProvider.createGatewayReceiverFactory(this, resourceEventNotifier); } @Override public AsyncEventQueueFactory createAsyncEventQueueFactory() { - return new AsyncEventQueueFactoryImpl(this); + return new AsyncEventQueueFactoryImpl(this, resourceEventNotifier); } public void setPdxReadSerialized(boolean readSerialized) { @@ -2419,4 +2424,9 @@ public void registerPdxMetaData(Object instance) { public InternalCacheForClientAccess getCacheForProcessingClientRequests() { throw new UnsupportedOperationException("Should not be invoked"); } + + @Override + public ResourceEventNotifier getResourceEventNotifier() { + throw new UnsupportedOperationException("Should not be invoked"); + } } diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/xmlcache/ParallelAsyncEventQueueCreation.java b/geode-core/src/main/java/org/apache/geode/internal/cache/xmlcache/ParallelAsyncEventQueueCreation.java index 4686b67ff4b7..452014a7388f 100644 --- a/geode-core/src/main/java/org/apache/geode/internal/cache/xmlcache/ParallelAsyncEventQueueCreation.java +++ b/geode-core/src/main/java/org/apache/geode/internal/cache/xmlcache/ParallelAsyncEventQueueCreation.java @@ -28,60 +28,75 @@ import org.apache.geode.internal.cache.InternalCache; import org.apache.geode.internal.cache.wan.AbstractGatewaySender; import org.apache.geode.internal.cache.wan.GatewaySenderAttributes; +import org.apache.geode.management.internal.resource.ResourceEventNotifier; public class ParallelAsyncEventQueueCreation extends AbstractGatewaySender implements GatewaySender { - public ParallelAsyncEventQueueCreation(InternalCache cache, GatewaySenderAttributes attrs) { - super(cache, attrs); + public ParallelAsyncEventQueueCreation(InternalCache cache, + ResourceEventNotifier resourceEventNotifier, GatewaySenderAttributes attrs) { + super(cache, resourceEventNotifier, attrs); } + @Override public void distribute(EnumListenerEvent operation, EntryEventImpl event, List remoteDSIds) {} @Override public void start() {} + @Override public void stop() {} + @Override public void rebalance() { throw new UnsupportedOperationException(); } + @Override public void fillInProfile(Profile profile) {} + @Override public CancelCriterion getCancelCriterion() { return null; } + @Override public DistributionAdvisor getDistributionAdvisor() { return null; } + @Override public DistributionManager getDistributionManager() { return null; } + @Override public String getFullPath() { return null; } + @Override public String getName() { return null; } + @Override public DistributionAdvisee getParentAdvisee() { return null; } + @Override public Profile getProfile() { return null; } + @Override public int getSerialNumber() { return 0; } + @Override public InternalDistributedSystem getSystem() { return null; } diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/xmlcache/ParallelGatewaySenderCreation.java b/geode-core/src/main/java/org/apache/geode/internal/cache/xmlcache/ParallelGatewaySenderCreation.java index 257ee753b3ed..07a2a1a99291 100644 --- a/geode-core/src/main/java/org/apache/geode/internal/cache/xmlcache/ParallelGatewaySenderCreation.java +++ b/geode-core/src/main/java/org/apache/geode/internal/cache/xmlcache/ParallelGatewaySenderCreation.java @@ -29,21 +29,26 @@ import org.apache.geode.internal.cache.InternalCache; import org.apache.geode.internal.cache.wan.AbstractGatewaySender; import org.apache.geode.internal.cache.wan.GatewaySenderAttributes; +import org.apache.geode.management.internal.resource.ResourceEventNotifier; public class ParallelGatewaySenderCreation extends AbstractGatewaySender implements GatewaySender { - public ParallelGatewaySenderCreation(InternalCache cache, GatewaySenderAttributes attrs) { - super(cache, attrs); + public ParallelGatewaySenderCreation(InternalCache cache, + ResourceEventNotifier resourceEventNotifier, GatewaySenderAttributes attrs) { + super(cache, resourceEventNotifier, attrs); } + @Override public void distribute(EnumListenerEvent operation, EntryEventImpl event, List remoteDSIds) {} @Override public void start() {} + @Override public void stop() {} + @Override public void rebalance() { throw new UnsupportedOperationException(); } @@ -51,40 +56,50 @@ public void rebalance() { @Override public void destroy() {} + @Override public void fillInProfile(Profile profile) {} + @Override public CancelCriterion getCancelCriterion() { return null; } + @Override public DistributionAdvisor getDistributionAdvisor() { return null; } + @Override public DistributionManager getDistributionManager() { return null; } + @Override public String getFullPath() { return null; } + @Override public String getName() { return null; } + @Override public DistributionAdvisee getParentAdvisee() { return null; } + @Override public Profile getProfile() { return null; } + @Override public int getSerialNumber() { return 0; } + @Override public InternalDistributedSystem getSystem() { return null; } @@ -92,10 +107,12 @@ public InternalDistributedSystem getSystem() { @Override public void setModifiedEventId(EntryEventImpl clonedEvent) {} + @Override protected GatewayQueueEvent getSynchronizationEvent(Object key, long timestamp) { throw new UnsupportedOperationException(); } + @Override protected void putSynchronizationEvent(GatewayQueueEvent event) { throw new UnsupportedOperationException(); } diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/xmlcache/SerialAsyncEventQueueCreation.java b/geode-core/src/main/java/org/apache/geode/internal/cache/xmlcache/SerialAsyncEventQueueCreation.java index cd0666128582..d6a459732456 100644 --- a/geode-core/src/main/java/org/apache/geode/internal/cache/xmlcache/SerialAsyncEventQueueCreation.java +++ b/geode-core/src/main/java/org/apache/geode/internal/cache/xmlcache/SerialAsyncEventQueueCreation.java @@ -28,59 +28,74 @@ import org.apache.geode.internal.cache.InternalCache; import org.apache.geode.internal.cache.wan.AbstractGatewaySender; import org.apache.geode.internal.cache.wan.GatewaySenderAttributes; +import org.apache.geode.management.internal.resource.ResourceEventNotifier; public class SerialAsyncEventQueueCreation extends AbstractGatewaySender implements GatewaySender { - public SerialAsyncEventQueueCreation(InternalCache cache, GatewaySenderAttributes attrs) { - super(cache, attrs); + public SerialAsyncEventQueueCreation(InternalCache cache, + ResourceEventNotifier resourceEventNotifier, GatewaySenderAttributes attrs) { + super(cache, resourceEventNotifier, attrs); } + @Override public void distribute(EnumListenerEvent operation, EntryEventImpl event, List remoteDSIds) {} @Override public void start() {} + @Override public void stop() {} + @Override public void rebalance() { throw new UnsupportedOperationException(); } + @Override public void fillInProfile(Profile profile) {} + @Override public CancelCriterion getCancelCriterion() { return null; } + @Override public DistributionAdvisor getDistributionAdvisor() { return null; } + @Override public DistributionManager getDistributionManager() { return null; } + @Override public String getFullPath() { return null; } + @Override public String getName() { return null; } + @Override public DistributionAdvisee getParentAdvisee() { return null; } + @Override public Profile getProfile() { return null; } + @Override public int getSerialNumber() { return 0; } + @Override public InternalDistributedSystem getSystem() { return null; } diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/xmlcache/SerialGatewaySenderCreation.java b/geode-core/src/main/java/org/apache/geode/internal/cache/xmlcache/SerialGatewaySenderCreation.java index b0766ffc16eb..24860a6cc454 100644 --- a/geode-core/src/main/java/org/apache/geode/internal/cache/xmlcache/SerialGatewaySenderCreation.java +++ b/geode-core/src/main/java/org/apache/geode/internal/cache/xmlcache/SerialGatewaySenderCreation.java @@ -29,59 +29,74 @@ import org.apache.geode.internal.cache.InternalCache; import org.apache.geode.internal.cache.wan.AbstractGatewaySender; import org.apache.geode.internal.cache.wan.GatewaySenderAttributes; +import org.apache.geode.management.internal.resource.ResourceEventNotifier; public class SerialGatewaySenderCreation extends AbstractGatewaySender implements GatewaySender { - public SerialGatewaySenderCreation(InternalCache cache, GatewaySenderAttributes attrs) { - super(cache, attrs); + public SerialGatewaySenderCreation(InternalCache cache, + ResourceEventNotifier resourceEventNotifier, GatewaySenderAttributes attrs) { + super(cache, resourceEventNotifier, attrs); } + @Override public void distribute(EnumListenerEvent operation, EntryEventImpl event, List remoteDSIds) {} @Override public void start() {} + @Override public void stop() {} + @Override public void rebalance() { throw new UnsupportedOperationException(); } + @Override public void fillInProfile(Profile profile) {} + @Override public CancelCriterion getCancelCriterion() { return null; } + @Override public DistributionAdvisor getDistributionAdvisor() { return null; } + @Override public DistributionManager getDistributionManager() { return null; } + @Override public String getFullPath() { return null; } + @Override public String getName() { return null; } + @Override public DistributionAdvisee getParentAdvisee() { return null; } + @Override public Profile getProfile() { return null; } + @Override public int getSerialNumber() { return 0; } + @Override public InternalDistributedSystem getSystem() { return null; } @@ -89,10 +104,12 @@ public InternalDistributedSystem getSystem() { @Override public void setModifiedEventId(EntryEventImpl clonedEvent) {} + @Override protected GatewayQueueEvent getSynchronizationEvent(Object key, long timestamp) { throw new UnsupportedOperationException(); } + @Override protected void putSynchronizationEvent(GatewayQueueEvent event) { throw new UnsupportedOperationException(); } diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/SystemManagementService.java b/geode-core/src/main/java/org/apache/geode/management/internal/SystemManagementService.java index 0ffa38def83f..b8716dfe0847 100755 --- a/geode-core/src/main/java/org/apache/geode/management/internal/SystemManagementService.java +++ b/geode-core/src/main/java/org/apache/geode/management/internal/SystemManagementService.java @@ -30,7 +30,6 @@ import org.apache.geode.distributed.DistributedMember; import org.apache.geode.distributed.DistributedSystemDisconnectedException; import org.apache.geode.distributed.internal.InternalDistributedSystem; -import org.apache.geode.distributed.internal.ResourceEvent; import org.apache.geode.distributed.internal.membership.InternalDistributedMember; import org.apache.geode.internal.cache.InternalCache; import org.apache.geode.internal.cache.InternalCacheForClientAccess; @@ -51,6 +50,8 @@ import org.apache.geode.management.MemberMXBean; import org.apache.geode.management.RegionMXBean; import org.apache.geode.management.internal.beans.ManagementAdapter; +import org.apache.geode.management.internal.resource.ResourceEvent; +import org.apache.geode.management.internal.resource.ResourceEventNotifier; import org.apache.geode.management.membership.MembershipEvent; import org.apache.geode.management.membership.MembershipListener; @@ -68,6 +69,8 @@ public class SystemManagementService extends BaseManagementService { */ private final InternalDistributedSystem system; + private final ResourceEventNotifier resourceEventNotifier; + /** * core component for distribution */ @@ -120,11 +123,13 @@ public class SystemManagementService extends BaseManagementService { public static BaseManagementService newSystemManagementService( InternalCacheForClientAccess cache) { - return new SystemManagementService(cache).init(); + return new SystemManagementService(cache, cache.getResourceEventNotifier()).init(); } - protected SystemManagementService(InternalCacheForClientAccess cache) { + protected SystemManagementService(InternalCacheForClientAccess cache, + ResourceEventNotifier resourceEventNotifier) { this.cache = cache; + this.resourceEventNotifier = resourceEventNotifier; this.system = (InternalDistributedSystem) cache.getDistributedSystem(); // This is a safe check to ensure Management service does not start for a // system which is disconnected. @@ -426,7 +431,7 @@ public void startManager() { if (needsToBeStarted) { boolean started = false; try { - system.handleResourceEvent(ResourceEvent.MANAGER_START, null); + resourceEventNotifier.handleResourceEvent(ResourceEvent.MANAGER_START, null); federatingManager.startManager(); if (this.agent != null) { this.agent.startAgent(getInternalCache()); @@ -441,7 +446,7 @@ public void startManager() { if (federatingManager != null) { federatingManager.stopManager(); } - system.handleResourceEvent(ResourceEvent.MANAGER_STOP, null); + resourceEventNotifier.handleResourceEvent(ResourceEvent.MANAGER_STOP, null); } } } @@ -460,7 +465,7 @@ public boolean createManager() { if (federatingManager != null) { return false; } - system.handleResourceEvent(ResourceEvent.MANAGER_CREATE, null); + resourceEventNotifier.handleResourceEvent(ResourceEvent.MANAGER_CREATE, null); // An initialised copy of federating manager federatingManager = new FederatingManager(jmxAdapter, repo, system, this, cache); getInternalCache().getJmxManagerAdvisor().broadcastChange(); @@ -477,7 +482,7 @@ public void stopManager() { verifyManagementService(); if (federatingManager != null) { federatingManager.stopManager(); - system.handleResourceEvent(ResourceEvent.MANAGER_STOP, null); + resourceEventNotifier.handleResourceEvent(ResourceEvent.MANAGER_STOP, null); getInternalCache().getJmxManagerAdvisor().broadcastChange(); if (this.agent != null && (this.agent.isRunning() || this.agent.isHttpServiceRunning())) { this.agent.stopAgent(); diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/beans/ManagementListener.java b/geode-core/src/main/java/org/apache/geode/management/internal/beans/ManagementListener.java index b9db71c069bb..b2acc30e4598 100644 --- a/geode-core/src/main/java/org/apache/geode/management/internal/beans/ManagementListener.java +++ b/geode-core/src/main/java/org/apache/geode/management/internal/beans/ManagementListener.java @@ -26,18 +26,18 @@ import org.apache.geode.cache.wan.GatewaySender; import org.apache.geode.distributed.Locator; import org.apache.geode.distributed.internal.InternalDistributedSystem; -import org.apache.geode.distributed.internal.ResourceEvent; -import org.apache.geode.distributed.internal.ResourceEventsListener; import org.apache.geode.distributed.internal.locks.DLockService; import org.apache.geode.internal.cache.CacheService; import org.apache.geode.internal.cache.InternalCache; import org.apache.geode.management.internal.AlertDetails; +import org.apache.geode.management.internal.resource.ResourceEvent; +import org.apache.geode.management.internal.resource.ResourceEventListener; /** * This Listener listens on various resource creation in GemFire and create/destroys GemFire * specific MBeans accordingly */ -public class ManagementListener implements ResourceEventsListener { +public class ManagementListener implements ResourceEventListener { private final InternalDistributedSystem system; diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/resource/ConcurrentResourceEventNotifier.java b/geode-core/src/main/java/org/apache/geode/management/internal/resource/ConcurrentResourceEventNotifier.java new file mode 100644 index 000000000000..431440bda736 --- /dev/null +++ b/geode-core/src/main/java/org/apache/geode/management/internal/resource/ConcurrentResourceEventNotifier.java @@ -0,0 +1,84 @@ +/* + * 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.management.internal.resource; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import org.apache.logging.log4j.Logger; + +import org.apache.geode.internal.logging.LogService; +import org.apache.geode.management.ManagementException; +import org.apache.geode.security.GemFireSecurityException; + +/** + * This is an implementation of {@link ResourceEventNotifier} that handles resource events in the + * thread that triggers them, except that a cache create or destroy stops other events from + * happening concurrently. + */ +public class ConcurrentResourceEventNotifier implements ResourceEventNotifier { + private static final Logger logger = LogService.getLogger(); + + private final Set resourceListeners; + + ConcurrentResourceEventNotifier() { + resourceListeners = Collections.synchronizedSet(new HashSet<>()); + } + + @Override + public void addResourceListener(ResourceEventListener listener) { + resourceListeners.add(listener); + } + + @Override + public Set getResourceListeners() { + return Collections.unmodifiableSet(resourceListeners); + } + + @Override + public void handleResourceEvent(ResourceEvent event, Object resource) { + if (resourceListeners.size() == 0) { + return; + } + notifyResourceEventListeners(event, resource); + } + + @Override + public void close() { + resourceListeners.clear(); + } + + /** + * Notifies all resource event listeners. All exceptions are caught here and only a warning + * message is printed in the log + * + * @param event Enumeration depicting particular resource event + * @param resource the actual resource object. + */ + private void notifyResourceEventListeners(ResourceEvent event, Object resource) { + for (ResourceEventListener listener : resourceListeners) { + try { + listener.handleEvent(event, resource); + } catch (GemFireSecurityException | ManagementException ex) { + if (event == ResourceEvent.CACHE_CREATE) { + throw ex; + } else { + logger.warn(ex.getMessage(), ex); + } + } + } + } +} diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/resource/DummyResourceEventNotifier.java b/geode-core/src/main/java/org/apache/geode/management/internal/resource/DummyResourceEventNotifier.java new file mode 100644 index 000000000000..5ae53137f02f --- /dev/null +++ b/geode-core/src/main/java/org/apache/geode/management/internal/resource/DummyResourceEventNotifier.java @@ -0,0 +1,48 @@ +/* + * 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.management.internal.resource; + +import java.util.Collections; +import java.util.Set; + +/** + * No-op implementation of {@link ResourceEventNotifier}. + */ +public class DummyResourceEventNotifier implements ResourceEventNotifier { + + DummyResourceEventNotifier() { + // nothing + } + + @Override + public void addResourceListener(ResourceEventListener listener) { + // nothing + } + + @Override + public Set getResourceListeners() { + return Collections.emptySet(); + } + + @Override + public void handleResourceEvent(ResourceEvent event, Object resource) { + // nothing + } + + @Override + public void close() { + // nothing + } +} diff --git a/geode-core/src/main/java/org/apache/geode/distributed/internal/ResourceEvent.java b/geode-core/src/main/java/org/apache/geode/management/internal/resource/ResourceEvent.java similarity index 91% rename from geode-core/src/main/java/org/apache/geode/distributed/internal/ResourceEvent.java rename to geode-core/src/main/java/org/apache/geode/management/internal/resource/ResourceEvent.java index 07bb94939039..0e0f89af54ac 100644 --- a/geode-core/src/main/java/org/apache/geode/distributed/internal/ResourceEvent.java +++ b/geode-core/src/main/java/org/apache/geode/management/internal/resource/ResourceEvent.java @@ -12,41 +12,50 @@ * or implied. See the License for the specific language governing permissions and limitations under * the License. */ -package org.apache.geode.distributed.internal; +package org.apache.geode.management.internal.resource; /** - * GemFire Resource Events - * + * Geode Resource Events */ public enum ResourceEvent { - CACHE_CREATE, - REGION_CREATE, - DISKSTORE_CREATE, - GATEWAYSENDER_CREATE, - LOCKSERVICE_CREATE, - CACHE_REMOVE, - REGION_REMOVE, - DISKSTORE_REMOVE, - GATEWAYSENDER_REMOVE, - LOCKSERVICE_REMOVE, - MANAGER_CREATE, - MANAGER_START, - MANAGER_STOP, - LOCATOR_START, ASYNCEVENTQUEUE_CREATE, ASYNCEVENTQUEUE_REMOVE, - SYSTEM_ALERT, + + CACHE_CREATE, + CACHE_REMOVE, + CACHE_SERVER_START, CACHE_SERVER_STOP, + + CACHE_SERVICE_CREATE, + CACHE_SERVICE_REMOVE, + + DISKSTORE_CREATE, + DISKSTORE_REMOVE, + + GATEWAYRECEIVER_CREATE, GATEWAYRECEIVER_DESTROY, GATEWAYRECEIVER_START, GATEWAYRECEIVER_STOP, - GATEWAYRECEIVER_CREATE, + + GATEWAYSENDER_CREATE, + GATEWAYSENDER_REMOVE, GATEWAYSENDER_START, GATEWAYSENDER_STOP, GATEWAYSENDER_PAUSE, GATEWAYSENDER_RESUME, - CACHE_SERVICE_CREATE, - CACHE_SERVICE_REMOVE + LOCATOR_START, + + LOCKSERVICE_CREATE, + LOCKSERVICE_REMOVE, + + MANAGER_CREATE, + MANAGER_START, + MANAGER_STOP, + + REGION_CREATE, + REGION_REMOVE, + + SYSTEM_ALERT } diff --git a/geode-core/src/main/java/org/apache/geode/distributed/internal/ResourceEventsListener.java b/geode-core/src/main/java/org/apache/geode/management/internal/resource/ResourceEventListener.java similarity index 81% rename from geode-core/src/main/java/org/apache/geode/distributed/internal/ResourceEventsListener.java rename to geode-core/src/main/java/org/apache/geode/management/internal/resource/ResourceEventListener.java index e06e4089182e..eb3462274274 100644 --- a/geode-core/src/main/java/org/apache/geode/distributed/internal/ResourceEventsListener.java +++ b/geode-core/src/main/java/org/apache/geode/management/internal/resource/ResourceEventListener.java @@ -12,21 +12,18 @@ * or implied. See the License for the specific language governing permissions and limitations under * the License. */ -package org.apache.geode.distributed.internal; +package org.apache.geode.management.internal.resource; /** * Internal interface to be implemented to catch various resource events - * - * */ -public interface ResourceEventsListener { +public interface ResourceEventListener { /** - * Handles various GFE resource life-cycle methods vis-a-vis Management and Monitoring + * Handles various Geode resource life-cycle methods. * * @param event Resource events for which invocation has happened - * @param resource the GFE resource type + * @param resource the Geode resource type */ void handleEvent(ResourceEvent event, Object resource); - } diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/resource/ResourceEventNotifier.java b/geode-core/src/main/java/org/apache/geode/management/internal/resource/ResourceEventNotifier.java new file mode 100644 index 000000000000..d366972b165b --- /dev/null +++ b/geode-core/src/main/java/org/apache/geode/management/internal/resource/ResourceEventNotifier.java @@ -0,0 +1,37 @@ +/* + * 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.management.internal.resource; + +import java.util.Set; + +/** + * Notifies {@link ResourceEventListener}s when {@link ResourceEvent}s occur. + */ +public interface ResourceEventNotifier { + + void addResourceListener(ResourceEventListener listener); + + Set getResourceListeners(); + + /** + * Handles a particular event associated with a resource + * + * @param event Resource event + * @param resource resource on which event is generated + */ + void handleResourceEvent(ResourceEvent event, Object resource); + + void close(); +} diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/resource/ResourceEventNotifierFactory.java b/geode-core/src/main/java/org/apache/geode/management/internal/resource/ResourceEventNotifierFactory.java new file mode 100644 index 000000000000..5bb122f35c5f --- /dev/null +++ b/geode-core/src/main/java/org/apache/geode/management/internal/resource/ResourceEventNotifierFactory.java @@ -0,0 +1,35 @@ +/* + * 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.management.internal.resource; + +import static org.apache.geode.distributed.internal.DistributionConfig.GEMFIRE_PREFIX; + +public class ResourceEventNotifierFactory { + + private static final String DISABLE_MANAGEMENT_PROPERTY = GEMFIRE_PREFIX + "disableManagement"; + + private final boolean disableManagement = Boolean.getBoolean(DISABLE_MANAGEMENT_PROPERTY); + + public ResourceEventNotifier createResourceEventNotifier() { + if (disableManagement) { + return createDummyResourceEventNotifier(); + } + return new ConcurrentResourceEventNotifier(); + } + + public ResourceEventNotifier createDummyResourceEventNotifier() { + return new DummyResourceEventNotifier(); + } +} diff --git a/geode-core/src/test/java/org/apache/geode/cache/asyncqueue/internal/AsyncEventQueueFactoryImplTest.java b/geode-core/src/test/java/org/apache/geode/cache/asyncqueue/internal/AsyncEventQueueFactoryImplTest.java index 2ecb45946ca0..36f335e43dc4 100644 --- a/geode-core/src/test/java/org/apache/geode/cache/asyncqueue/internal/AsyncEventQueueFactoryImplTest.java +++ b/geode-core/src/test/java/org/apache/geode/cache/asyncqueue/internal/AsyncEventQueueFactoryImplTest.java @@ -26,6 +26,8 @@ import org.apache.geode.cache.asyncqueue.AsyncEventQueueFactory; import org.apache.geode.internal.cache.InternalCache; +import org.apache.geode.management.internal.resource.ResourceEventNotifier; +import org.apache.geode.management.internal.resource.ResourceEventNotifierFactory; import org.apache.geode.test.junit.categories.AEQTest; /** @@ -35,12 +37,13 @@ public class AsyncEventQueueFactoryImplTest { private InternalCache cache; + private ResourceEventNotifier resourceEventNotifier; private AsyncEventQueueFactory asyncEventQueueFactory; @Before public void setUp() { cache = mock(InternalCache.class, RETURNS_DEEP_STUBS); - + resourceEventNotifier = new ResourceEventNotifierFactory().createDummyResourceEventNotifier(); } /** @@ -48,7 +51,7 @@ public void setUp() { */ @Test public void testCreateAsyncEventQueueWithNullListener() { - asyncEventQueueFactory = new AsyncEventQueueFactoryImpl(cache); + asyncEventQueueFactory = new AsyncEventQueueFactoryImpl(cache, resourceEventNotifier); assertThatThrownBy(() -> asyncEventQueueFactory.create("id", null)) .isInstanceOf(IllegalArgumentException.class); diff --git a/geode-core/src/test/java/org/apache/geode/internal/cache/AbstractDistributedRegionJUnitTest.java b/geode-core/src/test/java/org/apache/geode/internal/cache/AbstractDistributedRegionJUnitTest.java index 92d3ecb17081..6def36cf8527 100755 --- a/geode-core/src/test/java/org/apache/geode/internal/cache/AbstractDistributedRegionJUnitTest.java +++ b/geode-core/src/test/java/org/apache/geode/internal/cache/AbstractDistributedRegionJUnitTest.java @@ -33,6 +33,7 @@ import org.apache.geode.distributed.internal.membership.InternalDistributedMember; import org.apache.geode.internal.cache.versions.VersionTag; import org.apache.geode.internal.logging.LogService; +import org.apache.geode.management.internal.resource.ResourceEventNotifier; import org.apache.geode.test.fake.Fakes; public abstract class AbstractDistributedRegionJUnitTest { @@ -96,7 +97,8 @@ private void doTest(DistributedRegion region, EntryEventImpl event, int cnt) { protected abstract void setInternalRegionArguments(InternalRegionArguments ira); protected abstract DistributedRegion createAndDefineRegion(boolean isConcurrencyChecksEnabled, - RegionAttributes ra, InternalRegionArguments ira, GemFireCacheImpl cache); + RegionAttributes ra, InternalRegionArguments ira, GemFireCacheImpl cache, + ResourceEventNotifier resourceEventNotifier); protected abstract void verifyDistributeUpdate(DistributedRegion region, EntryEventImpl event, int cnt); @@ -113,6 +115,7 @@ protected abstract void verifyDistributeUpdateEntryVersion(DistributedRegion reg protected DistributedRegion prepare(boolean isConcurrencyChecksEnabled, boolean testHasSeenEvent) { GemFireCacheImpl cache = Fakes.cache(); + ResourceEventNotifier resourceEventNotifier = cache.getResourceEventNotifier(); // create region attributes and internal region arguments RegionAttributes ra = createRegionAttributes(isConcurrencyChecksEnabled); @@ -121,7 +124,8 @@ protected DistributedRegion prepare(boolean isConcurrencyChecksEnabled, setInternalRegionArguments(ira); // create a region object - DistributedRegion region = createAndDefineRegion(isConcurrencyChecksEnabled, ra, ira, cache); + DistributedRegion region = + createAndDefineRegion(isConcurrencyChecksEnabled, ra, ira, cache, resourceEventNotifier); if (isConcurrencyChecksEnabled) { region.enableConcurrencyChecks(); } diff --git a/geode-core/src/test/java/org/apache/geode/internal/cache/BucketRegionJUnitTest.java b/geode-core/src/test/java/org/apache/geode/internal/cache/BucketRegionJUnitTest.java index 8435c1b826ae..023850594866 100755 --- a/geode-core/src/test/java/org/apache/geode/internal/cache/BucketRegionJUnitTest.java +++ b/geode-core/src/test/java/org/apache/geode/internal/cache/BucketRegionJUnitTest.java @@ -32,6 +32,7 @@ import java.util.concurrent.locks.ReentrantReadWriteLock; import org.apache.geode.cache.RegionAttributes; +import org.apache.geode.management.internal.resource.ResourceEventNotifier; public class BucketRegionJUnitTest extends DistributedRegionJUnitTest { @@ -51,8 +52,9 @@ protected void setInternalRegionArguments(InternalRegionArguments ira) { @Override protected DistributedRegion createAndDefineRegion(boolean isConcurrencyChecksEnabled, - RegionAttributes ra, InternalRegionArguments ira, GemFireCacheImpl cache) { - BucketRegion br = new BucketRegion("testRegion", ra, null, cache, ira); + RegionAttributes ra, InternalRegionArguments ira, GemFireCacheImpl cache, + ResourceEventNotifier resourceEventNotifier) { + BucketRegion br = new BucketRegion("testRegion", ra, null, cache, resourceEventNotifier, ira); // it is necessary to set the event tracker to initialized, since initialize() in not being // called on the instantiated region br.getEventTracker().setInitialized(); diff --git a/geode-core/src/test/java/org/apache/geode/internal/cache/BucketRegionQueueJUnitTest.java b/geode-core/src/test/java/org/apache/geode/internal/cache/BucketRegionQueueJUnitTest.java index 86f1b3eef91a..bb2bf8ce06f7 100644 --- a/geode-core/src/test/java/org/apache/geode/internal/cache/BucketRegionQueueJUnitTest.java +++ b/geode-core/src/test/java/org/apache/geode/internal/cache/BucketRegionQueueJUnitTest.java @@ -29,6 +29,8 @@ import org.apache.geode.distributed.DistributedMember; import org.apache.geode.internal.cache.wan.AbstractGatewaySender; import org.apache.geode.internal.cache.wan.parallel.ParallelGatewaySenderHelper; +import org.apache.geode.management.internal.resource.ResourceEventNotifier; +import org.apache.geode.management.internal.resource.ResourceEventNotifierFactory; import org.apache.geode.test.fake.Fakes; public class BucketRegionQueueJUnitTest { @@ -38,6 +40,7 @@ public class BucketRegionQueueJUnitTest { private static final long KEY = 198; private GemFireCacheImpl cache; + private ResourceEventNotifier resourceEventNotifier; private PartitionedRegion queueRegion; private AbstractGatewaySender sender; private PartitionedRegion rootRegion; @@ -46,6 +49,7 @@ public class BucketRegionQueueJUnitTest { @Before public void setUpGemFire() { createCache(); + createResourceEventNotifier(); createQueueRegion(); createGatewaySender(); createRootRegion(); @@ -57,6 +61,10 @@ private void createCache() { this.cache = Fakes.cache(); } + private void createResourceEventNotifier() { + resourceEventNotifier = new ResourceEventNotifierFactory().createDummyResourceEventNotifier(); + } + private void createQueueRegion() { // Mock queue region this.queueRegion = @@ -79,7 +87,8 @@ private void createRootRegion() { private void createBucketRegionQueue() { BucketRegionQueue realBucketRegionQueue = ParallelGatewaySenderHelper - .createBucketRegionQueue(this.cache, this.rootRegion, this.queueRegion, BUCKET_ID); + .createBucketRegionQueue(this.cache, resourceEventNotifier, this.rootRegion, + this.queueRegion, BUCKET_ID); this.bucketRegionQueue = spy(realBucketRegionQueue); } diff --git a/geode-core/src/test/java/org/apache/geode/internal/cache/BucketRegionTest.java b/geode-core/src/test/java/org/apache/geode/internal/cache/BucketRegionTest.java index b408256669aa..b97bea2a6fc1 100644 --- a/geode-core/src/test/java/org/apache/geode/internal/cache/BucketRegionTest.java +++ b/geode-core/src/test/java/org/apache/geode/internal/cache/BucketRegionTest.java @@ -38,12 +38,14 @@ import org.apache.geode.cache.RegionDestroyedException; import org.apache.geode.cache.Scope; import org.apache.geode.internal.cache.partitioned.LockObject; +import org.apache.geode.management.internal.resource.ResourceEventNotifier; import org.apache.geode.test.fake.Fakes; public class BucketRegionTest { private RegionAttributes regionAttributes; private PartitionedRegion partitionedRegion; private InternalCache cache; + private ResourceEventNotifier resourceEventNotifier; private InternalRegionArguments internalRegionArgs; private DataPolicy dataPolicy; private EntryEventImpl event; @@ -61,6 +63,7 @@ public void setup() { regionAttributes = mock(RegionAttributes.class); partitionedRegion = mock(PartitionedRegion.class); cache = Fakes.cache(); + resourceEventNotifier = cache.getResourceEventNotifier(); internalRegionArgs = mock(InternalRegionArguments.class); dataPolicy = mock(DataPolicy.class); event = mock(EntryEventImpl.class, RETURNS_DEEP_STUBS); @@ -99,7 +102,7 @@ public void setup() { public void waitUntilLockedThrowsIfFoundLockAndPartitionedRegionIsClosing() { BucketRegion bucketRegion = spy(new BucketRegion(regionName, regionAttributes, partitionedRegion, - cache, internalRegionArgs)); + cache, resourceEventNotifier, internalRegionArgs)); Integer[] keys = {1}; doReturn(mock(LockObject.class)).when(bucketRegion).searchAndLock(keys); doThrow(regionDestroyedException).when(partitionedRegion) @@ -112,7 +115,7 @@ public void waitUntilLockedThrowsIfFoundLockAndPartitionedRegionIsClosing() { public void waitUntilLockedReturnsTrueIfNoOtherThreadLockedKeys() { BucketRegion bucketRegion = spy(new BucketRegion(regionName, regionAttributes, partitionedRegion, - cache, internalRegionArgs)); + cache, resourceEventNotifier, internalRegionArgs)); Integer[] keys = {1}; doReturn(null).when(bucketRegion).searchAndLock(keys); @@ -123,7 +126,7 @@ public void waitUntilLockedReturnsTrueIfNoOtherThreadLockedKeys() { public void basicPutEntryDoesNotReleaseLockIfKeysAndPrimaryNotLocked() { BucketRegion bucketRegion = spy(new BucketRegion(regionName, regionAttributes, partitionedRegion, - cache, internalRegionArgs)); + cache, resourceEventNotifier, internalRegionArgs)); doThrow(regionDestroyedException).when(bucketRegion).lockKeysAndPrimary(event); bucketRegion.basicPutEntry(event, 1); @@ -135,7 +138,7 @@ public void basicPutEntryDoesNotReleaseLockIfKeysAndPrimaryNotLocked() { public void basicPutEntryReleaseLockIfKeysAndPrimaryLocked() { BucketRegion bucketRegion = spy(new BucketRegion(regionName, regionAttributes, partitionedRegion, - cache, internalRegionArgs)); + cache, resourceEventNotifier, internalRegionArgs)); doReturn(true).when(bucketRegion).lockKeysAndPrimary(event); doReturn(mock(AbstractRegionMap.class)).when(bucketRegion).getRegionMap(); @@ -148,7 +151,7 @@ public void basicPutEntryReleaseLockIfKeysAndPrimaryLocked() { public void virtualPutDoesNotReleaseLockIfKeysAndPrimaryNotLocked() { BucketRegion bucketRegion = spy(new BucketRegion(regionName, regionAttributes, partitionedRegion, - cache, internalRegionArgs)); + cache, resourceEventNotifier, internalRegionArgs)); doThrow(regionDestroyedException).when(bucketRegion).lockKeysAndPrimary(event); bucketRegion.virtualPut(event, false, true, null, false, 1, true); @@ -160,7 +163,7 @@ public void virtualPutDoesNotReleaseLockIfKeysAndPrimaryNotLocked() { public void virtualPutReleaseLockIfKeysAndPrimaryLocked() { BucketRegion bucketRegion = spy(new BucketRegion(regionName, regionAttributes, partitionedRegion, - cache, internalRegionArgs)); + cache, resourceEventNotifier, internalRegionArgs)); doReturn(true).when(bucketRegion).lockKeysAndPrimary(event); doReturn(true).when(bucketRegion).hasSeenEvent(event); @@ -173,7 +176,7 @@ public void virtualPutReleaseLockIfKeysAndPrimaryLocked() { public void basicDestroyDoesNotReleaseLockIfKeysAndPrimaryNotLocked() { BucketRegion bucketRegion = spy(new BucketRegion(regionName, regionAttributes, partitionedRegion, - cache, internalRegionArgs)); + cache, resourceEventNotifier, internalRegionArgs)); doThrow(regionDestroyedException).when(bucketRegion).lockKeysAndPrimary(event); bucketRegion.basicDestroy(event, false, null); @@ -185,7 +188,7 @@ public void basicDestroyDoesNotReleaseLockIfKeysAndPrimaryNotLocked() { public void basicDestroyReleaseLockIfKeysAndPrimaryLocked() { BucketRegion bucketRegion = spy(new BucketRegion(regionName, regionAttributes, partitionedRegion, - cache, internalRegionArgs)); + cache, resourceEventNotifier, internalRegionArgs)); doReturn(true).when(bucketRegion).lockKeysAndPrimary(event); doReturn(true).when(bucketRegion).hasSeenEvent(event); @@ -198,7 +201,7 @@ public void basicDestroyReleaseLockIfKeysAndPrimaryLocked() { public void basicUpdateEntryVersionDoesNotReleaseLockIfKeysAndPrimaryNotLocked() { BucketRegion bucketRegion = spy(new BucketRegion(regionName, regionAttributes, partitionedRegion, - cache, internalRegionArgs)); + cache, resourceEventNotifier, internalRegionArgs)); doThrow(regionDestroyedException).when(bucketRegion).lockKeysAndPrimary(event); when(event.getRegion()).thenReturn(bucketRegion); doReturn(true).when(bucketRegion).hasSeenEvent(event); @@ -213,7 +216,7 @@ public void basicUpdateEntryVersionDoesNotReleaseLockIfKeysAndPrimaryNotLocked() public void basicUpdateEntryVersionReleaseLockIfKeysAndPrimaryLocked() { BucketRegion bucketRegion = spy(new BucketRegion(regionName, regionAttributes, partitionedRegion, - cache, internalRegionArgs)); + cache, resourceEventNotifier, internalRegionArgs)); doReturn(true).when(bucketRegion).lockKeysAndPrimary(event); when(event.getRegion()).thenReturn(bucketRegion); doReturn(true).when(bucketRegion).hasSeenEvent(event); @@ -228,7 +231,7 @@ public void basicUpdateEntryVersionReleaseLockIfKeysAndPrimaryLocked() { public void basicInvalidateDoesNotReleaseLockIfKeysAndPrimaryNotLocked() { BucketRegion bucketRegion = spy(new BucketRegion(regionName, regionAttributes, partitionedRegion, - cache, internalRegionArgs)); + cache, resourceEventNotifier, internalRegionArgs)); doThrow(regionDestroyedException).when(bucketRegion).lockKeysAndPrimary(event); bucketRegion.basicInvalidate(event, false, false); @@ -240,7 +243,7 @@ public void basicInvalidateDoesNotReleaseLockIfKeysAndPrimaryNotLocked() { public void basicInvalidateReleaseLockIfKeysAndPrimaryLocked() { BucketRegion bucketRegion = spy(new BucketRegion(regionName, regionAttributes, partitionedRegion, - cache, internalRegionArgs)); + cache, resourceEventNotifier, internalRegionArgs)); doReturn(true).when(bucketRegion).lockKeysAndPrimary(event); doReturn(true).when(bucketRegion).hasSeenEvent(event); @@ -253,7 +256,7 @@ public void basicInvalidateReleaseLockIfKeysAndPrimaryLocked() { public void lockKeysAndPrimaryReturnFalseIfDoesNotNeedWriteLock() { BucketRegion bucketRegion = spy(new BucketRegion(regionName, regionAttributes, partitionedRegion, - cache, internalRegionArgs)); + cache, resourceEventNotifier, internalRegionArgs)); doReturn(false).when(bucketRegion).needWriteLock(event); assertThat(bucketRegion.lockKeysAndPrimary(event)).isFalse(); @@ -263,7 +266,7 @@ public void lockKeysAndPrimaryReturnFalseIfDoesNotNeedWriteLock() { public void lockKeysAndPrimaryThrowsIfWaitUntilLockedThrows() { BucketRegion bucketRegion = spy(new BucketRegion(regionName, regionAttributes, partitionedRegion, - cache, internalRegionArgs)); + cache, resourceEventNotifier, internalRegionArgs)); doReturn(keys).when(bucketRegion).getKeysToBeLocked(event); doThrow(regionDestroyedException).when(bucketRegion).waitUntilLocked(keys); @@ -274,7 +277,7 @@ public void lockKeysAndPrimaryThrowsIfWaitUntilLockedThrows() { public void lockKeysAndPrimaryReleaseLockHeldIfDoLockForPrimaryThrows() { BucketRegion bucketRegion = spy(new BucketRegion(regionName, regionAttributes, partitionedRegion, - cache, internalRegionArgs)); + cache, resourceEventNotifier, internalRegionArgs)); doReturn(keys).when(bucketRegion).getKeysToBeLocked(event); doReturn(true).when(bucketRegion).waitUntilLocked(keys); doThrow(new PrimaryBucketException()).when(bucketRegion).doLockForPrimary(false); @@ -288,7 +291,7 @@ public void lockKeysAndPrimaryReleaseLockHeldIfDoLockForPrimaryThrows() { public void lockKeysAndPrimaryReleaseLockHeldIfDoesNotLockForPrimary() { BucketRegion bucketRegion = spy(new BucketRegion(regionName, regionAttributes, partitionedRegion, - cache, internalRegionArgs)); + cache, resourceEventNotifier, internalRegionArgs)); doReturn(keys).when(bucketRegion).getKeysToBeLocked(event); doReturn(true).when(bucketRegion).waitUntilLocked(keys); doReturn(true).when(bucketRegion).doLockForPrimary(false); diff --git a/geode-core/src/test/java/org/apache/geode/internal/cache/DistributedRegionJUnitTest.java b/geode-core/src/test/java/org/apache/geode/internal/cache/DistributedRegionJUnitTest.java index 2f58510b2ab8..3cb15d499b04 100755 --- a/geode-core/src/test/java/org/apache/geode/internal/cache/DistributedRegionJUnitTest.java +++ b/geode-core/src/test/java/org/apache/geode/internal/cache/DistributedRegionJUnitTest.java @@ -40,6 +40,7 @@ import org.apache.geode.internal.cache.ha.ThreadIdentifier; import org.apache.geode.internal.cache.tier.sockets.ClientProxyMembershipID; import org.apache.geode.internal.cache.versions.VersionTag; +import org.apache.geode.management.internal.resource.ResourceEventNotifier; public class DistributedRegionJUnitTest extends AbstractDistributedRegionJUnitTest { @@ -48,8 +49,10 @@ protected void setInternalRegionArguments(InternalRegionArguments ira) {} @Override protected DistributedRegion createAndDefineRegion(boolean isConcurrencyChecksEnabled, - RegionAttributes ra, InternalRegionArguments ira, GemFireCacheImpl cache) { - DistributedRegion region = new DistributedRegion("testRegion", ra, null, cache, ira); + RegionAttributes ra, InternalRegionArguments ira, GemFireCacheImpl cache, + ResourceEventNotifier resourceEventNotifier) { + DistributedRegion region = + new DistributedRegion("testRegion", ra, null, cache, resourceEventNotifier, ira); if (isConcurrencyChecksEnabled) { region.enableConcurrencyChecks(); } diff --git a/geode-core/src/test/java/org/apache/geode/internal/cache/DistributedRegionSearchLoadJUnitTest.java b/geode-core/src/test/java/org/apache/geode/internal/cache/DistributedRegionSearchLoadJUnitTest.java index f260c3f92f16..75af28e9c949 100755 --- a/geode-core/src/test/java/org/apache/geode/internal/cache/DistributedRegionSearchLoadJUnitTest.java +++ b/geode-core/src/test/java/org/apache/geode/internal/cache/DistributedRegionSearchLoadJUnitTest.java @@ -45,6 +45,8 @@ import org.apache.geode.internal.cache.versions.ConcurrentCacheModificationException; import org.apache.geode.internal.cache.versions.VersionStamp; import org.apache.geode.internal.cache.versions.VersionTag; +import org.apache.geode.management.internal.resource.ResourceEventNotifier; +import org.apache.geode.management.internal.resource.ResourceEventNotifierFactory; import org.apache.geode.test.fake.Fakes; @RunWith(PowerMockRunner.class) @@ -53,8 +55,10 @@ public class DistributedRegionSearchLoadJUnitTest { protected DistributedRegion createAndDefineRegion(boolean isConcurrencyChecksEnabled, - RegionAttributes ra, InternalRegionArguments ira, GemFireCacheImpl cache) { - DistributedRegion region = new DistributedRegion("testRegion", ra, null, cache, ira); + RegionAttributes ra, InternalRegionArguments ira, GemFireCacheImpl cache, + ResourceEventNotifier resourceEventNotifier) { + DistributedRegion region = + new DistributedRegion("testRegion", ra, null, cache, resourceEventNotifier, ira); if (isConcurrencyChecksEnabled) { region.enableConcurrencyChecks(); } @@ -113,13 +117,16 @@ protected VersionTag createVersionTag(boolean validVersionTag) { protected DistributedRegion prepare(boolean isConcurrencyChecksEnabled) { GemFireCacheImpl cache = Fakes.cache(); + ResourceEventNotifier resourceEventNotifier = + new ResourceEventNotifierFactory().createDummyResourceEventNotifier(); // create region attributes and internal region arguments RegionAttributes ra = createRegionAttributes(isConcurrencyChecksEnabled); InternalRegionArguments ira = new InternalRegionArguments(); // create a region object - DistributedRegion region = createAndDefineRegion(isConcurrencyChecksEnabled, ra, ira, cache); + DistributedRegion region = + createAndDefineRegion(isConcurrencyChecksEnabled, ra, ira, cache, resourceEventNotifier); if (isConcurrencyChecksEnabled) { region.enableConcurrencyChecks(); } diff --git a/geode-core/src/test/java/org/apache/geode/internal/cache/PartitionedRegionTest.java b/geode-core/src/test/java/org/apache/geode/internal/cache/PartitionedRegionTest.java index 2e1db3511263..a6483cb9b4b0 100644 --- a/geode-core/src/test/java/org/apache/geode/internal/cache/PartitionedRegionTest.java +++ b/geode-core/src/test/java/org/apache/geode/internal/cache/PartitionedRegionTest.java @@ -41,6 +41,7 @@ import org.apache.geode.cache.PartitionAttributesFactory; import org.apache.geode.distributed.internal.membership.InternalDistributedMember; import org.apache.geode.internal.cache.control.InternalResourceManager; +import org.apache.geode.management.internal.resource.ResourceEventNotifier; import org.apache.geode.test.fake.Fakes; public class PartitionedRegionTest { @@ -53,6 +54,7 @@ public class PartitionedRegionTest { @Before public void setup() { InternalCache internalCache = Fakes.cache(); + ResourceEventNotifier resourceEventNotifier = internalCache.getResourceEventNotifier(); InternalResourceManager resourceManager = mock(InternalResourceManager.class, RETURNS_DEEP_STUBS); when(internalCache.getInternalResourceManager()).thenReturn(resourceManager); @@ -60,7 +62,7 @@ public void setup() { attributesFactory.setPartitionAttributes( new PartitionAttributesFactory().setTotalNumBuckets(1).setRedundantCopies(1).create()); partitionedRegion = new PartitionedRegion(regionName, attributesFactory.create(), - null, internalCache, mock(InternalRegionArguments.class)); + null, internalCache, resourceEventNotifier, mock(InternalRegionArguments.class)); } diff --git a/geode-core/src/test/java/org/apache/geode/internal/cache/wan/parallel/ParallelGatewaySenderHelper.java b/geode-core/src/test/java/org/apache/geode/internal/cache/wan/parallel/ParallelGatewaySenderHelper.java index 53529afc95cd..11050a323d3b 100644 --- a/geode-core/src/test/java/org/apache/geode/internal/cache/wan/parallel/ParallelGatewaySenderHelper.java +++ b/geode-core/src/test/java/org/apache/geode/internal/cache/wan/parallel/ParallelGatewaySenderHelper.java @@ -55,6 +55,7 @@ import org.apache.geode.internal.cache.partitioned.RegionAdvisor; import org.apache.geode.internal.cache.wan.AbstractGatewaySender; import org.apache.geode.internal.cache.wan.GatewaySenderEventImpl; +import org.apache.geode.management.internal.resource.ResourceEventNotifier; public class ParallelGatewaySenderHelper { @@ -106,6 +107,7 @@ public static PartitionedRegion createMockQueueRegion(GemFireCacheImpl cache, St } public static BucketRegionQueue createBucketRegionQueue(GemFireCacheImpl cache, + ResourceEventNotifier resourceEventNotifier, PartitionedRegion parentRegion, PartitionedRegion queueRegion, int bucketId) { // Create InternalRegionArguments InternalRegionArguments ira = new InternalRegionArguments(); @@ -143,7 +145,8 @@ public String answer(final InvocationOnMock invocation) throws Throwable { // Create BucketRegionQueue return new BucketRegionQueue( - queueRegion.getBucketName(bucketId), attributes, parentRegion, cache, ira); + queueRegion.getBucketName(bucketId), attributes, parentRegion, cache, resourceEventNotifier, + ira); } public static String getRegionQueueName(String gatewaySenderId) { diff --git a/geode-core/src/test/java/org/apache/geode/internal/cache/wan/parallel/ParallelGatewaySenderQueueJUnitTest.java b/geode-core/src/test/java/org/apache/geode/internal/cache/wan/parallel/ParallelGatewaySenderQueueJUnitTest.java index d03a15c190e5..6d59ff93cacc 100644 --- a/geode-core/src/test/java/org/apache/geode/internal/cache/wan/parallel/ParallelGatewaySenderQueueJUnitTest.java +++ b/geode-core/src/test/java/org/apache/geode/internal/cache/wan/parallel/ParallelGatewaySenderQueueJUnitTest.java @@ -147,7 +147,8 @@ public void testLocalSize() throws Exception { PartitionedRegionDataStore dataStore = mock(PartitionedRegionDataStore.class); when(mockMetaRegion.getDataStore()).thenReturn(dataStore); when(dataStore.getSizeOfLocalPrimaryBuckets()).thenReturn(3); - when(metaRegionFactory.newMetataRegion(any(), any(), any(), any())).thenReturn(mockMetaRegion); + when(metaRegionFactory.newMetataRegion(any(), any(), any(), any(), any())) + .thenReturn(mockMetaRegion); when(cache.createVMRegion(any(), any(), any())).thenReturn(mockMetaRegion); queue.addShadowPartitionedRegionForUserPR(mockPR("region1")); diff --git a/geode-core/src/test/java/org/apache/geode/internal/cache/wan/parallel/ParallelQueueRemovalMessageJUnitTest.java b/geode-core/src/test/java/org/apache/geode/internal/cache/wan/parallel/ParallelQueueRemovalMessageJUnitTest.java index cbb6551b9d8f..2b3b1b2ec677 100644 --- a/geode-core/src/test/java/org/apache/geode/internal/cache/wan/parallel/ParallelQueueRemovalMessageJUnitTest.java +++ b/geode-core/src/test/java/org/apache/geode/internal/cache/wan/parallel/ParallelQueueRemovalMessageJUnitTest.java @@ -54,6 +54,8 @@ import org.apache.geode.internal.cache.wan.GatewaySenderEventImpl; import org.apache.geode.internal.cache.wan.GatewaySenderStats; import org.apache.geode.internal.statistics.DummyStatisticsFactory; +import org.apache.geode.management.internal.resource.ResourceEventNotifier; +import org.apache.geode.management.internal.resource.ResourceEventNotifierFactory; import org.apache.geode.test.fake.Fakes; public class ParallelQueueRemovalMessageJUnitTest { @@ -63,6 +65,7 @@ public class ParallelQueueRemovalMessageJUnitTest { private static final long KEY = 198; private GemFireCacheImpl cache; + private ResourceEventNotifier resourceEventNotifier; private PartitionedRegion queueRegion; private AbstractGatewaySender sender; private PartitionedRegion rootRegion; @@ -73,6 +76,7 @@ public class ParallelQueueRemovalMessageJUnitTest { @Before public void setUpGemFire() { createCache(); + createResourceEventNotifier(); createQueueRegion(); createGatewaySender(); createRootRegion(); @@ -84,6 +88,10 @@ private void createCache() { this.cache = Fakes.cache(); } + private void createResourceEventNotifier() { + resourceEventNotifier = new ResourceEventNotifierFactory().createDummyResourceEventNotifier(); + } + private void createQueueRegion() { // Mock queue region this.queueRegion = @@ -115,7 +123,8 @@ private void createRootRegion() { private void createBucketRegionQueue() { // Create BucketRegionQueue BucketRegionQueue realBucketRegionQueue = ParallelGatewaySenderHelper - .createBucketRegionQueue(this.cache, this.rootRegion, this.queueRegion, BUCKET_ID); + .createBucketRegionQueue(this.cache, resourceEventNotifier, this.rootRegion, + this.queueRegion, BUCKET_ID); this.bucketRegionQueue = spy(realBucketRegionQueue); // (this.queueRegion.getBucketName(BUCKET_ID), attributes, this.rootRegion, this.cache, ira); EntryEventImpl entryEvent = EntryEventImpl.create(this.bucketRegionQueue, Operation.DESTROY, diff --git a/geode-core/src/test/java/org/apache/geode/management/internal/beans/ManagementListenerTest.java b/geode-core/src/test/java/org/apache/geode/management/internal/beans/ManagementListenerTest.java index 9542e122f325..7547f527c21f 100644 --- a/geode-core/src/test/java/org/apache/geode/management/internal/beans/ManagementListenerTest.java +++ b/geode-core/src/test/java/org/apache/geode/management/internal/beans/ManagementListenerTest.java @@ -16,9 +16,9 @@ */ package org.apache.geode.management.internal.beans; -import static org.apache.geode.distributed.internal.ResourceEvent.CACHE_CREATE; -import static org.apache.geode.distributed.internal.ResourceEvent.CACHE_REMOVE; -import static org.apache.geode.distributed.internal.ResourceEvent.SYSTEM_ALERT; +import static org.apache.geode.management.internal.resource.ResourceEvent.CACHE_CREATE; +import static org.apache.geode.management.internal.resource.ResourceEvent.CACHE_REMOVE; +import static org.apache.geode.management.internal.resource.ResourceEvent.SYSTEM_ALERT; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.inOrder; import static org.mockito.Mockito.mock; @@ -35,8 +35,8 @@ import org.mockito.InOrder; import org.apache.geode.distributed.internal.InternalDistributedSystem; -import org.apache.geode.distributed.internal.ResourceEvent; import org.apache.geode.internal.cache.InternalCache; +import org.apache.geode.management.internal.resource.ResourceEvent; import org.apache.geode.test.junit.categories.ManagementTest; /** diff --git a/geode-core/src/test/java/org/apache/geode/management/internal/resource/ConcurrentResourceEventNotifierTest.java b/geode-core/src/test/java/org/apache/geode/management/internal/resource/ConcurrentResourceEventNotifierTest.java new file mode 100644 index 000000000000..3cebe360adc8 --- /dev/null +++ b/geode-core/src/test/java/org/apache/geode/management/internal/resource/ConcurrentResourceEventNotifierTest.java @@ -0,0 +1,74 @@ +/* + * 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.management.internal.resource; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +import org.junit.Before; +import org.junit.Test; + +import org.apache.geode.management.internal.beans.ManagementListener; + +/** + * Unit tests for {@link ConcurrentResourceEventNotifier}. + */ +public class ConcurrentResourceEventNotifierTest { + + private ConcurrentResourceEventNotifier concurrentResourceEventNotifier; + private ManagementListener managementListener; + + @Before + public void setup() { + managementListener = mock(ManagementListener.class); + concurrentResourceEventNotifier = new ConcurrentResourceEventNotifier(); + concurrentResourceEventNotifier.addResourceListener(managementListener); + } + + @Test + public void isAFunctionalCollection() { + assertThat(concurrentResourceEventNotifier.getResourceListeners()) + .containsOnly(managementListener); + + ResourceEventListener mockListener = mock(ResourceEventListener.class); + concurrentResourceEventNotifier.addResourceListener(mockListener); + + assertThat(concurrentResourceEventNotifier.getResourceListeners()) + .containsOnly(managementListener, mockListener); + } + + @Test + public void closeClears() { + concurrentResourceEventNotifier.close(); + + assertThat(concurrentResourceEventNotifier.getResourceListeners()).isEmpty(); + } + + @Test + public void handleResourceEventInvokesOnAllListeners() { + ResourceEventListener mockListener = mock(ResourceEventListener.class); + concurrentResourceEventNotifier.addResourceListener(mockListener); + + ResourceEvent event = ResourceEvent.CACHE_CREATE; + Object resource = new Object(); + + concurrentResourceEventNotifier.handleResourceEvent(event, resource); + + verify(managementListener).handleEvent(eq(event), eq(resource)); + verify(mockListener).handleEvent(eq(event), eq(resource)); + } +} diff --git a/geode-junit/src/main/java/org/apache/geode/test/fake/Fakes.java b/geode-junit/src/main/java/org/apache/geode/test/fake/Fakes.java index 95dea381457e..aad447e86c0f 100644 --- a/geode-junit/src/main/java/org/apache/geode/test/fake/Fakes.java +++ b/geode-junit/src/main/java/org/apache/geode/test/fake/Fakes.java @@ -39,6 +39,7 @@ import org.apache.geode.internal.cache.GemFireCacheImpl; import org.apache.geode.internal.cache.TXManagerImpl; import org.apache.geode.internal.security.SecurityService; +import org.apache.geode.management.internal.resource.ResourceEventNotifierFactory; import org.apache.geode.pdx.PdxInstanceFactory; import org.apache.geode.pdx.internal.TypeRegistry; @@ -93,6 +94,8 @@ public static GemFireCacheImpl cache() { when(cache.createPdxInstanceFactory(any())).thenReturn(pdxInstanceFactory); when(cache.getPdxRegistry()).thenReturn(pdxRegistryMock); when(cache.getTxManager()).thenReturn(txManager); + when(cache.getResourceEventNotifier()) + .thenReturn(new ResourceEventNotifierFactory().createDummyResourceEventNotifier()); when(system.getDistributedMember()).thenReturn(member); when(system.getConfig()).thenReturn(config); diff --git a/geode-wan/src/main/java/org/apache/geode/cache/client/internal/locator/wan/WANFactoryImpl.java b/geode-wan/src/main/java/org/apache/geode/cache/client/internal/locator/wan/WANFactoryImpl.java index 43d38710b534..15cbbdcaf129 100644 --- a/geode-wan/src/main/java/org/apache/geode/cache/client/internal/locator/wan/WANFactoryImpl.java +++ b/geode-wan/src/main/java/org/apache/geode/cache/client/internal/locator/wan/WANFactoryImpl.java @@ -23,6 +23,7 @@ import org.apache.geode.internal.cache.wan.GatewayReceiverFactoryImpl; import org.apache.geode.internal.cache.wan.GatewaySenderFactoryImpl; import org.apache.geode.internal.cache.wan.spi.WANFactory; +import org.apache.geode.management.internal.resource.ResourceEventNotifier; public class WANFactoryImpl implements WANFactory { @@ -45,13 +46,15 @@ public void initialize() { } @Override - public GatewaySenderFactory createGatewaySenderFactory(InternalCache cache) { - return new GatewaySenderFactoryImpl(cache); + public GatewaySenderFactory createGatewaySenderFactory(InternalCache cache, + ResourceEventNotifier resourceEventNotifier) { + return new GatewaySenderFactoryImpl(cache, resourceEventNotifier); } @Override - public GatewayReceiverFactory createGatewayReceiverFactory(InternalCache cache) { - return new GatewayReceiverFactoryImpl(cache); + public GatewayReceiverFactory createGatewayReceiverFactory(InternalCache cache, + ResourceEventNotifier resourceEventNotifier) { + return new GatewayReceiverFactoryImpl(cache, resourceEventNotifier); } @Override diff --git a/geode-wan/src/main/java/org/apache/geode/internal/cache/wan/AbstractRemoteGatewaySender.java b/geode-wan/src/main/java/org/apache/geode/internal/cache/wan/AbstractRemoteGatewaySender.java index d90ea174fc52..da4198ed2fbc 100644 --- a/geode-wan/src/main/java/org/apache/geode/internal/cache/wan/AbstractRemoteGatewaySender.java +++ b/geode-wan/src/main/java/org/apache/geode/internal/cache/wan/AbstractRemoteGatewaySender.java @@ -32,17 +32,20 @@ import org.apache.geode.internal.cache.InternalCache; import org.apache.geode.internal.cache.PoolFactoryImpl; import org.apache.geode.internal.logging.LogService; +import org.apache.geode.management.internal.resource.ResourceEventNotifier; public abstract class AbstractRemoteGatewaySender extends AbstractGatewaySender { private static final Logger logger = LogService.getLogger(); /** used to reduce warning logs in case remote locator is down (#47634) */ - protected int proxyFailureTries = 0; + private int proxyFailureTries; - public AbstractRemoteGatewaySender(InternalCache cache, GatewaySenderAttributes attrs) { - super(cache, attrs); + public AbstractRemoteGatewaySender(InternalCache cache, + ResourceEventNotifier resourceEventNotifier, GatewaySenderAttributes attrs) { + super(cache, resourceEventNotifier, attrs); } + @Override public synchronized void initProxy() { // return if it is being used for WBCL or proxy is already created if (this.remoteDSId == DEFAULT_DISTRIBUTED_SYSTEM_ID @@ -152,7 +155,7 @@ public synchronized void initProxy() { } } - protected boolean logProxyFailure() { + private boolean logProxyFailure() { assert Thread.holdsLock(this); // always log the first failure if (logger.isDebugEnabled() || this.proxyFailureTries == 0) { diff --git a/geode-wan/src/main/java/org/apache/geode/internal/cache/wan/GatewayReceiverFactoryImpl.java b/geode-wan/src/main/java/org/apache/geode/internal/cache/wan/GatewayReceiverFactoryImpl.java index f3b52bfe5b81..93ee7e4195f0 100644 --- a/geode-wan/src/main/java/org/apache/geode/internal/cache/wan/GatewayReceiverFactoryImpl.java +++ b/geode-wan/src/main/java/org/apache/geode/internal/cache/wan/GatewayReceiverFactoryImpl.java @@ -23,12 +23,12 @@ import org.apache.geode.cache.wan.GatewayReceiver; import org.apache.geode.cache.wan.GatewayReceiverFactory; import org.apache.geode.cache.wan.GatewayTransportFilter; -import org.apache.geode.distributed.internal.InternalDistributedSystem; -import org.apache.geode.distributed.internal.ResourceEvent; import org.apache.geode.internal.cache.GemFireCacheImpl; import org.apache.geode.internal.cache.InternalCache; import org.apache.geode.internal.cache.xmlcache.CacheCreation; import org.apache.geode.internal.cache.xmlcache.GatewayReceiverCreation; +import org.apache.geode.management.internal.resource.ResourceEvent; +import org.apache.geode.management.internal.resource.ResourceEventNotifier; /** * @since GemFire 7.0 @@ -49,16 +49,16 @@ public class GatewayReceiverFactoryImpl implements GatewayReceiverFactory { private boolean manualStart = GatewayReceiver.DEFAULT_MANUAL_START; - private List filters = new ArrayList(); + private final List filters = new ArrayList<>(); - private InternalCache cache; + private final InternalCache cache; - public GatewayReceiverFactoryImpl() { - // nothing - } + private final ResourceEventNotifier resourceEventNotifier; - public GatewayReceiverFactoryImpl(InternalCache cache) { + public GatewayReceiverFactoryImpl(InternalCache cache, + ResourceEventNotifier resourceEventNotifier) { this.cache = cache; + this.resourceEventNotifier = resourceEventNotifier; } @Override @@ -129,13 +129,12 @@ public GatewayReceiver create() { GatewayReceiver recv = null; if (this.cache instanceof GemFireCacheImpl) { - recv = new GatewayReceiverImpl(this.cache, this.startPort, this.endPort, this.timeBetPings, + recv = new GatewayReceiverImpl(this.cache, resourceEventNotifier, this.startPort, + this.endPort, this.timeBetPings, this.socketBuffSize, this.bindAdd, this.filters, this.hostnameForSenders, this.manualStart); this.cache.addGatewayReceiver(recv); - InternalDistributedSystem system = - (InternalDistributedSystem) this.cache.getDistributedSystem(); - system.handleResourceEvent(ResourceEvent.GATEWAYRECEIVER_CREATE, recv); + resourceEventNotifier.handleResourceEvent(ResourceEvent.GATEWAYRECEIVER_CREATE, recv); if (!this.manualStart) { try { recv.start(); diff --git a/geode-wan/src/main/java/org/apache/geode/internal/cache/wan/GatewayReceiverImpl.java b/geode-wan/src/main/java/org/apache/geode/internal/cache/wan/GatewayReceiverImpl.java index ef9112a2b3bd..1c479ea1f016 100644 --- a/geode-wan/src/main/java/org/apache/geode/internal/cache/wan/GatewayReceiverImpl.java +++ b/geode-wan/src/main/java/org/apache/geode/internal/cache/wan/GatewayReceiverImpl.java @@ -24,13 +24,13 @@ import org.apache.geode.cache.server.CacheServer; import org.apache.geode.cache.wan.GatewayReceiver; import org.apache.geode.cache.wan.GatewayTransportFilter; -import org.apache.geode.distributed.internal.InternalDistributedSystem; -import org.apache.geode.distributed.internal.ResourceEvent; import org.apache.geode.internal.AvailablePort; import org.apache.geode.internal.cache.CacheServerImpl; import org.apache.geode.internal.cache.InternalCache; import org.apache.geode.internal.logging.LogService; import org.apache.geode.internal.net.SocketCreator; +import org.apache.geode.management.internal.resource.ResourceEvent; +import org.apache.geode.management.internal.resource.ResourceEventNotifier; /** * @since GemFire 7.0 @@ -62,11 +62,13 @@ public class GatewayReceiverImpl implements GatewayReceiver { private final InternalCache cache; - public GatewayReceiverImpl(InternalCache cache, int startPort, int endPort, int timeBetPings, - int buffSize, String bindAdd, List filters, String hostnameForSenders, - boolean manualStart) { - this.cache = cache; + private final ResourceEventNotifier resourceEventNotifier; + public GatewayReceiverImpl(InternalCache cache, ResourceEventNotifier resourceEventNotifier, + int startPort, int endPort, int timeBetPings, int buffSize, String bindAdd, + List filters, String hostnameForSenders, boolean manualStart) { + this.cache = cache; + this.resourceEventNotifier = resourceEventNotifier; this.hostnameForSenders = hostnameForSenders; this.startPort = startPort; this.endPort = endPort; @@ -187,8 +189,7 @@ public void start() throws IOException { logger .info("The GatewayReceiver started on port : {}", this.port); - InternalDistributedSystem system = this.cache.getInternalDistributedSystem(); - system.handleResourceEvent(ResourceEvent.GATEWAYRECEIVER_START, this); + resourceEventNotifier.handleResourceEvent(ResourceEvent.GATEWAYRECEIVER_START, this); } private int getPortToStart() { @@ -224,8 +225,7 @@ public void destroy() { this.cache.removeGatewayReceiver(this); this.cache.removeCacheServer(receiver); } - InternalDistributedSystem system = this.cache.getInternalDistributedSystem(); - system.handleResourceEvent(ResourceEvent.GATEWAYRECEIVER_DESTROY, this); + resourceEventNotifier.handleResourceEvent(ResourceEvent.GATEWAYRECEIVER_DESTROY, this); } public String getBindAddress() { diff --git a/geode-wan/src/main/java/org/apache/geode/internal/cache/wan/GatewaySenderFactoryImpl.java b/geode-wan/src/main/java/org/apache/geode/internal/cache/wan/GatewaySenderFactoryImpl.java index 4a541b9b38df..49bdd9f95817 100644 --- a/geode-wan/src/main/java/org/apache/geode/internal/cache/wan/GatewaySenderFactoryImpl.java +++ b/geode-wan/src/main/java/org/apache/geode/internal/cache/wan/GatewaySenderFactoryImpl.java @@ -35,6 +35,7 @@ import org.apache.geode.internal.cache.xmlcache.ParallelGatewaySenderCreation; import org.apache.geode.internal.cache.xmlcache.SerialGatewaySenderCreation; import org.apache.geode.internal.logging.LogService; +import org.apache.geode.management.internal.resource.ResourceEventNotifier; /** * @since GemFire 7.0 @@ -47,92 +48,112 @@ public class GatewaySenderFactoryImpl implements InternalGatewaySenderFactory { * Used internally to pass the attributes from this factory to the real GatewaySender it is * creating. */ - private GatewaySenderAttributes attrs = new GatewaySenderAttributes(); + private final GatewaySenderAttributes attrs = new GatewaySenderAttributes(); - private InternalCache cache; + private final InternalCache cache; + + private final ResourceEventNotifier resourceEventNotifier; private static final AtomicBoolean GATEWAY_CONNECTION_READ_TIMEOUT_PROPERTY_CHECKED = new AtomicBoolean(false); - public GatewaySenderFactoryImpl(InternalCache cache) { + public GatewaySenderFactoryImpl(InternalCache cache, + ResourceEventNotifier resourceEventNotifier) { this.cache = cache; + this.resourceEventNotifier = resourceEventNotifier; } + @Override public GatewaySenderFactory setParallel(boolean isParallel) { this.attrs.isParallel = isParallel; return this; } + @Override public GatewaySenderFactory setForInternalUse(boolean isForInternalUse) { this.attrs.isForInternalUse = isForInternalUse; return this; } + @Override public GatewaySenderFactory addGatewayEventFilter(GatewayEventFilter filter) { this.attrs.addGatewayEventFilter(filter); return this; } + @Override public GatewaySenderFactory addGatewayTransportFilter(GatewayTransportFilter filter) { this.attrs.addGatewayTransportFilter(filter); return this; } + @Override public GatewaySenderFactory addAsyncEventListener(AsyncEventListener listener) { this.attrs.addAsyncEventListener(listener); return this; } + @Override public GatewaySenderFactory setSocketBufferSize(int socketBufferSize) { this.attrs.socketBufferSize = socketBufferSize; return this; } + @Override public GatewaySenderFactory setSocketReadTimeout(int socketReadTimeout) { this.attrs.socketReadTimeout = socketReadTimeout; return this; } + @Override public GatewaySenderFactory setDiskStoreName(String diskStoreName) { this.attrs.diskStoreName = diskStoreName; return this; } + @Override public GatewaySenderFactory setMaximumQueueMemory(int maximumQueueMemory) { this.attrs.maximumQueueMemory = maximumQueueMemory; return this; } + @Override public GatewaySenderFactory setBatchSize(int batchSize) { this.attrs.batchSize = batchSize; return this; } + @Override public GatewaySenderFactory setBatchTimeInterval(int batchTimeInterval) { this.attrs.batchTimeInterval = batchTimeInterval; return this; } + @Override public GatewaySenderFactory setBatchConflationEnabled(boolean enableBatchConflation) { this.attrs.isBatchConflationEnabled = enableBatchConflation; return this; } + @Override public GatewaySenderFactory setPersistenceEnabled(boolean enablePersistence) { this.attrs.isPersistenceEnabled = enablePersistence; return this; } + @Override public GatewaySenderFactory setAlertThreshold(int threshold) { this.attrs.alertThreshold = threshold; return this; } + @Override public GatewaySenderFactory setManualStart(boolean start) { this.attrs.manualStart = start; return this; } + @Override public GatewaySenderFactory setLocatorDiscoveryCallback(LocatorDiscoveryCallback locCallback) { this.attrs.locatorDiscoveryCallback = locCallback; return this; @@ -153,6 +174,7 @@ public GatewaySenderFactory setDispatcherThreads(int numThreads) { return this; } + @Override public GatewaySenderFactory setParallelFactorForReplicatedRegion(int parallel) { this.attrs.parallelism = parallel; this.attrs.policy = GatewaySender.DEFAULT_ORDER_POLICY; @@ -165,11 +187,13 @@ public GatewaySenderFactory setOrderPolicy(OrderPolicy policy) { return this; } + @Override public GatewaySenderFactory setBucketSorted(boolean isBucketSorted) { this.attrs.isBucketSorted = isBucketSorted; return this; } + @Override public GatewaySender create(String id, int remoteDSId) { int myDSId = InternalDistributedSystem.getAnyInstance().getDistributionManager() .getDistributedSystemId(); @@ -227,14 +251,14 @@ public GatewaySender create(String id, int remoteDSId) { id, this.attrs.getOrderPolicy())); } if (this.cache instanceof GemFireCacheImpl) { - sender = new ParallelGatewaySenderImpl(this.cache, this.attrs); + sender = new ParallelGatewaySenderImpl(cache, resourceEventNotifier, attrs); this.cache.addGatewaySender(sender); if (!this.attrs.isManualStart()) { sender.start(); } } else if (this.cache instanceof CacheCreation) { - sender = new ParallelGatewaySenderCreation(this.cache, this.attrs); + sender = new ParallelGatewaySenderCreation(cache, resourceEventNotifier, attrs); this.cache.addGatewaySender(sender); } } else { @@ -248,20 +272,21 @@ public GatewaySender create(String id, int remoteDSId) { this.attrs.policy = GatewaySender.DEFAULT_ORDER_POLICY; } if (this.cache instanceof GemFireCacheImpl) { - sender = new SerialGatewaySenderImpl(this.cache, this.attrs); + sender = new SerialGatewaySenderImpl(cache, resourceEventNotifier, attrs); this.cache.addGatewaySender(sender); if (!this.attrs.isManualStart()) { sender.start(); } } else if (this.cache instanceof CacheCreation) { - sender = new SerialGatewaySenderCreation(this.cache, this.attrs); + sender = new SerialGatewaySenderCreation(cache, resourceEventNotifier, attrs); this.cache.addGatewaySender(sender); } } return sender; } + @Override public GatewaySender create(String id) { this.attrs.id = id; GatewaySender sender = null; @@ -282,13 +307,13 @@ public GatewaySender create(String id) { } if (this.cache instanceof GemFireCacheImpl) { - sender = new ParallelGatewaySenderImpl(this.cache, this.attrs); + sender = new ParallelGatewaySenderImpl(cache, resourceEventNotifier, attrs); this.cache.addGatewaySender(sender); if (!this.attrs.isManualStart()) { sender.start(); } } else if (this.cache instanceof CacheCreation) { - sender = new ParallelGatewaySenderCreation(this.cache, this.attrs); + sender = new ParallelGatewaySenderCreation(cache, resourceEventNotifier, attrs); this.cache.addGatewaySender(sender); } } else { @@ -296,35 +321,39 @@ public GatewaySender create(String id) { this.attrs.policy = GatewaySender.DEFAULT_ORDER_POLICY; } if (this.cache instanceof GemFireCacheImpl) { - sender = new SerialGatewaySenderImpl(this.cache, this.attrs); + sender = new SerialGatewaySenderImpl(cache, resourceEventNotifier, attrs); this.cache.addGatewaySender(sender); if (!this.attrs.isManualStart()) { sender.start(); } } else if (this.cache instanceof CacheCreation) { - sender = new SerialGatewaySenderCreation(this.cache, this.attrs); + sender = new SerialGatewaySenderCreation(cache, resourceEventNotifier, attrs); this.cache.addGatewaySender(sender); } } return sender; } + @Override public GatewaySenderFactory removeGatewayEventFilter(GatewayEventFilter filter) { this.attrs.eventFilters.remove(filter); return this; } + @Override public GatewaySenderFactory removeGatewayTransportFilter(GatewayTransportFilter filter) { this.attrs.transFilters.remove(filter); return this; } + @Override public GatewaySenderFactory setGatewayEventSubstitutionFilter( GatewayEventSubstitutionFilter filter) { this.attrs.eventSubstitutionFilter = filter; return this; } + @Override public void configureGatewaySender(GatewaySender senderCreation) { this.attrs.isParallel = senderCreation.isParallel(); this.attrs.manualStart = senderCreation.isManualStart(); diff --git a/geode-wan/src/main/java/org/apache/geode/internal/cache/wan/parallel/ParallelGatewaySenderImpl.java b/geode-wan/src/main/java/org/apache/geode/internal/cache/wan/parallel/ParallelGatewaySenderImpl.java index 61f479a67053..c76cd91877fe 100644 --- a/geode-wan/src/main/java/org/apache/geode/internal/cache/wan/parallel/ParallelGatewaySenderImpl.java +++ b/geode-wan/src/main/java/org/apache/geode/internal/cache/wan/parallel/ParallelGatewaySenderImpl.java @@ -22,8 +22,6 @@ import org.apache.geode.cache.wan.GatewayTransportFilter; import org.apache.geode.distributed.internal.DistributionAdvisor.Profile; import org.apache.geode.distributed.internal.DistributionManager; -import org.apache.geode.distributed.internal.InternalDistributedSystem; -import org.apache.geode.distributed.internal.ResourceEvent; import org.apache.geode.internal.cache.DistributedRegion; import org.apache.geode.internal.cache.EntryEventImpl; import org.apache.geode.internal.cache.EventID; @@ -36,6 +34,8 @@ import org.apache.geode.internal.cache.wan.GatewaySenderAttributes; import org.apache.geode.internal.logging.LogService; import org.apache.geode.internal.monitoring.ThreadsMonitoring; +import org.apache.geode.management.internal.resource.ResourceEvent; +import org.apache.geode.management.internal.resource.ResourceEventNotifier; /** * @since GemFire 7.0 @@ -44,8 +44,9 @@ public class ParallelGatewaySenderImpl extends AbstractRemoteGatewaySender { private static final Logger logger = LogService.getLogger(); - public ParallelGatewaySenderImpl(InternalCache cache, GatewaySenderAttributes attrs) { - super(cache, attrs); + public ParallelGatewaySenderImpl(InternalCache cache, ResourceEventNotifier resourceEventNotifier, + GatewaySenderAttributes attrs) { + super(cache, resourceEventNotifier, attrs); } @Override @@ -81,8 +82,7 @@ public void start() { } new UpdateAttributesProcessor(this).distribute(false); - InternalDistributedSystem system = this.cache.getInternalDistributedSystem(); - system.handleResourceEvent(ResourceEvent.GATEWAYSENDER_START, this); + resourceEventNotifier.handleResourceEvent(ResourceEvent.GATEWAYSENDER_START, this); logger.info("Started {}", this); @@ -115,9 +115,7 @@ public void stop() { logger.info("Stopped {}", this); - InternalDistributedSystem system = - (InternalDistributedSystem) this.cache.getDistributedSystem(); - system.handleResourceEvent(ResourceEvent.GATEWAYSENDER_STOP, this); + resourceEventNotifier.handleResourceEvent(ResourceEvent.GATEWAYSENDER_STOP, this); clearTempEventsAfterSenderStopped(); // Keep the eventProcessor around so we can ask it for the regionQueues later. diff --git a/geode-wan/src/main/java/org/apache/geode/internal/cache/wan/serial/SerialGatewaySenderImpl.java b/geode-wan/src/main/java/org/apache/geode/internal/cache/wan/serial/SerialGatewaySenderImpl.java index d5cfe31cbc23..bb49b73be2b8 100644 --- a/geode-wan/src/main/java/org/apache/geode/internal/cache/wan/serial/SerialGatewaySenderImpl.java +++ b/geode-wan/src/main/java/org/apache/geode/internal/cache/wan/serial/SerialGatewaySenderImpl.java @@ -23,8 +23,6 @@ import org.apache.geode.distributed.DistributedLockService; import org.apache.geode.distributed.internal.DistributionAdvisor.Profile; import org.apache.geode.distributed.internal.DistributionManager; -import org.apache.geode.distributed.internal.InternalDistributedSystem; -import org.apache.geode.distributed.internal.ResourceEvent; import org.apache.geode.internal.cache.EntryEventImpl; import org.apache.geode.internal.cache.EventID; import org.apache.geode.internal.cache.InternalCache; @@ -37,6 +35,8 @@ import org.apache.geode.internal.cache.wan.GatewaySenderConfigurationException; import org.apache.geode.internal.logging.LogService; import org.apache.geode.internal.monitoring.ThreadsMonitoring; +import org.apache.geode.management.internal.resource.ResourceEvent; +import org.apache.geode.management.internal.resource.ResourceEventNotifier; /** * @since GemFire 7.0 @@ -45,8 +45,9 @@ public class SerialGatewaySenderImpl extends AbstractRemoteGatewaySender { private static final Logger logger = LogService.getLogger(); - public SerialGatewaySenderImpl(InternalCache cache, GatewaySenderAttributes attrs) { - super(cache, attrs); + public SerialGatewaySenderImpl(InternalCache cache, ResourceEventNotifier resourceEventNotifier, + GatewaySenderAttributes attrs) { + super(cache, resourceEventNotifier, attrs); } @Override @@ -93,8 +94,7 @@ public void start() { } new UpdateAttributesProcessor(this).distribute(false); - InternalDistributedSystem system = this.cache.getInternalDistributedSystem(); - system.handleResourceEvent(ResourceEvent.GATEWAYSENDER_START, this); + resourceEventNotifier.handleResourceEvent(ResourceEvent.GATEWAYSENDER_START, this); logger .info("Started {}", this); @@ -159,9 +159,7 @@ public void stop() { } } - InternalDistributedSystem system = - (InternalDistributedSystem) this.cache.getDistributedSystem(); - system.handleResourceEvent(ResourceEvent.GATEWAYSENDER_STOP, this); + resourceEventNotifier.handleResourceEvent(ResourceEvent.GATEWAYSENDER_STOP, this); this.eventProcessor = null; } diff --git a/geode-wan/src/test/java/org/apache/geode/internal/cache/wan/GatewayReceiverFactoryImplJUnitTest.java b/geode-wan/src/test/java/org/apache/geode/internal/cache/wan/GatewayReceiverFactoryImplJUnitTest.java index d01c874f0145..920021a6755b 100644 --- a/geode-wan/src/test/java/org/apache/geode/internal/cache/wan/GatewayReceiverFactoryImplJUnitTest.java +++ b/geode-wan/src/test/java/org/apache/geode/internal/cache/wan/GatewayReceiverFactoryImplJUnitTest.java @@ -38,6 +38,7 @@ import org.apache.geode.internal.cache.GemFireCacheImpl; import org.apache.geode.internal.cache.InternalCache; import org.apache.geode.internal.cache.xmlcache.CacheCreation; +import org.apache.geode.management.internal.resource.ResourceEventNotifierFactory; import org.apache.geode.test.junit.runners.CategoryWithParameterizedRunnerFactory; @RunWith(Parameterized.class) @@ -59,7 +60,8 @@ public static Collection cacheTypes() throws Exception { @Before public void setUp() { - gatewayReceiverFactory = spy(new GatewayReceiverFactoryImpl(cache)); + gatewayReceiverFactory = spy(new GatewayReceiverFactoryImpl(cache, + new ResourceEventNotifierFactory().createDummyResourceEventNotifier())); gatewayReceiverFactory.setManualStart(true); } diff --git a/geode-wan/src/test/java/org/apache/geode/internal/cache/wan/GatewayReceiverImplJUnitTest.java b/geode-wan/src/test/java/org/apache/geode/internal/cache/wan/GatewayReceiverImplJUnitTest.java index 2d9b8ecc256a..d919e5edf138 100644 --- a/geode-wan/src/test/java/org/apache/geode/internal/cache/wan/GatewayReceiverImplJUnitTest.java +++ b/geode-wan/src/test/java/org/apache/geode/internal/cache/wan/GatewayReceiverImplJUnitTest.java @@ -37,6 +37,7 @@ import org.apache.geode.internal.cache.CacheServerImpl; import org.apache.geode.internal.cache.InternalCache; import org.apache.geode.internal.net.SocketCreator; +import org.apache.geode.management.internal.resource.ResourceEventNotifierFactory; public class GatewayReceiverImplJUnitTest { @@ -44,7 +45,9 @@ public class GatewayReceiverImplJUnitTest { public void getHostOnUnstartedGatewayShouldReturnLocalhost() throws UnknownHostException { InternalCache cache = mock(InternalCache.class); GatewayReceiverImpl gateway = - new GatewayReceiverImpl(cache, 2000, 2001, 5, 100, null, null, null, true); + new GatewayReceiverImpl(cache, + new ResourceEventNotifierFactory().createDummyResourceEventNotifier(), 2000, 2001, 5, + 100, null, null, null, true); assertEquals(SocketCreator.getLocalHost().getHostName(), gateway.getHost()); } @@ -57,7 +60,9 @@ public void getHostOnRunningGatewayShouldReturnCacheServerAddress() throws IOExc when(server.getExternalAddress()).thenReturn("hello"); when(cache.addCacheServer(eq(true))).thenReturn(server); GatewayReceiverImpl gateway = - new GatewayReceiverImpl(cache, 2000, 2001, 5, 100, null, null, null, true); + new GatewayReceiverImpl(cache, + new ResourceEventNotifierFactory().createDummyResourceEventNotifier(), 2000, 2001, 5, + 100, null, null, null, true); gateway.start(); assertEquals("hello", gateway.getHost()); } @@ -72,7 +77,9 @@ public void destroyCalledOnRunningGatewayReceiverShouldThrowException() throws I when(server.isRunning()).thenReturn(true); when(cache.addCacheServer(eq(true))).thenReturn(server); GatewayReceiverImpl gateway = - new GatewayReceiverImpl(cache, 2000, 2001, 5, 100, null, null, null, true); + new GatewayReceiverImpl(cache, + new ResourceEventNotifierFactory().createDummyResourceEventNotifier(), 2000, 2001, 5, + 100, null, null, null, true); gateway.start(); try { gateway.destroy(); @@ -92,7 +99,9 @@ public void destroyCalledOnStoppedGatewayReceiverShouldRemoveReceiverFromCacheSe when(server.getExternalAddress()).thenReturn("hello"); when(cache.addCacheServer(eq(true))).thenReturn(server); GatewayReceiverImpl gateway = - new GatewayReceiverImpl(cache, 2000, 2001, 5, 100, null, null, null, true); + new GatewayReceiverImpl(cache, + new ResourceEventNotifierFactory().createDummyResourceEventNotifier(), 2000, 2001, 5, + 100, null, null, null, true); gateway.start(); // sender is mocked already to say running is false gateway.destroy(); @@ -109,7 +118,9 @@ public void destroyCalledOnStoppedGatewayReceiverShouldRemoveReceiverFromReceive when(server.getExternalAddress()).thenReturn("hello"); when(cache.addCacheServer(eq(true))).thenReturn(server); GatewayReceiverImpl gateway = - new GatewayReceiverImpl(cache, 2000, 2001, 5, 100, null, null, null, true); + new GatewayReceiverImpl(cache, + new ResourceEventNotifierFactory().createDummyResourceEventNotifier(), 2000, 2001, 5, + 100, null, null, null, true); gateway.start(); // sender is mocked already to say running is false gateway.destroy(); @@ -123,7 +134,9 @@ public void testFailToStartWith2NextPorts() throws IOException { when(cache.addCacheServer(eq(true))).thenReturn(server); doThrow(new SocketException("Address already in use")).when(server).start(); GatewayReceiverImpl gateway = - new GatewayReceiverImpl(cache, 2000, 2001, 5, 100, null, null, null, true); + new GatewayReceiverImpl(cache, + new ResourceEventNotifierFactory().createDummyResourceEventNotifier(), 2000, 2001, 5, + 100, null, null, null, true); assertThatThrownBy(() -> gateway.start()).isInstanceOf(GatewayReceiverException.class) .hasMessageContaining("No available free port found in the given range"); verify(server, times(2)).start(); @@ -136,7 +149,9 @@ public void testFailToStartWithSamePort() throws IOException { when(cache.addCacheServer(eq(true))).thenReturn(server); doThrow(new SocketException("Address already in use")).when(server).start(); GatewayReceiverImpl gateway = - new GatewayReceiverImpl(cache, 2000, 2000, 5, 100, null, null, null, true); + new GatewayReceiverImpl(cache, + new ResourceEventNotifierFactory().createDummyResourceEventNotifier(), 2000, 2000, 5, + 100, null, null, null, true); assertThatThrownBy(() -> gateway.start()).isInstanceOf(GatewayReceiverException.class) .hasMessageContaining("No available free port found in the given range"); verify(server, times(1)).start(); @@ -149,7 +164,9 @@ public void testFailToStartWithARangeOfPorts() throws IOException { when(cache.addCacheServer(eq(true))).thenReturn(server); doThrow(new SocketException("Address already in use")).when(server).start(); GatewayReceiverImpl gateway = - new GatewayReceiverImpl(cache, 2000, 2100, 5, 100, null, null, null, true); + new GatewayReceiverImpl(cache, + new ResourceEventNotifierFactory().createDummyResourceEventNotifier(), 2000, 2100, 5, + 100, null, null, null, true); assertThatThrownBy(() -> gateway.start()).isInstanceOf(GatewayReceiverException.class) .hasMessageContaining("No available free port found in the given range"); assertTrue(gateway.getPort() == 0); @@ -173,7 +190,9 @@ public void testSuccessToStartAtSpecifiedPort() throws IOException { return 0; }).when(server).start(); GatewayReceiverImpl gateway = - new GatewayReceiverImpl(cache, 2000, 2010, 5, 100, null, null, null, true); + new GatewayReceiverImpl(cache, + new ResourceEventNotifierFactory().createDummyResourceEventNotifier(), 2000, 2010, 5, + 100, null, null, null, true); gateway.start(); assertTrue(gateway.getPort() >= 2000); assertEquals(2, callCount.get()); From 488dbffd5325365e0b8145adcff07b28bd1bb732 Mon Sep 17 00:00:00 2001 From: Kirk Lund Date: Fri, 11 Jan 2019 15:49:08 -0800 Subject: [PATCH 2/2] GEODE-6232: Remove ReadWriteLock from ManagementListener --- .../geode/cache30/TXDistributedDUnitTest.java | 4 +- .../internal/cache/GemFireCacheImpl.java | 2 +- .../internal/beans/ManagementListener.java | 25 ++-- .../ConcurrentResourceEventNotifier.java | 16 ++- .../resource/DummyResourceEventNotifier.java | 13 +- .../resource/QueuedResourceEventNotifier.java | 121 ++++++++++++++++++ .../resource/ResourceEventNotifier.java | 16 ++- .../ConcurrentResourceEventNotifierTest.java | 12 +- .../QueuedResourceEventNotifierTest.java | 115 +++++++++++++++++ 9 files changed, 293 insertions(+), 31 deletions(-) create mode 100644 geode-core/src/main/java/org/apache/geode/management/internal/resource/QueuedResourceEventNotifier.java create mode 100644 geode-core/src/test/java/org/apache/geode/management/internal/resource/QueuedResourceEventNotifierTest.java diff --git a/geode-core/src/distributedTest/java/org/apache/geode/cache30/TXDistributedDUnitTest.java b/geode-core/src/distributedTest/java/org/apache/geode/cache30/TXDistributedDUnitTest.java index e7b5cea1940c..5639a9be6e9e 100644 --- a/geode-core/src/distributedTest/java/org/apache/geode/cache30/TXDistributedDUnitTest.java +++ b/geode-core/src/distributedTest/java/org/apache/geode/cache30/TXDistributedDUnitTest.java @@ -1389,7 +1389,7 @@ public void run2() { af.setDiskStoreName(diskStoreName); gfc.createVMRegion(rgnName1, af.create(), ira); gfc.createVMRegion(rgnName2, af.create(), ira); - gfc.getResourceEventNotifier().addResourceListener(new ShutdownListener()); + gfc.getResourceEventNotifier().addResourceEventListener(new ShutdownListener()); } catch (IOException ioe) { fail(ioe.toString()); } catch (TimeoutException e) { @@ -1463,7 +1463,7 @@ public void run2() { @Override public Object call() throws Exception { Collection resourceListeners = - getCache().getResourceEventNotifier().getResourceListeners(); + getCache().getResourceEventNotifier().getResourceEventListeners(); for (ResourceEventListener l : resourceListeners) { if (l instanceof ShutdownListener) { ShutdownListener shutListener = (ShutdownListener) l; diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/GemFireCacheImpl.java b/geode-core/src/main/java/org/apache/geode/internal/cache/GemFireCacheImpl.java index 20f5c2dcbace..f3a036573cde 100755 --- a/geode-core/src/main/java/org/apache/geode/internal/cache/GemFireCacheImpl.java +++ b/geode-core/src/main/java/org/apache/geode/internal/cache/GemFireCacheImpl.java @@ -875,7 +875,7 @@ private GemFireCacheImpl(boolean isClient, PoolFactory pf, InternalDistributedSy if (!this.isClient && PoolManager.getAll().isEmpty()) { // We only support management on members of a distributed system resourceEventNotifier = new ResourceEventNotifierFactory().createResourceEventNotifier(); - resourceEventNotifier.addResourceListener(new ManagementListener(this.system)); + resourceEventNotifier.addResourceEventListener(new ManagementListener(this.system)); } else { resourceEventNotifier = new ResourceEventNotifierFactory().createDummyResourceEventNotifier(); diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/beans/ManagementListener.java b/geode-core/src/main/java/org/apache/geode/management/internal/beans/ManagementListener.java index b2acc30e4598..1916b252862d 100644 --- a/geode-core/src/main/java/org/apache/geode/management/internal/beans/ManagementListener.java +++ b/geode-core/src/main/java/org/apache/geode/management/internal/beans/ManagementListener.java @@ -103,12 +103,17 @@ public void handleEvent(ResourceEvent event, Object resource) { if (!shouldProceed(event)) { return; } + // try { + // if (event == ResourceEvent.CACHE_CREATE || event == ResourceEvent.CACHE_REMOVE) { + // readWriteLock.writeLock().lockInterruptibly(); + // } else if (event != ResourceEvent.SYSTEM_ALERT) { + // readWriteLock.readLock().lockInterruptibly(); + // } + // } catch (InterruptedException e) { + // system.getCancelCriterion().checkCancelInProgress(null); + // throw new RuntimeException(e); + // } try { - if (event == ResourceEvent.CACHE_CREATE || event == ResourceEvent.CACHE_REMOVE) { - readWriteLock.writeLock().lock(); - } else if (event != ResourceEvent.SYSTEM_ALERT) { - readWriteLock.readLock().lock(); - } switch (event) { case CACHE_CREATE: InternalCache createdCache = (InternalCache) resource; @@ -223,11 +228,11 @@ public void handleEvent(ResourceEvent event, Object resource) { break; } } finally { - if (event == ResourceEvent.CACHE_CREATE || event == ResourceEvent.CACHE_REMOVE) { - readWriteLock.writeLock().unlock(); - } else if (event != ResourceEvent.SYSTEM_ALERT) { - readWriteLock.readLock().unlock(); - } + // if (event == ResourceEvent.CACHE_CREATE || event == ResourceEvent.CACHE_REMOVE) { + // readWriteLock.writeLock().unlock(); + // } else if (event != ResourceEvent.SYSTEM_ALERT) { + // readWriteLock.readLock().unlock(); + // } } } diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/resource/ConcurrentResourceEventNotifier.java b/geode-core/src/main/java/org/apache/geode/management/internal/resource/ConcurrentResourceEventNotifier.java index 431440bda736..e216e32aaa38 100644 --- a/geode-core/src/main/java/org/apache/geode/management/internal/resource/ConcurrentResourceEventNotifier.java +++ b/geode-core/src/main/java/org/apache/geode/management/internal/resource/ConcurrentResourceEventNotifier.java @@ -17,6 +17,8 @@ import java.util.Collections; import java.util.HashSet; import java.util.Set; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Future; import org.apache.logging.log4j.Logger; @@ -39,21 +41,25 @@ public class ConcurrentResourceEventNotifier implements ResourceEventNotifier { } @Override - public void addResourceListener(ResourceEventListener listener) { + public void addResourceEventListener(ResourceEventListener listener) { resourceListeners.add(listener); } @Override - public Set getResourceListeners() { + public Set getResourceEventListeners() { return Collections.unmodifiableSet(resourceListeners); } @Override public void handleResourceEvent(ResourceEvent event, Object resource) { - if (resourceListeners.size() == 0) { - return; - } notifyResourceEventListeners(event, resource); + + } + + @Override + public Future handleResourceEventAsync(ResourceEvent event, Object resource) { + handleResourceEvent(event, resource); + return CompletableFuture.completedFuture(null); } @Override diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/resource/DummyResourceEventNotifier.java b/geode-core/src/main/java/org/apache/geode/management/internal/resource/DummyResourceEventNotifier.java index 5ae53137f02f..be3bc64f194b 100644 --- a/geode-core/src/main/java/org/apache/geode/management/internal/resource/DummyResourceEventNotifier.java +++ b/geode-core/src/main/java/org/apache/geode/management/internal/resource/DummyResourceEventNotifier.java @@ -16,6 +16,8 @@ import java.util.Collections; import java.util.Set; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Future; /** * No-op implementation of {@link ResourceEventNotifier}. @@ -27,18 +29,21 @@ public class DummyResourceEventNotifier implements ResourceEventNotifier { } @Override - public void addResourceListener(ResourceEventListener listener) { + public void addResourceEventListener(ResourceEventListener listener) { // nothing } @Override - public Set getResourceListeners() { + public Set getResourceEventListeners() { return Collections.emptySet(); } @Override - public void handleResourceEvent(ResourceEvent event, Object resource) { - // nothing + public void handleResourceEvent(ResourceEvent event, Object resource) {} + + @Override + public Future handleResourceEventAsync(ResourceEvent event, Object resource) { + return CompletableFuture.completedFuture(null); } @Override diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/resource/QueuedResourceEventNotifier.java b/geode-core/src/main/java/org/apache/geode/management/internal/resource/QueuedResourceEventNotifier.java new file mode 100644 index 000000000000..c2250486b921 --- /dev/null +++ b/geode-core/src/main/java/org/apache/geode/management/internal/resource/QueuedResourceEventNotifier.java @@ -0,0 +1,121 @@ +/* + * 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.management.internal.resource; + +import java.util.Collections; +import java.util.List; +import java.util.Set; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CopyOnWriteArraySet; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; + +import org.apache.logging.log4j.Logger; + +import org.apache.geode.annotations.TestingOnly; +import org.apache.geode.internal.logging.LogService; +import org.apache.geode.management.ManagementException; +import org.apache.geode.security.GemFireSecurityException; + +public class QueuedResourceEventNotifier implements ResourceEventNotifier { + private static final Logger logger = LogService.getLogger(); + + private final ExecutorService executorService; + private final Set resourceListeners; + + private boolean running = true; + + QueuedResourceEventNotifier() { + executorService = Executors.newCachedThreadPool(); + resourceListeners = new CopyOnWriteArraySet<>(); + } + + @Override + public void addResourceEventListener(ResourceEventListener listener) { + resourceListeners.add(listener); + } + + @Override + public Set getResourceEventListeners() { + return Collections.unmodifiableSet(resourceListeners); + } + + @Override + public void handleResourceEvent(ResourceEvent event, Object resource) { + if (false) { + notifyResourceEventListeners(event, resource); + } else { + try { + handleResourceEventAsync(event, resource).get(); + + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } catch (ExecutionException e) { + Throwable cause = e.getCause(); + if (cause instanceof RuntimeException) { + throw (RuntimeException) cause; + } else if (cause instanceof Error) { + throw (Error) cause; + } else { + throw new RuntimeException("Exception while handling ResourceEvent " + event, cause); + } + } + } + } + + @Override + public synchronized Future handleResourceEventAsync(ResourceEvent event, Object resource) { + if (running) { + return CompletableFuture.runAsync(() -> notifyResourceEventListeners(event, resource), + executorService); + } + return CompletableFuture.completedFuture(null); + } + + @Override + public synchronized void close() { + running = false; + resourceListeners.clear(); + shutdown(); + } + + @TestingOnly + List shutdown() { + return executorService.shutdownNow(); + } + + /** + * Notifies all resource event listeners. All exceptions are caught here and only a warning + * message is printed in the log + * + * @param event Enumeration depicting particular resource event + * @param resource the actual resource object. + */ + private void notifyResourceEventListeners(ResourceEvent event, Object resource) { + for (ResourceEventListener listener : resourceListeners) { + try { + listener.handleEvent(event, resource); + } catch (GemFireSecurityException | ManagementException ex) { + if (event == ResourceEvent.CACHE_CREATE) { + throw ex; + } else { + logger.warn(ex.getMessage(), ex); + } + } + } + } +} diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/resource/ResourceEventNotifier.java b/geode-core/src/main/java/org/apache/geode/management/internal/resource/ResourceEventNotifier.java index d366972b165b..10b1efb563b8 100644 --- a/geode-core/src/main/java/org/apache/geode/management/internal/resource/ResourceEventNotifier.java +++ b/geode-core/src/main/java/org/apache/geode/management/internal/resource/ResourceEventNotifier.java @@ -15,15 +15,16 @@ package org.apache.geode.management.internal.resource; import java.util.Set; +import java.util.concurrent.Future; /** * Notifies {@link ResourceEventListener}s when {@link ResourceEvent}s occur. */ -public interface ResourceEventNotifier { +public interface ResourceEventNotifier extends AutoCloseable { - void addResourceListener(ResourceEventListener listener); + void addResourceEventListener(ResourceEventListener listener); - Set getResourceListeners(); + Set getResourceEventListeners(); /** * Handles a particular event associated with a resource @@ -33,5 +34,14 @@ public interface ResourceEventNotifier { */ void handleResourceEvent(ResourceEvent event, Object resource); + /** + * Handles a particular event associated with a resource, possibly asynchronously. + * + * @param event Resource event + * @param resource resource on which event is generated + */ + Future handleResourceEventAsync(ResourceEvent event, Object resource); + + @Override void close(); } diff --git a/geode-core/src/test/java/org/apache/geode/management/internal/resource/ConcurrentResourceEventNotifierTest.java b/geode-core/src/test/java/org/apache/geode/management/internal/resource/ConcurrentResourceEventNotifierTest.java index 3cebe360adc8..a92803fc6085 100644 --- a/geode-core/src/test/java/org/apache/geode/management/internal/resource/ConcurrentResourceEventNotifierTest.java +++ b/geode-core/src/test/java/org/apache/geode/management/internal/resource/ConcurrentResourceEventNotifierTest.java @@ -36,18 +36,18 @@ public class ConcurrentResourceEventNotifierTest { public void setup() { managementListener = mock(ManagementListener.class); concurrentResourceEventNotifier = new ConcurrentResourceEventNotifier(); - concurrentResourceEventNotifier.addResourceListener(managementListener); + concurrentResourceEventNotifier.addResourceEventListener(managementListener); } @Test public void isAFunctionalCollection() { - assertThat(concurrentResourceEventNotifier.getResourceListeners()) + assertThat(concurrentResourceEventNotifier.getResourceEventListeners()) .containsOnly(managementListener); ResourceEventListener mockListener = mock(ResourceEventListener.class); - concurrentResourceEventNotifier.addResourceListener(mockListener); + concurrentResourceEventNotifier.addResourceEventListener(mockListener); - assertThat(concurrentResourceEventNotifier.getResourceListeners()) + assertThat(concurrentResourceEventNotifier.getResourceEventListeners()) .containsOnly(managementListener, mockListener); } @@ -55,13 +55,13 @@ public void isAFunctionalCollection() { public void closeClears() { concurrentResourceEventNotifier.close(); - assertThat(concurrentResourceEventNotifier.getResourceListeners()).isEmpty(); + assertThat(concurrentResourceEventNotifier.getResourceEventListeners()).isEmpty(); } @Test public void handleResourceEventInvokesOnAllListeners() { ResourceEventListener mockListener = mock(ResourceEventListener.class); - concurrentResourceEventNotifier.addResourceListener(mockListener); + concurrentResourceEventNotifier.addResourceEventListener(mockListener); ResourceEvent event = ResourceEvent.CACHE_CREATE; Object resource = new Object(); diff --git a/geode-core/src/test/java/org/apache/geode/management/internal/resource/QueuedResourceEventNotifierTest.java b/geode-core/src/test/java/org/apache/geode/management/internal/resource/QueuedResourceEventNotifierTest.java new file mode 100644 index 000000000000..c015cb0640f1 --- /dev/null +++ b/geode-core/src/test/java/org/apache/geode/management/internal/resource/QueuedResourceEventNotifierTest.java @@ -0,0 +1,115 @@ +/* + * 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.management.internal.resource; + +import static org.apache.geode.test.awaitility.GeodeAwaitility.getTimeout; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.timeout; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyZeroInteractions; + +import java.util.List; +import java.util.concurrent.Future; + +import org.junit.Before; +import org.junit.Test; + +public class QueuedResourceEventNotifierTest { + + private static final long TIMEOUT_MILLIS = getTimeout().getValueInMS(); + + private QueuedResourceEventNotifier notifier; + + @Before + public void setup() { + notifier = new QueuedResourceEventNotifier(); + } + + @Test + public void isAFunctionalCollection() { + assertThat(notifier.getResourceEventListeners()).isEmpty(); + + ResourceEventListener mockListener = mock(ResourceEventListener.class); + notifier.addResourceEventListener(mockListener); + + assertThat(notifier.getResourceEventListeners()) + .containsOnly(mockListener); + } + + @Test + public void closeClears() { + notifier.close(); + + assertThat(notifier.getResourceEventListeners()).isEmpty(); + } + + @Test + public void closeStopsFunctioning() { + notifier.close(); + + ResourceEventListener mock = mock(ResourceEventListener.class); + notifier.addResourceEventListener(mock); + + notifier.close(); + assertThat(notifier.getResourceEventListeners()).isEmpty(); + + notifier.handleResourceEvent(ResourceEvent.REGION_CREATE, new Object()); + verifyZeroInteractions(mock); + } + + @Test + public void furtherEventsWillNotTriggerAfterClose() { + notifier.addResourceEventListener(getSlowResourceEventListener()); + + Future future1 = notifier.handleResourceEventAsync(ResourceEvent.REGION_CREATE, null); + Future future2 = notifier.handleResourceEventAsync(ResourceEvent.REGION_CREATE, null); + + List shutdownEvents = notifier.shutdown(); + assertThat(shutdownEvents).hasSize(1); + + assertThat(future1.isDone()).isTrue(); + assertThat(future2.isDone()).isFalse(); + + } + + @Test + public void handleResourceEventInvokesOnAllListeners() { + ResourceEventListener mockListener = mock(ResourceEventListener.class); + ResourceEventListener mockListener2 = mock(ResourceEventListener.class); + + notifier.addResourceEventListener(mockListener); + notifier.addResourceEventListener(mockListener2); + + ResourceEvent event = ResourceEvent.CACHE_CREATE; + Object resource = new Object(); + + notifier.handleResourceEvent(event, resource); + + verify(mockListener, timeout(TIMEOUT_MILLIS)).handleEvent(eq(event), eq(resource)); + verify(mockListener2, timeout(TIMEOUT_MILLIS)).handleEvent(eq(event), eq(resource)); + } + + private ResourceEventListener getSlowResourceEventListener() { + return (event, resource) -> { + try { + Thread.sleep(Long.MAX_VALUE); + } catch (InterruptedException e) { + // ok + } + }; + } +}