/*
* Copyright (c) 2008-2011 EMC Corporation
* All Rights Reserved
*/
package com.emc.storageos.volumecontroller.impl.plugins;
import java.net.URI;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import com.emc.storageos.db.client.constraint.AlternateIdConstraint;
import com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedCifsShareACL;
import com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedFileExportRule;
import com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedNFSShareACL;
import com.emc.storageos.volumecontroller.ControllerLockingService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.emc.storageos.coordinator.client.service.CoordinatorClient;
import com.emc.storageos.db.client.DbClient;
import com.emc.storageos.db.client.constraint.ContainmentConstraint;
import com.emc.storageos.db.client.constraint.URIQueryResultList;
import com.emc.storageos.db.client.model.Stat;
import com.emc.storageos.db.client.model.StatTimeSeries;
import com.emc.storageos.db.client.model.StorageSystem;
import com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedFileSystem;
import com.emc.storageos.db.exceptions.DatabaseException;
import com.emc.storageos.networkcontroller.impl.NetworkDeviceController;
import com.emc.storageos.plugins.AccessProfile;
import com.emc.storageos.plugins.BaseCollectionException;
import com.emc.storageos.plugins.common.Constants;
import com.emc.storageos.plugins.common.PartitionManager;
import com.emc.storageos.volumecontroller.TaskCompleter;
import com.emc.storageos.volumecontroller.impl.plugins.metering.XMLStatsDumpGenerator;
/**
* This class provides base implementation of {@link ExtendedCommunicationInterface} functions to avoid having many empty implementations in
* the subclasses. It is also
* a good place to add re-usable code.
*
*/
public abstract class ExtendedCommunicationInterfaceImpl implements ExtendedCommunicationInterface {
private static final Logger _logger = LoggerFactory
.getLogger(ExtendedCommunicationInterfaceImpl.class);
protected DbClient _dbClient;
protected CoordinatorClient _coordinator;
protected NetworkDeviceController _networkDeviceController;
protected ControllerLockingService _locker;
protected TaskCompleter _completer;
protected Map<String, Object> _cache;
protected Map<String, Object> _keyMap = new ConcurrentHashMap<String, Object>();
protected static final String METERING = "metering";
protected static final String SCAN = "scan";
protected static final String DISCOVER = "discover";
protected static final String SCAN_INTERVAL = "scan-interval";
protected static final String DISCOVERY_INTERVAL = "discovery-interval";
protected static final String NS_DISCOVERY_INTERVAL = "ns-discovery-interval";
protected static final String METERING_INTERVAL = "metering-interval";
protected PartitionManager _partitionManager;
public static final String UNMANAGED_VOLUME = "UnManagedVolume";
public static final String UNMANAGED_FILESYSTEM = "UnManagedFileSystem";
public static final String UNMANAGED_EXPORT_MASK = "UnManagedExportMask";
private XMLStatsDumpGenerator _xmlDumpGenerator;
@Override
public final void injectCache(Map<String, Object> cache) {
_cache = cache;
}
@Override
public final void injectDBClient(DbClient dbClient) {
_dbClient = dbClient;
}
@Override
public final void injectCoordinatorClient(CoordinatorClient coordinator) {
_coordinator = coordinator;
}
@Override
public final void injectControllerLockingService(ControllerLockingService locker) {
_locker = locker;
}
@Override
public void injectTaskCompleter(TaskCompleter completer) {
_completer = completer;
}
/**
* Dump stat records in /tmp location.
*/
protected void dumpStatRecords() {
@SuppressWarnings("unchecked")
Map<String, String> meteringProps = (Map<String, String>) _keyMap.get(Constants.PROPS);
if (Boolean.parseBoolean(meteringProps.get(Constants.METERINGDUMP))) {
_xmlDumpGenerator.dumpRecordstoXML(_keyMap);
}
}
/**
* Inject Stats to Cassandra. To-Do: To verify, how fast batch insertion is
* working for entries in 1000s. If its taking time, then will need to work
* out, splitting again the batch into smaller batches.
*
* @throws BaseCollectionException
*/
protected void injectStats() throws BaseCollectionException {
DbClient client = (DbClient) _keyMap.get(Constants.dbClient);
@SuppressWarnings("unchecked")
List<Stat> stats = (List<Stat>) _keyMap.get(Constants._Stats);
@SuppressWarnings("unchecked")
Map<String, String> props = (Map<String, String>) _keyMap.get(Constants.PROPS);
String collectionType = props.get(Constants.METERING_COLLECTION_TYPE);
if (collectionType != null && Constants.METERING_COLLECTION_TYPE_FULL.equalsIgnoreCase(collectionType)) {
_logger.info("Started Injection of Stats to Cassandra");
// insert in batches
int size = Constants.DEFAULT_PARTITION_SIZE;
if (null != props.get(Constants.METERING_RECORDS_PARTITION_SIZE)) {
size = Integer.parseInt(props.get(Constants.METERING_RECORDS_PARTITION_SIZE));
}
if (null == _partitionManager) {
Stat[] statBatch = new Stat[stats.size()];
statBatch = stats.toArray(statBatch);
try {
client.insertTimeSeries(StatTimeSeries.class, statBatch);
_logger.info("{} Stat records persisted to DB", statBatch.length);
} catch (DatabaseException e) {
_logger.error("Error inserting records into the database", e);
}
} else {
_partitionManager.insertInBatches(stats, size, client);
}
} else {
_logger.info("Stat records not persisted to DB");
}
}
@Override
public void cleanup() {
// do nothing
}
public void setXmlDumpGenerator(XMLStatsDumpGenerator xmlDumpGenerator) {
_xmlDumpGenerator = xmlDumpGenerator;
}
public void setPartitionManager(PartitionManager partitionManager) {
_partitionManager = partitionManager;
}
/**
* Synchronize the existing active DB Un-Managed FS objects with the newly discovered
* Un-Managed FS objects listed by the Array.
*/
protected void markUnManagedFSObjectsInActive(StorageSystem storageSystem,
Set<URI> discoveredUnManagedFileSystems) {
_logger.info(" -- Processing {} discovered Un-Managed FS Objects from -- {}",
discoveredUnManagedFileSystems.size(), storageSystem.getLabel());
if (discoveredUnManagedFileSystems.isEmpty()) {
return;
}
// Get all available existing unmanaged FS URIs for this array from DB
URIQueryResultList allAvailableUnManagedFileSystemsInDB = new URIQueryResultList();
_dbClient.queryByConstraint(ContainmentConstraint.Factory
.getStorageDeviceUnManagedFileSystemConstraint(storageSystem.getId()),
allAvailableUnManagedFileSystemsInDB);
List<UnManagedFileSystem> unManagedFileSystems = new ArrayList<UnManagedFileSystem>();
int totalObjs = 0;
while (allAvailableUnManagedFileSystemsInDB.iterator().hasNext()) {
URI unManagedFileSystemUri = allAvailableUnManagedFileSystemsInDB.iterator()
.next();
if (!discoveredUnManagedFileSystems.contains(unManagedFileSystemUri)) {
UnManagedFileSystem uFS = _dbClient.queryObject(
UnManagedFileSystem.class, unManagedFileSystemUri);
_logger.info(
"Found a stale un-managed active file system in DB {} - Marking this to In-Active",
uFS.getNativeGuid());
uFS.setInactive(true);
unManagedFileSystems.add(uFS);
if (unManagedFileSystems.size() == 1000) {
totalObjs += 1000;
_partitionManager.updateInBatches(unManagedFileSystems,
Constants.DEFAULT_PARTITION_SIZE, _dbClient,
UNMANAGED_FILESYSTEM);
unManagedFileSystems.clear();
}
}
}
totalObjs += unManagedFileSystems.size();
if (!unManagedFileSystems.isEmpty()) {
_partitionManager.updateInBatches(unManagedFileSystems,
Constants.DEFAULT_PARTITION_SIZE, _dbClient, UNMANAGED_FILESYSTEM);
}
_logger.info("Total number of stale unmanaged file systems processed {}",
totalObjs);
}
/**
* check Pre Existing Storage Export Rule exists in DB
*
* @param dbClient
* @param exportRuleNativeGuid
* @return unManagedFileExportRule
* @throws java.io.IOException
*/
protected UnManagedFileExportRule checkUnManagedFsExportRuleExistsInDB(DbClient dbClient,
String exportRuleNativeGuid) {
UnManagedFileExportRule unManagedExportRule = null;
URIQueryResultList result = new URIQueryResultList();
dbClient.queryByConstraint(AlternateIdConstraint.Factory
.getFileExporRuleNativeGUIdConstraint(exportRuleNativeGuid), result);
Iterator<URI> iter = result.iterator();
while (iter.hasNext()) {
URI unExportRuleURI = iter.next();
unManagedExportRule = dbClient.queryObject(UnManagedFileExportRule.class, unExportRuleURI);
return unManagedExportRule;
}
return unManagedExportRule;
}
/**
* check Pre Existing Storage CIFS ACLs exists in DB
*
* @param dbClient
* @param cifsNativeGuid
* @return UnManagedCifsShareACL
* @throws java.io.IOException
*/
protected UnManagedCifsShareACL checkUnManagedFsCifsACLExistsInDB(DbClient dbClient,
String cifsACLNativeGuid) {
UnManagedCifsShareACL unManagedCifsAcl = null;
URIQueryResultList result = new URIQueryResultList();
dbClient.queryByConstraint(AlternateIdConstraint.Factory
.getFileCifsACLNativeGUIdConstraint(cifsACLNativeGuid), result);
Iterator<URI> iter = result.iterator();
while (iter.hasNext()) {
URI cifsAclURI = iter.next();
unManagedCifsAcl = dbClient.queryObject(UnManagedCifsShareACL.class, cifsAclURI);
return unManagedCifsAcl;
}
return unManagedCifsAcl;
}
/**
* check Pre Existing Storage NFS ACLs exists in DB
*
* @param dbClient
* @param nfsNativeGuid
* @return UnManagedNFSShareACL
* @throws java.io.IOException
*/
protected UnManagedNFSShareACL checkUnManagedFsNfssACLExistsInDB(DbClient dbClient,
String nfsACLNativeGuid) {
UnManagedNFSShareACL unManagedNfsAcl = null;
URIQueryResultList result = new URIQueryResultList();
dbClient.queryByConstraint(AlternateIdConstraint.Factory
.getFileNfsACLNativeGUIdConstraint(nfsACLNativeGuid), result);
Iterator<URI> iter = result.iterator();
while (iter.hasNext()) {
URI cifsAclURI = iter.next();
unManagedNfsAcl = dbClient.queryObject(UnManagedNFSShareACL.class, cifsAclURI);
return unManagedNfsAcl;
}
return unManagedNfsAcl;
}
@Override
public void injectNetworkDeviceController(
NetworkDeviceController networkDeviceController) {
_networkDeviceController = networkDeviceController;
}
public void discoverArrayAffinity(AccessProfile accessProfile) {
_logger.info("Calling discoverArrayAffinity");
}
}