/*
* Copyright (c) 2016 EMC Corporation
* All Rights Reserved
*/
package com.emc.storageos.volumecontroller.impl.utils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.emc.storageos.customconfigcontroller.CustomConfigConstants;
import com.emc.storageos.customconfigcontroller.DataSource;
import com.emc.storageos.customconfigcontroller.DataSourceFactory;
import com.emc.storageos.customconfigcontroller.impl.CustomConfigHandler;
import com.emc.storageos.db.client.DbClient;
import com.emc.storageos.db.client.model.Project;
import com.emc.storageos.db.client.model.TenantOrg;
import com.emc.storageos.db.client.model.Volume;
import com.emc.storageos.util.VPlexUtil;
import com.emc.storageos.vplex.api.VPlexApiClient;
import com.emc.storageos.vplex.api.VPlexVirtualVolumeInfo;
/**
* A utility class that supports custom naming of volumes.
*/
public class CustomVolumeNamingUtils {
// Logger reference.
private static final Logger s_logger = LoggerFactory.getLogger(CustomVolumeNamingUtils.class);
/**
* Returns whether or not custom volume naming is enabled.
*
* @param customConfigHandler A reference to the custom configuration handler.
* @param String scope The custom configuration scope.
*
* @return true if custom volume naming is enabled, else false.
*/
public static Boolean isCustomVolumeNamingEnabled(CustomConfigHandler customConfigHandler, String scope) {
return customConfigHandler.getComputedCustomConfigBooleanValue(
CustomConfigConstants.CUSTOM_VOLUME_NAMING_ENABLED, scope, null);
}
/**
* Create the custom volume naming datasource for the passed volume.
*
* @param project A reference to the volume's project.
* @param tenant A reference to the project's tenant.
* @param volumeLabel The user specified volume name.
* @param volumeWWN The WWN for the volume.
* @param hostOrClusterName The name of the host or cluster to which the volume will be exported, or null.
* @param dataSourceFactory A reference to a data source factory.
* @param customConfigName The name of the volume naming custom configuration.
* @param dbClient A reference to a database client.
*
* @return A reference to the created data source or null on error.
*/
public static DataSource getCustomConfigDataSource(Project project, TenantOrg tenant, String volumeLabel, String volumeWWN,
String hostOrClusterName, DataSourceFactory dataSourceFactory, String customConfigName,
DbClient dbClient) {
DataSource dataSource = null;
try {
// Create the data source.
dataSource = dataSourceFactory.createCustomVolumeNameDataSource(project, tenant, volumeLabel,
volumeWWN, hostOrClusterName, customConfigName);
} catch (Exception e) {
s_logger.warn(String.format("Error creating the custom volume name datasource for volume %s", volumeLabel), e);
}
return dataSource;
}
/**
* Get the volume custom configuration name.
*
* @param withExport true if the volume will be provisioned to a specific host or cluster, false otherwise.
*
* @return The volume custom configuration name.
*/
public static String getCustomConfigName(boolean withExport) {
String customConfigName = null;
if (withExport) {
customConfigName = CustomConfigConstants.CUSTOM_VOLUME_NAME_WITH_EXPORT;
} else {
customConfigName = CustomConfigConstants.CUSTOM_VOLUME_NAME;
}
return customConfigName;
}
/**
* Returns the volume's custom name.
*
* @param customConfigHandler A reference to the custom configuration handler.
* @param customConfigName The custom configuration name;
* @param dataSource The custom volume name datasource for the volume.
* @param scope The custom configuration scope.
*
* @return The volume's custom name.
*/
public static String getCustomName(CustomConfigHandler customConfigHandler,
String customConfigName, DataSource dataSource, String scope) {
return customConfigHandler.getComputedCustomConfigValue(customConfigName,
scope, dataSource);
}
/**
* Renames the volume represented by the passed VPLEX volume info with the passed name.
*
* @param vplexVolume A reference to the VPLEX volume.
* @param newVolumeName The new name for the volume.
* @param client A reference to the VPLEX API client.
* @param dbClient A reference to a database client.
*
* @return A reference to the updated virtual volume info.
*
* @throws Exception if the volume to rename cannot be found.
*/
public static void renameVPlexVolume(Volume vplexVolume, String newVolumeName,
VPlexApiClient client, DbClient dbClient) throws Exception {
try {
if (vplexVolume == null) {
s_logger.warn("The passed volume is null.");
return;
}
if (!VPlexUtil.isVplexVolume(vplexVolume, dbClient)) {
s_logger.warn("Volume {} can not be renamed because it is not a VPLEX volume.", vplexVolume.getId());
return;
}
// Find and rename the volume on the VPLEX and in ViPR.
VPlexVirtualVolumeInfo vvInfo = client.findVirtualVolume(vplexVolume.getDeviceLabel(), vplexVolume.getNativeId());
vvInfo = renameVolumeOnVPlex(vvInfo, newVolumeName, client);
vplexVolume.setNativeId(vvInfo.getPath());
vplexVolume.setNativeGuid(vvInfo.getPath());
vplexVolume.setLabel(vvInfo.getName());
vplexVolume.setDeviceLabel(vvInfo.getName());
dbClient.updateObject(vplexVolume);
} catch (Exception e) {
s_logger.warn(String.format("Error attempting to rename VPLEX volume %s", vplexVolume.getDeviceLabel()), e);
throw e;
}
}
/**
* Renames the volume represented by the passed VPLEX volume info with the passed name.
*
* @param vvInfo A reference to the VPLEX volume info.
* @param newVolumeName The new name for the volume.
* @param client A reference to the VPLEX API client.
*
* @return A reference to the updated virtual volume info.
*/
public static VPlexVirtualVolumeInfo renameVolumeOnVPlex(VPlexVirtualVolumeInfo vvInfo,
String newVolumeName, VPlexApiClient client) {
VPlexVirtualVolumeInfo updateVolumeInfo = vvInfo;
try {
String currentVolumeName = vvInfo.getName();
if (!currentVolumeName.equals(newVolumeName)) {
s_logger.info("Renaming VPLEX volume {} to custom name {}", vvInfo.getName(), newVolumeName);
updateVolumeInfo = client.renameResource(vvInfo, newVolumeName);
} else {
s_logger.info("Skip rename as volume is already named {}", newVolumeName);
}
} catch (Exception e) {
s_logger.warn(String.format("Error attempting to rename VPLEX volume %s to %s", vvInfo.getName(), newVolumeName), e);
}
return updateVolumeInfo;
}
}