/*
* Copyright (c) 2015 EMC Corporation
* All Rights Reserved
*/
package com.emc.storageos.volumecontroller.impl.plugins.discovery.smis.processor;
import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.google.common.base.Joiner;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.AutoTieringPolicy;
import com.emc.storageos.db.client.model.StorageSystem;
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.Processor;
import com.emc.storageos.plugins.common.domainmodel.Operation;
import com.google.common.base.Strings;
/**
* This processor will be run directly and should be called after the StoragePoolSettingProcessor. The processing here is to look
* at all the SLO Names that were collected by the StoragePoolSettingProcessor. This should be a complete list of the SLOs that
* are known to the array. We can then evaluate whether any of them no longer exist by comparing to what is currently in the
* database.
*/
public class VmaxSLOBookkeepingProcessor extends Processor {
private Logger log = LoggerFactory.getLogger(VmaxSLOBookkeepingProcessor.class);
@Override
public void processResult(Operation operation, Object resultObj, Map<String, Object> keyMap) throws BaseCollectionException {
DbClient dbClient = (DbClient) keyMap.get(Constants.dbClient);
Set<String> policyNames = (Set<String>) keyMap.get(Constants.SLO_NAMES);
AccessProfile profile = (AccessProfile) keyMap.get(Constants.ACCESSPROFILE);
StorageSystem storageSystem = dbClient.queryObject(StorageSystem.class, profile.getSystemId());
boolean isVmax3 = storageSystem.checkIfVmax3();
if (isVmax3 && policyNames != null && !policyNames.isEmpty()) {
try {
performPolicyBookKeeping(dbClient, policyNames, storageSystem);
} catch (IOException e) {
log.error("Exception caught while trying to run bookkeeping on VMAX3 SLO AutoTieringPolicies", e);
}
}
}
/**
* if the policy had been removed from the Array, the rediscovery cycle should set the fast Policy to inactive.
*
* @param dbClient [in] - Database client
* @param policyNames [in] - List SLO nativeGUIDs
* @param storageSystem [in] - StorageSystem object representing the array being discovered
* @throws java.io.IOException
*/
private void performPolicyBookKeeping(DbClient dbClient, Set<String> policyNames, StorageSystem storageSystem) throws IOException {
log.debug(String.format("SLO policyNames found by discovery for array %s:%n%s", storageSystem.getNativeGuid(),
Joiner.on(',').join(policyNames)));
List<AutoTieringPolicy> policiesToUpdate = new ArrayList<>();
URIQueryResultList policiesInDB = new URIQueryResultList();
dbClient.queryByConstraint(ContainmentConstraint.Factory.getStorageDeviceFASTPolicyConstraint(storageSystem.getId()), policiesInDB);
for (URI policy : policiesInDB) {
AutoTieringPolicy policyObject = dbClient.queryObject(AutoTieringPolicy.class, policy);
// Process only SLO based AutoTieringPolicies here.
if (policyObject == null || Strings.isNullOrEmpty(policyObject.getVmaxSLO())) {
continue;
}
String policyName = policyObject.getPolicyName();
if (!policyNames.contains(policyName)) {
log.info(String.format("SLO %s no longer exists on array %s, marking associated AutoTieringPolicy %s inactive", policyName,
storageSystem.getNativeGuid(), policy));
policyObject.setPolicyEnabled(false);
policyObject.getPools().clear();
policyObject.setInactive(true);
policiesToUpdate.add(policyObject);
}
}
if (!policiesToUpdate.isEmpty()) {
dbClient.updateAndReindexObject(policiesToUpdate);
}
}
}