/*
* Copyright 2016 EMC Corporation
* All Rights Reserved
*/
package com.emc.storageos.hp3par.impl;
import java.util.HashMap;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.emc.storageos.hp3par.command.ConsistencyGroupResult;
import com.emc.storageos.hp3par.command.VolumeDetailsCommandResult;
import com.emc.storageos.hp3par.command.VVSetCloneList.VVSetVolumeClone;
import com.emc.storageos.hp3par.utils.HP3PARConstants;
import com.emc.storageos.hp3par.utils.HP3PARUtil;
import com.emc.storageos.storagedriver.DriverTask;
import com.emc.storageos.storagedriver.Registry;
import com.emc.storageos.storagedriver.model.VolumeClone;
import com.emc.storageos.storagedriver.model.VolumeConsistencyGroup;
import com.emc.storageos.storagedriver.model.VolumeSnapshot;
import com.emc.storageos.storagedriver.model.StorageObject.AccessStatus;
import com.emc.storageos.storagedriver.model.StorageVolume;
import com.emc.storageos.storagedriver.storagecapabilities.CapabilityInstance;
public class HP3PARCGHelper {
private static final Logger _log = LoggerFactory.getLogger(HP3PARCGHelper.class);
private HP3PARUtil hp3parUtil;
public DriverTask createConsistencyGroup(VolumeConsistencyGroup consistencyGroup, DriverTask task,
Registry driverRegistry) {
try {
_log.info(
"3PARDriver: createConsistencyGroup for storage system id {}, display name {} , native id {}, device lable id {} , cosistency group id {} - start",
consistencyGroup.getStorageSystemId(), consistencyGroup.getDisplayName(),
consistencyGroup.getNativeId(), consistencyGroup.getDeviceLabel(),
consistencyGroup.getConsistencyGroup());
// get Api client
HP3PARApi hp3parApi = hp3parUtil.getHP3PARDeviceFromNativeId(consistencyGroup.getStorageSystemId(),
driverRegistry);
ConsistencyGroupResult cgResult = null;
// Create VV Set / Consistency Group
hp3parApi.createVVset(consistencyGroup.getDisplayName());
cgResult = hp3parApi.getVVsetDetails(consistencyGroup.getDisplayName());
_log.info("3PARDriver: createConsistencyGroup getDetails " + cgResult.getDetails());
consistencyGroup.setNativeId(consistencyGroup.getDisplayName());
consistencyGroup.setDeviceLabel(consistencyGroup.getDisplayName());
task.setStatus(DriverTask.TaskStatus.READY);
_log.info(
"3PARDriver: createConsistencyGroup for storage system id {}, display name {} , native id {}, device lable id {} , cosistency group id {} - end",
consistencyGroup.getStorageSystemId(), consistencyGroup.getDisplayName(),
consistencyGroup.getNativeId(), consistencyGroup.getDeviceLabel(),
consistencyGroup.getConsistencyGroup());
} catch (Exception e) {
String msg = String.format(
"3PARDriver: Unable to create consistency group name %s in storage system native id is %s; Error: %s.\n",
consistencyGroup.getDisplayName(), consistencyGroup.getStorageSystemId(), e.getMessage());
_log.error(msg);
task.setMessage(msg);
task.setStatus(DriverTask.TaskStatus.FAILED);
e.printStackTrace();
}
return task;
}
public DriverTask deleteConsistencyGroup(VolumeConsistencyGroup consistencyGroup, DriverTask task,
Registry driverRegistry) {
_log.info(
"3PARDriver: deleteConsistencyGroup for storage system id {}, display name {} , native id {}, device lable id {} , cosistency group id {} - start",
consistencyGroup.getStorageSystemId(), consistencyGroup.getDisplayName(),
consistencyGroup.getNativeId(), consistencyGroup.getDeviceLabel(),
consistencyGroup.getConsistencyGroup());
try {
// get Api client
HP3PARApi hp3parApi = hp3parUtil.getHP3PARDeviceFromNativeId(consistencyGroup.getStorageSystemId(),
driverRegistry);
// Delete virtual copies of CG
hp3parApi.deleteVVset(consistencyGroup.getNativeId());
task.setStatus(DriverTask.TaskStatus.READY);
_log.info("3PARDriver: deleteConsistencyGroup for storage system native id {}, volume name {} - end",
consistencyGroup.getStorageSystemId(), consistencyGroup.getDisplayName());
} catch (Exception e) {
String msg = String.format(
"3PARDriver: deleteConsistencyGroup Unable to delete CG %s with native id %s which is part of storage system native id %s; Error: %s.\n",
consistencyGroup.getDisplayName(), consistencyGroup.getNativeId(),
consistencyGroup.getStorageSystemId(), e.getMessage());
_log.error(msg);
task.setMessage(msg);
task.setStatus(DriverTask.TaskStatus.FAILED);
e.printStackTrace();
}
return task;
}
public DriverTask createConsistencyGroupSnapshot(VolumeConsistencyGroup consistencyGroup,
List<VolumeSnapshot> snapshots, List<CapabilityInstance> capabilities, DriverTask task,
Registry driverRegistry) {
_log.info(
"3PARDriver: createConsistencyGroupSnapshot for storage system id {}, display name {} , native id {} - start",
consistencyGroup.getStorageSystemId(), consistencyGroup.getDisplayName(),
consistencyGroup.getNativeId());
String VVsetSnapshotName = consistencyGroup.getDisplayName();
VolumeDetailsCommandResult volResult = null;
try {
Boolean readOnly = true;
int noOfSnaps = snapshots.size();
// get Vipr generated Snapshot name
for (VolumeSnapshot snap : snapshots) {
// native id = null ,
_log.info(
"3PARDriver: createConsistencyGroupSnapshot for volume native id {}, snap shot name generated is {} ",
snap.getParentId(), snap.getDisplayName());
if (snap.getAccessStatus() != AccessStatus.READ_ONLY) {
readOnly = false;
}
String generatedSnapshotName = snap.getDisplayName();
if (noOfSnaps > 1) {
VVsetSnapshotName = generatedSnapshotName.substring(0, generatedSnapshotName.lastIndexOf("-")) + "-";
}
else {
VVsetSnapshotName = generatedSnapshotName;
}
_log.info("3PARDriver: createConsistencyGroupSnapshot VVsetSnapshotName {} ", VVsetSnapshotName);
break;
}
// get Api client
HP3PARApi hp3parApi = hp3parUtil.getHP3PARDeviceFromNativeId(consistencyGroup.getStorageSystemId(),
driverRegistry);
// Create vvset snapshot
hp3parApi.createVVsetVirtualCopy(consistencyGroup.getNativeId(), VVsetSnapshotName, readOnly);
int volumeNumber = 0;
int snapVolumeCount = snapshots.size();
/**
* for each volume snapshot available find correct snapshot object
* and set the values
*/
while (volumeNumber < snapVolumeCount) {
String snapshotCreated = VVsetSnapshotName + volumeNumber;
_log.info(
"3PARDriver: createConsistencyGroupSnapshot snapshotCreated {}, volumeNumber {} , snapVolumeCount {} ",
snapshotCreated, volumeNumber, snapVolumeCount);
volResult = hp3parApi.getVolumeDetails(VVsetSnapshotName + volumeNumber);
if (volResult != null) {
String baseVolume = volResult.getCopyOf();
if (baseVolume != null) {
for (VolumeSnapshot snap : snapshots) {
String parentName = snap.getParentId();
if (parentName.equals(baseVolume)) {
_log.info(
"createConsistencyGroupSnapshot Snapshot system native id {}, Parent id {}, base volume {}, "
+ "access status {}, display name {}, native Name {}, DeviceLabel {}, wwn {} - Before ",
snap.getStorageSystemId(), snap.getParentId(), baseVolume,
snap.getAccessStatus(), snap.getDisplayName(), snap.getNativeId(),
snap.getDeviceLabel(), snap.getWwn());
snap.setWwn(volResult.getWwn());
snap.setNativeId(volResult.getName());
snap.setDeviceLabel(volResult.getName());
// snap.setAccessStatus(volResult.getAccessStatus());
snap.setDisplayName(volResult.getName());
_log.info(
"createConsistencyGroupSnapshot Snapshot system native id {}, Parent Volume {}, access status {}, display name {},"
+ " native Name {}, DeviceLabel {}, wwn {} - After",
snap.getStorageSystemId(), snap.getParentId(), snap.getAccessStatus(),
snap.getDisplayName(), snap.getNativeId(), snap.getDeviceLabel(),
snap.getWwn());
}
}
} else {
_log.info("3PARDriver: createConsistencyGroupSnapshot baseVolume is null");
}
}
volumeNumber++;
}
task.setStatus(DriverTask.TaskStatus.READY);
_log.info(
"createConsistencyGroupSnapshot for storage system native id {}, CG display Name {}, CG native id {} - end",
consistencyGroup.getStorageSystemId(), consistencyGroup.getDisplayName(),
consistencyGroup.getNativeId());
} catch (Exception e) {
String msg = String.format(
"3PARDriver: Unable to create vv set snap name %s and its native id %s whose storage system id is %s; Error: %s.\n",
VVsetSnapshotName, consistencyGroup.getNativeId(), consistencyGroup.getStorageSystemId(),
e.getMessage());
_log.error(msg);
task.setMessage(msg);
task.setStatus(DriverTask.TaskStatus.PARTIALLY_FAILED);
e.printStackTrace();
}
return task;
}
public DriverTask deleteConsistencyGroupSnapshot(List<VolumeSnapshot> snapshots, DriverTask task,
Registry driverRegistry) {
String storageSystemId = null;
HP3PARApi hp3parApi = null;
// For each requested CG volume snapshot
for (VolumeSnapshot snap : snapshots) {
try {
_log.info(
"3PARDriver: deleteConsistencyGroupSnapshot for storage system native id {}, volume name {} , native id {} - start",
snap.getStorageSystemId(), snap.getDisplayName(), snap.getNativeId());
String localStorageSystemId = snap.getStorageSystemId();
// get Api client
if (storageSystemId == null || storageSystemId != localStorageSystemId) {
storageSystemId = localStorageSystemId;
hp3parApi = hp3parUtil.getHP3PARDeviceFromNativeId(localStorageSystemId, driverRegistry);
}
// Delete virtual copy
hp3parApi.deleteVirtualCopy(snap.getNativeId());
task.setStatus(DriverTask.TaskStatus.READY);
_log.info(
"3PARDriver: deleteConsistencyGroupSnapshot for storage system native id {}, volume name {} - end",
snap.getStorageSystemId(), snap.getDisplayName());
} catch (Exception e) {
String msg = String.format(
"3PARDriver: deleteConsistencyGroupSnapshot Unable to delete cg snapshot name %s with native id %s for storage system native id %s; Error: %s.\n",
snap.getDisplayName(), snap.getNativeId(), snap.getStorageSystemId(), e.getMessage());
_log.error(msg);
task.setMessage(msg);
task.setStatus(DriverTask.TaskStatus.PARTIALLY_FAILED);
e.printStackTrace();
}
} // end for each delete snapshot
return task;
}
/**
* Creating physical copy for VVset or CG clone Rest API expects created
* VVset with its corresponding volumes types for clone destination So,
* There are many ways for implementation
*
* 1. Customer will provide the VVSet name which already exist in Array
* with its corresponding similar volumes for cloning
*
* 2. Customer will not provide any existing and matching VV set with
* corresponding volumes for CG clone
*
* 3. Customer will provide VVset name which is created but volumes are not
* matching for clone creation.
*
* Create new VV Set / CG . Create new volumes similar to parent VVSet
* volumes Use this newly created VV set for CG clone
*
* option 2 is implemented, need to handle negative / error cases of option
* 3
*/
public DriverTask createConsistencyGroupClone(VolumeConsistencyGroup consistencyGroup, List<VolumeClone> clones,
List<CapabilityInstance> capabilities, DriverTask task, Registry driverRegistry) {
_log.info(
"3PARDriver: createConsistencyGroupClone for storage system id {}, Base CG name {} , Base CG native id {} - start",
consistencyGroup.getStorageSystemId(), consistencyGroup.getDisplayName(),
consistencyGroup.getNativeId());
String VVsetNameForClone = consistencyGroup.getDisplayName();
VolumeDetailsCommandResult volResult = null;
HashMap<String, VolumeClone> clonesMap = new HashMap<String, VolumeClone>();
try {
Boolean saveSnapshot = true;
// get Api client
HP3PARApi hp3parApi = hp3parUtil.getHP3PARDeviceFromNativeId(consistencyGroup.getStorageSystemId(),
driverRegistry);
// get Vipr generated clone name
for (VolumeClone clone : clones) {
// native id = null ,
_log.info("3PARDriver: createConsistencyGroupClone generated clone parent id {}, display name {} ",
clone.getParentId(), clone.getDisplayName());
String generatedCloneName = clone.getDisplayName();
VVsetNameForClone = generatedCloneName.substring(0, generatedCloneName.lastIndexOf("-"));
_log.info("3PARDriver: createConsistencyGroupClone CG name {} to be used in cloning ",
VVsetNameForClone);
clonesMap.put(clone.getParentId(), clone);
}
_log.info("3PARDriver: createConsistencyGroupClone clonesMap {}", clonesMap.toString());
// Create vvset clone
VVSetVolumeClone[] result = hp3parApi.createVVsetPhysicalCopy(consistencyGroup.getNativeId(),
VVsetNameForClone, clones, saveSnapshot);
_log.info("3PARDriver: createConsistencyGroupClone outPut of CG clone result {} ", result.toString());
for (VVSetVolumeClone cloneCreated : result) {
VolumeClone clone = clonesMap.get(cloneCreated.getParent());
_log.info(
"createConsistencyGroupClone cloneCreated {} and local clone obj nativeid = {} , parent id = {}",
cloneCreated.getValues(), clone.getNativeId(), clone.getParentId());
volResult = hp3parApi.getVolumeDetails(cloneCreated.getChild());
_log.info("createConsistencyGroupClone cloneCreated All values {} ", volResult.getAllValues());
clone.setWwn(volResult.getWwn());
clone.setNativeId(volResult.getId());
clone.setDeviceLabel(volResult.getName());
// snap.setAccessStatus(volResult.getAccessStatus());
clone.setDisplayName(volResult.getName());
clone.setReplicationState(VolumeClone.ReplicationState.SYNCHRONIZED);
clone.setProvisionedCapacity(clone.getRequestedCapacity());
clone.setAllocatedCapacity(clone.getRequestedCapacity());
}
task.setStatus(DriverTask.TaskStatus.READY);
_log.info(
"createConsistencyGroupClone for storage system native id {}, CG display Name {}, CG native id {} - end",
consistencyGroup.getStorageSystemId(), consistencyGroup.getDisplayName(),
consistencyGroup.getNativeId());
} catch (Exception e) {
String msg = String.format(
"3PARDriver: createConsistencyGroupClone Unable to create vv set snap name %s and its native id %s whose storage system id is %s; Error: %s.\n",
VVsetNameForClone, consistencyGroup.getNativeId(), consistencyGroup.getStorageSystemId(),
e.getMessage());
_log.error(msg);
task.setMessage(msg);
task.setStatus(DriverTask.TaskStatus.PARTIALLY_FAILED);
e.printStackTrace();
}
return task;
}
public HP3PARUtil getHp3parUtil() {
return hp3parUtil;
}
public void setHp3parUtil(HP3PARUtil hp3parUtil) {
this.hp3parUtil = hp3parUtil;
}
public DriverTask addOrRemoveConsistencyGroupVolume(List<StorageVolume> volumes, DriverTask task,
Registry driverRegistry, int action) {
String storageSystemId = null;
HP3PARApi hp3parApi = null;
for (StorageVolume volume : volumes) {
try {
_log.info(
"3PARDriver: removeConsistencyGroupVolume for storage system id {}, display name {} , native id {}, device lable id {} , cosistency group id {}",
volume.getStorageSystemId(), volume.getDisplayName(), volume.getNativeId(),
volume.getDeviceLabel(), volume.getConsistencyGroup());
String localStorageSystemId = volume.getStorageSystemId();
// get Api client
if (storageSystemId == null || storageSystemId != localStorageSystemId) {
storageSystemId = localStorageSystemId;
hp3parApi = hp3parUtil.getHP3PARDeviceFromNativeId(localStorageSystemId, driverRegistry);
}
// update VV Set / Consistency Group
hp3parApi.updateVVset(volume.getConsistencyGroup(), volume.getDisplayName(), action);
task.setStatus(DriverTask.TaskStatus.READY);
} catch (Exception e) {
String msg = String.format(
"3PARDriver: Unable to create consistency group name %s in storage system native id is %s; Error: %s.\n",
volume.getDisplayName(), volume.getStorageSystemId(), e.getMessage());
_log.error(msg);
task.setMessage(msg);
task.setStatus(DriverTask.TaskStatus.PARTIALLY_FAILED);
e.printStackTrace();
}
}
return task;
}
}