/* * Copyright (c) 2015 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.StoragePool; import com.emc.storageos.db.client.model.StringMap; import com.emc.storageos.db.client.model.Volume; import com.emc.storageos.db.client.model.Volume.ReplicationState; import com.emc.storageos.volumecontroller.JobContext; import com.emc.storageos.volumecontroller.TaskCompleter; import com.emc.storageos.volumecontroller.impl.NativeGUIDGenerator; import com.emc.storageos.volumecontroller.impl.block.taskcompleter.CloneCreateCompleter; import com.emc.storageos.volumecontroller.impl.smis.CIMConnectionFactory; import com.emc.storageos.volumecontroller.impl.smis.CIMPropertyFactory; import com.emc.storageos.volumecontroller.impl.smis.SmisConstants; import com.emc.storageos.volumecontroller.impl.smis.SmisUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.cim.CIMInstance; import javax.cim.CIMObjectPath; import javax.wbem.CloseableIterator; import javax.wbem.client.WBEMClient; import java.net.URI; public class SmisCloneVolumeJob extends SmisReplicaCreationJobs { private static final Logger _log = LoggerFactory.getLogger(SmisCloneVolumeJob.class); public SmisCloneVolumeJob(CIMObjectPath job, URI storgeSystemURI, TaskCompleter taskCompleter) { super(job, storgeSystemURI, taskCompleter, "CloneVolume"); } @Override public void updateStatus(JobContext jobContext) throws Exception { _log.info("START updateStatus for clone volume"); CloseableIterator<CIMObjectPath> iterator = null; DbClient dbClient = jobContext.getDbClient(); JobStatus jobStatus = getJobStatus(); try { CIMConnectionFactory cimConnectionFactory; WBEMClient client = null; CloneCreateCompleter completer = (CloneCreateCompleter) getTaskCompleter(); Volume cloneVolume = dbClient.queryObject(Volume.class, completer.getId()); // If terminal state update storage pool capacity and remove reservation for volume capacity // from pool's reserved capacity map. if (jobStatus == JobStatus.SUCCESS || jobStatus == JobStatus.FAILED || jobStatus == JobStatus.FATAL_ERROR) { cimConnectionFactory = jobContext.getCimConnectionFactory(); client = getWBEMClient(dbClient, cimConnectionFactory); URI poolURI = cloneVolume.getPool(); SmisUtils.updateStoragePoolCapacity(dbClient, client, poolURI); StoragePool pool = dbClient.queryObject(StoragePool.class, poolURI); StringMap reservationMap = pool.getReservedCapacityMap(); // remove from reservation map reservationMap.remove(cloneVolume.getId().toString()); dbClient.persistObject(pool); } if (jobStatus == JobStatus.SUCCESS) { _log.info("Clone creation success"); iterator = client.associatorNames(getCimJob(), null, SmisConstants.CIM_STORAGE_VOLUME, null, null); if (iterator.hasNext()) { CIMObjectPath cloneVolumePath = iterator.next(); CIMInstance syncVolume = client.getInstance(cloneVolumePath, false, false, null); String deviceId = cloneVolumePath.getKey(SmisConstants.CP_DEVICE_ID).getValue().toString(); String elementName = CIMPropertyFactory.getPropertyValue(syncVolume, SmisConstants.CP_ELEMENT_NAME); String wwn = CIMPropertyFactory.getPropertyValue(syncVolume, SmisConstants.CP_WWN_NAME); String alternateName = CIMPropertyFactory.getPropertyValue(syncVolume, SmisConstants.CP_NAME); cloneVolume.setProvisionedCapacity(getProvisionedCapacityInformation(client, syncVolume)); cloneVolume.setAllocatedCapacity(getAllocatedCapacityInformation(client, syncVolume)); cloneVolume.setWWN(wwn.toUpperCase()); cloneVolume.setAlternateName(alternateName); cloneVolume.setNativeId(deviceId); cloneVolume.setDeviceLabel(elementName); cloneVolume.setNativeGuid(NativeGUIDGenerator.generateNativeGuid(dbClient, cloneVolume)); cloneVolume.setInactive(false); if (cloneVolume.getSyncActive()) { cloneVolume.setReplicaState(ReplicationState.CREATED.name()); } else { cloneVolume.setReplicaState(ReplicationState.INACTIVE.name()); } dbClient.persistObject(cloneVolume); } /* * for (URI id : completer.getIds()) { * completer.ready(dbClient); * } */ } else if (jobStatus == JobStatus.FAILED || jobStatus == JobStatus.FATAL_ERROR) { String msg = String.format("Failed job to create full copy from %s to %s", cloneVolume.getAssociatedSourceVolume(), cloneVolume.getId()); _log.error(msg); cloneVolume.setInactive(true); dbClient.persistObject(cloneVolume); } } catch (Exception e) { String errorMsg = String.format("Encountered an internal error during block create clone job status " + "processing: %s", e.getMessage()); setPostProcessingErrorStatus(errorMsg); _log.error("Failed to update status for " + getClass().getSimpleName(), e); } finally { if (iterator != null) { iterator.close(); } super.updateStatus(jobContext); _log.info("FINISH updateStatus for clone volume"); } } }