/*
* Copyright (c) 2012 EMC Corporation
* All Rights Reserved
*/
package com.emc.storageos.volumecontroller.impl.smis.job;
import com.emc.storageos.db.client.DbClient;
import com.emc.storageos.db.client.model.NamedURI;
import com.emc.storageos.db.client.model.Operation;
import com.emc.storageos.db.client.model.Volume;
import com.emc.storageos.db.client.util.NullColumnValueGetter;
import com.emc.storageos.volumecontroller.JobContext;
import com.emc.storageos.volumecontroller.TaskCompleter;
import com.emc.storageos.volumecontroller.impl.smis.CIMConnectionFactory;
import com.emc.storageos.volumecontroller.impl.smis.SmisUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.cim.CIMObjectPath;
import javax.wbem.client.WBEMClient;
import java.net.URI;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* A VMAX Volume Delete job
*/
@SuppressWarnings("serial")
public class SmisDeleteVolumeJob extends SmisJob
{
private static final Logger _log = LoggerFactory.getLogger(SmisDeleteVolumeJob.class);
public SmisDeleteVolumeJob(CIMObjectPath cimJob,
URI storageSystem,
TaskCompleter taskCompleter) {
super(cimJob, storageSystem, taskCompleter, "DeleteVolume");
}
/**
* Called to update the job status when the volume delete job completes.
*
* @param jobContext The job context.
*/
public void updateStatus(JobContext jobContext) throws Exception {
DbClient dbClient = jobContext.getDbClient();
JobStatus jobStatus = getJobStatus();
try {
if (jobStatus == JobStatus.IN_PROGRESS) {
return;
}
CIMConnectionFactory cimConnectionFactory = jobContext.getCimConnectionFactory();
WBEMClient client = getWBEMClient(dbClient, cimConnectionFactory);
// Get list of volumes; get set of storage pool ids to which they belong.
List<Volume> volumes = new ArrayList<Volume>();
Set<URI> poolURIs = new HashSet<URI>();
for (URI id : getTaskCompleter().getIds()) {
Volume volume = dbClient.queryObject(Volume.class, id);
volumes.add(volume);
poolURIs.add(volume.getPool());
}
// If terminal job state update storage pool capacity
if (jobStatus == JobStatus.SUCCESS || jobStatus == JobStatus.FAILED || jobStatus == JobStatus.FATAL_ERROR) {
// Update capacity of storage pools.
for (URI poolURI : poolURIs) {
SmisUtils.updateStoragePoolCapacity(dbClient, client, poolURI);
}
}
StringBuilder logMsgBuilder = new StringBuilder();
if (jobStatus == JobStatus.SUCCESS) {
for (Volume volume : volumes) {
if (logMsgBuilder.length() != 0) {
logMsgBuilder.append("\n");
}
logMsgBuilder.append(String.format("Successfully deleted volume %s", volume.getId()));
}
} else if (jobStatus == JobStatus.FAILED || jobStatus == JobStatus.FATAL_ERROR) {
for (URI id : getTaskCompleter().getIds()) {
if (logMsgBuilder.length() != 0) {
logMsgBuilder.append("\n");
}
logMsgBuilder.append(String.format("Failed to delete volume: %s", id));
}
// if SRDF Protected Volume, then change it to a normal device.
// in case of array locks, target volume deletions fail some times.
// This fix, converts a RDF device to non-rdf device in ViPr, so that this volume is exposed to UI for deletion again.
for (Volume volume : volumes) {
if (volume.checkForSRDF()) {
volume.setPersonality(NullColumnValueGetter.getNullStr());
volume.setAccessState(Volume.VolumeAccessState.READWRITE.name());
volume.setLinkStatus(NullColumnValueGetter.getNullStr());
if (!NullColumnValueGetter.isNullNamedURI(volume.getSrdfParent())) {
volume.setSrdfParent(new NamedURI(NullColumnValueGetter.getNullURI(), NullColumnValueGetter.getNullStr()));
volume.setSrdfCopyMode(NullColumnValueGetter.getNullStr());
volume.setSrdfGroup(NullColumnValueGetter.getNullURI());
} else if (null != volume.getSrdfTargets()) {
volume.getSrdfTargets().clear();
}
}
}
dbClient.updateObject(volumes);
}
if (logMsgBuilder.length() > 0) {
_log.info(logMsgBuilder.toString());
}
} catch (Exception e) {
setPostProcessingErrorStatus("Encountered an internal error during delete volume job status processing: " + e.getMessage());
_log.error("Caught exception while handling updateStatus for delete volume job.", e);
} finally {
super.updateStatus(jobContext);
}
}
}