/* * Copyright (c) 2016 EMC Corporation * All Rights Reserved */ package com.emc.storageos.volumecontroller.impl.externaldevice.job; import java.net.URI; import java.util.Collections; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; 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.Volume; import com.emc.storageos.exceptions.DeviceControllerException; import com.emc.storageos.storagedriver.DriverTask; import com.emc.storageos.storagedriver.model.VolumeClone; import com.emc.storageos.storagedriver.task.CreateVolumeCloneDriverTask; import com.emc.storageos.volumecontroller.TaskCompleter; import com.emc.storageos.volumecontroller.impl.externaldevice.ExternalBlockStorageDevice; import com.emc.storageos.volumecontroller.impl.externaldevice.ExternalDeviceUtils; /** * This ExternalDeviceJob derived class is created to monitor the progress * of a request to a create volume clone that will complete asynchronously. */ public class CreateVolumeCloneExternalDeviceJob extends ExternalDeviceJob { private static final long serialVersionUID = 1L; // The URI of the volume serving as the clone. private URI _volumeURI; // Logger reference. private static final Logger s_logger = LoggerFactory.getLogger(CreateVolumeCloneExternalDeviceJob.class); /** * Constructor. * * @param storageSystemURI The URI of the external storage system on which the task is running. * @param volumeURI The URI of the volume serving as the clone. * @param driverTaskId The id of the task monitored by the job. * @param taskCompleter The task completer. */ public CreateVolumeCloneExternalDeviceJob(URI storageSystemURI, URI volumeURI, String driverTaskId, TaskCompleter taskCompleter) { super(storageSystemURI, driverTaskId, taskCompleter); _volumeURI = volumeURI; } /** * {@inheritDoc} */ @Override protected void doTaskSucceeded(DriverTask driverTask, DbClient dbClient) throws Exception { // Get the ViPR volume representing the clone. s_logger.info(String.format("Successfully created volume clone %s:%s", _volumeURI, driverTask.getMessage())); Volume volume = dbClient.queryObject(Volume.class, _volumeURI); if (volume == null) { s_logger.error(String.format("Failed to find volume %s", _volumeURI)); throw DeviceControllerException.exceptions.objectNotFound(_volumeURI); } // Update the ViPR clone with the driver clone information. // Note that we know ViPR only allows creation of a single // in a given request. CreateVolumeCloneDriverTask createCloneDriverTask = (CreateVolumeCloneDriverTask) driverTask; List<VolumeClone> updatedClones = createCloneDriverTask.getClones(); VolumeClone updatedClone = updatedClones.get(0); ExternalDeviceUtils.updateNewlyCreatedClone(volume, updatedClone, dbClient); try { // Update storage pool capacity in database. ExternalDeviceUtils.updateStoragePoolCapacityAfterOperationComplete(volume.getPool(), _storageSystemURI, Collections.singletonList(_volumeURI), dbClient); } catch (Exception ex) { s_logger.error("Failed to update storage pool {} after create clone operation completion.", volume.getPool(), ex); } } /** * {@inheritDoc} */ @Override protected void doTaskFailed(DriverTask driverTask, DbClient dbClient) throws Exception { s_logger.error(String.format("Failed to create volume clone %s:%s", _volumeURI, driverTask.getMessage())); Volume volume = dbClient.queryObject(Volume.class, _volumeURI); if (volume == null) { s_logger.error(String.format("Failed to find volume %s", _volumeURI)); } else { volume.setInactive(true); dbClient.updateObject(volume); try { // Update storage pool capacity in database. ExternalDeviceUtils.updateStoragePoolCapacityAfterOperationComplete(volume.getPool(), _storageSystemURI, Collections.singletonList(_volumeURI), dbClient); } catch (Exception ex) { s_logger.error("Failed to update storage pool {} after create clone operation completion.", volume.getPool(), ex); } } } }