/* * Copyright (c) 2013 EMC Corporation * All Rights Reserved */ package com.emc.storageos.volumecontroller.impl.block.taskcompleter; import java.net.URI; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; 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.BlockObject; import com.emc.storageos.db.client.model.ExportGroup; import com.emc.storageos.db.client.model.ExportMask; import com.emc.storageos.db.client.model.Operation; 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.svcs.errorhandling.model.ServiceCoded; import com.emc.storageos.svcs.errorhandling.model.ServiceError; import com.emc.storageos.workflow.WorkflowService; public class ExportMaskRemoveVolumeCompleter extends ExportTaskCompleter { private static final Logger _log = LoggerFactory.getLogger(ExportMaskRemoveVolumeCompleter.class); private Collection<URI> _volumes; /** * Constructor for ExportMaskRemoveVolumeCompleter. * * @param egUri -- ExportGroup URI * @param emUri -- ExportMask URI * @param volumes -- List<URI> of volumes being removed. * @param task -- API task id. */ public ExportMaskRemoveVolumeCompleter(URI egUri, URI emUri, Collection<URI> volumes, String task) { super(ExportGroup.class, egUri, emUri, task); _volumes = new ArrayList<URI>(); _volumes.addAll(volumes); } @Override protected void complete(DbClient dbClient, Operation.Status status, ServiceCoded coded) throws DeviceControllerException { try { boolean isRollback = WorkflowService.getInstance().isStepInRollbackState(getOpId()); ExportMask exportMask = (getMask() != null) ? dbClient.queryObject(ExportMask.class, getMask()) : null; if (exportMask != null) { if ((status == Operation.Status.error) && (isRollback) && (coded instanceof ServiceError)) { ServiceError error = (ServiceError) coded; String originalMessage = error.getMessage(); StorageSystem storageSystem = exportMask != null ? dbClient.queryObject(StorageSystem.class, exportMask.getStorageDevice()) : null; List<Volume> volumes = dbClient.queryObject(Volume.class, _volumes); StringBuffer volumesJoined = new StringBuffer(); if (volumes != null && !volumes.isEmpty()) { Iterator<Volume> initIter = volumes.iterator(); while (initIter.hasNext()) { Volume volume = initIter.next(); volumesJoined.append(volume.forDisplay()); if (initIter.hasNext()) { volumesJoined.append(","); } } } String additionMessage = String.format( "Rollback encountered problems removing volume(s) %s from export mask %s on storage system %s and may require manual clean up", volumesJoined.toString(), exportMask.getMaskName(), storageSystem != null ? storageSystem.forDisplay() : "Unknown"); String updatedMessage = String.format("%s\n%s", originalMessage, additionMessage); error.setMessage(updatedMessage); } if (status == Operation.Status.ready || (status == Operation.Status.error && isRollback)) { ExportGroup exportGroup = dbClient.queryObject(ExportGroup.class, getId()); for (URI volumeURI : _volumes) { BlockObject volume = BlockObject.fetch(dbClient, volumeURI); exportMask.removeFromUserCreatedVolumes(volume); exportMask.removeVolume(volume.getId()); } if (exportMask != null) { if (exportMask.getVolumes() == null || exportMask.getVolumes().isEmpty()) { exportGroup.removeExportMask(exportMask.getId()); dbClient.markForDeletion(exportMask); dbClient.updateObject(exportGroup); } else { dbClient.updateObject(exportMask); } } _log.info(String.format( "Done ExportMaskRemoveVolume - Id: %s, OpId: %s, status: %s", getId().toString(), getOpId(), status.name())); } } } catch (Exception e) { _log.error(String.format( "Failed updating status for ExportMaskRemoveVolume - Id: %s, OpId: %s", getId().toString(), getOpId()), e); } finally { super.complete(dbClient, status, coded); } } }