/*
* Copyright (c) 2016 EMC Corporation
* All Rights Reserved
*/
package com.emc.storageos.db.server.upgrade.impl.callback;
import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.emc.storageos.db.client.URIUtil;
import com.emc.storageos.db.client.model.BlockMirror;
import com.emc.storageos.db.client.model.BlockObject;
import com.emc.storageos.db.client.model.BlockSnapshot;
import com.emc.storageos.db.client.model.DiscoveredDataObject;
import com.emc.storageos.db.client.model.StorageSystem;
import com.emc.storageos.db.client.model.Volume;
import com.emc.storageos.db.client.upgrade.BaseCustomMigrationCallback;
import com.emc.storageos.db.client.upgrade.callbacks.BlockObjectSystemTypeMigration;
import com.emc.storageos.db.server.DbsvcTestBase;
import com.emc.storageos.db.server.upgrade.DbSimpleMigrationTestBase;
public class BlockObjectSystemTypeMigrationTest extends DbSimpleMigrationTestBase {
private static final Logger log = LoggerFactory.getLogger(BlockObjectSystemTypeMigrationTest.class);
private static final int VPLEX_VOLUME_COUNT = 125;
private static final int VNX_VOLUME_COUNT = 125;
private static final int VMAX_VOLUME_COUNT = 50;
private static final int VMAX3_VOLUME_COUNT = 50;
private static final int SNAPSHOT_COUNT = 33;
private static final int MIRROR_COUNT = 33;
@BeforeClass
public static void setup() throws IOException {
customMigrationCallbacks.put("3.5", new ArrayList<BaseCustomMigrationCallback>() {
private static final long serialVersionUID = 2L;
{
add(new BlockObjectSystemTypeMigration());
}
});
DbsvcTestBase.setup();
}
@Override
protected void prepareData() throws Exception {
List<Volume> volumesToCreate = new ArrayList<Volume>();
// set up a vplex system
StorageSystem vplex = new StorageSystem();
vplex.setId(URIUtil.createId(StorageSystem.class));
vplex.setLabel("TEST_VPLEX");
vplex.setSystemType(DiscoveredDataObject.Type.vplex.name());
_dbClient.createObject(vplex);
// create vplex test volumes
for (int i = 1; i <= VPLEX_VOLUME_COUNT; i++) {
Volume volume = new Volume();
volume.setId(URIUtil.createId(Volume.class));
volume.setLabel("VplexSystemTypeMigrationTester" + i);
volume.setStorageController(vplex.getId());
volumesToCreate.add(volume);
}
// set up a vnx system
StorageSystem vnx = new StorageSystem();
vnx.setId(URIUtil.createId(StorageSystem.class));
vnx.setLabel("TEST_VNX");
vnx.setSystemType(DiscoveredDataObject.Type.vnxblock.name());
_dbClient.createObject(vnx);
// create vnx test volumes
for (int i = 1; i <= VNX_VOLUME_COUNT; i++) {
Volume volume = new Volume();
volume.setId(URIUtil.createId(Volume.class));
volume.setLabel("VnxSystemTypeMigrationTester" + i);
volume.setStorageController(vnx.getId());
volumesToCreate.add(volume);
}
// set up a vmax system
StorageSystem vmax = new StorageSystem();
vmax.setId(URIUtil.createId(StorageSystem.class));
vmax.setLabel("TEST_VMAX");
vmax.setSystemType(DiscoveredDataObject.Type.vmax.name());
_dbClient.createObject(vmax);
// create vmax test volumes
for (int i = 1; i <= VMAX_VOLUME_COUNT; i++) {
Volume volume = new Volume();
volume.setId(URIUtil.createId(Volume.class));
volume.setLabel("VmaxSystemTypeMigrationTester" + i);
volume.setStorageController(vmax.getId());
volumesToCreate.add(volume);
}
// set up a vmax3 system
StorageSystem vmax3 = new StorageSystem();
vmax3.setId(URIUtil.createId(StorageSystem.class));
vmax3.setLabel("TEST_VMAX3");
// vmax3 systems are created with a "vmax" type, just to make things difficult;
// actual type is determine by the firmware version number
vmax3.setSystemType(DiscoveredDataObject.Type.vmax.name());
vmax3.setFirmwareVersion("5977.931.886");
_dbClient.createObject(vmax3);
// create vmax3 test volumes
for (int i = 1; i <= VMAX3_VOLUME_COUNT; i++) {
Volume volume = new Volume();
volume.setId(URIUtil.createId(Volume.class));
volume.setLabel("Vmax3SystemTypeMigrationTester" + i);
volume.setStorageController(vmax3.getId());
volumesToCreate.add(volume);
}
_dbClient.createObject(volumesToCreate);
List<BlockSnapshot> snapsToCreate = new ArrayList<BlockSnapshot>();
// create vmax3 test snapshots
for (int i = 1; i <= SNAPSHOT_COUNT; i++) {
BlockSnapshot snap = new BlockSnapshot();
snap.setId(URIUtil.createId(BlockSnapshot.class));
snap.setLabel("SnapshotSystemTypeMigrationTester" + i);
snap.setStorageController(vmax3.getId());
snapsToCreate.add(snap);
}
_dbClient.createObject(snapsToCreate);
List<BlockMirror> mirrorsToCreate = new ArrayList<BlockMirror>();
// create vmax3 test mirrors
for (int i = 1; i <= MIRROR_COUNT; i++) {
BlockMirror mirror = new BlockMirror();
mirror.setId(URIUtil.createId(BlockMirror.class));
mirror.setLabel("MirrorSystemTypeMigrationTester" + i);
mirror.setStorageController(vmax3.getId());
mirrorsToCreate.add(mirror);
}
_dbClient.createObject(mirrorsToCreate);
}
@Override
protected void verifyResults() throws Exception {
log.info("Verifying results of volume system type migration test now.");
Map<URI, String> storageSystemTypeMap = new HashMap<URI, String>();
List<URI> volumeUris = _dbClient.queryByType(Volume.class, true);
Iterator<Volume> volumes = _dbClient.queryIterativeObjects(Volume.class, volumeUris, true);
int vplexMigratedCount = 0;
int vnxMigratedCount = 0;
int vmaxMigratedCount = 0;
int vmax3MigratedCount = 0;
while (volumes.hasNext()) {
Volume volume = volumes.next();
String deviceSystemType = getDeviceSystemType(storageSystemTypeMap, volume);
if (deviceSystemType != null && deviceSystemType.equalsIgnoreCase(volume.getSystemType())) {
log.info("found block object system type {}", volume.getSystemType());
switch (deviceSystemType) {
case "vplex":
vplexMigratedCount++;
break;
case "vnxblock":
vnxMigratedCount++;
break;
case "vmax":
vmaxMigratedCount++;
break;
case "vmax3":
vmax3MigratedCount++;
break;
default:
log.error("unknown device system type {}", deviceSystemType);
break;
}
} else {
log.error("volume {} found not migrated properly with system type {}",
volume.forDisplay(), volume.getSystemType());
}
}
int snapshotMigratedCount = 0;
List<URI> snapshotUris = _dbClient.queryByType(BlockSnapshot.class, true);
Iterator<BlockSnapshot> snapshots = _dbClient.queryIterativeObjects(BlockSnapshot.class, snapshotUris, true);
while (snapshots.hasNext()) {
BlockSnapshot snapshot = snapshots.next();
String deviceSystemType = getDeviceSystemType(storageSystemTypeMap, snapshot);
if (deviceSystemType != null && deviceSystemType.equalsIgnoreCase(snapshot.getSystemType())) {
log.info("found block snapshot system type {}", snapshot.getSystemType());
snapshotMigratedCount++;
} else {
log.error("snapshot {} found not migrated properly with system type {}",
snapshot.forDisplay(), snapshot.getSystemType());
}
}
int mirrorMigratedCount = 0;
List<URI> mirrorUris = _dbClient.queryByType(BlockMirror.class, true);
Iterator<BlockMirror> mirrors = _dbClient.queryIterativeObjects(BlockMirror.class, mirrorUris, true);
while (mirrors.hasNext()) {
BlockMirror mirror = mirrors.next();
String deviceSystemType = getDeviceSystemType(storageSystemTypeMap, mirror);
if (deviceSystemType != null && deviceSystemType.equalsIgnoreCase(mirror.getSystemType())) {
log.info("found block mirror system type {}", mirror.getSystemType());
mirrorMigratedCount++;
} else {
log.error("mirror {} found not migrated properly with system type {}",
mirror.forDisplay(), mirror.getSystemType());
}
}
log.info("vplexMigratedCount: " + vplexMigratedCount);
log.info("vnxMigratedCount: " + vnxMigratedCount);
log.info("vmaxMigratedCount: " + vmaxMigratedCount);
log.info("vmax3MigratedCount: " + vmax3MigratedCount);
log.info("snapshotMigratedCount: " + snapshotMigratedCount);
log.info("mirrorMigratedCount: " + mirrorMigratedCount);
Assert.assertEquals(String.format("We should have found %d migrated VPLEX volumes.", VPLEX_VOLUME_COUNT),
VPLEX_VOLUME_COUNT, vplexMigratedCount);
Assert.assertEquals(String.format("We should have found %d migrated VNX volumes.", VNX_VOLUME_COUNT),
VNX_VOLUME_COUNT, vnxMigratedCount);
Assert.assertEquals(String.format("We should have found %d migrated VMAX volumes.", VMAX_VOLUME_COUNT),
VMAX_VOLUME_COUNT, vmaxMigratedCount);
Assert.assertEquals(String.format("We should have found %d migrated VMAX3 volumes.", VMAX3_VOLUME_COUNT),
VMAX3_VOLUME_COUNT, vmax3MigratedCount);
Assert.assertEquals(String.format("We should have found %d migrated VMAX3 snapshots.", SNAPSHOT_COUNT),
SNAPSHOT_COUNT, snapshotMigratedCount);
Assert.assertEquals(String.format("We should have found %d migrated VMAX3 mirrors.", MIRROR_COUNT),
MIRROR_COUNT, mirrorMigratedCount);
}
private String getDeviceSystemType(Map<URI, String> storageSystemTypeMap, BlockObject blockObject) {
String deviceSystemType = null;
URI storageSystemUri = blockObject.getStorageController();
if (storageSystemTypeMap.containsKey(storageSystemUri)) {
deviceSystemType = storageSystemTypeMap.get(storageSystemUri);
} else {
StorageSystem storageSystem = _dbClient.queryObject(StorageSystem.class, storageSystemUri);
if (storageSystem != null) {
deviceSystemType = storageSystem.checkIfVmax3() ? DiscoveredDataObject.Type.vmax3.name()
: storageSystem.getSystemType();
storageSystemTypeMap.put(storageSystemUri, deviceSystemType);
log.info("adding storage system type {} for storage system URI {}",
deviceSystemType, storageSystemUri);
} else {
log.warn("could not find storage system by URI {} for BlockObject {}",
storageSystemUri, blockObject.forDisplay());
}
}
return deviceSystemType;
}
}