/* * Copyright (c) 2016 EMC Corporation * All Rights Reserved */ package com.emc.storageos.volumecontroller.impl.block.rollback; import com.emc.storageos.db.client.constraint.ContainmentConstraint; import com.emc.storageos.db.client.model.BlockSnapshot; import com.emc.storageos.db.client.model.BlockSnapshotSession; import com.emc.storageos.db.client.model.DataObject; import com.emc.storageos.db.client.model.StringSet; import com.emc.storageos.db.client.util.CustomQueryUtility; import com.google.common.base.Predicate; import com.google.common.base.Strings; import com.google.common.collect.Collections2; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.net.URI; import java.util.ArrayList; import java.util.Collection; import java.util.List; /** * Implementation of {@link ReplicaCleanup} for deleting failed instances of {@link BlockSnapshot} and * updating any existing {@link BlockSnapshotSession} instances. */ public class BlockSnapshotCleanup extends ReplicaCleanup { private static final Logger log = LoggerFactory.getLogger(BlockSnapshotCleanup.class); /** * Cleans up instances of {@link BlockSnapshot} that failed to be created. Also, any stale entries in * {@link BlockSnapshotSession#getLinkedTargets()} will be cleaned up. * * @param volume Volume URI to process. * @param itemsToUpdate Items to be updated. * @param itemsToDelete Items to be deleted. */ @Override public void process(URI volume, Collection<DataObject> itemsToUpdate, Collection<DataObject> itemsToDelete) { List<BlockSnapshot> snapshots = CustomQueryUtility.queryActiveResourcesByConstraint(getDbClient(), BlockSnapshot.class, ContainmentConstraint.Factory.getVolumeSnapshotConstraint(volume)); List<BlockSnapshot> failedSnapshots = new ArrayList<>(); List<BlockSnapshotSession> updateSessions = new ArrayList<>(); failedSnapshots.addAll(Collections2.filter(snapshots, new Predicate<BlockSnapshot>() { @Override public boolean apply(BlockSnapshot snapshot) { return Strings.isNullOrEmpty(snapshot.getNativeId()); } })); // Removed failed snapshots from any existing sessions for (BlockSnapshot failedSnapshot : failedSnapshots) { log.info("Removing failed snapshot: {}", failedSnapshot.getLabel()); List<BlockSnapshotSession> sessions = CustomQueryUtility.queryActiveResourcesByConstraint(getDbClient(), BlockSnapshotSession.class, ContainmentConstraint.Factory.getLinkedTargetSnapshotSessionConstraint(failedSnapshot.getId())); for (BlockSnapshotSession session : sessions) { log.info("Updating existing session: {}", session.getSessionLabel()); StringSet linkedTargets = session.getLinkedTargets(); linkedTargets.remove(failedSnapshot.getId().toString()); updateSessions.add(session); } } itemsToUpdate.addAll(updateSessions); itemsToDelete.addAll(failedSnapshots); } }