Search in sources :

Example 16 with InterProcessLock

use of org.apache.curator.framework.recipes.locks.InterProcessLock in project coprhd-controller by CoprHD.

the class DataCollectionJobConsumer method triggerScanning.

/**
 * 1. refreshConnections - needs to get called on each Controller, before acquiring lock.
 * 2. Try to acquire lock, if found
 * 3. Acquiring lock is not made as a Blocking Call, hence Controllers will return immediately,
 * if lock not found
 * 3. If lock found, spawn a new thread to do triggerScanning.
 * 4. Release lock immediately.
 */
private void triggerScanning(DataCollectionScanJob job) throws Exception {
    _logger.info("Started scanning Providers : triggerScanning()");
    List<URI> providerList = job.getProviders();
    String providerType = null;
    if (!providerList.isEmpty()) {
        providerType = _dbClient.queryObject(StorageProvider.class, providerList.iterator().next()).getInterfaceType();
    }
    _jobScheduler.refreshProviderConnections(providerType);
    List<URI> allProviderURI = _dbClient.queryByType(StorageProvider.class, true);
    List<StorageProvider> allProvidersAllTypes = _dbClient.queryObject(StorageProvider.class, allProviderURI);
    List<StorageProvider> allProviders = new ArrayList<StorageProvider>();
    // since dbQuery does not return a normal list required by bookkeeping, we need to rebuild it.
    allProviderURI = new ArrayList<URI>();
    for (StorageProvider provider : allProvidersAllTypes) {
        if (providerType == null || providerType.equals(provider.getInterfaceType())) {
            allProviderURI.add(provider.getId());
            allProviders.add(provider);
        }
    }
    Map<String, StorageSystemViewObject> storageSystemsCache = Collections.synchronizedMap(new HashMap<String, StorageSystemViewObject>());
    boolean exceptionIntercepted = false;
    /**
     * Run "Scheduled" Scanner Jobs of all Providers in only one Controller.
     * means our Cache is populated with the latest
     * physicalStorageSystems ID got from this scheduled Scan Job.
     * Compare the list against the ones in DB, and decide the physicalStorageSystem's
     * state REACHABLE
     */
    String lockKey = ControllerServiceImpl.Lock.SCAN_COLLECTION_LOCK.toString();
    if (providerType != null) {
        lockKey += providerType;
    }
    InterProcessLock scanLock = _coordinator.getLock(lockKey);
    if (scanLock.acquire(ControllerServiceImpl.Lock.SCAN_COLLECTION_LOCK.getRecommendedTimeout(), TimeUnit.SECONDS)) {
        _logger.info("Acquired a lock {} to run scanning Job", ControllerServiceImpl.Lock.SCAN_COLLECTION_LOCK.toString() + providerType);
        List<URI> cacheProviders = new ArrayList<URI>();
        Map<URI, Exception> cacheErrorProviders = new HashMap<URI, Exception>();
        try {
            boolean scanIsNeeded = false;
            boolean hasProviders = false;
            // First find out if scan is needed. If it needed for a single system , it is needed for all
            for (StorageProvider provider : allProviders) {
                if (provider.connected() || provider.initializing()) {
                    hasProviders = true;
                    if (_jobScheduler.isProviderScanJobSchedulingNeeded(provider, ControllerServiceImpl.SCANNER, job.isSchedulerJob())) {
                        scanIsNeeded = true;
                        break;
                    }
                }
            }
            if (!scanIsNeeded) {
                for (StorageProvider provider : allProviders) {
                    ScanTaskCompleter scanCompleter = job.findProviderTaskCompleter(provider.getId());
                    if (scanCompleter == null) {
                        continue;
                    }
                    if (provider.connected() || provider.initializing()) {
                        scanCompleter.ready(_dbClient);
                    } else {
                        String errMsg = "Failed to establish connection to the storage provider";
                        scanCompleter.error(_dbClient, DeviceControllerErrors.smis.unableToCallStorageProvider(errMsg));
                        provider.setLastScanStatusMessage(errMsg);
                        _dbClient.updateObject(provider);
                    }
                }
                if (!hasProviders) {
                    _util.performBookKeeping(storageSystemsCache, allProviderURI);
                }
                _logger.info("Scan is not needed");
            } else {
                // If scan is needed for a single system,
                // it must be performed for all available providers in the database at the same time.
                // update each provider that is reachable to scan in progress
                List<StorageProvider> connectedProviders = new ArrayList<StorageProvider>();
                for (StorageProvider provider : allProviders) {
                    if (provider.connected() || provider.initializing()) {
                        ScanTaskCompleter scanCompleter = job.findProviderTaskCompleter(provider.getId());
                        if (scanCompleter == null) {
                            String taskId = UUID.randomUUID().toString();
                            scanCompleter = new ScanTaskCompleter(StorageProvider.class, provider.getId(), taskId);
                            job.addCompleter(scanCompleter);
                        }
                        scanCompleter.createDefaultOperation(_dbClient);
                        scanCompleter.updateObjectState(_dbClient, DiscoveredDataObject.DataCollectionJobStatus.IN_PROGRESS);
                        scanCompleter.setNextRunTime(_dbClient, System.currentTimeMillis() + DataCollectionJobScheduler.JobIntervals.get(ControllerServiceImpl.SCANNER).getInterval() * 1000);
                        provider.setLastScanStatusMessage("");
                        _dbClient.updateObject(provider);
                        connectedProviders.add(provider);
                    } else {
                        if (null != provider.getStorageSystems() && !provider.getStorageSystems().isEmpty()) {
                            provider.getStorageSystems().clear();
                        }
                        if (providerList.contains(provider.getId())) {
                            String errMsg = "Failed to establish connection to the storage provider";
                            provider.setLastScanStatusMessage(errMsg);
                            job.findProviderTaskCompleter(provider.getId()).error(_dbClient, DeviceControllerErrors.smis.unableToCallStorageProvider(errMsg));
                        }
                        _dbClient.updateObject(provider);
                    }
                }
                // now scan each connected provider
                for (StorageProvider provider : connectedProviders) {
                    try {
                        _logger.info("provider.getInterfaceType():{}", provider.getInterfaceType());
                        ScanTaskCompleter scanCompleter = job.findProviderTaskCompleter(provider.getId());
                        performScan(provider.getId(), scanCompleter, storageSystemsCache);
                        cacheProviders.add(provider.getId());
                    } catch (Exception ex) {
                        _logger.error("Scan failed for {}--->", provider.getId(), ex);
                        cacheErrorProviders.put(provider.getId(), ex);
                    }
                }
                // Perform BooKKeeping
                // TODO: we need to access the status of job completer.
                // for now we assume that this operation can not fail.
                _util.performBookKeeping(storageSystemsCache, allProviderURI);
            }
        } catch (final Exception ex) {
            _logger.error("Scan failed for {} ", ex.getMessage());
            exceptionIntercepted = true;
            for (URI provider : cacheProviders) {
                job.findProviderTaskCompleter(provider).error(_dbClient, DeviceControllerErrors.dataCollectionErrors.scanFailed(ex.getLocalizedMessage(), ex));
                _logger.error("Scan failed for {}--->", provider, ex);
            }
            throw ex;
        } finally {
            if (!exceptionIntercepted) {
                for (URI provider : cacheProviders) {
                    job.findProviderTaskCompleter(provider).ready(_dbClient);
                    _logger.info("Scan complete successfully for " + provider);
                }
            }
            for (Entry<URI, Exception> entry : cacheErrorProviders.entrySet()) {
                URI provider = entry.getKey();
                Exception ex = entry.getValue();
                job.findProviderTaskCompleter(provider).error(_dbClient, DeviceControllerErrors.dataCollectionErrors.scanFailed(ex.getLocalizedMessage(), ex));
            }
            scanLock.release();
            _logger.info("Released a lock {} to run scanning Job", lockKey);
            try {
                if (!exceptionIntercepted) /* && job.isSchedulerJob() */
                {
                    // Manually trigger discoveries, if any new Arrays detected
                    triggerDiscoveryNew(storageSystemsCache, (job.isSchedulerJob() ? DataCollectionJob.JobOrigin.SCHEDULER : DataCollectionJob.JobOrigin.USER_API));
                }
            } catch (Exception ex) {
                _logger.error("Exception occurred while triggering discovery of new systems", ex);
            }
        }
    } else {
        job.setTaskError(_dbClient, DeviceControllerErrors.dataCollectionErrors.scanLockFailed());
        _logger.error("Not able to Acquire Scanning {} lock-->{}", lockKey, Thread.currentThread().getId());
    }
}
Also used : StorageSystemViewObject(com.emc.storageos.plugins.StorageSystemViewObject) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) StorageProvider(com.emc.storageos.db.client.model.StorageProvider) URI(java.net.URI) InternalException(com.emc.storageos.svcs.errorhandling.resources.InternalException) DatabaseException(com.emc.storageos.db.exceptions.DatabaseException) DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException) BeansException(org.springframework.beans.BeansException) BaseCollectionException(com.emc.storageos.plugins.BaseCollectionException) InterProcessLock(org.apache.curator.framework.recipes.locks.InterProcessLock)

Example 17 with InterProcessLock

use of org.apache.curator.framework.recipes.locks.InterProcessLock in project coprhd-controller by CoprHD.

the class VPlexApiLockManager method acquireLock.

/**
 * Attempts to acquire the passed lock.
 *
 * @param lockName The name of the lock to acquire.
 * @param waitInSeconds The amount of time to wait to acquire the lock in
 *            seconds. A value less than 0 will cause the function
 *            to wait indefinitely for the lock.
 *
 * @return true if lock acquired, false otherwise.
 */
public boolean acquireLock(String lockName, long waitInSeconds) {
    if (lockName == null || lockName.isEmpty()) {
        s_logger.info("No lock name specified.");
        return false;
    }
    try {
        InterProcessLock lock = _coordinator.getLock(lockName);
        if (lock != null) {
            if (waitInSeconds >= 0) {
                s_logger.info("Attempting to acquire lock: " + lockName + " for a maximum of " + waitInSeconds + " seconds.");
                if (!lock.acquire(waitInSeconds, TimeUnit.SECONDS)) {
                    s_logger.info("Failed to acquire lock: " + lockName);
                    return false;
                }
            } else {
                s_logger.info("Attempting to acquire lock: " + lockName + " for as long as it takes.");
                // will only throw exception or pass
                lock.acquire();
            }
            s_acquiredLocks.put(lockName, lock);
        } else {
            return false;
        }
        s_logger.info("Acquired lock: " + lockName);
        return true;
    } catch (Exception e) {
        s_logger.error("Acquisition of lock: {} failed with Exception: ", lockName, e);
        return false;
    }
}
Also used : InterProcessLock(org.apache.curator.framework.recipes.locks.InterProcessLock)

Example 18 with InterProcessLock

use of org.apache.curator.framework.recipes.locks.InterProcessLock in project coprhd-controller by CoprHD.

the class VPlexApiLockManager method releaseLock.

/**
 * Release the passed lock.
 *
 * @param lockName The name of the lock to release.
 *
 * @return true if the lock is released, false otherwise.
 */
public boolean releaseLock(String lockName) {
    if (lockName == null || lockName.isEmpty()) {
        s_logger.info("No lock name specified.");
        return false;
    }
    try {
        InterProcessLock lock = s_acquiredLocks.get(lockName);
        if (lock != null) {
            s_acquiredLocks.remove(lockName);
            lock.release();
            s_logger.info("Released lock: " + lockName);
        } else {
            return false;
        }
        return true;
    } catch (Exception e) {
        s_logger.error("Release of lock: {} failed with Exception: ", lockName, e);
        return false;
    }
}
Also used : InterProcessLock(org.apache.curator.framework.recipes.locks.InterProcessLock)

Example 19 with InterProcessLock

use of org.apache.curator.framework.recipes.locks.InterProcessLock in project coprhd-controller by CoprHD.

the class GarbageCollectionExecutorLoop method getLockForGC.

private InterProcessLock getLockForGC() {
    InterProcessLock lock = null;
    String lockName = getGCZKLockName();
    try {
        log.info("try to get ZK GC lock {}", lockName);
        lock = coordinator.getLock(lockName);
        if (!lock.acquire(0, TimeUnit.SECONDS)) {
            // try to get the lock timeout=0
            log.info("Can't get ZK lock for GC");
            // failed to get the lock
            return null;
        }
        log.info("Get GC lock {}", lockName);
    } catch (Exception e) {
        log.warn("Failed to acquire lock for GC {} Exception e=", lockName, e);
        lock = null;
    }
    return lock;
}
Also used : InterProcessLock(org.apache.curator.framework.recipes.locks.InterProcessLock) ExecutionException(java.util.concurrent.ExecutionException)

Example 20 with InterProcessLock

use of org.apache.curator.framework.recipes.locks.InterProcessLock in project coprhd-controller by CoprHD.

the class DbManager method getLastRepairStatus.

@Override
public DbRepairStatus getLastRepairStatus(boolean forCurrentNodesOnly) {
    try {
        DbRepairJobState state = DbRepairRunnable.queryRepairState(this.coordinator, this.schemaUtil.getKeyspaceName(), this.schemaUtil.isGeoDbsvc());
        log.info("cluster state digest stored in ZK: {}", state.getCurrentDigest());
        DbRepairStatus retState = getLastRepairStatus(state, forCurrentNodesOnly ? DbRepairRunnable.getClusterStateDigest() : null, this.repairRetryTimes);
        if (retState != null && retState.getStatus() == DbRepairStatus.Status.IN_PROGRESS) {
            // See if current state holder is still active, if not, we need to resume it
            String lockName = DbRepairRunnable.getLockName();
            InterProcessLock lock = coordinator.getLock(lockName);
            String currentHolder = DbRepairRunnable.getSelfLockNodeId(lock);
            if (currentHolder == null) {
                // No thread is actually driving the repair, we need to resume it
                if (startNodeRepair(this.schemaUtil.getKeyspaceName(), this.repairRetryTimes, false, true)) {
                    log.info("Successfully resumed a previously paused repair");
                } else {
                    log.warn("Cannot resume a previously paused repair, it could be another thread resumed and finished it");
                }
            }
        }
        return retState;
    } catch (Exception e) {
        log.error("Failed to get node repair state from ZK", e);
        return null;
    }
}
Also used : DbRepairStatus(com.emc.vipr.model.sys.recovery.DbRepairStatus) InterProcessLock(org.apache.curator.framework.recipes.locks.InterProcessLock) TimeoutException(java.util.concurrent.TimeoutException) ExecutionException(java.util.concurrent.ExecutionException)

Aggregations

InterProcessLock (org.apache.curator.framework.recipes.locks.InterProcessLock)98 APIException (com.emc.storageos.svcs.errorhandling.resources.APIException)25 DatabaseException (com.emc.storageos.db.exceptions.DatabaseException)21 DeviceControllerException (com.emc.storageos.exceptions.DeviceControllerException)15 IOException (java.io.IOException)15 ControllerException (com.emc.storageos.volumecontroller.ControllerException)14 Configuration (com.emc.storageos.coordinator.common.Configuration)12 CoordinatorException (com.emc.storageos.coordinator.exceptions.CoordinatorException)12 UnknownHostException (java.net.UnknownHostException)12 Site (com.emc.storageos.coordinator.client.model.Site)11 RetryableCoordinatorException (com.emc.storageos.coordinator.exceptions.RetryableCoordinatorException)11 NetworkDeviceControllerException (com.emc.storageos.networkcontroller.exceptions.NetworkDeviceControllerException)10 CheckPermission (com.emc.storageos.security.authorization.CheckPermission)9 ServiceError (com.emc.storageos.svcs.errorhandling.model.ServiceError)9 BiosCommandResult (com.emc.storageos.volumecontroller.impl.BiosCommandResult)9 ArrayList (java.util.ArrayList)9 POST (javax.ws.rs.POST)9 NetworkSystem (com.emc.storageos.db.client.model.NetworkSystem)8 Path (javax.ws.rs.Path)8 ConfigurationImpl (com.emc.storageos.coordinator.common.impl.ConfigurationImpl)6