/* * Copyright (c) 2014 EMC Corporation * All Rights Reserved */ package com.emc.storageos.volumecontroller.impl.cinder.job; import java.net.URI; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.emc.storageos.cinder.CinderConstants; import com.emc.storageos.cinder.CinderEndPointInfo; import com.emc.storageos.cinder.api.CinderApi; import com.emc.storageos.db.client.DbClient; import com.emc.storageos.db.client.model.StoragePool; import com.emc.storageos.db.client.model.StorageSystem; import com.emc.storageos.db.client.model.StringMap; import com.emc.storageos.db.client.model.Volume; import com.emc.storageos.volumecontroller.JobContext; import com.emc.storageos.volumecontroller.TaskCompleter; import com.emc.storageos.volumecontroller.impl.block.taskcompleter.VolumeExpandCompleter; import com.emc.storageos.volumecontroller.impl.cinder.CinderUtils; public class CinderVolumeExpandJob extends CinderJob { private static final long serialVersionUID = -1005208786425264847L; private static final Logger _logger = LoggerFactory .getLogger(CinderVolumeExpandJob.class); private URI storagePoolUri = null; public CinderVolumeExpandJob(String jobId, String jobName, URI storageSystem, String componentType, CinderEndPointInfo ep, TaskCompleter taskCompleter, URI storagePoolUri) { super(jobId, "ExpandVolume:VolumeName:" + jobName, storageSystem, componentType, ep, taskCompleter); this.storagePoolUri = storagePoolUri; } @Override public void updateStatus(JobContext jobContext) throws Exception { DbClient dbClient = jobContext.getDbClient(); try { // Do nothing if the job is not completed yet if (status == JobStatus.IN_PROGRESS) { return; } String opId = getTaskCompleter().getOpId(); _logger.info(String.format("Updating status of job %s to %s", opId, status.name())); StorageSystem storageSystem = dbClient.queryObject( StorageSystem.class, getStorageSystemURI()); CinderApi cinderApi = jobContext.getCinderApiFactory().getApi( storageSystem.getActiveProviderURI(), getEndPointInfo()); URI volumeId = getTaskCompleter().getId(); // If terminal state update storage pool capacity and remove reservation for volume capacity // from pool's reserved capacity map. StoragePool storagePool = null; if (status == JobStatus.SUCCESS || status == JobStatus.FAILED) { storagePool = dbClient.queryObject(StoragePool.class, storagePoolUri); StringMap reservationMap = storagePool.getReservedCapacityMap(); // remove from reservation map reservationMap.remove(volumeId.toString()); dbClient.persistObject(storagePool); } if (status == JobStatus.SUCCESS) { VolumeExpandCompleter taskCompleter = (VolumeExpandCompleter) getTaskCompleter(); Volume volume = dbClient.queryObject(Volume.class, taskCompleter.getId()); long oldCapacity = volume.getCapacity(); long newCapacity = taskCompleter.getSize(); // set requested capacity volume.setCapacity(newCapacity / CinderConstants.BYTES_TO_GB); volume.setProvisionedCapacity(taskCompleter.getSize()); volume.setAllocatedCapacity(taskCompleter.getSize()); dbClient.persistObject(volume); long increasedCapacity = newCapacity - oldCapacity; CinderUtils.updateStoragePoolCapacity(dbClient, cinderApi, storagePool, String.valueOf(increasedCapacity / CinderConstants.BYTES_TO_GB), false); } } catch (Exception e) { _logger.error("Caught an exception while trying to updateStatus for CinderExpandVolumeJob", e); setErrorStatus("Encountered an internal error during expand volume job status processing : " + e.getMessage()); } finally { super.updateStatus(jobContext); } } @Override protected boolean isJobSucceeded(String currentStatus) { return (CinderConstants.ComponentStatus.AVAILABLE.getStatus().equalsIgnoreCase(currentStatus)); } @Override protected boolean isJobFailed(String currentStatus) { return (CinderConstants.ComponentStatus.ERROR.getStatus().equalsIgnoreCase(currentStatus) || CinderConstants.ComponentStatus.ERROR_EXTENDING .getStatus().equalsIgnoreCase(currentStatus)); } }