/* * Copyright (c) 2008-2014 EMC Corporation * All Rights Reserved */ package com.emc.storageos.volumecontroller.impl.plugins.discovery.smis; import java.net.URI; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.UUID; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.emc.storageos.coordinator.client.service.DistributedQueueItemProcessedCallback; import com.emc.storageos.db.client.DbClient; import com.emc.storageos.db.client.model.StorageProvider; import com.emc.storageos.db.client.model.StorageSystem; import com.emc.storageos.db.client.model.StorageSystem.Discovery_Namespaces; import com.emc.storageos.db.client.util.CustomQueryUtility; import com.emc.storageos.exceptions.DeviceControllerErrors; import com.emc.storageos.plugins.StorageSystemViewObject; import com.emc.storageos.volumecontroller.ControllerException; import com.emc.storageos.volumecontroller.impl.ControllerServiceImpl; import com.emc.storageos.volumecontroller.impl.plugins.discovery.smis.DataCollectionJob.JobOrigin; /* * Based on DataCollectionJobConsumer * Modified for standalone testing */ public class TestDataCollectionJobConsumer extends DataCollectionJobConsumer { private static final Logger _logger = LoggerFactory .getLogger(TestDataCollectionJobConsumer.class); private DbClient _dbClient = null; private DataCollectionJobUtil _util = null; @Override public void setDbClient(DbClient dbClient) { _dbClient = dbClient; super.setDbClient(dbClient); } @Override public void setUtil(DataCollectionJobUtil util) { _util = util; super.setUtil(util); } @Override public void consumeItem(final DataCollectionJob job, final DistributedQueueItemProcessedCallback callback) throws Exception { try { if (job instanceof DataCollectionScanJob) { triggerScanning((DataCollectionScanJob) job); } else { invokeJob(job); } } catch (ControllerException e) { _logger.error(job.getType() + " job failed for {}---> ", job.systemString(), e); } catch (Exception e) { _logger.error(job.getType() + " job failed for {}---> ", job.systemString(), e); } } private void triggerScanning(DataCollectionScanJob job) throws Exception { _logger.info("Started scanning SMIS Providers : triggerScanning()"); List<URI> allProviderURI = _dbClient.queryByType(StorageProvider.class, true); List<StorageProvider> allProviders = _dbClient.queryObject( StorageProvider.class, allProviderURI); Map<String, StorageSystemViewObject> storageSystemsCache = Collections .synchronizedMap(new HashMap<String, StorageSystemViewObject>()); boolean exceptionIntercepted = false; try { List<URI> cacheProviders = new ArrayList<URI>(); // since dbQuery does not return a normal list required by // bookkeeping, we need to rebuild it. allProviderURI = new ArrayList<URI>(); // If scan is needed for a single system, // it must be performed for all available providers in the database // at the same time. for (StorageProvider provider : allProviders) { allProviderURI.add(provider.getId()); 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); } try { provider.setLastScanStatusMessage(""); _dbClient.persistObject(provider); _logger.info("provider.getInterfaceType():{}", provider.getInterfaceType()); performScan(provider.getId(), scanCompleter, storageSystemsCache); cacheProviders.add(provider.getId()); } catch (Exception ex) { _logger.error("Scan failed for {}--->", provider.getId(), ex); } _dbClient.persistObject(provider); } // 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); for (URI provider : cacheProviders) { job.findProviderTaskCompleter(provider).ready(_dbClient); _logger.info("Scan complete successfully for " + provider); } } catch (final Exception ex) { _logger.error("Scan failed for {} ", ex.getMessage()); job.error(_dbClient, DeviceControllerErrors.dataCollectionErrors.scanFailed(ex.getLocalizedMessage(), ex)); exceptionIntercepted = true; throw ex; } finally { try { if (!exceptionIntercepted && job.isSchedulerJob()) { // Manually trigger discoveries, if any new Arrays detected triggerDiscoveryNew(storageSystemsCache, DataCollectionJob.JobOrigin.SCHEDULER); } } catch (Exception ex) { _logger.error(ex.getMessage(), ex); } } } @Override public void triggerDiscoveryNew( Map<String, StorageSystemViewObject> storageSystemsCache, JobOrigin origin) throws Exception { Set<String> sysNativeGuidSet = storageSystemsCache.keySet(); for (String sysNativeGuid : sysNativeGuidSet) { StorageSystem system = null; try { List<StorageSystem> systems = CustomQueryUtility .getActiveStorageSystemByNativeGuid(_dbClient, sysNativeGuid); if (systems.isEmpty()) { continue; } system = systems.get(0); _logger.info("Triggering discovery of new storage system {}", sysNativeGuid); String taskId = UUID.randomUUID().toString(); DiscoverTaskCompleter completer = new DiscoverTaskCompleter( system.getClass(), system.getId(), taskId, ControllerServiceImpl.DISCOVERY); invokeJob(new DataCollectionDiscoverJob(completer, Discovery_Namespaces.ALL.toString())); } catch (Exception e) { _logger.error("Triggering Manual Array Discovery Failed {}:", system, e); } } } }