/*
* 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.Volume;
import com.emc.storageos.volumecontroller.Job;
import com.emc.storageos.volumecontroller.JobContext;
import com.emc.storageos.volumecontroller.impl.NativeGUIDGenerator;
import com.emc.storageos.volumecontroller.impl.block.taskcompleter.MetaVolumeTaskCompleter;
import com.emc.storageos.volumecontroller.impl.smis.CIMConnectionFactory;
import com.emc.storageos.volumecontroller.impl.smis.SmisConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.cim.CIMObjectPath;
import javax.cim.CIMProperty;
import javax.wbem.CloseableIterator;
import javax.wbem.client.WBEMClient;
import java.net.URI;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
public class SmisCreateMetaVolumeHeadJob extends SmisJob {
private static final Logger _log = LoggerFactory.getLogger(SmisCreateMetaVolumeHeadJob.class);
private URI _metaHeadId;
private List<String> _metaMembers = new ArrayList<String>();
private MetaVolumeTaskCompleter _metaVolumeTaskCompleter;
public SmisCreateMetaVolumeHeadJob(CIMObjectPath cimJob, URI storageSystem, MetaVolumeTaskCompleter metaVolumeTaskCompleter,
URI metaHeadId) {
super(cimJob, storageSystem, metaVolumeTaskCompleter.getVolumeTaskCompleter(), "CreateMetaVolumeHead");
_metaVolumeTaskCompleter = metaVolumeTaskCompleter;
_metaHeadId = metaHeadId;
}
/**
* Called to update the job status when the create meta volume head job completes.
* Sets native device ID to meta head volume.
*
* @param jobContext The job context.
*/
public void updateStatus(JobContext jobContext) throws Exception {
CloseableIterator<CIMObjectPath> iterator = null;
DbClient dbClient = jobContext.getDbClient();
JobStatus jobStatus = getJobStatus();
try {
if (jobStatus == Job.JobStatus.IN_PROGRESS) {
return;
}
String opId = getTaskCompleter().getOpId();
StringBuilder logMsgBuilder =
new StringBuilder(String.format("Updating post processing status of job %s to %s, task: %s", this.getJobName(),
jobStatus.name(), opId));
CIMConnectionFactory cimConnectionFactory = jobContext.getCimConnectionFactory();
WBEMClient client = getWBEMClient(dbClient, cimConnectionFactory);
iterator = client.associatorNames(getCimJob(), null, SmisConstants.CIM_STORAGE_VOLUME, null, null);
Calendar now = Calendar.getInstance();
Volume metaHead = dbClient.queryObject(Volume.class, _metaHeadId);
if (jobStatus == Job.JobStatus.SUCCESS) {
CIMObjectPath volumePath = iterator.next();
CIMProperty<String> deviceID = (CIMProperty<String>) volumePath.getKey(SmisConstants.CP_DEVICE_ID);
String headNativeID = deviceID.getValue();
metaHead.setCreationTime(now);
metaHead.setNativeId(headNativeID);
metaHead.setNativeGuid(NativeGUIDGenerator.generateNativeGuid(dbClient, metaHead));
dbClient.persistObject(metaHead);
logMsgBuilder.append("\n");
logMsgBuilder.append(String.format(
"%n Task %s created meta head volume: %s with device ID: %s", opId, metaHead.getLabel(), headNativeID));
_log.info(logMsgBuilder.toString());
} else if (jobStatus == JobStatus.FAILED || jobStatus == JobStatus.FATAL_ERROR) {
logMsgBuilder.append("\n");
logMsgBuilder.append(String.format(
"Task %s failed to create meta head volume: %s caused by: %s", opId, metaHead.getLabel(), _errorDescription));
Volume volume = dbClient.queryObject(Volume.class, _metaHeadId);
volume.setInactive(true);
dbClient.persistObject(volume);
_log.error(logMsgBuilder.toString());
setFailedStatus(logMsgBuilder.toString());
}
} catch (Exception e) {
_log.error("Caught an exception while trying to process status for " + this.getJobName(), e);
setPostProcessingErrorStatus("Encountered an internal error during " + this.getJobName() + " job status processing : "
+ e.getMessage());
} finally {
if (iterator != null) {
iterator.close();
}
_metaVolumeTaskCompleter.setLastStepStatus(jobStatus);
if (isJobInTerminalFailedState()) {
super.updateStatus(jobContext);
}
}
}
}