blob: a82a7fb01797c140ff2e15f9ccd8578571a5d411 [file] [log] [blame]
/*
* 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.beans;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.apache.geode.CancelCriterion;
import org.apache.geode.annotations.VisibleForTesting;
import org.apache.geode.cache.DiskStore;
import org.apache.geode.cache.Region;
import org.apache.geode.cache.asyncqueue.AsyncEventQueue;
import org.apache.geode.cache.server.CacheServer;
import org.apache.geode.cache.wan.GatewayReceiver;
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;
/**
* This Listener listens on various resource creation in GemFire and create/destroys GemFire
* specific MBeans accordingly
*/
public class ManagementListener implements ResourceEventsListener {
private final InternalDistributedSystem system;
private final CancelCriterion cancelCriterion;
/**
* Adapter to co-ordinate between GemFire and Federation framework
*/
private final ManagementAdapter adapter;
/**
* ReadWriteLock to protect between handling cache creation/removal vs other notifications
*/
private final ReadWriteLock readWriteLock;
public ManagementListener(InternalDistributedSystem system) {
this(system.getCancelCriterion(), system, new ManagementAdapter(),
new ReentrantReadWriteLock());
}
@VisibleForTesting
ManagementListener(CancelCriterion cancelCriterion, InternalDistributedSystem system,
ManagementAdapter adapter,
ReadWriteLock readWriteLock) {
this.cancelCriterion = cancelCriterion;
this.system = system;
this.adapter = adapter;
this.readWriteLock = readWriteLock;
}
/**
* Checks various conditions which might arise due to race condition for lock of
* GemFireCacheImpl.class which is obtained while GemFireCacheImpl constructor, cache.close(),
* DistributedSystem.disconnect().
*
* As ManagementService creation logic is called in cache.init() method it leaves a small window
* of loosing the lock of GemFireCacheImpl.class
*
* These checks ensures that something unwanted has not happened during that small window
*
* @return true or false depending on the status of Cache and System
*/
boolean shouldProceed(ResourceEvent event) {
InternalDistributedSystem.getConnectedInstance();
// CACHE_REMOVE is a special event. ForcedDisconnectException may raise this event.
if (!system.isConnected() && !event.equals(ResourceEvent.CACHE_REMOVE)) {
return false;
}
InternalCache currentCache = system.getCache();
if (currentCache == null) {
return false;
}
return !currentCache.isClosed();
}
/**
* Handles various GFE resource life-cycle methods vis-a-vis Management and Monitoring
*
* It checks for race conditions cases by calling shouldProceed();
*
* @param event Management event for which invocation has happened
* @param resource the GFE resource type
*/
@Override
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) {
// prefer CancelException if shutting down
cancelCriterion.checkCancelInProgress(e);
throw new RuntimeException(e);
}
try {
switch (event) {
case CACHE_CREATE:
InternalCache createdCache = (InternalCache) resource;
adapter.handleCacheCreation(createdCache);
break;
case CACHE_REMOVE:
InternalCache removedCache = (InternalCache) resource;
adapter.handleCacheRemoval(removedCache);
break;
case REGION_CREATE:
Region createdRegion = (Region) resource;
adapter.handleRegionCreation(createdRegion);
break;
case REGION_REMOVE:
Region removedRegion = (Region) resource;
adapter.handleRegionRemoval(removedRegion);
break;
case DISKSTORE_CREATE:
DiskStore createdDisk = (DiskStore) resource;
adapter.handleDiskCreation(createdDisk);
break;
case DISKSTORE_REMOVE:
DiskStore removedDisk = (DiskStore) resource;
adapter.handleDiskRemoval(removedDisk);
break;
case GATEWAYRECEIVER_CREATE:
GatewayReceiver createdRecv = (GatewayReceiver) resource;
adapter.handleGatewayReceiverCreate(createdRecv);
break;
case GATEWAYRECEIVER_DESTROY:
GatewayReceiver destroyedRecv = (GatewayReceiver) resource;
adapter.handleGatewayReceiverDestroy(destroyedRecv);
break;
case GATEWAYRECEIVER_START:
GatewayReceiver startedRecv = (GatewayReceiver) resource;
adapter.handleGatewayReceiverStart(startedRecv);
break;
case GATEWAYRECEIVER_STOP:
GatewayReceiver stoppededRecv = (GatewayReceiver) resource;
adapter.handleGatewayReceiverStop(stoppededRecv);
break;
case GATEWAYSENDER_CREATE:
GatewaySender sender = (GatewaySender) resource;
adapter.handleGatewaySenderCreation(sender);
break;
case GATEWAYSENDER_START:
GatewaySender startedSender = (GatewaySender) resource;
adapter.handleGatewaySenderStart(startedSender);
break;
case GATEWAYSENDER_STOP:
GatewaySender stoppedSender = (GatewaySender) resource;
adapter.handleGatewaySenderStop(stoppedSender);
break;
case GATEWAYSENDER_PAUSE:
GatewaySender pausedSender = (GatewaySender) resource;
adapter.handleGatewaySenderPaused(pausedSender);
break;
case GATEWAYSENDER_RESUME:
GatewaySender resumedSender = (GatewaySender) resource;
adapter.handleGatewaySenderResumed(resumedSender);
break;
case GATEWAYSENDER_REMOVE:
GatewaySender removedSender = (GatewaySender) resource;
adapter.handleGatewaySenderRemoved(removedSender);
break;
case LOCKSERVICE_CREATE:
DLockService createdLockService = (DLockService) resource;
adapter.handleLockServiceCreation(createdLockService);
break;
case LOCKSERVICE_REMOVE:
DLockService removedLockService = (DLockService) resource;
adapter.handleLockServiceRemoval(removedLockService);
break;
case MANAGER_CREATE:
adapter.handleManagerCreation();
break;
case MANAGER_START:
adapter.handleManagerStart();
break;
case MANAGER_STOP:
adapter.handleManagerStop();
break;
case ASYNCEVENTQUEUE_CREATE:
AsyncEventQueue queue = (AsyncEventQueue) resource;
adapter.handleAsyncEventQueueCreation(queue);
break;
case ASYNCEVENTQUEUE_REMOVE:
AsyncEventQueue removedQueue = (AsyncEventQueue) resource;
adapter.handleAsyncEventQueueRemoval(removedQueue);
break;
case SYSTEM_ALERT:
AlertDetails details = (AlertDetails) resource;
adapter.handleSystemNotification(details);
break;
case CACHE_SERVER_START:
CacheServer startedServer = (CacheServer) resource;
adapter.handleCacheServerStart(startedServer);
break;
case CACHE_SERVER_STOP:
CacheServer stoppedServer = (CacheServer) resource;
adapter.handleCacheServerStop(stoppedServer);
break;
case LOCATOR_START:
Locator loc = (Locator) resource;
adapter.handleLocatorStart(loc);
break;
case CACHE_SERVICE_CREATE:
CacheService service = (CacheService) resource;
adapter.handleCacheServiceCreation(service);
break;
default:
break;
}
} finally {
if (event == ResourceEvent.CACHE_CREATE || event == ResourceEvent.CACHE_REMOVE) {
readWriteLock.writeLock().unlock();
} else if (event != ResourceEvent.SYSTEM_ALERT) {
readWriteLock.readLock().unlock();
}
}
}
}