/* * Copyright (c) 2016 EMC Corporation * All Rights Reserved */ package com.emc.storageos.driver.driversimulator; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.UUID; import org.apache.commons.lang.mutable.MutableBoolean; import org.apache.commons.lang.mutable.MutableInt; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.emc.storageos.driver.driversimulator.operations.CreateGroupCloneSimulatorOperation; import com.emc.storageos.driver.driversimulator.operations.CreateVolumeCloneSimulatorOperation; import com.emc.storageos.driver.driversimulator.operations.DriverSimulatorOperation; import com.emc.storageos.driver.driversimulator.operations.ExpandVolumeSimulatorOperation; import com.emc.storageos.driver.driversimulator.operations.RestoreFromCloneSimulatorOperation; import com.emc.storageos.driver.driversimulator.operations.RestoreFromSnapshotSimulatorOperation; import com.emc.storageos.storagedriver.BlockStorageDriver; import com.emc.storageos.storagedriver.DefaultStorageDriver; import com.emc.storageos.storagedriver.DriverTask; import com.emc.storageos.storagedriver.HostExportInfo; import com.emc.storageos.storagedriver.RegistrationData; import com.emc.storageos.storagedriver.model.Initiator; import com.emc.storageos.storagedriver.model.StorageBlockObject; import com.emc.storageos.storagedriver.model.StorageHostComponent; import com.emc.storageos.storagedriver.model.StorageObject; import com.emc.storageos.storagedriver.model.StoragePool; import com.emc.storageos.storagedriver.model.StoragePort; import com.emc.storageos.storagedriver.model.StorageProvider; import com.emc.storageos.storagedriver.model.StorageSystem; import com.emc.storageos.storagedriver.model.StorageVolume; import com.emc.storageos.storagedriver.model.VolumeClone; import com.emc.storageos.storagedriver.model.VolumeConsistencyGroup; import com.emc.storageos.storagedriver.model.VolumeMirror; import com.emc.storageos.storagedriver.model.VolumeSnapshot; import com.emc.storageos.storagedriver.storagecapabilities.AutoTieringPolicyCapabilityDefinition; import com.emc.storageos.storagedriver.storagecapabilities.CapabilityInstance; import com.emc.storageos.storagedriver.storagecapabilities.StorageCapabilities; public class StorageDriverSimulator extends DefaultStorageDriver implements BlockStorageDriver { private static final Logger _log = LoggerFactory.getLogger(StorageDriverSimulator.class); public static final String DRIVER_NAME = "SimulatorDriver"; private static final int NUMBER_OF_VOLUME_PAGES = 3; private static final int NUMBER_OF_VOLUMES_ON_PAGE = 2; private static final int NUMBER_OF_CLONES_FOR_VOLUME = 2; private static final int NUMBER_OF_SNAPS_FOR_VOLUME = 2; private static final boolean VOLUMES_IN_CG = true; private static final boolean SNAPS_IN_CG = true; private static final boolean CLONES_IN_CG = true; private static final boolean GENERATE_EXPORT_DATA = true; private static final String SIMULATOR_CONF_FILE = "simulator-conf.xml"; private static final String CONFIG_BEAN_NAME = "simulatorConfig"; private ApplicationContext parentApplicationContext; private SimulatorConfiguration simulatorConfig; private Map<String, DriverSimulatorOperation> taskOperationMap = new HashMap<String, DriverSimulatorOperation>(); private static Integer portIndex = 0; private static Map<String, Integer> systemNameToPortIndexName = new HashMap<>(); // map for storage system to host export info data for a volume; // key: array native id // value: map where key is volume native id and value is list of volume export info object for this volume for different hosts (one entry for each host) private static Map<String, Map<String, List<HostExportInfo>>> arrayToVolumeToVolumeExportInfoMap = new HashMap<>(); // defines which volume page is exported to which host private static Map<Integer, List<String>> pageToHostMap; private static Map<String, List<Integer>> hostToPageMap; static { pageToHostMap = new HashMap<>(); pageToHostMap.put(0, Arrays.asList("10.20.30.40", "10.20.30.50")); pageToHostMap.put(1, Arrays.asList("10.20.30.50")); pageToHostMap.put(2, Arrays.asList("10.20.30.60")); hostToPageMap = new HashMap<>(); hostToPageMap.put("10.20.30.40",Arrays.asList(0)); hostToPageMap.put("10.20.30.50", Arrays.asList(0,1)); hostToPageMap.put("10.20.30.60", Arrays.asList(2)); } private static Map<String, List<String>> hostToInitiatorPortIdMap; static { // each host with two initiators hostToInitiatorPortIdMap = new HashMap<>(); hostToInitiatorPortIdMap.put(pageToHostMap.get(0).get(0), new ArrayList<>(Arrays.asList("50:06:01:61:36:68:08:81", "50:06:01:61:36:68:08:82"))); hostToInitiatorPortIdMap.put(pageToHostMap.get(1).get(0), new ArrayList<>(Arrays.asList("50:06:01:61:36:68:09:81", "50:06:01:61:36:68:09:82"))); hostToInitiatorPortIdMap.put(pageToHostMap.get(2).get(0), new ArrayList<>(Arrays.asList("50:06:01:61:36:68:10:81", "50:06:01:61:36:68:10:82"))); } //StorageDriver implementation public StorageDriverSimulator() { ApplicationContext context = new ClassPathXmlApplicationContext(new String[] {SIMULATOR_CONF_FILE}, parentApplicationContext); simulatorConfig = (SimulatorConfiguration) context.getBean(CONFIG_BEAN_NAME); } public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.parentApplicationContext = applicationContext; } @Override public RegistrationData getRegistrationData() { RegistrationData registrationData = new RegistrationData("driverSimulator", "driversystem", null); return registrationData; } @Override public DriverTask getTask(String taskId) { if (!taskOperationMap.containsKey(taskId)) { _log.error("Invalid task Id {}", taskId); return null; } DriverSimulatorOperation taskOperation = taskOperationMap.get(taskId); if (taskOperation.getLookupCount() < simulatorConfig.getMaxAsynchronousLookups()) { taskOperation.incrementLookupCount(); _log.info("This is lookup {} for task {}", taskOperation.getLookupCount(), taskId); } else { taskOperationMap.remove(taskId); if (simulatorConfig.getSimulateFailures()) { _log.info("Simulating asynchronous failure for task {} of type {}", taskId, taskOperation.getType()); String errorMsg = taskOperation.getFailureMessage(); taskOperation.doFailure(errorMsg); } else { _log.info("Simulating asynchronous success for task {} of type {}", taskId, taskOperation.getType()); taskOperation.updateOnAsynchronousSuccess(); String successMsg = taskOperation.getSuccessMessage(); taskOperation.doSuccess(successMsg); } } return taskOperation.getDriverTask(); } @Override public <T extends StorageObject> T getStorageObject(String storageSystemId, String objectId, Class<T> type) { if (StorageVolume.class.getSimpleName().equals(type.getSimpleName())) { StorageVolume obj = new StorageVolume(); obj.setAllocatedCapacity(200L); _log.info("getStorageObject: storage volume allocated capacity: {}", obj.getAllocatedCapacity()); return (T) obj; } else if (VolumeConsistencyGroup.class.getSimpleName().equals(type.getSimpleName())) { VolumeConsistencyGroup cg = new VolumeConsistencyGroup(); cg.setStorageSystemId(storageSystemId); cg.setNativeId(objectId); cg.setDeviceLabel(objectId); _log.info("Return volume cg {} from array {}", objectId, storageSystemId); return (T) cg; } else if (StoragePool.class.getSimpleName().equals(type.getSimpleName())) { StoragePool pool = new StoragePool(); pool.setFreeCapacity(40000000L); // 40 GB pool.setSubscribedCapacity(10000000L); // 10 GB pool.setNativeId(objectId); pool.setStorageSystemId(storageSystemId); _log.info("getStorageObject: storage pool free capacity: {}, subscribed capacity: {}", pool.getFreeCapacity(), pool.getSubscribedCapacity()); return (T) pool; } else { _log.error("getStorageObject: not supported for type: {}", type.getSimpleName()); return null; } } // DiscoveryDriver implementation @Override public DriverTask discoverStorageSystem(StorageSystem storageSystem) { _log.info("StorageDriver: discoverStorageSystem information for storage system {}, name {} - start", storageSystem.getIpAddress(), storageSystem.getSystemName()); String taskType = "discover-storage-system"; String taskId = String.format("%s+%s+%s", DRIVER_NAME, taskType, UUID.randomUUID().toString()); DriverTask task = new DriverSimulatorTask(taskId); try { if (storageSystem.getSerialNumber() == null) { storageSystem.setSerialNumber(storageSystem.getSystemName()); } if (storageSystem.getNativeId() == null) { storageSystem.setNativeId(storageSystem.getSystemName()); } storageSystem.setFirmwareVersion("2.4-3.12"); storageSystem.setIsSupportedVersion(true); setConnInfoToRegistry(storageSystem.getNativeId(), storageSystem.getIpAddress(), storageSystem.getPortNumber(), storageSystem.getUsername(), storageSystem.getPassword()); // Support both, element and group replicas. Set<StorageSystem.SupportedReplication> supportedReplications = new HashSet<>(); supportedReplications.add(StorageSystem.SupportedReplication.elementReplica); supportedReplications.add(StorageSystem.SupportedReplication.groupReplica); storageSystem.setSupportedReplications(supportedReplications); task.setStatus(DriverTask.TaskStatus.READY); _log.info("StorageDriver: discoverStorageSystem information for storage system {}, nativeId {} - end", storageSystem.getIpAddress(), storageSystem.getNativeId()); return task; } catch (Exception e) { task.setStatus(DriverTask.TaskStatus.FAILED); e.printStackTrace(); } return task; } @Override public DriverTask discoverStoragePools(StorageSystem storageSystem, List<StoragePool> storagePools) { _log.info("Discovery of storage pools for storage system {} .", storageSystem.getNativeId()); String taskType = "discover-storage-pools"; String taskId = String.format("%s+%s+%s", DRIVER_NAME, taskType, UUID.randomUUID().toString()); DriverTask task = new DriverSimulatorTask(taskId); AutoTieringPolicyCapabilityDefinition capabilityDefinition = new AutoTieringPolicyCapabilityDefinition(); try { // Get connection information. Map<String, List<String>> connectionInfo = driverRegistry.getDriverAttributesForKey("StorageDriverSimulator", storageSystem.getNativeId()); _log.info("Storage system connection info: {} : {}", storageSystem.getNativeId(), connectionInfo); for (int i =0; i <= 2; i++ ) { StoragePool pool = new StoragePool(); pool.setNativeId("pool-1234577-" + i + storageSystem.getNativeId()); pool.setStorageSystemId(storageSystem.getNativeId()); _log.info("Discovered Pool {}, storageSystem {}", pool.getNativeId(), pool.getStorageSystemId()); pool.setDeviceLabel("er-pool-1234577" + i + storageSystem.getNativeId()); pool.setPoolName(pool.getDeviceLabel()); Set<StoragePool.Protocols> protocols = new HashSet<>(); protocols.add(StoragePool.Protocols.FC); protocols.add(StoragePool.Protocols.iSCSI); //protocols.add(StoragePool.Protocols.ScaleIO); pool.setProtocols(protocols); pool.setPoolServiceType(StoragePool.PoolServiceType.block); pool.setMaximumThickVolumeSize(3000000L); pool.setMinimumThickVolumeSize(1000L); pool.setMaximumThinVolumeSize(5000000L); pool.setMinimumThinVolumeSize(1000L); if (i%2 == 0) { pool.setSupportedResourceType(StoragePool.SupportedResourceType.THIN_ONLY); } else { pool.setSupportedResourceType(StoragePool.SupportedResourceType.THICK_ONLY); } pool.setSubscribedCapacity(5000000L); pool.setFreeCapacity(45000000L); pool.setTotalCapacity(48000000L); pool.setOperationalStatus(StoragePool.PoolOperationalStatus.READY); Set<StoragePool.SupportedDriveTypes> supportedDriveTypes = new HashSet<>(); supportedDriveTypes.add(StoragePool.SupportedDriveTypes.FC); supportedDriveTypes.add(StoragePool.SupportedDriveTypes.SATA); pool.setSupportedDriveTypes(supportedDriveTypes); // Set<StoragePool.RaidLevels> raidLevels = new HashSet<>(); // raidLevels.add(StoragePool.RaidLevels.RAID5); // raidLevels.add(StoragePool.RaidLevels.RAID6); // pool.setSupportedRaidLevels(raidLevels); List<CapabilityInstance> capabilities = new ArrayList<>(); for (int j = 1; j <= 2; j++) { String policyId = "Auto-Tier-Policy-" + i + j; Map<String, List<String>> props = new HashMap<>(); props.put(AutoTieringPolicyCapabilityDefinition.PROPERTY_NAME.POLICY_ID.name(), Arrays.asList(policyId)); String provisioningType; if (i%2 == 0) { provisioningType = StoragePool.AutoTieringPolicyProvisioningType.ThinlyProvisioned.name(); } else { provisioningType = StoragePool.AutoTieringPolicyProvisioningType.ThicklyProvisioned.name(); } props.put(AutoTieringPolicyCapabilityDefinition.PROPERTY_NAME.PROVISIONING_TYPE.name(), Arrays.asList(provisioningType)); CapabilityInstance capabilityInstance = new CapabilityInstance(capabilityDefinition.getId(), policyId, props); capabilities.add(capabilityInstance); } pool.setCapabilities(capabilities); storagePools.add(pool); } task.setStatus(DriverTask.TaskStatus.READY); _log.info("StorageDriver: discoverStoragePools information for storage system {}, nativeId {} - end", storageSystem.getIpAddress(), storageSystem.getNativeId()); } catch (Exception e) { task.setStatus(DriverTask.TaskStatus.FAILED); e.printStackTrace(); } return task; } @Override public DriverTask discoverStoragePorts(StorageSystem storageSystem, List<StoragePort> storagePorts) { _log.info("Discovery of storage ports for storage system {} .", storageSystem.getNativeId()); int index = 0; // Get "portIndexes" attribute map Map<String, List<String>> portIndexes = driverRegistry.getDriverAttributesForKey("simulatordriver", "portIndexes"); if (portIndexes != null) { List<String> indexes = portIndexes.get(storageSystem.getNativeId()); if (indexes != null) { index = Integer.parseInt(indexes.get(0)); _log.info("Storage ports index for storage system {} is {} .", storageSystem.getNativeId(), index); } } if (index == 0) { // no index for this system in the registry // get the last used index and increment by 1 to generate an index if (portIndexes != null) { List<String> indexes = portIndexes.get("lastIndex"); if (indexes != null) { index = Integer.parseInt(indexes.get(0)) + 1; } else { index ++; } } else { index ++; } // set this index for the system in registry driverRegistry.addDriverAttributeForKey("simulatordriver", "portIndexes", storageSystem.getNativeId(), Collections.singletonList(String.valueOf(index))); driverRegistry.addDriverAttributeForKey("simulatordriver", "portIndexes", "lastIndex", Collections.singletonList(String.valueOf(index))); _log.info("Storage ports index for storage system {} is {} .", storageSystem.getNativeId(), index); } // Integer index = systemNameToPortIndexName.get(storageSystem.getNativeId()); // if(index == null) { // // Get "portIndexes" attribute map // //Map<String, List<String>> portIndexes = driverRegistry.getDriverAttributesForKey("simulatordriver", "portIndexes"); // // index = ++portIndex; // systemNameToPortIndexName.put(storageSystem.getNativeId(), index); // } // Create ports with network for (int i =0; i <= 2; i++ ) { StoragePort port = new StoragePort(); port.setNativeId("port-1234577-" + i + storageSystem.getNativeId()); port.setStorageSystemId(storageSystem.getNativeId()); _log.info("Discovered Port {}, storageSystem {}", port.getNativeId(), port.getStorageSystemId()); port.setDeviceLabel("er-port-1234577" + i + storageSystem.getNativeId()); port.setPortName(port.getDeviceLabel()); //port.setNetworkId("er-network77"+ storageSystem.getNativeId()); port.setNetworkId("11"); port.setTransportType(StoragePort.TransportType.FC); //port.setTransportType(StoragePort.TransportType.IP); port.setPortNetworkId("6" + Integer.toHexString(index) + ":FE:FE:FE:FE:FE:FE:1" + i); port.setOperationalStatus(StoragePort.OperationalStatus.OK); port.setPortHAZone("zone-"+i); storagePorts.add(port); } // Create ports without network for (int i =3; i <= 6; i++ ) { StoragePort port = new StoragePort(); port.setNativeId("port-1234577-" + i+ storageSystem.getNativeId()); port.setStorageSystemId(storageSystem.getNativeId()); _log.info("Discovered Port {}, storageSystem {}", port.getNativeId(), port.getStorageSystemId()); port.setDeviceLabel("er-port-1234577" + i+ storageSystem.getNativeId()); port.setPortName(port.getDeviceLabel()); //port.setNetworkId("er-network77"+ storageSystem.getNativeId()); port.setTransportType(StoragePort.TransportType.FC); port.setPortNetworkId("6" + Integer.toHexString(index) + ":FE:FE:FE:FE:FE:FE:1" + i); port.setOperationalStatus(StoragePort.OperationalStatus.OK); port.setPortHAZone("zone-with-many-ports"); storagePorts.add(port); } String taskType = "discover-storage-ports"; String taskId = String.format("%s+%s+%s", DRIVER_NAME, taskType, UUID.randomUUID().toString()); DriverTask task = new DriverSimulatorTask(taskId); task.setStatus(DriverTask.TaskStatus.READY); _log.info("StorageDriver: discoverStoragePorts information for storage system {}, nativeId {} - end", storageSystem.getIpAddress(), storageSystem.getNativeId()); return task; } @Override public DriverTask stopManagement(StorageSystem driverStorageSystem){ _log.info("Stopping management for StorageSystem {}", driverStorageSystem.getNativeId()); String driverName = this.getClass().getSimpleName(); String taskId = String.format("%s+%s+%s", driverName, "stopManagement", UUID.randomUUID().toString()); DriverTask task = new DriverSimulatorTask(taskId); task.setStatus(DriverTask.TaskStatus.READY); String msg = String.format("Driver stopped managing storage system %s.",driverStorageSystem.getNativeId()); _log.info(msg); task.setMessage(msg); return task; } @Override public DriverTask createVolumes(List<StorageVolume> volumes, StorageCapabilities capabilities) { //String newVolumes = ""; Set<String> newVolumes = new HashSet<>(); for (StorageVolume volume : volumes) { volume.setNativeId("driverSimulatorVolume" + UUID.randomUUID().toString()); volume.setAccessStatus(StorageVolume.AccessStatus.READ_WRITE); volume.setProvisionedCapacity(volume.getRequestedCapacity()); volume.setAllocatedCapacity(volume.getRequestedCapacity()); volume.setDeviceLabel(volume.getNativeId()); volume.setWwn(String.format("%s%s", volume.getStorageSystemId(), volume.getNativeId())); // newVolumes = newVolumes + volume.getNativeId() + " "; newVolumes.add(volume.getNativeId()); } String taskType = "create-storage-volumes"; String taskId = String.format("%s+%s+%s", DRIVER_NAME, taskType, UUID.randomUUID().toString()); DriverTask task = new DriverSimulatorTask(taskId); task.setStatus(DriverTask.TaskStatus.READY); String msg = String.format("StorageDriver: createVolumes information for storage system %s, volume nativeIds %s - end", volumes.get(0).getStorageSystemId(), newVolumes.toString()); _log.info(msg); task.setMessage(msg); return task; } @Override public DriverTask expandVolume(StorageVolume volume, long newCapacity) { ExpandVolumeSimulatorOperation expandVolumeSimulatorOperation = new ExpandVolumeSimulatorOperation(volume, newCapacity); if (simulatorConfig.getSimulateAsynchronousResponses()) { DriverTask driverTask = expandVolumeSimulatorOperation.getDriverTask(); taskOperationMap.put(driverTask.getTaskId(), expandVolumeSimulatorOperation); return driverTask; } else if (simulatorConfig.getSimulateFailures()) { String failMsg = expandVolumeSimulatorOperation.getFailureMessage(); return expandVolumeSimulatorOperation.doFailure(failMsg); } else { expandVolumeSimulatorOperation.updateVolumeInfo(volume, newCapacity); String successMsg = expandVolumeSimulatorOperation.getSuccessMessage(volume); return expandVolumeSimulatorOperation.doSuccess(successMsg); } } @Override public DriverTask deleteVolume(StorageVolume volume) { String taskType = "delete-storage-volumes"; String taskId = String.format("%s+%s+%s", DRIVER_NAME, taskType, UUID.randomUUID().toString()); DriverTask task = new DriverSimulatorTask(taskId); task.setStatus(DriverTask.TaskStatus.READY); _log.info("StorageDriver: deleteVolumes information for storage system {}, volume nativeIds {} - end", volume.getStorageSystemId(), volume.toString()); return task; } @Override public DriverTask addVolumesToConsistencyGroup (List<StorageVolume> volumes, StorageCapabilities capabilities){ _log.info("Adding {} Volumes to Consistency Group {}", volumes.toString(), volumes.get(0).getConsistencyGroup()); String taskType = "add-volumes-to-consistency-groupd"; String taskId = String.format("%s+%s+%s", DRIVER_NAME, taskType, UUID.randomUUID().toString()); DriverTask task = new DriverSimulatorTask(taskId); task.setStatus(DriverTask.TaskStatus.READY); String msg = String.format("StorageDriver: addVolumesToConsistencyGroup information for storage system %s, volume nativeIds %s, Consistency Group - end", volumes.get(0).getStorageSystemId(), volumes.toString()); _log.info(msg); task.setMessage(msg); return task; } @Override public DriverTask removeVolumesFromConsistencyGroup(List<StorageVolume> volumes, StorageCapabilities capabilities){ _log.info("Remove {} Volumes from Consistency Group {}", volumes.toString(), volumes.get(0).getConsistencyGroup()); String taskType = "remove-volumes-to-consistency-groupd"; String taskId = String.format("%s+%s+%s", DRIVER_NAME, taskType, UUID.randomUUID().toString()); DriverTask task = new DriverSimulatorTask(taskId); task.setStatus(DriverTask.TaskStatus.READY); String msg = String.format("StorageDriver: removeVolumesFromConsistencyGroup information for storage system %s, volume nativeIds %s, Consistency Group - end", volumes.get(0).getStorageSystemId(), volumes.toString()); _log.info(msg); task.setMessage(msg); return task; } @Override public DriverTask createVolumeSnapshot(List<VolumeSnapshot> snapshots, StorageCapabilities capabilities) { String snapTimestamp = Long.toString(System.currentTimeMillis()); for (VolumeSnapshot snapshot : snapshots) { snapshot.setNativeId("snap-" + snapshot.getParentId() + UUID.randomUUID().toString()); snapshot.setConsistencyGroup(snapTimestamp); snapshot.setAllocatedCapacity(1000L); snapshot.setProvisionedCapacity(2000L); } String taskType = "create-volume-snapshot"; String taskId = String.format("%s+%s+%s", DRIVER_NAME, taskType, UUID.randomUUID().toString()); DriverTask task = new DriverSimulatorTask(taskId); task.setStatus(DriverTask.TaskStatus.READY); _log.info("StorageDriver: createVolumeSnapshot information for storage system {}, snapshots nativeIds {} - end", snapshots.get(0).getStorageSystemId(), snapshots.toString()); return task; } @Override public DriverTask restoreSnapshot(List<VolumeSnapshot> snapshots) { RestoreFromSnapshotSimulatorOperation restoreSnapshotSimulatorOperation = new RestoreFromSnapshotSimulatorOperation(snapshots); if (simulatorConfig.getSimulateAsynchronousResponses()) { DriverTask driverTask = restoreSnapshotSimulatorOperation.getDriverTask(); taskOperationMap.put(driverTask.getTaskId(), restoreSnapshotSimulatorOperation); return driverTask; } else if (simulatorConfig.getSimulateFailures()) { String failMsg = restoreSnapshotSimulatorOperation.getFailureMessage(); return restoreSnapshotSimulatorOperation.doFailure(failMsg); } else { String successMsg = restoreSnapshotSimulatorOperation.getSuccessMessage(snapshots); return restoreSnapshotSimulatorOperation.doSuccess(successMsg); } } @Override public DriverTask deleteVolumeSnapshot(VolumeSnapshot snapshot) { String taskType = "delete-volume-snapshot"; String taskId = String.format("%s+%s+%s", DRIVER_NAME, taskType, UUID.randomUUID().toString()); DriverTask task = new DriverSimulatorTask(taskId); task.setStatus(DriverTask.TaskStatus.READY); String msg = String.format("StorageDriver: deleteVolumSnapshot for storage system %s, " + "snapshots nativeId %s - end", snapshot.getStorageSystemId(), snapshot.toString()); _log.info(msg); task.setMessage(msg); return task; } @Override public DriverTask createVolumeClone(List<VolumeClone> clones, StorageCapabilities capabilities) { CreateVolumeCloneSimulatorOperation createCloneSimulatorOperation = new CreateVolumeCloneSimulatorOperation(clones); if (simulatorConfig.getSimulateAsynchronousResponses()) { DriverTask driverTask = createCloneSimulatorOperation.getDriverTask(); taskOperationMap.put(driverTask.getTaskId(), createCloneSimulatorOperation); return driverTask; } else if (simulatorConfig.getSimulateFailures()) { String failMsg = createCloneSimulatorOperation.getFailureMessage(); return createCloneSimulatorOperation.doFailure(failMsg); } else { createCloneSimulatorOperation.updateCloneInfo(clones); String successMsg = createCloneSimulatorOperation.getSuccessMessage(clones); return createCloneSimulatorOperation.doSuccess(successMsg); } } @Override public DriverTask detachVolumeClone(List<VolumeClone> clones) { String taskType = "detach-volume-clone"; String taskId = String.format("%s+%s+%s", DRIVER_NAME, taskType, UUID.randomUUID().toString()); DriverTask task = new DriverSimulatorTask(taskId); task.setStatus(DriverTask.TaskStatus.READY); String msg = String.format("StorageDriver: detachVolumeClone for storage system %s, " + "clones nativeId %s - end", clones.get(0).getStorageSystemId(), clones.toString()); _log.info(msg); task.setMessage(msg); return task; } @Override public DriverTask restoreFromClone(List<VolumeClone> clones) { RestoreFromCloneSimulatorOperation restoreCloneSimulatorOperation = new RestoreFromCloneSimulatorOperation(clones); if (simulatorConfig.getSimulateAsynchronousResponses()) { DriverTask driverTask = restoreCloneSimulatorOperation.getDriverTask(); taskOperationMap.put(driverTask.getTaskId(), restoreCloneSimulatorOperation); return driverTask; } else if (simulatorConfig.getSimulateFailures()) { String failMsg = restoreCloneSimulatorOperation.getFailureMessage(); return restoreCloneSimulatorOperation.doFailure(failMsg); } else { restoreCloneSimulatorOperation.updateCloneInfo(clones); String successMsg = restoreCloneSimulatorOperation.getSuccessMessage(clones); return restoreCloneSimulatorOperation.doSuccess(successMsg); } } @Deprecated public DriverTask deleteVolumeClone(VolumeClone clone) { String taskType = "delete-volume-clone"; String taskId = String.format("%s+%s+%s", DRIVER_NAME, taskType, UUID.randomUUID().toString()); DriverTask task = new DriverSimulatorTask(taskId); task.setStatus(DriverTask.TaskStatus.READY); String msg = String.format("StorageDriver: deleteVolumeClone for storage system %s, " + "clones nativeId %s - end", clone.getStorageSystemId(), clone.toString()); _log.info(msg); task.setMessage(msg); return task; } @Override public DriverTask createVolumeMirror(List<VolumeMirror> mirrors, StorageCapabilities capabilities) { return null; } @Override public DriverTask deleteVolumeMirror(VolumeMirror mirror) { return null; } @Override public DriverTask splitVolumeMirror(List<VolumeMirror> mirrors) { return null; } @Override public DriverTask resumeVolumeMirror(List<VolumeMirror> mirrors) { return null; } @Override public Map<String, HostExportInfo> getVolumeExportInfoForHosts(StorageVolume volume) { _log.info("Processing export info for volume: {}", volume); Map<String, HostExportInfo> exportInfoMap = getStorageObjectExportInfo(volume.getStorageSystemId(), volume.getNativeId()); _log.info("Export info data for volume {}: {} .", volume, exportInfoMap); return exportInfoMap; } @Override public Map<String, HostExportInfo> getSnapshotExportInfoForHosts(VolumeSnapshot snapshot) { _log.info("Processing export info for snapshot: {}", snapshot); Map<String, HostExportInfo> exportInfoMap = getStorageObjectExportInfo(snapshot.getStorageSystemId(), snapshot.getNativeId()); _log.info("Export info data for volume {}: {} .", snapshot, exportInfoMap); return exportInfoMap; } @Override public Map<String, HostExportInfo> getCloneExportInfoForHosts(VolumeClone clone) { _log.info("Processing export info for volume: {}", clone); Map<String, HostExportInfo> exportInfoMap = getStorageObjectExportInfo(clone.getStorageSystemId(), clone.getNativeId()); _log.info("Export info data for volume {}: {} .", clone, exportInfoMap); return exportInfoMap; } @Override public Map<String, HostExportInfo> getMirrorExportInfoForHosts(VolumeMirror mirror) { _log.info("Processing export info for volume: {}", mirror); Map<String, HostExportInfo> exportInfoMap = getStorageObjectExportInfo(mirror.getStorageSystemId(), mirror.getNativeId()); _log.info("Export info data for volume {}: {} .", mirror, exportInfoMap); return exportInfoMap; } private Map<String, HostExportInfo> getStorageObjectExportInfo(String systemId, String objectId) { Map<String, HostExportInfo> resultMap = new HashMap<>(); Map<String, List<HostExportInfo>> volumeToHostExportInfoMap = arrayToVolumeToVolumeExportInfoMap.get(systemId); // get storage object export data if (volumeToHostExportInfoMap != null) { List<HostExportInfo> volumeExportInfo = volumeToHostExportInfoMap.get(objectId); if (volumeExportInfo != null) { for (HostExportInfo exportInfo : volumeExportInfo) { resultMap.put(exportInfo.getHostName(), exportInfo); } } } return resultMap; } @Override public DriverTask exportVolumesToInitiators(List<Initiator> initiators, List<StorageVolume> volumes, Map<String, String> volumeToHLUMap, List<StoragePort> recommendedPorts, List<StoragePort> availablePorts, StorageCapabilities capabilities, MutableBoolean usedRecommendedPorts, List<StoragePort> selectedPorts) { usedRecommendedPorts.setValue(true); selectedPorts.addAll(recommendedPorts); String taskType = "export-volumes-to-initiators"; String taskId = String.format("%s+%s+%s", DRIVER_NAME, taskType, UUID.randomUUID().toString()); DriverTask task = new DriverSimulatorTask(taskId); task.setStatus(DriverTask.TaskStatus.READY); String msg = String.format("StorageDriver: exportVolumesToInitiators: export type %s, initiators %s .", initiators.get(0).getInitiatorType(), initiators.toString()); _log.info(msg); task.setMessage(msg); return task; } @Override public DriverTask unexportVolumesFromInitiators(List<Initiator> initiators, List<StorageVolume> volumes) { String taskType = "unexport-volumes-from-initiators"; String taskId = String.format("%s+%s+%s", DRIVER_NAME, taskType, UUID.randomUUID().toString()); DriverTask task = new DriverSimulatorTask(taskId); task.setStatus(DriverTask.TaskStatus.READY); String msg = String.format("StorageDriver: unexportVolumesFromInitiators: export type %s, initiators %s .", initiators.get(0).getInitiatorType(), initiators.toString()); _log.info(msg); task.setMessage(msg); return task; } @Override public DriverTask createConsistencyGroup(VolumeConsistencyGroup consistencyGroup) { consistencyGroup.setNativeId(consistencyGroup.getDisplayName()); consistencyGroup.setDeviceLabel(consistencyGroup.getDisplayName()); String taskType = "create-volume-cg"; String taskId = String.format("%s+%s+%s", DRIVER_NAME, taskType, UUID.randomUUID().toString()); DriverTask task = new DriverSimulatorTask(taskId); task.setStatus(DriverTask.TaskStatus.READY); String msg = String.format("StorageDriver: createConsistencyGroup information for storage system %s, consistencyGroup nativeId %s - end", consistencyGroup.getStorageSystemId(), consistencyGroup.getNativeId()); _log.info(msg); task.setMessage(msg); return task; } @Override public DriverTask deleteConsistencyGroup(VolumeConsistencyGroup consistencyGroup) { String taskType = "delete-volume-cg"; String taskId = String.format("%s+%s+%s", DRIVER_NAME, taskType, UUID.randomUUID().toString()); DriverTask task = new DriverSimulatorTask(taskId); task.setStatus(DriverTask.TaskStatus.READY); String msg = String.format("StorageDriver: deleteConsistencyGroup information for storage system %s, consistencyGroup nativeId %s - end", consistencyGroup.getStorageSystemId(), consistencyGroup.getNativeId()); _log.info(msg); task.setMessage(msg); return task; } @Override public DriverTask createConsistencyGroupSnapshot(VolumeConsistencyGroup consistencyGroup, List<VolumeSnapshot> snapshots, List<CapabilityInstance> capabilities) { String snapTimestamp = Long.toString(System.currentTimeMillis()); for (VolumeSnapshot snapshot : snapshots) { snapshot.setNativeId("snap-" + snapshot.getParentId() + consistencyGroup.getDisplayName() + UUID.randomUUID().toString()); snapshot.setConsistencyGroup(snapTimestamp); snapshot.setSnapSetId(snapTimestamp); } String taskType = "create-group-snapshot"; String taskId = String.format("%s+%s+%s", DRIVER_NAME, taskType, UUID.randomUUID().toString()); DriverTask task = new DriverSimulatorTask(taskId); task.setStatus(DriverTask.TaskStatus.READY); task.setMessage("Created snapshots for consistency group " + snapshots.get(0).getConsistencyGroup()); _log.info("StorageDriver: createGroupSnapshot information for storage system {}, snapshots nativeIds {} - end", snapshots.get(0).getStorageSystemId(), snapshots.toString()); return task; } @Override public DriverTask deleteConsistencyGroupSnapshot(List<VolumeSnapshot> snapshots) { String taskType = "delete-volume-cg-snapshot"; String taskId = String.format("%s+%s+%s", DRIVER_NAME, taskType, UUID.randomUUID().toString()); DriverTask task = new DriverSimulatorTask(taskId); task.setStatus(DriverTask.TaskStatus.READY); String msg = String.format("StorageDriver: deleteConsistencyGroupSnapshot for storage system %s, " + "snapshot consistencyGroup nativeId %s, group snapshots %s - end", snapshots.get(0).getStorageSystemId(), snapshots.get(0).getConsistencyGroup(), snapshots.toString()); _log.info(msg); task.setMessage(msg); return task; } @Override public DriverTask createConsistencyGroupClone(VolumeConsistencyGroup consistencyGroup, List<VolumeClone> clones, List<CapabilityInstance> capabilities) { CreateGroupCloneSimulatorOperation createCloneSimulatorOperation = new CreateGroupCloneSimulatorOperation(consistencyGroup, clones); if (simulatorConfig.getSimulateAsynchronousResponses()) { DriverTask driverTask = createCloneSimulatorOperation.getDriverTask(); taskOperationMap.put(driverTask.getTaskId(), createCloneSimulatorOperation); return driverTask; } else if (simulatorConfig.getSimulateFailures()) { String failMsg = createCloneSimulatorOperation.getFailureMessage(); return createCloneSimulatorOperation.doFailure(failMsg); } else { createCloneSimulatorOperation.updateGroupCloneInfo(consistencyGroup, clones); String successMsg = createCloneSimulatorOperation.getSuccessMessage(clones); return createCloneSimulatorOperation.doSuccess(successMsg); } } @Override public DriverTask getStorageVolumes(StorageSystem storageSystem, List<StorageVolume> storageVolumes, MutableInt token) { // create set of native volumes for our storage pools // all volumes on the same page belong to the same consistency group if (token.intValue() == 0) { arrayToVolumeToVolumeExportInfoMap.clear(); } List<StoragePort> ports = new ArrayList<>(); discoverStoragePorts(storageSystem, ports); for (int vol = 0; vol < NUMBER_OF_VOLUMES_ON_PAGE; vol ++) { StorageVolume driverVolume = new StorageVolume(); driverVolume.setStorageSystemId(storageSystem.getNativeId()); driverVolume.setStoragePoolId("pool-1234577-" + token.intValue() + storageSystem.getNativeId()); driverVolume.setNativeId("driverSimulatorVolume-1234567-" + token.intValue() + "-" + vol); if (VOLUMES_IN_CG) { driverVolume.setConsistencyGroup("driverSimulatorCG-" + token.intValue()); } driverVolume.setAccessStatus(StorageVolume.AccessStatus.READ_WRITE); driverVolume.setThinlyProvisioned(true); driverVolume.setThinVolumePreAllocationSize(3000L); driverVolume.setProvisionedCapacity(3*1024*1024*1024L); driverVolume.setAllocatedCapacity(50000L); driverVolume.setDeviceLabel(driverVolume.getNativeId()); driverVolume.setWwn(String.format("%s%s", driverVolume.getStorageSystemId(), driverVolume.getNativeId())); storageVolumes.add(driverVolume); _log.info("Unmanaged volume info: pool {}, volume {}", driverVolume.getStoragePoolId(), driverVolume); if (GENERATE_EXPORT_DATA) { // add entry to arrayToVolumeToVolumeExportInfoMap for this volume // get host for this page for (String hostName : pageToHostMap.get(token.intValue())) { _log.info("Process host {}", hostName); generateExportDataForVolume(hostName, driverVolume.getStorageSystemId(), driverVolume.getNativeId(), vol, ports, token.intValue()); } } } String taskType = "create-storage-volumes"; String taskId = String.format("%s+%s+%s", DRIVER_NAME, taskType, UUID.randomUUID().toString()); DriverTask task = new DriverSimulatorTask(taskId); task.setStatus(DriverTask.TaskStatus.READY); task.setMessage("Get storage volumes: page " + token); _log.info("StorageDriver: get storage volumes information for storage system {}, token {} - end", storageSystem.getNativeId(), token); // set next value if (token.intValue() < NUMBER_OF_VOLUME_PAGES-1) { // each page has different consistency group token.setValue(token.intValue() + 1); // token.setValue(0); // last page } else { token.setValue(0); // last page } return task; } private void generateExportDataForVolume(String hostName, String storageSystemId, String volumeId, int volumeIndex, List<StoragePort> ports, int page) { Map<String, List<HostExportInfo>> volumeToExportInfoMap = arrayToVolumeToVolumeExportInfoMap.get(storageSystemId); if (volumeToExportInfoMap == null) { volumeToExportInfoMap = new HashMap<>(); arrayToVolumeToVolumeExportInfoMap.put(storageSystemId, volumeToExportInfoMap); } List<HostExportInfo> volumeToHostExportInfoList = volumeToExportInfoMap.get(volumeId); if (volumeToHostExportInfoList == null) { volumeToHostExportInfoList = new ArrayList<>(); volumeToExportInfoMap.put(volumeId, volumeToHostExportInfoList); } // build volume export info HostExportInfo exportInfo; // get volume info List<String> volumeIds = new ArrayList<>(); volumeIds.add(volumeId); // for initiators we only know port network id and host name List<String> hostInitiatorIds = hostToInitiatorPortIdMap.get(hostName); List<Initiator> initiators = new ArrayList<>(); for (String initiatorId : hostInitiatorIds) { Initiator initiator = new Initiator(); initiator.setHostName(hostName); initiator.setPort(initiatorId); initiators.add(initiator); } // decide about ports. if (page % 2 == 1) { // for odd pages we generate invalid masks for volumes (to test negative scenarios) int portIndex = volumeIndex < ports.size() ? volumeIndex : ports.size() - 1; List<StoragePort> exportPorts = Collections.singletonList(ports.get(portIndex)); exportInfo = new HostExportInfo(hostName, volumeIds, initiators, exportPorts); } else { exportInfo = new HostExportInfo(hostName, volumeIds, initiators, ports); } volumeToHostExportInfoList.add(exportInfo); _log.info("VolumeToHostExportInfo: " + volumeToHostExportInfoList); } @Override public DriverTask discoverStorageHostComponents(StorageSystem storageSystem, List<StorageHostComponent> embeddedHostComponents) { return null; } public void setConnInfoToRegistry(String systemNativeId, String ipAddress, int port, String username, String password) { Map<String, List<String>> attributes = new HashMap<>(); List<String> listIP = new ArrayList<>(); List<String> listPort = new ArrayList<>(); List<String> listUserName = new ArrayList<>(); List<String> listPwd = new ArrayList<>(); listIP.add(ipAddress); attributes.put("IP_ADDRESS", listIP); listPort.add(Integer.toString(port)); attributes.put("PORT_NUMBER", listPort); listUserName.add(username); attributes.put("USER_NAME", listUserName); listPwd.add(password); attributes.put("PASSWORD", listPwd); _log.info(String.format("StorageDriver: setting connection information for %s, attributes: %s ", systemNativeId, attributes)); this.driverRegistry.setDriverAttributesForKey("StorageDriverSimulator", systemNativeId, attributes); } @Override public List<VolumeSnapshot> getVolumeSnapshots(StorageVolume volume) { List<VolumeSnapshot> snapshots = new ArrayList<>(); for (int i=0; i<NUMBER_OF_SNAPS_FOR_VOLUME; i++) { VolumeSnapshot snapshot = new VolumeSnapshot(); snapshot.setParentId(volume.getNativeId()); snapshot.setNativeId(volume.getNativeId() + "snap-" + i); snapshot.setDeviceLabel(volume.getNativeId() + "snap-" + i); snapshot.setStorageSystemId(volume.getStorageSystemId()); snapshot.setAccessStatus(StorageObject.AccessStatus.READ_ONLY); if (SNAPS_IN_CG) { snapshot.setConsistencyGroup(volume.getConsistencyGroup() + "snapSet-" + i); } snapshot.setAllocatedCapacity(1000L); snapshot.setProvisionedCapacity(volume.getProvisionedCapacity()); snapshot.setWwn(String.format("%s%s", snapshot.getStorageSystemId(), snapshot.getNativeId())); snapshots.add(snapshot); if (GENERATE_EXPORT_DATA) { // generate export data for this snap --- the same export data as for its parent volume generateExportDataForVolumeReplica(volume, snapshot); } } return snapshots; } @Override public List<VolumeClone> getVolumeClones(StorageVolume volume) { List<VolumeClone> clones = new ArrayList<>(); for (int i=0; i<NUMBER_OF_CLONES_FOR_VOLUME; i++) { VolumeClone clone = new VolumeClone(); clone.setParentId(volume.getNativeId()); clone.setNativeId(volume.getNativeId() + "clone-" + i); clone.setDeviceLabel(volume.getNativeId() + "clone-" + i); clone.setStorageSystemId(volume.getStorageSystemId()); clone.setStoragePoolId(volume.getStoragePoolId()); clone.setAccessStatus(StorageObject.AccessStatus.READ_WRITE); if (CLONES_IN_CG) { clone.setConsistencyGroup(volume.getConsistencyGroup() + "cloneGroup-" + i); } clone.setAllocatedCapacity(volume.getAllocatedCapacity()); clone.setProvisionedCapacity(volume.getProvisionedCapacity()); clone.setThinlyProvisioned(true); clone.setWwn(String.format("%s%s", clone.getStorageSystemId(), clone.getNativeId())); clone.setReplicationState(VolumeClone.ReplicationState.SYNCHRONIZED); clones.add(clone); if (GENERATE_EXPORT_DATA) { // generate export data for this clone --- the same export data as for its parent volume generateExportDataForVolumeReplica(volume, clone); } } return clones; } @Override public List<VolumeMirror> getVolumeMirrors(StorageVolume volume) { return null; } private void generateExportDataForVolumeReplica(StorageVolume volume, StorageBlockObject replica) { Map<String, List<HostExportInfo>> volumeToExportInfoMap = arrayToVolumeToVolumeExportInfoMap.get(volume.getStorageSystemId()); if (volumeToExportInfoMap != null) { List<HostExportInfo> volumeExportInfoList = volumeToExportInfoMap.get(volume.getNativeId()); if (volumeExportInfoList != null && !volumeExportInfoList.isEmpty()) { List<HostExportInfo> replicaExportInfoList = new ArrayList<>(); // build replica export info from info of parent volume for (HostExportInfo hostExportInfo : volumeExportInfoList) { List<String> snapIds = new ArrayList<>(); snapIds.add(replica.getNativeId()); List<Initiator> hostInitiators = hostExportInfo.getInitiators(); List<StoragePort> exportPorts = hostExportInfo.getTargets(); HostExportInfo exportInfo = new HostExportInfo(hostExportInfo.getHostName(), snapIds, hostInitiators, exportPorts); replicaExportInfoList.add(exportInfo); } _log.info("Export Info for replica: {} --- {}", replica.getNativeId(), replicaExportInfoList); volumeToExportInfoMap.put(replica.getNativeId(), replicaExportInfoList); } } } @Override public DriverTask createConsistencyGroupMirror(VolumeConsistencyGroup consistencyGroup, List<VolumeMirror> mirrors, List<CapabilityInstance> capabilities) { return null; } @Override public DriverTask deleteConsistencyGroupMirror(List<VolumeMirror> mirrors) { return null; } @Override public DriverTask restoreVolumeMirror(List<VolumeMirror> mirrors) { return null; } @Override public DriverTask discoverStorageProvider(StorageProvider storageProvider, List<StorageSystem> storageSystems) { storageProvider.setIsSupportedVersion(true); StorageSystem providerSystem = new StorageSystem(); providerSystem.setSystemType("providersystem"); providerSystem.setNativeId("providerSystem-1"); providerSystem.setSerialNumber("1234567-1"); providerSystem.setFirmwareVersion("1.2.3"); storageSystems.add(providerSystem); providerSystem = new StorageSystem(); providerSystem.setSystemType("providersystem"); providerSystem.setNativeId("providerSystem-2"); providerSystem.setSerialNumber("1234567-2"); providerSystem.setFirmwareVersion("1.2.3"); storageSystems.add(providerSystem); providerSystem = new StorageSystem(); providerSystem.setSystemType("providersystem"); providerSystem.setNativeId("providerSystem-3"); providerSystem.setSerialNumber("1234567-3"); providerSystem.setFirmwareVersion("1.2.3"); storageSystems.add(providerSystem); String taskType = "discover-storage-provider"; String taskId = String.format("%s+%s+%s", DRIVER_NAME, taskType, UUID.randomUUID().toString()); DriverTask task = new DriverSimulatorTask(taskId); task.setStatus(DriverTask.TaskStatus.READY); String msg = String.format("Discovered provider: %s, discovered %s storage systems.", storageProvider.getProviderName(), storageSystems.size()); task.setMessage(msg); _log.info(msg); return task; } @Override public boolean validateStorageProviderConnection(StorageProvider storageProvider) { String msg = String.format("Request to validate connection to storage provider with type: %s, host: %s, port: %s ", storageProvider.getProviderType(), storageProvider.getProviderHost(), storageProvider.getPortNumber()); _log.info(msg); return true; } }