use of com.emc.storageos.vplex.api.VPlexApiClient in project coprhd-controller by CoprHD.
the class VPlexCommunicationInterface method discover.
/**
* Implementation for discovery of VPLEX storage systems.
*
* @param accessProfile providing context for this discovery session
*
* @throws BaseCollectionException
*/
@Override
public void discover(AccessProfile accessProfile) throws BaseCollectionException {
s_logger.info("initiating discovery of VPLEX system {}", accessProfile.getProfileName());
if ((null != accessProfile.getnamespace()) && (accessProfile.getnamespace().equals(StorageSystem.Discovery_Namespaces.UNMANAGED_VOLUMES.toString()))) {
try {
VPlexApiClient client = getVPlexAPIClient(accessProfile);
long timer = System.currentTimeMillis();
UnmanagedDiscoveryPerformanceTracker tracker = new UnmanagedDiscoveryPerformanceTracker();
tracker.discoveryMode = ControllerUtils.getPropertyValueFromCoordinator(_coordinator, VplexBackendIngestionContext.DISCOVERY_MODE);
// get all the detailed virtual volume info from the VPLEX API
Map<String, VPlexVirtualVolumeInfo> vvolMap = client.getVirtualVolumes(true);
tracker.virtualVolumeFetch = System.currentTimeMillis() - timer;
tracker.totalVolumesFetched = vvolMap.size();
// discover unmanaged storage views
timer = System.currentTimeMillis();
Map<String, Set<UnManagedExportMask>> volumeToExportMasksMap = new HashMap<String, Set<UnManagedExportMask>>();
Map<String, Set<VPlexStorageViewInfo>> volumeToStorageViewMap = new HashMap<String, Set<VPlexStorageViewInfo>>();
Set<String> recoverPointExportMasks = new HashSet<String>();
discoverUnmanagedStorageViews(accessProfile, client, vvolMap, volumeToExportMasksMap, volumeToStorageViewMap, recoverPointExportMasks);
tracker.storageViewFetch = System.currentTimeMillis() - timer;
// discover unmanaged volumes
timer = System.currentTimeMillis();
discoverUnmanagedVolumes(accessProfile, client, vvolMap, volumeToExportMasksMap, volumeToStorageViewMap, recoverPointExportMasks, tracker);
tracker.unmanagedVolumeProcessing = System.currentTimeMillis() - timer;
// re-run vpool matching for all vpools so that backend volumes will
// be updated after vvol discovery to match their parent's matched vpools
timer = System.currentTimeMillis();
List<URI> vpoolURIs = _dbClient.queryByType(VirtualPool.class, true);
List<VirtualPool> vpoolList = _dbClient.queryObject(VirtualPool.class, vpoolURIs);
Set<URI> srdfEnabledTargetVPools = SRDFUtils.fetchSRDFTargetVirtualPools(_dbClient);
Set<URI> rpEnabledTargetVPools = RPHelper.fetchRPTargetVirtualPools(_dbClient);
for (VirtualPool vpool : vpoolList) {
ImplicitUnManagedObjectsMatcher.matchVirtualPoolsWithUnManagedVolumes(vpool, srdfEnabledTargetVPools, rpEnabledTargetVPools, _dbClient, true);
}
tracker.vpoolMatching = System.currentTimeMillis() - timer;
s_logger.info(tracker.getPerformanceReport());
} catch (URISyntaxException ex) {
s_logger.error(ex.getLocalizedMessage());
throw VPlexCollectionException.exceptions.vplexUnmanagedVolumeDiscoveryFailed(accessProfile.getSystemId().toString(), ex.getLocalizedMessage());
}
} else {
discoverAll(accessProfile);
}
}
use of com.emc.storageos.vplex.api.VPlexApiClient in project coprhd-controller by CoprHD.
the class AbstractConsistencyGroupManager method deleteCG.
/**
* Deletes the consistency group with the passed URI on the VPLEX storage
* system with the passed URU.
*
* @param vplexSystemURI The URI of the VPlex system.
* @param cgUri The URI of the ViPR consistency group.
* @param cgName The name of the VPlex consistency group to delete.
* @param clusterName The name of the VPlex cluster.
* @param setInactive true to mark the CG for deletion.
* @param stepId The workflow step identifier.
*
* @throws WorkflowException When an error occurs updating the work step
* state.
*/
public void deleteCG(URI vplexSystemURI, URI cgUri, String cgName, String clusterName, Boolean setInactive, String stepId) throws WorkflowException {
StorageSystem vplexSystem = null;
try {
// Update step state to executing.
WorkflowStepCompleter.stepExecuting(stepId);
log.info(String.format("Executing workflow step deleteCG. Storage System: %s, CG Name: %s, Cluster Name: %s", vplexSystemURI, cgName, clusterName));
vplexSystem = getDataObject(StorageSystem.class, vplexSystemURI, dbClient);
VPlexApiClient client = getVPlexAPIClient(vplexApiFactory, vplexSystem, dbClient);
log.info("Got VPlex API client for VPlex system {}", vplexSystemURI);
InvokeTestFailure.internalOnlyInvokeTestFailure(InvokeTestFailure.ARTIFICIAL_FAILURE_085);
// Make a call to the VPlex API client to delete the consistency group.
client.deleteConsistencyGroup(cgName);
log.info(String.format("Deleted consistency group %s", cgName));
cleanUpVplexCG(vplexSystemURI, cgUri, cgName, setInactive);
// Update step status to success.
WorkflowStepCompleter.stepSucceded(stepId);
} catch (VPlexApiException vae) {
if (vae.getServiceCode().getCode() == ServiceCode.VPLEX_CG_NOT_FOUND.getCode()) {
log.info(String.format("Consistency group %s not found on storage system: %s. Assumed already deleted.", clusterName + ":" + cgName, (vplexSystem != null && vplexSystem.forDisplay() != null) ? vplexSystem.forDisplay() : vplexSystemURI));
cleanUpVplexCG(vplexSystemURI, cgUri, cgName, setInactive);
WorkflowStepCompleter.stepSucceded(stepId);
} else {
log.error("Exception deleting consistency group: " + vae.getMessage(), vae);
WorkflowStepCompleter.stepFailed(stepId, vae);
}
} catch (Exception ex) {
log.error("Exception deleting consistency group: " + ex.getMessage(), ex);
String opName = ResourceOperationTypeEnum.DELETE_CONSISTENCY_GROUP.getName();
ServiceError serviceError = VPlexApiException.errors.deleteCGFailed(opName, ex);
WorkflowStepCompleter.stepFailed(stepId, serviceError);
}
}
use of com.emc.storageos.vplex.api.VPlexApiClient in project coprhd-controller by CoprHD.
the class RPVplexConsistencyGroupManager method getClusterConsistencyGroup.
/**
* Maps a VPlex cluster/consistency group to its volumes.
*
* @param vplexVolume The virtual volume from which to obtain the VPlex cluster.
* @param clusterConsistencyGroupVolumes The map to store cluster/cg/volume relationships.
* @param cgName The VPlex consistency group name.
* @throws Exception
*/
@Override
public ClusterConsistencyGroupWrapper getClusterConsistencyGroup(Volume vplexVolume, BlockConsistencyGroup cg) throws Exception {
ClusterConsistencyGroupWrapper clusterConsistencyGroup = new ClusterConsistencyGroupWrapper();
String vplexCgName = null;
// Find the correct VPLEX cluster for this volume
String vplexCluster = VPlexControllerUtils.getVPlexClusterName(dbClient, vplexVolume);
// Determine if the volume is distributed
boolean distributed = false;
StringSet assocVolumes = vplexVolume.getAssociatedVolumes();
// Associated volume for the consistency group cannot be null, indicates back-end volumes are not ingested.
if (vplexVolume.getAssociatedVolumes() != null && !vplexVolume.getAssociatedVolumes().isEmpty()) {
if (assocVolumes.size() > 1) {
distributed = true;
}
} else {
String reason = "Associated volume is empty";
throw VPlexApiException.exceptions.emptyAssociatedVolumes(vplexVolume.getDeviceLabel(), vplexCluster, reason);
}
// Keep a reference to the VPLEX
URI vplexURI = vplexVolume.getStorageController();
log.info(String.format("Find correct VPLEX CG for VPLEX %s volume [%s](%s) at cluster [%s] on VPLEX (%s)", (distributed ? "distribitued" : "local"), vplexVolume.getLabel(), vplexVolume.getId(), vplexCluster, vplexURI));
// line up the CG name from the ViPR CG to the VPLEX CGs.
if (cg.created(vplexURI)) {
log.info("CG already exists on VPLEX, but we need to figure out the correct one to use...");
List<String> validVPlexCGsForCluster = new ArrayList<String>();
// Extract all the CG names for the VPLEX
// These names are in the format of: cluster-1:cgName or cluster-2:cgName
StringSet cgNames = cg.getSystemConsistencyGroups().get(vplexURI.toString());
// Iterate over the names to line up with the cluster
Iterator<String> cgNamesIter = cgNames.iterator();
while (cgNamesIter.hasNext()) {
String clusterCgName = cgNamesIter.next();
String cluster = BlockConsistencyGroupUtils.fetchClusterName(clusterCgName);
String cgName = BlockConsistencyGroupUtils.fetchCgName(clusterCgName);
// We will narrow this down afterwards for distributed.
if (vplexCluster.equals(cluster) || distributed) {
validVPlexCGsForCluster.add(cgName);
}
}
// Get the API client.
StorageSystem vplexSystem = getDataObject(StorageSystem.class, vplexURI, dbClient);
VPlexApiClient client = getVPlexAPIClient(vplexApiFactory, vplexSystem, dbClient);
log.info("Got VPLEX API client.");
// This is not ideal but we need to call the VPlex client to fetch all consistency
// groups so we can find the exact one we are looking for.
List<VPlexConsistencyGroupInfo> vplexCGs = client.getConsistencyGroups();
log.info("Iterating over returned VPLEX CGs to find the one we should use...");
for (VPlexConsistencyGroupInfo vplexCG : vplexCGs) {
boolean cgNameFound = validVPlexCGsForCluster.contains(vplexCG.getName());
boolean volumeFound = vplexCG.getVirtualVolumes().contains(vplexVolume.getDeviceLabel());
// either way it's valid.
if (cgNameFound || volumeFound) {
// Determine if the VPLEX CG is distributed.
// NOTE: VPlexConsistencyGroupInfo.isDistributed() is not returning
// the correct information. This is probably due to teh fact that
// visibleClusters is not being returned in the response.
// Instead we are checking getStorageAtClusters().size().
boolean vplexCGIsDistributed = (vplexCG.getStorageAtClusters().size() > 1);
if ((distributed && vplexCGIsDistributed) || (!distributed && !vplexCGIsDistributed)) {
log.info(String.format("Found correct VPLEX CG: %s", vplexCG.getName()));
vplexCgName = vplexCG.getName();
break;
}
}
}
}
// The format for VPLEX local: cgName-vplexCluster
if (vplexCgName == null) {
// If we do not have a VPLEX CG name it's time to create one.
if (distributed) {
// Add '-dist' to the end of the CG name for distributed consistency groups.
vplexCgName = cg.getLabel() + "-dist";
} else {
vplexCgName = cg.getLabel() + "-" + vplexCluster;
}
log.info(String.format("There was no existing VPLEX CG, created CG name: %s", vplexCgName));
}
clusterConsistencyGroup.setClusterName(vplexCluster);
clusterConsistencyGroup.setCgName(vplexCgName);
clusterConsistencyGroup.setDistributed(distributed);
return clusterConsistencyGroup;
}
use of com.emc.storageos.vplex.api.VPlexApiClient in project coprhd-controller by CoprHD.
the class VPlexConsistencyGroupManager method addVolumesToCG.
/**
* Adds volumes to a BlockConsistencyGroup.
* @param vplexSystem - StorageSystem representing the Vplex
* @param cg -- Block Consistency Group the volumes are to be added to
* @param vplexVolumes -- Collection of Vplex volumes to be added
* @param stepId -- String Stepid. WorkflowStepCompleter is called if successful or not.
* @return true if successful, false if not
*/
private boolean addVolumesToCG(StorageSystem vplexSystem, BlockConsistencyGroup cg, Collection<Volume> vplexVolumes, String stepId) {
try {
VPlexApiClient client = getVPlexAPIClient(vplexApiFactory, vplexSystem, dbClient);
// Get the names of the volumes to be added.
Volume protoVolume = null;
List<String> vplexVolumeNames = new ArrayList<String>();
for (Volume vplexVolume : vplexVolumes) {
if (protoVolume == null) {
protoVolume = vplexVolume;
}
vplexVolumeNames.add(vplexVolume.getDeviceLabel());
log.info("VPLEX volume:" + vplexVolume.getDeviceLabel());
}
log.info("Got VPLEX volume names.");
String cgName = getVplexCgName(protoVolume, cg.getId());
long startTime = System.currentTimeMillis();
// Add the volumes to the CG.
client.addVolumesToConsistencyGroup(cgName, vplexVolumeNames);
long elapsed = System.currentTimeMillis() - startTime;
log.info(String.format("TIMER: Adding %s virtual volume(s) %s to the consistency group %s took %f seconds", vplexVolumeNames.size(), vplexVolumeNames, cgName, (double) elapsed / (double) 1000));
// adding volumes to a CG after volume creation.
for (Volume vplexVolume : vplexVolumes) {
vplexVolume.setConsistencyGroup(cg.getId());
dbClient.updateObject(vplexVolume);
}
// Update workflow step state to success.
WorkflowStepCompleter.stepSucceded(stepId);
log.info("Updated workflow step state to success for add volumes to consistency group.");
return true;
} catch (VPlexApiException vae) {
log.error("Exception adding volumes to consistency group: " + vae.getMessage(), vae);
WorkflowStepCompleter.stepFailed(stepId, vae);
return false;
} catch (Exception ex) {
log.error("Exception adding volumes to consistency group: " + ex.getMessage(), ex);
ServiceError svcError = VPlexApiException.errors.jobFailed(ex);
WorkflowStepCompleter.stepFailed(stepId, svcError);
return false;
}
}
use of com.emc.storageos.vplex.api.VPlexApiClient in project coprhd-controller by CoprHD.
the class VPlexConsistencyGroupManager method updateConsistencyGroupReadOnlyState.
/**
* Step to call the VPLEX to update the read-only flag on a consistency group.
* If the Vplex Api library detects the firmware does not properly handle the flag,
* a warning message is put in the SUCCESS status.
* @param vplexVolumeURIs -- List of at least some volumes in the consistency group.
* @param isReadOnly - if true marks read-only, false read-write
* @param stepId - Workflow step id
*/
public void updateConsistencyGroupReadOnlyState(List<URI> vplexVolumeURIs, Boolean isReadOnly, String stepId) {
try {
WorkflowStepCompleter.stepExecuting(stepId);
// Get the first virtual volume, as all volumes should be in the same CG
Volume vplexVolume = dbClient.queryObject(Volume.class, vplexVolumeURIs.get(0));
// Get the storage system for the Vplex.
StorageSystem vplexSystem = dbClient.queryObject(StorageSystem.class, vplexVolume.getStorageController());
// And from that a handle to the VplexApiClient
VPlexApiClient client = getVPlexAPIClient(vplexApiFactory, vplexSystem, dbClient);
// From that get the Consistency Group, if there is not one, just return success
if (NullColumnValueGetter.isNullURI(vplexVolume.getConsistencyGroup())) {
log.info("Volume has no ConsistencyGroup: " + vplexVolume.getLabel());
WorkflowStepCompleter.stepSucceded(stepId);
return;
}
BlockConsistencyGroup cg = dbClient.queryObject(BlockConsistencyGroup.class, vplexVolume.getConsistencyGroup());
// Get the consistency group parameters.
ClusterConsistencyGroupWrapper clusterConsistencyGroup = getClusterConsistencyGroup(vplexVolume, cg);
String cgName = clusterConsistencyGroup.getCgName();
String clusterName = clusterConsistencyGroup.getClusterName();
boolean isDistributed = clusterConsistencyGroup.isDistributed();
// Make the call to update the consistency group read-only status
client.updateConsistencyGroupReadOnly(cgName, clusterName, isDistributed, isReadOnly);
// Complete the step
WorkflowStepCompleter.stepSucceded(stepId);
} catch (VPlexApiException ex) {
if (ServiceCode.VPLEX_API_FIRMWARE_UPDATE_NEEDED.equals(ex.getServiceCode())) {
// The firmware doesn't support read-only flag, inform the user, but do not fail.
WorkflowStepCompleter.stepSucceeded(stepId, ex.getLocalizedMessage());
} else {
log.info("Exception setting Consistency Group read-only state: " + ex.getMessage());
ServiceError svcError = VPlexApiException.errors.jobFailed(ex);
WorkflowStepCompleter.stepFailed(stepId, svcError);
}
} catch (Exception ex) {
log.info("Exception setting Consistency Group read-only state: " + ex.getMessage());
ServiceError svcError = VPlexApiException.errors.jobFailed(ex);
WorkflowStepCompleter.stepFailed(stepId, svcError);
}
}
Aggregations