/*
* Copyright (c) 2014 EMC Corporation
* All Rights Reserved
*/
package com.emc.storageos.volumecontroller.impl.vnxe;
import java.io.File;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.emc.storageos.db.client.model.BlockConsistencyGroup;
import com.emc.storageos.db.client.model.BlockConsistencyGroup.Types;
import com.emc.storageos.db.client.model.BlockObject;
import com.emc.storageos.db.client.model.BlockSnapshot;
import com.emc.storageos.db.client.model.ExportMask;
import com.emc.storageos.db.client.model.FSExportMap;
import com.emc.storageos.db.client.model.FileExport;
import com.emc.storageos.db.client.model.FileShare;
import com.emc.storageos.db.client.model.Initiator;
import com.emc.storageos.db.client.model.Operation;
import com.emc.storageos.db.client.model.QuotaDirectory;
import com.emc.storageos.db.client.model.SMBFileShare;
import com.emc.storageos.db.client.model.Snapshot;
import com.emc.storageos.db.client.model.StorageHADomain;
import com.emc.storageos.db.client.model.StoragePool;
import com.emc.storageos.db.client.model.StoragePort;
import com.emc.storageos.db.client.model.StorageProtocol;
import com.emc.storageos.db.client.model.StorageSystem;
import com.emc.storageos.db.client.model.StringMap;
import com.emc.storageos.db.client.model.StringSet;
import com.emc.storageos.db.client.model.TenantOrg;
import com.emc.storageos.db.client.model.VirtualPool;
import com.emc.storageos.db.client.model.Volume;
import com.emc.storageos.db.client.model.util.BlockConsistencyGroupUtils;
import com.emc.storageos.db.client.util.NameGenerator;
import com.emc.storageos.db.client.util.NullColumnValueGetter;
import com.emc.storageos.db.exceptions.DatabaseException;
import com.emc.storageos.exceptions.DeviceControllerErrors;
import com.emc.storageos.exceptions.DeviceControllerException;
import com.emc.storageos.model.file.ExportRule;
import com.emc.storageos.plugins.common.Constants;
import com.emc.storageos.svcs.errorhandling.model.ServiceError;
import com.emc.storageos.util.InvokeTestFailure;
import com.emc.storageos.vnxe.VNXeApiClient;
import com.emc.storageos.vnxe.VNXeConstants;
import com.emc.storageos.vnxe.VNXeException;
import com.emc.storageos.vnxe.VNXeUtils;
import com.emc.storageos.vnxe.models.AccessEnum;
import com.emc.storageos.vnxe.models.VNXeBase;
import com.emc.storageos.vnxe.models.VNXeCommandJob;
import com.emc.storageos.vnxe.models.VNXeCommandResult;
import com.emc.storageos.vnxe.models.VNXeFSSupportedProtocolEnum;
import com.emc.storageos.vnxe.models.VNXeFileSystem;
import com.emc.storageos.vnxe.models.VNXeFileSystemSnap;
import com.emc.storageos.vnxe.models.VNXeHost;
import com.emc.storageos.vnxe.models.VNXeNfsShare;
import com.emc.storageos.volumecontroller.BlockStorageDevice;
import com.emc.storageos.volumecontroller.ControllerException;
import com.emc.storageos.volumecontroller.FileDeviceInputOutput;
import com.emc.storageos.volumecontroller.FileSMBShare;
import com.emc.storageos.volumecontroller.FileShareExport;
import com.emc.storageos.volumecontroller.FileStorageDevice;
import com.emc.storageos.volumecontroller.SnapshotOperations;
import com.emc.storageos.volumecontroller.TaskCompleter;
import com.emc.storageos.volumecontroller.impl.BiosCommandResult;
import com.emc.storageos.volumecontroller.impl.ControllerServiceImpl;
import com.emc.storageos.volumecontroller.impl.ControllerUtils;
import com.emc.storageos.volumecontroller.impl.VolumeURIHLU;
import com.emc.storageos.volumecontroller.impl.block.ExportMaskPolicy;
import com.emc.storageos.volumecontroller.impl.block.taskcompleter.CleanupMetaVolumeMembersCompleter;
import com.emc.storageos.volumecontroller.impl.block.taskcompleter.VolumeCreateCompleter;
import com.emc.storageos.volumecontroller.impl.block.taskcompleter.VolumeExpandCompleter;
import com.emc.storageos.volumecontroller.impl.job.QueueJob;
import com.emc.storageos.volumecontroller.impl.smis.ExportMaskOperations;
import com.emc.storageos.volumecontroller.impl.smis.MetaVolumeRecommendation;
import com.emc.storageos.volumecontroller.impl.utils.VirtualPoolCapabilityValuesWrapper;
import com.emc.storageos.volumecontroller.impl.vnxe.job.VNXeCreateFileSystemJob;
import com.emc.storageos.volumecontroller.impl.vnxe.job.VNXeCreateFileSystemSnapshotJob;
import com.emc.storageos.volumecontroller.impl.vnxe.job.VNXeCreateShareJob;
import com.emc.storageos.volumecontroller.impl.vnxe.job.VNXeCreateVolumesJob;
import com.emc.storageos.volumecontroller.impl.vnxe.job.VNXeDeleteFileSystemSnapshotJob;
import com.emc.storageos.volumecontroller.impl.vnxe.job.VNXeDeleteShareJob;
import com.emc.storageos.volumecontroller.impl.vnxe.job.VNXeDeleteVolumesJob;
import com.emc.storageos.volumecontroller.impl.vnxe.job.VNXeExpandFileSystemJob;
import com.emc.storageos.volumecontroller.impl.vnxe.job.VNXeExpandVolumeJob;
import com.emc.storageos.volumecontroller.impl.vnxe.job.VNXeExportFileSystemJob;
import com.emc.storageos.volumecontroller.impl.vnxe.job.VNXeFSSnapshotTaskCompleter;
import com.emc.storageos.volumecontroller.impl.vnxe.job.VNXeFileTaskCompleter;
import com.emc.storageos.volumecontroller.impl.vnxe.job.VNXeModifyExportJob;
import com.emc.storageos.volumecontroller.impl.vnxe.job.VNXeRestoreFileSystemSnapshotJob;
import com.emc.storageos.volumecontroller.impl.vnxe.job.VNXeUnexportFileSystemJob;
import com.google.common.collect.Sets;
public class VNXeStorageDevice extends VNXeOperations
implements FileStorageDevice, BlockStorageDevice {
private static final Logger _logger = LoggerFactory.getLogger(VNXeStorageDevice.class);
private SnapshotOperations _snapshotOperations;
private NameGenerator nameGenerator;
public NameGenerator getNameGenerator() {
return nameGenerator;
}
public void setNameGenerator(NameGenerator nameGenerator) {
this.nameGenerator = nameGenerator;
}
private ExportMaskOperations exportMaskOperationsHelper;
public ExportMaskOperations getExportMaskOperationsHelper() {
return exportMaskOperationsHelper;
}
public void setExportMaskOperationsHelper(
ExportMaskOperations exportMaskOperationsHelper) {
this.exportMaskOperationsHelper = exportMaskOperationsHelper;
}
public void setSnapshotOperations(final SnapshotOperations snapshotOperations) {
_snapshotOperations = snapshotOperations;
}
@Override
public BiosCommandResult doCreateFS(StorageSystem storage,
FileDeviceInputOutput fileInOut) throws ControllerException {
_logger.info("creating file system: ", fileInOut.getFsName());
Long fsSize = fileInOut.getFsCapacity();
if (fsSize < 1) {
// Invalid size throw an error
_logger.error("doCreateFS failed : FileSystem size in bytes is not valid {}", fileInOut.getFsCapacity());
ServiceError error = DeviceControllerErrors.vnxe.unableToCreateFileSystem("FileSystem size in bytes is not valid");
return BiosCommandResult.createErrorResult(error);
}
VNXeFileTaskCompleter completer = null;
VNXeApiClient apiClient = getVnxeClient(storage);
VNXeCommandJob job = null;
try {
FileShare fs = fileInOut.getFs();
URI port = fs.getStoragePort();
if (port == null) {
_logger.error("No storageport uri found in the fs");
ServiceError error = DeviceControllerErrors.vnxe.unableToCreateFileSystem("No storageport uri found in the fs");
return BiosCommandResult.createErrorResult(error);
}
StoragePort portObj = _dbClient.queryObject(StoragePort.class, port);
URI haDomainUri = portObj.getStorageHADomain();
StorageHADomain haDomainObj = _dbClient.queryObject(StorageHADomain.class, haDomainUri);
StringSet protocols = fs.getProtocol();
if (protocols.contains(StorageProtocol.File.NFS_OR_CIFS.name())) {
/*
* the protocol is set to NFS_OR_CIFS, only if virtual pool's protocol is not set
* and the pool's protocol is set to NFS_OR_CIFS, since pool's protocol is set based on
* storageHADomain's protocol, setting the protocols to the selected StorageHADomain.
*/
protocols = haDomainObj.getFileSharingProtocols();
}
VNXeFSSupportedProtocolEnum protocolEnum = null;
if (protocols.contains(StorageProtocol.File.NFS.name())
&& protocols.contains(StorageProtocol.File.CIFS.name())) {
protocolEnum = VNXeFSSupportedProtocolEnum.NFS_CIFS;
} else if (protocols.contains(StorageProtocol.File.NFS.name())) {
protocolEnum = VNXeFSSupportedProtocolEnum.NFS;
} else if (protocols.contains(StorageProtocol.File.CIFS.name())) {
protocolEnum = VNXeFSSupportedProtocolEnum.CIFS;
} else {
_logger.error("protocol is not support: " + protocols);
ServiceError error = DeviceControllerErrors.vnxe.unableToCreateFileSystem("protocol is not support:" + protocols);
return BiosCommandResult.createErrorResult(error);
}
job = apiClient.createFileSystem(fileInOut.getFsName(),
fsSize,
fileInOut.getPoolNativeId(),
haDomainObj.getSerialNumber(),
fileInOut.getThinProvision(),
protocolEnum);
if (job != null) {
_logger.info("opid:" + fileInOut.getOpId());
completer = new VNXeFileTaskCompleter(FileShare.class, fileInOut.getFsId(), fileInOut.getOpId());
if (fileInOut.getFs() == null) {
_logger.error("Could not find the fs object");
}
VNXeCreateFileSystemJob createFSJob = new VNXeCreateFileSystemJob(job.getId(), storage.getId(),
completer, fileInOut.getPoolId());
ControllerServiceImpl.enqueueJob(new QueueJob(createFSJob));
} else {
_logger.error("No job returned from creatFileSystem");
ServiceError error = DeviceControllerErrors.vnxe.unableToCreateFileSystem("No Job returned from createFileSystem");
return BiosCommandResult.createErrorResult(error);
}
} catch (VNXeException e) {
_logger.error("Create file system got the exception", e);
if (completer != null) {
completer.error(_dbClient, e);
}
return BiosCommandResult.createErrorResult(e);
} catch (Exception ex) {
_logger.error("Create file system got the exception", ex);
ServiceError error = DeviceControllerErrors.vnxe.jobFailed("CreateFileSystem", ex.getMessage());
if (completer != null) {
completer.error(_dbClient, error);
}
return BiosCommandResult.createErrorResult(error);
}
StringBuilder logMsgBuilder = new StringBuilder(String.format(
"Create filesystem job submitted - Array:%s, Pool:%s, fileSystem: %s", storage.getSerialNumber(),
fileInOut.getPoolNativeId(), fileInOut.getFsName()));
_logger.info(logMsgBuilder.toString());
return BiosCommandResult.createPendingResult();
}
@Override
public boolean doCheckFSExists(StorageSystem storage,
FileDeviceInputOutput fileInOut) throws ControllerException {
_logger.info("checking file system existence on array: ", fileInOut.getFsName());
boolean isFSExists = true;
try {
String name = fileInOut.getFsName();
VNXeApiClient apiClient = getVnxeClient(storage);
VNXeFileSystem fs = apiClient.getFileSystemByFSName(name);
if (fs != null && (fs.getName().equals(name))) {
isFSExists = true;
} else {
isFSExists = false;
}
} catch (Exception e) {
_logger.error("Querying File System failed with exception:", e);
}
return isFSExists;
}
/*
* @Override
* public BiosCommandResult doDeleteFS(StorageSystem storage,
* FileDeviceInputOutput fileInOut) throws ControllerException {
* _logger.info("deleting file system: ", fileInOut.getFsName());
* VNXeApiClient apiClient = getVnxeClient(storage);
* VNXeCommandJob job = null;
* VNXeFileTaskCompleter completer = null;
* try {
* job = apiClient.deleteFileSystem(fileInOut.getFsNativeId(), fileInOut.getForceDelete());
* if (job != null) {
* completer = new VNXeFileTaskCompleter(FileShare.class, fileInOut.getFsId(), fileInOut.getOpId(),
* OperationTypeEnum.DELETE_FILE_SYSTEM);
* VNXeDeleteFileSystemJob deleteFSJob = new VNXeDeleteFileSystemJob(job.getId(), storage.getId(),
* completer, fileInOut.getForceDelete());
* ControllerServiceImpl.enqueueJob(new QueueJob(deleteFSJob));
* } else {
* _logger.error("No job returned from deleteFileSystem");
* ServiceError error = DeviceControllerErrors.vnxe.jobFailed("DeleteFileSystem",
* "No Job returned from deleteFileSystem");
* return BiosCommandResult.createErrorResult(error);
* }
*
* }catch (VNXeException e) {
* _logger.error("Delete file system got the exception", e);
* if (completer != null) {
* completer.error(_dbClient, e);
* }
* return BiosCommandResult.createErrorResult(e);
* } catch (Exception ex) {
* _logger.error("Delete file system got the exception", ex);
* ServiceError error = DeviceControllerErrors.vnxe.jobFailed("DeleteFileSystem", ex.getMessage());
* if (completer != null) {
* completer.error(_dbClient, error);
* }
* return BiosCommandResult.createErrorResult(error);
* }
* StringBuilder logMsgBuilder = new StringBuilder(String.format(
* "Delete filesystem job submitted - Array:%s, fileSystem: %s", storage.getSerialNumber(),
* fileInOut.getFsName()));
* _logger.info(logMsgBuilder.toString());
* return BiosCommandResult.createPendingResult();
* }
*/
/*
* To get around the KH API delete file system async issues, using sync call for now.
*/
@Override
public BiosCommandResult doDeleteFS(StorageSystem storage,
FileDeviceInputOutput fileInOut) throws ControllerException {
_logger.info("deleting file system: ", fileInOut.getFsName());
VNXeApiClient apiClient = getVnxeClient(storage);
BiosCommandResult result = null;
try {
apiClient.deleteFileSystemSync(fileInOut.getFsNativeId(), fileInOut.getForceDelete());
StringBuilder logMsgBuilder = new StringBuilder(String.format(
"Deleted filesystem - Array:%s, fileSystem: %s", storage.getSerialNumber(),
fileInOut.getFsName()));
_logger.info(logMsgBuilder.toString());
result = BiosCommandResult.createSuccessfulResult();
} catch (VNXeException e) {
_logger.error("Delete file system got the exception", e);
result = BiosCommandResult.createErrorResult(e);
} catch (Exception ex) {
_logger.error("Delete file system got the exception", ex);
ServiceError error = DeviceControllerErrors.vnxe.jobFailed("DeleteFileSystem", ex.getMessage());
result = BiosCommandResult.createErrorResult(error);
}
return result;
}
@Override
public BiosCommandResult doExport(StorageSystem storage,
FileDeviceInputOutput args, List<FileExport> exportList)
throws ControllerException {
_logger.info("exporting the file system: " + args.getFsName());
if (args.getFileObjExports() == null || args.getFileObjExports().isEmpty()) {
args.initFileObjExports();
}
for (FileExport exp : exportList) {
VNXeApiClient apiClient = getVnxeClient(storage);
String fsId = args.getFs().getNativeId();
String fsName = args.getFsName();
String permission = exp.getPermissions();
String path = "/";
String subdirName = "";
String mountPathArg = exp.getMountPath();
String comments = exp.getComments();
VNXeCommandJob job = null;
VNXeFileTaskCompleter completer = null;
String exportKey = exp.getFileExportKey();
FileShareExport newExport = new FileShareExport(exp);
try {
AccessEnum access = null;
List<String> roClients = null;
List<String> rwClients = null;
List<String> rootClients = null;
FileExport existingExport = null;
if (args.getFileOperation()) {
FSExportMap exportMap = args.getFileObjExports();
existingExport = exportMap.get(exportKey);
} else {
FSExportMap exportMap = args.getSnapshotExports();
existingExport = exportMap.get(exportKey);
}
if (existingExport != null) {
if (permission.equalsIgnoreCase(FileShareExport.Permissions.rw.name())) {
access = AccessEnum.READWRITE;
if (existingExport.getClients() != null && !existingExport.getClients().isEmpty()) {
if (rwClients == null) {
rwClients = new ArrayList<String>();
}
rwClients.addAll(existingExport.getClients());
}
} else if (permission.equalsIgnoreCase(FileShareExport.Permissions.ro.name())) {
access = AccessEnum.READ;
if (existingExport.getClients() != null && !existingExport.getClients().isEmpty()) {
if (roClients == null) {
roClients = new ArrayList<String>();
}
roClients.addAll(existingExport.getClients());
}
} else if (permission.equalsIgnoreCase(FileShareExport.Permissions.root.name())) {
access = AccessEnum.ROOT;
if (existingExport.getClients() != null && !existingExport.getClients().isEmpty()) {
if (rootClients == null) {
rootClients = new ArrayList<String>();
}
rootClients.addAll(existingExport.getClients());
}
}
}
if (permission.equalsIgnoreCase(FileShareExport.Permissions.rw.name())) {
access = AccessEnum.READWRITE;
if (exp.getClients() != null && !exp.getClients().isEmpty()) {
if (rwClients == null) {
rwClients = new ArrayList<String>();
}
rwClients.addAll(exp.getClients());
}
} else if (permission.equalsIgnoreCase(FileShareExport.Permissions.ro.name())) {
access = AccessEnum.READ;
if (exp.getClients() != null && !exp.getClients().isEmpty()) {
if (roClients == null) {
roClients = new ArrayList<String>();
}
roClients.addAll(exp.getClients());
}
} else if (permission.equalsIgnoreCase(FileShareExport.Permissions.root.name())) {
access = AccessEnum.ROOT;
if (exp.getClients() != null && !exp.getClients().isEmpty()) {
if (rootClients == null) {
rootClients = new ArrayList<String>();
}
rootClients.addAll(exp.getClients());
}
}
if (args.getFileOperation()) {
String mountPathFs = args.getFsMountPath();
if (!mountPathArg.equals(mountPathFs)) {
// subdirectory specified.
subdirName = mountPathArg.substring(mountPathFs.length() + 1);
path += subdirName;
}
String shareName = VNXeUtils.buildNfsShareName(fsName, subdirName);
job = apiClient.exportFileSystem(fsId, roClients, rwClients, rootClients, access, path, shareName, null, comments);
if (job != null) {
completer = new VNXeFileTaskCompleter(FileShare.class, args.getFsId(), args.getOpId());
VNXeExportFileSystemJob exportFSJob = new VNXeExportFileSystemJob(job.getId(), storage.getId(),
completer, newExport, shareName, true);
ControllerServiceImpl.enqueueJob(new QueueJob(exportFSJob));
} else {
_logger.error("No job returned from exportFileSystem");
ServiceError error = DeviceControllerErrors.vnxe.jobFailed("exportFileSystem",
"No Job returned from exportFileSystem");
return BiosCommandResult.createErrorResult(error);
}
} else {
String snapId = args.getSnapNativeId();
String snapName = args.getSnapshotName();
String shareName = VNXeUtils.buildNfsShareName(snapName, path);
job = apiClient.createNfsShareForSnap(snapId, roClients, rwClients, rootClients, access, path, shareName, comments);
if (job != null) {
completer = new VNXeFileTaskCompleter(Snapshot.class, args.getSnapshotId(), args.getOpId());
VNXeExportFileSystemJob exportFSJob = new VNXeExportFileSystemJob(job.getId(), storage.getId(),
completer, newExport, shareName, false);
ControllerServiceImpl.enqueueJob(new QueueJob(exportFSJob));
} else {
_logger.error("No job returned from exportFileSystem");
ServiceError error = DeviceControllerErrors.vnxe.jobFailed("exportFileSystem",
"No Job returned from exportFileSystem");
return BiosCommandResult.createErrorResult(error);
}
}
} catch (VNXeException e) {
_logger.error("Export file system got the exception", e);
if (completer != null) {
completer.error(_dbClient, e);
}
return BiosCommandResult.createErrorResult(e);
} catch (Exception ex) {
_logger.error("export file system got the exception", ex);
ServiceError error = DeviceControllerErrors.vnxe.jobFailed("exportFileSystem", ex.getMessage());
if (completer != null) {
completer.error(_dbClient, error);
}
return BiosCommandResult.createErrorResult(error);
}
_logger.info("Export job submitted");
}
return BiosCommandResult.createPendingResult();
}
@Override
public BiosCommandResult doShare(StorageSystem storage,
FileDeviceInputOutput args, SMBFileShare smbFileShare) throws ControllerException {
_logger.info("creating smbShare: " + smbFileShare.getName());
VNXeApiClient apiClient = getVnxeClient(storage);
String permission = smbFileShare.getPermission();
String shareName = smbFileShare.getName();
String path = "/";
VNXeCommandJob job = null;
VNXeFileTaskCompleter completer = null;
FileSMBShare newShare = new FileSMBShare(smbFileShare);
String absolutePath = smbFileShare.getPath();
newShare.setStoragePortNetworkId(smbFileShare.getStoragePortNetworkId());
newShare.setStoragePortName(smbFileShare.getStoragePortName());
try {
if (args.getFileOperation()) {
if (newShare.isSubDirPath()) {
String basePath = args.getFsPath();
/*
* The below line will allow us to get the relative path of subdir
* For example: absolutePath = /vnxeShare1/subdir1
* Then, the below line will assign path = subdir
* VNXe takes the relative path of the sub-directory. Not the absolute path
*/
path = "/" + new File(basePath).toURI().relativize(new File(absolutePath).toURI()).getPath();
}
String fsNativeId = args.getFs().getNativeId();
_logger.info("Creating CIFS share for path {}", path);
job = apiClient.createCIFSShare(fsNativeId, shareName, permission, path);
if (job != null) {
newShare.setNetBIOSName(apiClient.getNetBios());
completer = new VNXeFileTaskCompleter(FileShare.class, args.getFsId(), args.getOpId());
VNXeCreateShareJob createShareJob = new VNXeCreateShareJob(job.getId(), storage.getId(),
completer, newShare, true);
ControllerServiceImpl.enqueueJob(new QueueJob(createShareJob));
} else {
_logger.error("No job returned from creaetCifsShare");
ServiceError error = DeviceControllerErrors.vnxe.jobFailed("createShare", "No Job returned");
return BiosCommandResult.createErrorResult(error);
}
} else {
// create share for a snapshot
if (newShare.isSubDirPath()) {
String basePath = args.getSnapshotPath();
/*
* The below line will allow us to get the relative path of subdir
* For example: absolutePath = /vnxeShare1/subdir1
* Then, the below line will assign path = subdir
* VNXe takes the relative path of the sub-directory. Not the absolute path
*/
path = "/" + new File(basePath).toURI().relativize(new File(absolutePath).toURI()).getPath();
}
String fsNativeId = args.getFs().getNativeId();
String snapId = args.getSnapNativeId();
job = apiClient.createCifsShareForSnap(snapId, shareName, permission, path, fsNativeId);
if (job != null) {
newShare.setNetBIOSName(apiClient.getNetBios());
completer = new VNXeFileTaskCompleter(Snapshot.class, args.getSnapshotId(), args.getOpId());
VNXeCreateShareJob createShareJob = new VNXeCreateShareJob(job.getId(), storage.getId(),
completer, newShare, false);
ControllerServiceImpl.enqueueJob(new QueueJob(createShareJob));
} else {
_logger.error("No job returned from creaetCifsShare");
ServiceError error = DeviceControllerErrors.vnxe.jobFailed("createShare", "No Job returned");
return BiosCommandResult.createErrorResult(error);
}
}
} catch (VNXeException e) {
_logger.error("Create share got the exception", e);
if (completer != null) {
completer.error(_dbClient, e);
}
return BiosCommandResult.createErrorResult(e);
} catch (Exception ex) {
_logger.error("create share got the exception", ex);
ServiceError error = DeviceControllerErrors.vnxe.jobFailed("create share", ex.getMessage());
if (completer != null) {
completer.error(_dbClient, error);
}
return BiosCommandResult.createErrorResult(error);
}
StringBuilder logMsgBuilder = new StringBuilder(String.format(
"Create share job submitted - Array:%s, share: %s", storage.getSerialNumber(),
smbFileShare.getName()));
_logger.info(logMsgBuilder.toString());
return BiosCommandResult.createPendingResult();
}
@Override
public BiosCommandResult doDeleteShare(StorageSystem storage,
FileDeviceInputOutput args, SMBFileShare smbFileShare) throws ControllerException {
_logger.info(String.format(String.format("Deleting smbShare: %s, nativeId: %s",
smbFileShare.getName(), smbFileShare.getNativeId())));
VNXeApiClient apiClient = getVnxeClient(storage);
String shareId = smbFileShare.getNativeId();
VNXeCommandJob job = null;
VNXeFileTaskCompleter completer = null;
boolean isFile = args.getFileOperation();
FileSMBShare newShare = new FileSMBShare(smbFileShare);
try {
if (isFile) {
String fsId = args.getFs().getNativeId();
job = apiClient.removeCifsShare(shareId, fsId);
} else {
job = apiClient.deleteCifsShareForSnapshot(shareId);
}
if (job != null) {
if (isFile) {
completer = new VNXeFileTaskCompleter(FileShare.class, args.getFsId(), args.getOpId());
} else {
completer = new VNXeFileTaskCompleter(Snapshot.class, args.getSnapshotId(), args.getOpId());
}
VNXeDeleteShareJob deleteShareJob = new VNXeDeleteShareJob(job.getId(), storage.getId(),
completer, newShare, isFile);
ControllerServiceImpl.enqueueJob(new QueueJob(deleteShareJob));
} else {
_logger.error("No job returned from deleteCifsShare");
ServiceError error = DeviceControllerErrors.vnxe.jobFailed("deleteShare", "No Job returned");
return BiosCommandResult.createErrorResult(error);
}
} catch (VNXeException e) {
_logger.error("Create share got the exception", e);
if (completer != null) {
completer.error(_dbClient, e);
}
return BiosCommandResult.createErrorResult(e);
} catch (Exception ex) {
_logger.error("delete share got the exception", ex);
ServiceError error = DeviceControllerErrors.vnxe.jobFailed("create share", ex.getMessage());
if (completer != null) {
completer.error(_dbClient, error);
}
return BiosCommandResult.createErrorResult(error);
}
StringBuilder logMsgBuilder = new StringBuilder(String.format(
"Delete share job submitted - Array:%s, share: %s", storage.getSerialNumber(),
smbFileShare.getName()));
_logger.info(logMsgBuilder.toString());
return BiosCommandResult.createPendingResult();
}
@Override
public BiosCommandResult doDeleteShares(StorageSystem storage,
FileDeviceInputOutput args) throws ControllerException {
return null;
}
@Override
public BiosCommandResult doUnexport(StorageSystem storage,
FileDeviceInputOutput args, List<FileExport> exportList) throws ControllerException {
_logger.info("unexporting the file system: " + args.getFsName());
boolean isFile = args.getFileOperation();
for (FileExport exp : exportList) {
VNXeApiClient apiClient = getVnxeClient(storage);
String vnxeShareId = exp.getIsilonId();
VNXeCommandJob job = null;
VNXeFileTaskCompleter completer = null;
try {
if (isFile) {
String fsId = args.getFs().getNativeId();
job = apiClient.removeNfsShare(vnxeShareId, fsId);
} else {
job = apiClient.deleteNfsShareForSnapshot(vnxeShareId);
}
if (job != null) {
if (isFile) {
completer = new VNXeFileTaskCompleter(FileShare.class, args.getFsId(), args.getOpId());
} else {
completer = new VNXeFileTaskCompleter(Snapshot.class, args.getSnapshotId(), args.getOpId());
}
FileShareExport export = new FileShareExport(exp);
VNXeUnexportFileSystemJob unexportFSJob = new VNXeUnexportFileSystemJob(job.getId(), storage.getId(),
completer, export, export.getPath(), isFile);
ControllerServiceImpl.enqueueJob(new QueueJob(unexportFSJob));
} else {
_logger.error("No job returned from exportFileSystem");
ServiceError error = DeviceControllerErrors.vnxe.jobFailed("DeleteFileSystem", "No Job returned from deleteFileSystem");
return BiosCommandResult.createErrorResult(error);
}
} catch (VNXeException e) {
_logger.error("Unexport file system got the exception", e);
if (completer != null) {
completer.error(_dbClient, e);
}
return BiosCommandResult.createErrorResult(e);
} catch (Exception ex) {
_logger.error("Delete file system got the exception", ex);
ServiceError error = DeviceControllerErrors.vnxe.jobFailed("DeleteFileSystem", ex.getMessage());
if (completer != null) {
completer.error(_dbClient, error);
}
return BiosCommandResult.createErrorResult(error);
}
StringBuilder logMsgBuilder = new StringBuilder(String.format(
"Unexport filesystem job submitted - Array:%s, fileSystem: %s", storage.getSerialNumber(),
args.getFsName()));
_logger.info(logMsgBuilder.toString());
}
return BiosCommandResult.createPendingResult();
}
@Override
public BiosCommandResult doModifyFS(StorageSystem storage,
FileDeviceInputOutput fd) throws ControllerException {
BiosCommandResult result = new BiosCommandResult();
result.setCommandSuccess(false);
result.setCommandStatus(Operation.Status.error.name());
result.setMessage("Modify FS NOT supported for VNXe.");
return result;
}
@Override
public BiosCommandResult doExpandFS(StorageSystem storage,
FileDeviceInputOutput args) throws ControllerException {
_logger.info("expanding file system: ", args.getFsName());
VNXeApiClient apiClient = getVnxeClient(storage);
VNXeCommandJob job = null;
VNXeFileTaskCompleter completer = null;
try {
job = apiClient.expandFileSystem(args.getFsNativeId(), args.getNewFSCapacity());
if (job != null) {
completer = new VNXeFileTaskCompleter(FileShare.class, args.getFsId(), args.getOpId());
VNXeExpandFileSystemJob expandFSJob = new VNXeExpandFileSystemJob(job.getId(), storage.getId(),
completer);
ControllerServiceImpl.enqueueJob(new QueueJob(expandFSJob));
} else {
_logger.error("No job returned from expandFileSystem");
ServiceError error = DeviceControllerErrors.vnxe.jobFailed(
"expandFileSystem", "No Job returned from expandFileSystem");
return BiosCommandResult.createErrorResult(error);
}
} catch (VNXeException e) {
_logger.error("Expand file system got the exception", e);
if (completer != null) {
completer.error(_dbClient, e);
}
return BiosCommandResult.createErrorResult(e);
} catch (Exception ex) {
_logger.error("Expand file system got the exception", ex);
ServiceError error = DeviceControllerErrors.vnxe.jobFailed("ExpandFileSystem", ex.getMessage());
if (completer != null) {
completer.error(_dbClient, error);
}
return BiosCommandResult.createErrorResult(error);
}
StringBuilder logMsgBuilder = new StringBuilder(String.format(
"Expand filesystem job submitted - Array:%s, fileSystem: %s, new size: %d", storage.getSerialNumber(),
args.getFsName(), args.getNewFSCapacity()));
_logger.info(logMsgBuilder.toString());
return BiosCommandResult.createPendingResult();
}
@Override
public BiosCommandResult doSnapshotFS(StorageSystem storage,
FileDeviceInputOutput args) throws ControllerException {
_logger.info("creating file system {} snap {} ", args.getFsName(), args.getSnapshotLabel());
VNXeApiClient apiClient = getVnxeClient(storage);
VNXeCommandJob job = null;
VNXeFSSnapshotTaskCompleter completer = null;
try {
job = apiClient.createFileSystemSnap(args.getFsNativeId(), args.getSnapshotName());
if (job != null) {
completer = new VNXeFSSnapshotTaskCompleter(Snapshot.class, args.getSnapshotId(), args.getOpId());
VNXeCreateFileSystemSnapshotJob snapJob = new VNXeCreateFileSystemSnapshotJob(job.getId(), storage.getId(),
completer);
ControllerServiceImpl.enqueueJob(new QueueJob(snapJob));
} else {
_logger.error("No job returned from createFileSystemSnap");
ServiceError error = DeviceControllerErrors.vnxe.jobFailed(
"snapshotFileSystem", "No Job returned from createFileSystemSnap");
return BiosCommandResult.createErrorResult(error);
}
} catch (VNXeException e) {
_logger.error("Create file system snapshot got the exception", e);
if (completer != null) {
completer.error(_dbClient, e);
}
return BiosCommandResult.createErrorResult(e);
} catch (Exception ex) {
_logger.error("Create file system snpashot got the exception", ex);
ServiceError error = DeviceControllerErrors.vnxe.jobFailed("CreateFileSystemSnapshot", ex.getMessage());
if (completer != null) {
completer.error(_dbClient, error);
}
return BiosCommandResult.createErrorResult(error);
}
StringBuilder logMsgBuilder = new StringBuilder(String.format(
"Create filesystem snapshot job submitted - Array:%s, fileSystem: %s", storage.getSerialNumber(),
args.getFsName()));
_logger.info(logMsgBuilder.toString());
return BiosCommandResult.createPendingResult();
}
@Override
public BiosCommandResult doRestoreFS(StorageSystem storage,
FileDeviceInputOutput args) throws ControllerException {
_logger.info("restoring file system {} snap {} ", args.getFsName(), args.getSnapshotLabel());
VNXeApiClient apiClient = getVnxeClient(storage);
VNXeCommandJob job = null;
VNXeFSSnapshotTaskCompleter completer = null;
try {
job = apiClient.restoreFileSystemSnap(args.getSnapNativeId());
if (job != null) {
completer = new VNXeFSSnapshotTaskCompleter(Snapshot.class, args.getSnapshotId(), args.getOpId());
VNXeRestoreFileSystemSnapshotJob snapJob = new VNXeRestoreFileSystemSnapshotJob(job.getId(), storage.getId(),
completer);
ControllerServiceImpl.enqueueJob(new QueueJob(snapJob));
} else {
_logger.error("No job returned from restoreFileSystemSnap");
ServiceError error = DeviceControllerErrors.vnxe.jobFailed(
"restoreSnapshotFileSystem", "No Job returned from restoreFileSystemSnap");
return BiosCommandResult.createErrorResult(error);
}
} catch (VNXeException e) {
_logger.error("Restore file system snapshot got the exception", e);
if (completer != null) {
completer.error(_dbClient, e);
}
return BiosCommandResult.createErrorResult(e);
} catch (Exception ex) {
_logger.error("Restore file system snpashot got the exception", ex);
ServiceError error = DeviceControllerErrors.vnxe.jobFailed("RestoreFileSystemSnapshot", ex.getMessage());
if (completer != null) {
completer.error(_dbClient, error);
}
return BiosCommandResult.createErrorResult(error);
}
StringBuilder logMsgBuilder = new StringBuilder(String.format(
"Restore filesystem snapshot job submitted - Array:%s, fileSystem: %s, snapshot: %s",
storage.getSerialNumber(), args.getFsName(), args.getSnapshotLabel()));
_logger.info(logMsgBuilder.toString());
return BiosCommandResult.createPendingResult();
}
@Override
public BiosCommandResult doDeleteSnapshot(StorageSystem storage,
FileDeviceInputOutput args) throws ControllerException {
_logger.info("Deleting file system {} snapshot {} ", args.getFsName(), args.getSnapshotLabel());
VNXeApiClient apiClient = getVnxeClient(storage);
VNXeCommandJob job = null;
VNXeFileTaskCompleter completer = null;
try {
job = apiClient.deleteFileSystemSnap(args.getSnapNativeId());
if (job != null) {
completer = new VNXeFileTaskCompleter(Snapshot.class, args.getSnapshotId(), args.getOpId());
VNXeDeleteFileSystemSnapshotJob snapJob = new VNXeDeleteFileSystemSnapshotJob(job.getId(), storage.getId(),
completer);
ControllerServiceImpl.enqueueJob(new QueueJob(snapJob));
} else {
_logger.error("No job returned from deleteFileSystemSnap");
ServiceError error = DeviceControllerErrors.vnxe.jobFailed(
"snapshotFileSystem", "No Job returned from deleteFileSystemSnap");
return BiosCommandResult.createErrorResult(error);
}
} catch (VNXeException e) {
_logger.error("Delete file system snapshot got the exception", e);
if (completer != null) {
completer.error(_dbClient, e);
}
return BiosCommandResult.createErrorResult(e);
} catch (Exception ex) {
_logger.error("Delete file system snpashot got the exception", ex);
ServiceError error = DeviceControllerErrors.vnxe.jobFailed("DeleteFileSystemSnapshot", ex.getMessage());
if (completer != null) {
completer.error(_dbClient, error);
}
return BiosCommandResult.createErrorResult(error);
}
StringBuilder logMsgBuilder = new StringBuilder(String.format(
"Delete filesystem snapshot job submitted - Array:%s, fileSystem: %s, snapshot: %s", storage.getSerialNumber(),
args.getFsName(), args.getSnapshotName()));
_logger.info(logMsgBuilder.toString());
return BiosCommandResult.createPendingResult();
}
@Override
public void doConnect(StorageSystem storage) throws ControllerException {
try {
_logger.info("doConnect {} - start", storage.getId());
VNXeApiClient client = getVnxeClient(storage);
client.getStorageSystem();
String msg = String.format("doConnect %1$s - complete", storage.getId());
_logger.info(msg);
} catch (VNXeException e) {
_logger.error("doConnect failed.", e);
throw DeviceControllerException.exceptions.connectStorageFailed(e);
}
}
@Override
public void doDisconnect(StorageSystem storage) {
try {
_logger.info("doConnect {} - start", storage.getId());
VNXeApiClient client = getVnxeClient(storage);
client.logout();
String msg = String.format("doDisconnect %1$s - complete", storage.getId());
_logger.info(msg);
} catch (VNXeException e) {
_logger.error("doDisconnect failed.", e);
throw DeviceControllerException.exceptions.disconnectStorageFailed(e);
}
}
@Override
public BiosCommandResult getPhysicalInventory(StorageSystem storage) {
// TODO Auto-generated method stub
return null;
}
@Override
public BiosCommandResult getFSSnapshotList(StorageSystem storage,
FileDeviceInputOutput fd, List<String> snapshots) throws ControllerException {
_logger.info("getFSSnapshotList {} - start", fd.getFsId());
VNXeApiClient client = getVnxeClient(storage);
try {
List<VNXeFileSystemSnap> snaps = client.getFileSystemSnaps(fd.getFsNativeId());
for (VNXeFileSystemSnap snap : snaps) {
snapshots.add(snap.getName());
}
return BiosCommandResult.createSuccessfulResult();
} catch (VNXeException e) {
_logger.error("getFSSnapshotList failed.", e);
return BiosCommandResult.createErrorResult(e);
}
}
@Override
public void doCreateVolumes(StorageSystem storage, StoragePool storagePool,
String opId, List<Volume> volumes,
VirtualPoolCapabilityValuesWrapper capabilities,
TaskCompleter taskCompleter) throws DeviceControllerException {
_logger.info("creating volumes, array: {}, pool : {}", storage.getSerialNumber(),
storagePool.getNativeId());
VNXeApiClient apiClient = getVnxeClient(storage);
List<String> jobs = new ArrayList<String>();
boolean opFailed = false;
try {
boolean isCG = false;
Volume vol = volumes.get(0);
if (vol.getConsistencyGroup() != null) {
isCG = true;
}
List<String> volNames = new ArrayList<String>();
String autoTierPolicyName = null;
InvokeTestFailure.internalOnlyInvokeTestFailure(InvokeTestFailure.ARTIFICIAL_FAILURE_022);
for (Volume volume : volumes) {
String tenantName = "";
try {
TenantOrg tenant = _dbClient.queryObject(TenantOrg.class, volume.getTenant()
.getURI());
tenantName = tenant.getLabel();
} catch (DatabaseException e) {
_logger.error("Error lookup TenantOrb object", e);
}
String label = nameGenerator.generate(tenantName, volume.getLabel(), volume.getId()
.toString(), '-', VNXeConstants.MAX_NAME_LENGTH);
autoTierPolicyName = ControllerUtils.getAutoTieringPolicyName(volume.getId(), _dbClient);
if (autoTierPolicyName.equals(Constants.NONE)) {
autoTierPolicyName = null;
}
volume.setNativeGuid(label);
_dbClient.persistObject(volume);
if (!isCG) {
VNXeCommandJob job = apiClient.createLun(label, storagePool.getNativeId(), volume.getCapacity(),
volume.getThinlyProvisioned(), autoTierPolicyName);
jobs.add(job.getId());
} else {
volNames.add(label);
}
}
if (isCG) {
URI cg = vol.getConsistencyGroup();
BlockConsistencyGroup cgObj = _dbClient.queryObject(BlockConsistencyGroup.class, cg);
String cgId = cgObj.getCgNameOnStorageSystem(storage.getId());
VNXeCommandJob job = apiClient.createLunsInLunGroup(volNames, storagePool.getNativeId(), vol.getCapacity(),
vol.getThinlyProvisioned(), autoTierPolicyName, cgId);
jobs.add(job.getId());
}
VNXeCreateVolumesJob createVolumesJob = new VNXeCreateVolumesJob(jobs, storage.getId(),
taskCompleter, storagePool.getId(), isCG);
ControllerServiceImpl.enqueueJob(new QueueJob(createVolumesJob));
InvokeTestFailure.internalOnlyInvokeTestFailure(InvokeTestFailure.ARTIFICIAL_FAILURE_023);
} catch (VNXeException e) {
_logger.error("Create volumes got the exception", e);
opFailed = true;
taskCompleter.error(_dbClient, e);
} catch (Exception ex) {
_logger.error("Create volumes got the exception", ex);
opFailed = true;
ServiceError error = DeviceControllerErrors.vnxe.jobFailed("CreateVolumes", ex.getMessage());
taskCompleter.error(_dbClient, error);
}
if (opFailed) {
for (Volume vol : volumes) {
vol.setInactive(true);
_dbClient.persistObject(vol);
}
}
}
@Override
public void doCreateMetaVolume(StorageSystem storage,
StoragePool storagePool, Volume volume,
VirtualPoolCapabilityValuesWrapper capabilities,
MetaVolumeRecommendation recommendation,
VolumeCreateCompleter completer) throws DeviceControllerException {
// TODO Auto-generated method stub
}
@Override
public void doExpandVolume(StorageSystem storage, StoragePool pool,
Volume volume, Long size, TaskCompleter taskCompleter)
throws DeviceControllerException {
_logger.info(String.format("Expand Volume Start - Array: %s, Pool: %s, Volume: %s, New size: %d",
storage.getSerialNumber(), pool.getNativeGuid(), volume.getLabel(), size));
String consistencyGroupId = null;
URI consistencyGroupURI = volume.getConsistencyGroup();
if (consistencyGroupURI != null) {
BlockConsistencyGroup consistencyGroup = _dbClient.queryObject(BlockConsistencyGroup.class,
consistencyGroupURI);
if (consistencyGroup != null) {
consistencyGroupId = consistencyGroup.getCgNameOnStorageSystem(storage.getId());
}
}
try {
VNXeApiClient apiClient = getVnxeClient(storage);
VNXeCommandJob commandJob = apiClient.expandLun(volume.getNativeId(), size, consistencyGroupId);
VNXeExpandVolumeJob expandVolumeJob = new VNXeExpandVolumeJob(commandJob.getId(), storage.getId(), taskCompleter);
ControllerServiceImpl.enqueueJob(new QueueJob(expandVolumeJob));
} catch (VNXeException e) {
_logger.error("Expand volume got the exception", e);
taskCompleter.error(_dbClient, e);
} catch (Exception ex) {
_logger.error("Expand volume got the exception", ex);
ServiceError error = DeviceControllerErrors.vnxe.jobFailed("ExpandVolume", ex.getMessage());
taskCompleter.error(_dbClient, error);
}
}
/*
* @Override
* public void doExpandAsMetaVolume(StorageSystem storageSystem,
* StoragePool storagePool, Volume volume, long size,
* MetaVolumeRecommendation recommendation,
* TaskCompleter volumeCompleter) throws DeviceControllerException {
* // TODO Auto-generated method stub
*
* }
*/
@Override
public void doDeleteVolumes(StorageSystem storageSystem, String opId,
List<Volume> volumes, TaskCompleter completer)
throws DeviceControllerException {
_logger.info("deleting volumes, array: {}", storageSystem.getSerialNumber());
VNXeApiClient apiClient = getVnxeClient(storageSystem);
List<String> jobs = new ArrayList<String>();
Map<String, List<String>> consistencyGroupMap = new HashMap<String, List<String>>();
try {
for (Volume volume : volumes) {
if (volume.getConsistencyGroup() != null) {
BlockConsistencyGroup consistencyGroupObj = _dbClient.queryObject(BlockConsistencyGroup.class,
volume.getConsistencyGroup());
List<String> lunIds = consistencyGroupMap.get(consistencyGroupObj.getCgNameOnStorageSystem(storageSystem.getId()));
if (lunIds == null) {
lunIds = new ArrayList<String>();
consistencyGroupMap.put(consistencyGroupObj.getCgNameOnStorageSystem(storageSystem.getId()), lunIds);
}
lunIds.add(volume.getNativeId());
} else {
VNXeCommandJob job = apiClient.deleteLun(volume.getNativeId(), true);
jobs.add(job.getId());
}
}
for (String consistencyGroup : consistencyGroupMap.keySet()) {
List<String> lunIDs = consistencyGroupMap.get(consistencyGroup);
VNXeCommandJob job = apiClient.deleteLunsFromLunGroup(consistencyGroup, lunIDs);
jobs.add(job.getId());
}
VNXeDeleteVolumesJob deleteVolumesJob = new VNXeDeleteVolumesJob(jobs, storageSystem.getId(),
completer);
ControllerServiceImpl.enqueueJob(new QueueJob(deleteVolumesJob));
} catch (VNXeException e) {
_logger.error("Delete volumes got the exception", e);
completer.error(_dbClient, e);
} catch (Exception ex) {
_logger.error("Delete volumes got the exception", ex);
ServiceError error = DeviceControllerErrors.vnxe.jobFailed("DeleteVolumes", ex.getMessage());
completer.error(_dbClient, error);
}
}
@Override
public void doExportCreate(StorageSystem storage,
ExportMask exportMask, Map<URI, Integer> volumeMap,
List<Initiator> initiators, List<URI> targets,
TaskCompleter taskCompleter) throws DeviceControllerException {
_logger.info("{} doExportCreate START ...", storage.getSerialNumber());
VolumeURIHLU[] volumeLunArray = ControllerUtils.getVolumeURIHLUArray(
storage.getSystemType(), volumeMap, _dbClient);
exportMaskOperationsHelper.createExportMask(storage, exportMask.getId(), volumeLunArray,
targets, initiators, taskCompleter);
_logger.info("{} doExportCreate END ...", storage.getSerialNumber());
}
@Override
public void doExportDelete(StorageSystem storage,
ExportMask exportMask, List<URI> volumeURIs, List<URI> initiatorURIs, TaskCompleter taskCompleter)
throws DeviceControllerException {
_logger.info("{} doExportDelete START ...", storage.getSerialNumber());
List<URI> volumesImpacted = new ArrayList<URI>();
StringMap maskVolumes = exportMask.getVolumes();
if (maskVolumes != null && !maskVolumes.isEmpty()) {
for (String volURI : maskVolumes.keySet()) {
volumesImpacted.add(URI.create(volURI));
}
}
exportMaskOperationsHelper.deleteExportMask(storage, exportMask.getId(),
volumesImpacted, new ArrayList<URI>(), new ArrayList<Initiator>(),
taskCompleter);
_logger.info("{} doExportDelete END ...", storage.getSerialNumber());
}
@Override
public void doExportAddVolume(StorageSystem storage, ExportMask exportMask,
URI volume, Integer lun, List<Initiator> initiators, TaskCompleter taskCompleter)
throws DeviceControllerException {
_logger.info("{} doExportAddVolume START ...", storage.getSerialNumber());
Map<URI, Integer> map = new HashMap<URI, Integer>();
map.put(volume, lun);
VolumeURIHLU[] volumeLunArray = ControllerUtils.getVolumeURIHLUArray(
storage.getSystemType(), map, _dbClient);
exportMaskOperationsHelper.addVolumes(storage, exportMask.getId(), volumeLunArray,
initiators, taskCompleter);
_logger.info("{} doExportAddVolume END ...", storage.getSerialNumber());
}
@Override
public void doExportAddVolumes(StorageSystem storage,
ExportMask exportMask, List<Initiator> initiators,
Map<URI, Integer> volumes, TaskCompleter taskCompleter) throws DeviceControllerException {
_logger.info("{} doExportAddVolume START ...", storage.getSerialNumber());
VolumeURIHLU[] volumeLunArray = ControllerUtils.getVolumeURIHLUArray(
storage.getSystemType(), volumes, _dbClient);
exportMaskOperationsHelper.addVolumes(storage, exportMask.getId(), volumeLunArray,
initiators, taskCompleter);
_logger.info("{} doExportAddVolume END ...", storage.getSerialNumber());
}
@Override
public void doExportRemoveVolume(StorageSystem storage,
ExportMask exportMask, URI volume, List<Initiator> initiators, TaskCompleter taskCompleter)
throws DeviceControllerException {
_logger.info("{} doExportRemoveVolume START ...", storage.getSerialNumber());
exportMaskOperationsHelper.removeVolumes(storage, exportMask.getId(),
Arrays.asList(volume), initiators, taskCompleter);
_logger.info("{} doExportRemoveVolume END ...", storage.getSerialNumber());
}
@Override
public void doExportRemoveVolumes(StorageSystem storage,
ExportMask exportMask, List<URI> volumes,
List<Initiator> initiators, TaskCompleter taskCompleter) throws DeviceControllerException {
_logger.info("{} doExportRemoveVolume START ...", storage.getSerialNumber());
exportMaskOperationsHelper.removeVolumes(storage, exportMask.getId(), volumes,
initiators, taskCompleter);
_logger.info("{} doExportRemoveVolume END ...", storage.getSerialNumber());
}
@Override
public void doExportAddInitiator(StorageSystem storage,
ExportMask exportMask, List<URI> volumeURIs, Initiator initiator,
List<URI> targets, TaskCompleter taskCompleter) throws DeviceControllerException {
_logger.info("{} doExportAddInitiator START ...", storage.getSerialNumber());
exportMaskOperationsHelper.addInitiators(storage, exportMask.getId(),
volumeURIs, Arrays.asList(initiator), targets, taskCompleter);
_logger.info("{} doExportAddInitiator END ...", storage.getSerialNumber());
}
@Override
public void doExportAddInitiators(StorageSystem storage,
ExportMask exportMask, List<URI> volumeURIs,
List<Initiator> initiators, List<URI> targets, TaskCompleter taskCompleter)
throws DeviceControllerException {
_logger.info("{} doExportAddInitiator START ...", storage.getSerialNumber());
exportMaskOperationsHelper.addInitiators(storage, exportMask.getId(), volumeURIs, initiators,
targets, taskCompleter);
_logger.info("{} doExportAddInitiator END ...", storage.getSerialNumber());
}
@Override
public void doExportRemoveInitiator(StorageSystem storage,
ExportMask exportMask, List<URI> volumes, Initiator initiator,
List<URI> targets, TaskCompleter taskCompleter) throws DeviceControllerException {
_logger.info("{} doExportRemoveInitiator START ...", storage.getSerialNumber());
exportMaskOperationsHelper.removeInitiators(storage, exportMask.getId(),
volumes, Arrays.asList(initiator), targets, taskCompleter);
_logger.info("{} doExportRemoveInitiator END ...", storage.getSerialNumber());
}
@Override
public void doExportRemoveInitiators(StorageSystem storage,
ExportMask exportMask, List<URI> volumes,
List<Initiator> initiators, List<URI> targets, TaskCompleter taskCompleter)
throws DeviceControllerException {
_logger.info("{} doExportRemoveInitiator START ...", storage.getSerialNumber());
exportMaskOperationsHelper.removeInitiators(storage, exportMask.getId(),
volumes, initiators, targets, taskCompleter);
_logger.info("{} doExportRemoveInitiator END ...", storage.getSerialNumber());
}
@Override
public void doCreateSingleSnapshot(StorageSystem storage, List<URI> snapshotList, Boolean createInactive, Boolean readOnly,
TaskCompleter taskCompleter) throws DeviceControllerException {
_logger.info("{} doCreateSingleSnapshot START ...", storage.getSerialNumber());
List<BlockSnapshot> snapshots = _dbClient
.queryObject(BlockSnapshot.class, snapshotList);
URI snapshot = snapshots.get(0).getId();
_snapshotOperations.createSingleVolumeSnapshot(storage, snapshot, createInactive,
readOnly, taskCompleter);
_logger.info("{} doCreateSingleSnapshot END ...", storage.getSerialNumber());
}
@Override
public void doCreateSnapshot(StorageSystem storage, List<URI> snapshotList,
Boolean createInactive, Boolean readOnly, TaskCompleter taskCompleter)
throws DeviceControllerException {
_logger.info("{} doCreateSnapshot START ...", storage.getSerialNumber());
List<BlockSnapshot> snapshots = _dbClient
.queryObject(BlockSnapshot.class, snapshotList);
if (ControllerUtils.checkSnapshotsInConsistencyGroup(snapshots, _dbClient, taskCompleter)) {
_snapshotOperations.createGroupSnapshots(storage, snapshotList, createInactive, readOnly, taskCompleter);
} else {
URI snapshot = snapshots.get(0).getId();
_snapshotOperations.createSingleVolumeSnapshot(storage, snapshot, createInactive,
readOnly, taskCompleter);
}
_logger.info("{} doCreateSnapshot END ...", storage.getSerialNumber());
}
@Override
public void doActivateSnapshot(StorageSystem storage,
List<URI> snapshotList, TaskCompleter taskCompleter)
throws DeviceControllerException {
_logger.info("{} doActivateSnapshot START ...", storage.getSerialNumber());
List<BlockSnapshot> snapshots = _dbClient.queryObject(BlockSnapshot.class, snapshotList);
URI snapshot = snapshots.get(0).getId();
if (ControllerUtils.checkSnapshotsInConsistencyGroup(snapshots, _dbClient, taskCompleter)) {
_snapshotOperations.activateGroupSnapshots(storage, snapshot, taskCompleter);
} else {
_snapshotOperations.activateSingleVolumeSnapshot(storage, snapshot, taskCompleter);
}
_logger.info("{} doDeleteSnapshot END ...", storage.getSerialNumber());
}
@Override
public void doDeleteSnapshot(StorageSystem storage, URI snapshot,
TaskCompleter taskCompleter) throws DeviceControllerException {
_logger.info("{} doDeleteSnapshot START ...", storage.getSerialNumber());
List<BlockSnapshot> snapshots = _dbClient.queryObject(BlockSnapshot.class, Arrays.asList(snapshot));
if (ControllerUtils.checkSnapshotsInConsistencyGroup(snapshots, _dbClient, taskCompleter)) {
_snapshotOperations.deleteGroupSnapshots(storage, snapshot, taskCompleter);
} else {
_snapshotOperations.deleteSingleVolumeSnapshot(storage, snapshot, taskCompleter);
}
_logger.info("{} doDeleteSnapshot END ...", storage.getSerialNumber());
}
@Override
public void doDeleteSelectedSnapshot(StorageSystem storage, URI snapshot, TaskCompleter taskCompleter)
throws DeviceControllerException {
_logger.info("{} doDeleteSelectedSnapshot START ...", storage.getSerialNumber());
try {
_snapshotOperations.deleteSingleVolumeSnapshot(storage, snapshot, taskCompleter);
} catch (DatabaseException e) {
String message = String.format(
"IO exception when trying to delete snapshot(s) on array %s",
storage.getSerialNumber());
_logger.error(message, e);
ServiceError error = DeviceControllerErrors.smis.methodFailed("doDeleteSnapshot",
e.getMessage());
taskCompleter.error(_dbClient, error);
}
_logger.info("{} doDeleteSelectedSnapshot END ...", storage.getSerialNumber());
}
@Override
public void doRestoreFromSnapshot(StorageSystem storage, URI volume,
URI snapshot, TaskCompleter taskCompleter)
throws DeviceControllerException {
_logger.info("{} doRestoreFromSnapshot START ...", storage.getSerialNumber());
List<BlockSnapshot> snapshots = _dbClient.queryObject(BlockSnapshot.class, Arrays.asList(snapshot));
if (ControllerUtils.checkSnapshotsInConsistencyGroup(snapshots, _dbClient, taskCompleter)) {
_snapshotOperations.restoreGroupSnapshots(storage, volume, snapshot, taskCompleter);
} else {
_snapshotOperations.restoreSingleVolumeSnapshot(storage, volume, snapshot, taskCompleter);
}
_logger.info("{} doRestoreFromSnapshot END ...", storage.getSerialNumber());
}
@Override
public void doFractureMirror(StorageSystem storage, URI mirror,
Boolean sync, TaskCompleter taskCompleter)
throws DeviceControllerException {
throw DeviceControllerException.exceptions.blockDeviceOperationNotSupported();
}
@Override
public void doDetachMirror(StorageSystem storage, URI mirror,
TaskCompleter taskCompleter) throws DeviceControllerException {
throw DeviceControllerException.exceptions.blockDeviceOperationNotSupported();
}
@Override
public void doResumeNativeContinuousCopy(StorageSystem storage, URI mirror,
TaskCompleter taskCompleter) throws DeviceControllerException {
throw DeviceControllerException.exceptions.blockDeviceOperationNotSupported();
}
@Override
public void doEstablishVolumeNativeContinuousCopyGroupRelation(
StorageSystem storage, URI sourceVolume, URI mirror,
TaskCompleter taskCompleter) throws DeviceControllerException {
throw DeviceControllerException.exceptions.blockDeviceOperationNotSupported();
}
@Override
public void doEstablishVolumeSnapshotGroupRelation(
StorageSystem storage, URI sourceVolume, URI snapshot,
TaskCompleter taskCompleter) throws DeviceControllerException {
throw DeviceControllerException.exceptions
.blockDeviceOperationNotSupported();
}
@Override
public void doDeleteMirror(StorageSystem storage, URI mirror,
TaskCompleter taskCompleter) throws DeviceControllerException {
throw DeviceControllerException.exceptions.blockDeviceOperationNotSupported();
}
@Override
public void doCreateClone(StorageSystem storageSystem, URI sourceVolume,
URI cloneVolume, Boolean createInactive, TaskCompleter taskCompleter) {
throw DeviceControllerException.exceptions.blockDeviceOperationNotSupported();
}
@Override
public void doDetachClone(StorageSystem storage, URI cloneVolume,
TaskCompleter taskCompleter) {
throw DeviceControllerException.exceptions.blockDeviceOperationNotSupported();
}
@Override
public void doCreateConsistencyGroup(StorageSystem storage,
URI consistencyGroup, String replicationGroupName, TaskCompleter taskCompleter)
throws DeviceControllerException {
_logger.info("creating consistency group, array: {}", storage.getSerialNumber());
BlockConsistencyGroup consistencyGroupObj = _dbClient.queryObject(BlockConsistencyGroup.class,
consistencyGroup);
VNXeApiClient apiClient = getVnxeClient(storage);
String tenantName = "";
try {
TenantOrg tenant = _dbClient.queryObject(TenantOrg.class, consistencyGroupObj.getTenant()
.getURI());
tenantName = tenant.getLabel();
} catch (DatabaseException e) {
_logger.error("Error lookup TenantOrb object", e);
}
String label = nameGenerator.generate(tenantName, consistencyGroupObj.getLabel(),
consistencyGroupObj.getId().toString(), '-', VNXeConstants.MAX_NAME_LENGTH);
try {
VNXeCommandResult result = apiClient.createLunGroup(label);
if (result.getStorageResource() != null) {
consistencyGroupObj.addSystemConsistencyGroup(storage.getId().toString(),
result.getStorageResource().getId());
consistencyGroupObj.addConsistencyGroupTypes(Types.LOCAL.name());
if (NullColumnValueGetter.isNullURI(consistencyGroupObj.getStorageController())) {
consistencyGroupObj.setStorageController(storage.getId());
}
_dbClient.persistObject(consistencyGroupObj);
taskCompleter.ready(_dbClient);
} else {
_logger.error("No storage resource Id returned");
consistencyGroupObj.setInactive(true);
_dbClient.persistObject(consistencyGroupObj);
ServiceError error = DeviceControllerErrors.vnxe.jobFailed("CreateConsistencyGroup failed");
taskCompleter.error(_dbClient, error);
}
} catch (Exception e) {
_logger.error("Exception caught when createing consistency group ", e);
consistencyGroupObj.setInactive(true);
_dbClient.persistObject(consistencyGroupObj);
ServiceError error = DeviceControllerErrors.vnxe.jobFailed("CreateConsistencyGroup", e.getMessage());
taskCompleter.error(_dbClient, error);
}
}
@Override
public void doDeleteConsistencyGroup(StorageSystem storage,
URI consistencyGroupId, String replicationGroupName, Boolean keepRGName, Boolean markInactive, TaskCompleter taskCompleter)
throws DeviceControllerException {
_logger.info("Deleting consistency group, array: {}", storage.getSerialNumber());
BlockConsistencyGroup consistencyGroup = _dbClient.queryObject(BlockConsistencyGroup.class,
consistencyGroupId);
// check if lungroup has been created in the array
String lunGroupId = consistencyGroup.getCgNameOnStorageSystem(storage.getId());
if (lunGroupId == null || lunGroupId.isEmpty()) {
_logger.error("The consistency group does not exist in the array: {}", storage.getSerialNumber());
taskCompleter.error(_dbClient, DeviceControllerException.exceptions
.consistencyGroupNotFound(consistencyGroup.getLabel(),
consistencyGroup.getCgNameOnStorageSystem(storage.getId())));
return;
}
VNXeApiClient apiClient = getVnxeClient(storage);
try {
apiClient.deleteLunGroup(lunGroupId, false, false);
if (keepRGName) {
taskCompleter.ready(_dbClient);
return;
}
// Clean up the system consistency group references
BlockConsistencyGroupUtils.cleanUpCGAndUpdate(consistencyGroup, storage.getId(), lunGroupId, markInactive, _dbClient);
_logger.info("Consistency group {} deleted", consistencyGroup.getLabel());
taskCompleter.ready(_dbClient);
} catch (Exception e) {
_logger.info("Failed to delete consistency group: " + e);
// Set task to error
ServiceError error = DeviceControllerErrors.vnxe.jobFailed(
"doDeleteConsistencyGroup", e.getMessage());
taskCompleter.error(_dbClient, error);
}
}
@Override
public void doDeleteConsistencyGroup(StorageSystem storage, final URI consistencyGroupId,
String replicationGroupName, Boolean keepRGName, Boolean markInactive,
String sourceReplicationGroup, final TaskCompleter taskCompleter) throws DeviceControllerException {
doDeleteConsistencyGroup(storage, consistencyGroupId, replicationGroupName, keepRGName, markInactive, taskCompleter);
}
@Override
public String doAddStorageSystem(StorageSystem storage)
throws DeviceControllerException {
// TODO Auto-generated method stub
return null;
}
@Override
public void doRemoveStorageSystem(StorageSystem storage)
throws DeviceControllerException {
// TODO Auto-generated method stub
}
@Override
public void doCopySnapshotsToTarget(StorageSystem storage,
List<URI> snapshotList, TaskCompleter taskCompleter)
throws DeviceControllerException {
// TODO Auto-generated method stub
}
@Override
public Map<String, Set<URI>> findExportMasks(StorageSystem storage,
List<String> initiatorNames, boolean mustHaveAllPorts) throws DeviceControllerException {
// TODO Auto-generated method stub
return null;
}
@Override
public Set<Integer> findHLUsForInitiators(StorageSystem storage, List<String> initiatorNames, boolean mustHaveAllPorts) {
// TODO Auto-generated method stub
return null;
}
@Override
public ExportMask refreshExportMask(StorageSystem storage, ExportMask mask) throws DeviceControllerException {
// TODO Auto-generated method stub
return null;
}
@Override
public void doActivateFullCopy(StorageSystem storageSystem, URI fullCopy,
TaskCompleter completer) {
throw DeviceControllerException.exceptions.blockDeviceOperationNotSupported();
}
@Override
public void doCleanupMetaMembers(StorageSystem storageSystem,
Volume volume, CleanupMetaVolumeMembersCompleter cleanupCompleter)
throws DeviceControllerException {
throw DeviceControllerException.exceptions.blockDeviceOperationNotSupported();
}
@Override
public Integer checkSyncProgress(URI storage, URI source, URI target) {
// TODO Auto-generated method stub
return null;
}
@Override
public void doWaitForSynchronized(Class<? extends BlockObject> clazz,
StorageSystem storageObj, URI target, TaskCompleter completer) {
throw DeviceControllerException.exceptions.blockDeviceOperationNotSupported();
}
@Override
public void doWaitForGroupSynchronized(StorageSystem storageObj, List<URI> target, TaskCompleter completer) {
throw DeviceControllerException.exceptions.blockDeviceOperationNotSupported();
}
@Override
public void doAddToConsistencyGroup(StorageSystem storage,
URI consistencyGroupId, String replicationGroupName, List<URI> blockObjects,
TaskCompleter taskCompleter) throws DeviceControllerException {
BlockConsistencyGroup consistencyGroup = _dbClient.queryObject(BlockConsistencyGroup.class,
consistencyGroupId);
// check if lungroup has been created in the array
String lunGroupId = consistencyGroup.getCgNameOnStorageSystem(storage.getId());
if (lunGroupId == null || lunGroupId.isEmpty()) {
// lun group has not created yet. return error
_logger.error("The consistency group does not exist in the array: {}", storage.getSerialNumber());
taskCompleter.error(_dbClient, DeviceControllerException.exceptions
.consistencyGroupNotFound(consistencyGroup.getLabel(),
consistencyGroup.getCgNameOnStorageSystem(storage.getId())));
return;
}
VNXeApiClient apiClient = getVnxeClient(storage);
try {
List<String> luns = new ArrayList<String>();
for (URI volume : blockObjects) {
luns.add(volume.toString());
}
apiClient.addLunsToLunGroup(lunGroupId, luns);
for (URI blockObjectURI : blockObjects) {
BlockObject blockObject = BlockObject.fetch(_dbClient, blockObjectURI);
if (blockObject != null) {
blockObject.setConsistencyGroup(consistencyGroupId);
}
_dbClient.updateAndReindexObject(blockObject);
}
taskCompleter.ready(_dbClient);
_logger.info("Added volumes to the consistency group successfully");
} catch (Exception e) {
_logger.error("Exception caught when adding volumes to the consistency group ", e);
// Remove any references to the consistency group
for (URI blockObjectURI : blockObjects) {
BlockObject blockObject = BlockObject.fetch(_dbClient, blockObjectURI);
if (blockObject != null) {
blockObject.setConsistencyGroup(NullColumnValueGetter.getNullURI());
}
_dbClient.persistObject(blockObject);
}
taskCompleter.error(_dbClient, DeviceControllerException.exceptions
.failedToAddMembersToConsistencyGroup(consistencyGroup.getLabel(),
consistencyGroup.getCgNameOnStorageSystem(storage.getId()), e.getMessage()));
}
}
@Override
public void doRemoveFromConsistencyGroup(StorageSystem storage,
URI consistencyGroupId, List<URI> blockObjects,
TaskCompleter taskCompleter) throws DeviceControllerException {
BlockConsistencyGroup consistencyGroup = _dbClient.queryObject(BlockConsistencyGroup.class,
consistencyGroupId);
// check if lungroup has been created in the array
String lunGroupId = consistencyGroup.getCgNameOnStorageSystem(storage.getId());
if (lunGroupId == null || lunGroupId.isEmpty()) {
// lun group has not created yet. return error
_logger.error("The consistency group does not exist in the array: {}", storage.getSerialNumber());
taskCompleter.error(_dbClient, DeviceControllerException.exceptions
.consistencyGroupNotFound(consistencyGroup.getLabel(),
consistencyGroup.getCgNameOnStorageSystem(storage.getId())));
return;
}
VNXeApiClient apiClient = getVnxeClient(storage);
try {
List<String> luns = new ArrayList<String>();
for (URI volume : blockObjects) {
luns.add(volume.toString());
}
apiClient.removeLunsFromLunGroup(lunGroupId, luns);
for (URI blockObjectURI : blockObjects) {
BlockObject blockObject = BlockObject.fetch(_dbClient, blockObjectURI);
if (blockObject != null) {
blockObject.setConsistencyGroup(NullColumnValueGetter.getNullURI());
}
_dbClient.updateAndReindexObject(blockObject);
}
taskCompleter.ready(_dbClient);
_logger.info("Remove volumes from the consistency group successfully");
} catch (Exception e) {
_logger.error("Exception caught when removing volumes from the consistency group ", e);
taskCompleter.error(_dbClient, DeviceControllerException.exceptions
.failedToRemoveMembersToConsistencyGroup(consistencyGroup.getLabel(),
consistencyGroup.getCgNameOnStorageSystem(storage.getId()), e.getMessage()));
}
}
@Override
public void doAddToReplicationGroup(StorageSystem storage,
URI consistencyGroupId, String replicationGroupName, List<URI> blockObjects,
TaskCompleter taskCompleter) throws DeviceControllerException {
throw DeviceControllerException.exceptions
.blockDeviceOperationNotSupported();
}
@Override
public void doRemoveFromReplicationGroup(StorageSystem storage,
URI consistencyGroupId, String replicationGroupName, List<URI> blockObjects,
TaskCompleter taskCompleter) throws DeviceControllerException {
throw DeviceControllerException.exceptions
.blockDeviceOperationNotSupported();
}
@Override
public boolean validateStorageProviderConnection(String ipAddress,
Integer portNumber) {
// TODO Auto-generated method stub
return false;
}
@Override
public void doCreateMetaVolumes(StorageSystem storage,
StoragePool storagePool, List<Volume> volumes,
VirtualPoolCapabilityValuesWrapper capabilities,
MetaVolumeRecommendation recommendation, TaskCompleter completer)
throws DeviceControllerException {
// TODO Auto-generated method stub
}
@Override
public void doExpandAsMetaVolume(StorageSystem storageSystem,
StoragePool storagePool, Volume volume, long size,
MetaVolumeRecommendation recommendation,
VolumeExpandCompleter volumeCompleter)
throws DeviceControllerException {
// TODO Auto-generated method stub
}
@Override
public void updatePolicyAndLimits(StorageSystem storage, ExportMask exportMask,
List<URI> volumeURIs, VirtualPool newVpool, boolean rollback,
TaskCompleter taskCompleter) throws Exception {
throw DeviceControllerException.exceptions.blockDeviceOperationNotSupported();
}
@Override
public BiosCommandResult updateExportRules(StorageSystem storage,
FileDeviceInputOutput args) {
// Requested Export Rules
List<ExportRule> exportAdd = args.getExportRulesToAdd();
List<ExportRule> exportDelete = args.getExportRulesToDelete();
List<ExportRule> exportModify = args.getExportRulesToModify();
// To be processed export rules
List<ExportRule> exportsToRemove = new ArrayList<>();
List<ExportRule> exportsToAdd = new ArrayList<>();
List<ExportRule> newExportsForDelete = new ArrayList<>();
VNXeFileTaskCompleter completer = null;
VNXeApiClient apiClient = getVnxeClient(storage);
String subDir = args.getSubDirectory();
// ALL EXPORTS
List<ExportRule> exportsToprocess = args.getExistingDBExportRules();
Map<String, ArrayList<ExportRule>> existingExportsMapped = new HashMap();
try {
String exportPath;
if (!args.getFileOperation()) {
exportPath = args.getSnapshotPath();
if (subDir != null
&& subDir.length() > 0) {
exportPath = args.getSnapshotPath() + "/"
+ subDir;
}
} else {
exportPath = args.getFs().getPath();
if (subDir != null
&& subDir.length() > 0) {
exportPath = args.getFs().getPath() + "/"
+ subDir;
}
}
_logger.info("exportPath : {}", exportPath);
args.setExportPath(exportPath);
try {
// add the new export rule from the array into the update request.
Map<String, ExportRule> arrayExportRuleMap = extraExportRuleFromArray(storage, args);
if (!arrayExportRuleMap.isEmpty()) {
if (exportModify != null) {
// merge the end point for which sec flavor is common.
for (ExportRule exportRule : exportModify) {
ExportRule arrayExportRule = arrayExportRuleMap.remove(exportRule.getSecFlavor());
if (arrayExportRule != null) {
if (exportRule.getReadOnlyHosts() != null) {
exportRule.getReadOnlyHosts().addAll(arrayExportRule.getReadOnlyHosts());
} else {
exportRule.setReadOnlyHosts(arrayExportRule.getReadOnlyHosts());
}
if (exportRule.getReadWriteHosts() != null) {
exportRule.getReadWriteHosts().addAll(arrayExportRule.getReadWriteHosts());
} else {
exportRule.setReadWriteHosts(arrayExportRule.getReadWriteHosts());
}
if (exportRule.getRootHosts() != null) {
exportRule.getRootHosts().addAll(arrayExportRule.getRootHosts());
} else {
exportRule.setRootHosts(arrayExportRule.getRootHosts());
}
}
}
// now add the remaining export rule
exportModify.addAll(arrayExportRuleMap.values());
} else {
// if exportModify is null then create a new export rule and add
exportModify = new ArrayList<ExportRule>();
exportModify.addAll(arrayExportRuleMap.values());
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
_logger.error("Not able to fetch latest Export rule from backend array.", e);
}
if (exportsToprocess == null) {
exportsToprocess = new ArrayList<>();
}
_logger.info("Number of existng Rules found {}", exportsToprocess.size());
// Process Exports
for (ExportRule existingRule : exportsToprocess) {
ArrayList<ExportRule> exps = existingExportsMapped.get(existingRule.getExportPath());
if (exps == null) {
exps = new ArrayList<>();
}
exps.add(existingRule);
_logger.info("Checking existing export for {} : exps : {}", existingRule.getExportPath(), exps);
existingExportsMapped.put(existingRule.getExportPath(), exps);
}
// Handle Add export Rules
if (exportAdd != null && !exportAdd.isEmpty()) {
// Check for existing exports for the export path including subdirectory
ArrayList<ExportRule> exps = existingExportsMapped.get(exportPath);
if (exps != null && !exps.isEmpty()) {
_logger.error("Adding export rules is not supported as there can be only one export rule for VNXe.");
ServiceError error = DeviceControllerErrors.vnxe.jobFailed("updateExportRules",
"Adding export rule is not supported for VNXe");
return BiosCommandResult.createErrorResult(error);
}
}
// Handle Modified export Rules
if (!exportsToprocess.isEmpty()) {
if (subDir != null && !subDir.isEmpty()) {
for (ExportRule existingRule : exportsToprocess) {
if (existingRule.getExportPath().endsWith("/" + subDir)) {
// Filter for a specific Sub Directory export
_logger.info(
"Updating all subdir exports rules at ViPR and sub directory export at device {}",
subDir);
processModifyRules(exportModify, existingRule, exportsToRemove, exportsToAdd);
} else {
exportsToRemove.add(existingRule);
}
}
// Handle Delete export Rules
if (exportDelete != null && !exportDelete.isEmpty()) {
for (ExportRule existingRule : exportsToprocess) {
if (existingRule.getExportPath().endsWith("/" + subDir)) {
processDeleteRules(exportDelete, existingRule, exportsToRemove, newExportsForDelete);
} else {
exportsToRemove.add(existingRule);
}
}
exportsToAdd.addAll(newExportsForDelete);
}
} else {
for (ExportRule existingRule : exportsToprocess) {
if (existingRule.getExportPath().equalsIgnoreCase(exportPath)) {
processModifyRules(exportModify, existingRule, exportsToRemove, exportsToAdd);
} else {
exportsToRemove.add(existingRule);
}
}
// Handle Delete export Rules
if (exportDelete != null && !exportDelete.isEmpty()) {
for (ExportRule existingRule : exportsToprocess) {
if (existingRule.getExportPath().equalsIgnoreCase(exportPath)) {
processDeleteRules(exportDelete, existingRule, exportsToRemove, newExportsForDelete);
} else {
exportsToRemove.add(existingRule);
}
}
exportsToAdd.addAll(newExportsForDelete);
}
}
// No of exports found to remove from the list
_logger.info("No of exports found to remove from the existing exports list {}", exportsToRemove.size());
exportsToprocess.removeAll(exportsToRemove);
_logger.info("No of exports found to add to the existing exports list {}", exportsToAdd.size());
exportsToprocess.addAll(exportsToAdd);
} else {
// Handle Add Export Rules
// This is valid only if no rules to modify exists
if (exportAdd != null && !exportAdd.isEmpty()) {
for (ExportRule newExport : exportAdd) {
if (args.getFileObjExports() != null) {
Collection<FileExport> expList = args.getFileObjExports().values();
Iterator<FileExport> it = expList.iterator();
FileExport exp = null;
while (it.hasNext()) {
FileExport export = it.next();
if (export.getPath().equalsIgnoreCase(exportPath)) {
exp = export;
}
}
if (exp != null) {
if (exp.getIsilonId() != null) {
newExport.setDeviceExportId(exp.getIsilonId());
}
if (exp.getNativeId() != null) {
newExport.setDeviceExportId(exp.getNativeId());
}
}
}
_logger.info("Add Export Rule {}", newExport);
newExport.setExportPath(exportPath);
exportsToAdd.add(newExport);
}
}
exportsToprocess.addAll(exportsToAdd);
}
_logger.info("exportPath : {}", exportPath);
args.setExportPath(exportPath);
VNXeCommandJob job = null;
for (ExportRule rule : exportsToprocess) {
AccessEnum access = null;
List<String> roHosts = null;
List<String> rwHosts = null;
List<String> rootHosts = null;
String path = "/";
String subdirName = "";
String mountPathFs = args.getFsMountPath();
String shareName = null;
FileShareExport fsExport = null;
boolean isDeleteRule = false;
if (args.getFileObjExports() != null) {
Collection<FileExport> expList = args.getFileObjExports().values();
Iterator<FileExport> it = expList.iterator();
FileExport exp = null;
while (it.hasNext()) {
FileExport export = it.next();
if (export.getPath().equalsIgnoreCase(rule.getExportPath())) {
exp = export;
}
}
fsExport = new FileShareExport(exp);
}
String mountPathArg = rule.getExportPath();
if (rule.getReadWriteHosts() != null && !rule.getReadWriteHosts().isEmpty()) {
access = AccessEnum.READWRITE;
if (rwHosts == null) {
rwHosts = new ArrayList<String>();
}
rwHosts.addAll(rule.getReadWriteHosts());
}
if (rule.getReadOnlyHosts() != null && !rule.getReadOnlyHosts().isEmpty()) {
access = AccessEnum.READ;
if (roHosts == null) {
roHosts = new ArrayList<String>();
}
roHosts.addAll(rule.getReadOnlyHosts());
}
if (rule.getRootHosts() != null && !rule.getRootHosts().isEmpty()) {
access = AccessEnum.ROOT;
if (rootHosts == null) {
rootHosts = new ArrayList<String>();
}
rootHosts.addAll(rule.getRootHosts());
}
if (newExportsForDelete.contains(rule)) {
isDeleteRule = true;
}
if (args.getFileOperation()) {
if (!mountPathArg.equals(mountPathFs)) {
// subdirectory specified.
subdirName = mountPathArg.substring(mountPathFs.length() + 1);
path += subdirName;
}
if (isDeleteRule) {
job = apiClient.removeNfsShare(rule.getDeviceExportId(), args.getFs().getNativeId());
if (job != null) {
completer = new VNXeFileTaskCompleter(FileShare.class, args.getFsId(), args.getOpId());
VNXeUnexportFileSystemJob unexportFSJob = new VNXeUnexportFileSystemJob(job.getId(), storage.getId(),
completer, fsExport, args.getExportPath(), true);
ControllerServiceImpl.enqueueJob(new QueueJob(unexportFSJob));
} else {
_logger.error("No job returned from unexport FileSystem");
ServiceError error = DeviceControllerErrors.vnxe.jobFailed("UnExportFileSystem",
"No Job returned from UnExportFileSystem");
return BiosCommandResult.createErrorResult(error);
}
} else {
job = apiClient.exportFileSystem(args.getFs().getNativeId(), roHosts, rwHosts, rootHosts, access, path, null,
rule.getDeviceExportId(), null);
if (job != null) {
completer = new VNXeFileTaskCompleter(FileShare.class, args.getFsId(), args.getOpId());
VNXeModifyExportJob modifyExportJob = new VNXeModifyExportJob(job.getId(), storage.getId(),
completer, rule, fsExport, args.getExportPath(), args.getFileOperation(), isDeleteRule, shareName);
ControllerServiceImpl.enqueueJob(new QueueJob(modifyExportJob));
} else {
_logger.error("No job returned from updateExportRules");
ServiceError error = DeviceControllerErrors.vnxe.jobFailed("updateExportRules",
"No Job returned from updateExportRules");
return BiosCommandResult.createErrorResult(error);
}
}
} else {
shareName = VNXeUtils.buildNfsShareName(args.getSnapshotName(), path);
if (isDeleteRule) {
job = apiClient.deleteNfsShareForSnapshot(rule.getDeviceExportId());
if (job != null) {
completer = new VNXeFileTaskCompleter(Snapshot.class, args.getSnapshotId(), args.getOpId());
VNXeUnexportFileSystemJob unexportFSJob = new VNXeUnexportFileSystemJob(job.getId(), storage.getId(),
completer, fsExport, rule.getExportPath(), false);
ControllerServiceImpl.enqueueJob(new QueueJob(unexportFSJob));
} else {
_logger.error("No job returned from unexportFileSystem Snapshot");
ServiceError error = DeviceControllerErrors.vnxe.jobFailed("UnExportFileSystem",
"No Job returned from UnExportFileSystem");
return BiosCommandResult.createErrorResult(error);
}
} else {
job = apiClient.createNfsShareForSnap(args.getSnapNativeId(), roHosts, rwHosts, rootHosts, access, path, shareName,
null);
if (job != null) {
completer = new VNXeFileTaskCompleter(Snapshot.class, args.getSnapshotId(), args.getOpId());
VNXeModifyExportJob modifyExportJob = new VNXeModifyExportJob(job.getId(), storage.getId(),
completer, rule, fsExport, args.getExportPath(), args.getFileOperation(), isDeleteRule, shareName);
ControllerServiceImpl.enqueueJob(new QueueJob(modifyExportJob));
} else {
_logger.error("No job returned from updateExportRules");
ServiceError error = DeviceControllerErrors.vnxe.jobFailed("updateExportRules",
"No Job returned from updateExportRules");
return BiosCommandResult.createErrorResult(error);
}
}
}
}
} catch (VNXeException e) {
_logger.error("updateExportRules got the exception", e);
if (completer != null) {
completer.error(_dbClient, e);
}
return BiosCommandResult.createErrorResult(e);
} catch (Exception ex) {
_logger.error("updateExportRules got the exception", ex);
ServiceError error = DeviceControllerErrors.vnxe.jobFailed("updateExportRules", ex.getMessage());
if (completer != null) {
completer.error(_dbClient, error);
}
return BiosCommandResult.createErrorResult(error);
}
_logger.info("UpdateExportRules job submitted");
return BiosCommandResult.createPendingResult();
}
private void processModifyRules(List<ExportRule> exportModify, ExportRule existingRule,
List<ExportRule> exportsToRemove, List<ExportRule> exportsToAdd) {
for (ExportRule modifiedrule : exportModify) {
if (modifiedrule.getSecFlavor().equals(
existingRule.getSecFlavor())) {
_logger.info("Modifying Export Rule from {}, To {}",
existingRule, modifiedrule);
// use a separate list to avoid concurrent modification exception for now.
exportsToRemove.add(existingRule);
ExportRule modifyRule = new ExportRule();
copyPropertiesToSave(modifyRule, modifiedrule);
modifyRule.setDeviceExportId(existingRule.getDeviceExportId());
modifyRule.setExportPath(existingRule.getExportPath());
exportsToAdd.add(modifyRule);
break;
}
}
}
private void processDeleteRules(List<ExportRule> exportDelete, ExportRule existingRule,
List<ExportRule> exportsToRemove, List<ExportRule> exportsToAdd) {
for (ExportRule oldExport : exportDelete) {
if (oldExport.getSecFlavor().equals(
existingRule.getSecFlavor())) {
_logger.info("Deleting Export Rule {}", existingRule);
exportsToRemove.add(existingRule);
ExportRule rule = new ExportRule();
rule.setSecFlavor("sys");
rule.setAnon("root");
rule.setExportPath(existingRule.getExportPath());
rule.setDeviceExportId(existingRule.getDeviceExportId());
exportsToAdd.add(rule);
break;
}
}
}
private void copyPropertiesToSave(ExportRule dest, ExportRule orig) {
_logger.info("Origin {}", orig.toString());
dest.setSecFlavor(orig.getSecFlavor());
dest.setAnon(orig.getAnon());
if (orig.getReadOnlyHosts() != null && !orig.getReadOnlyHosts().isEmpty()) {
dest.setReadOnlyHosts(new StringSet(orig.getReadOnlyHosts()));
_logger.info("Read Only Hosts {}", dest.getReadOnlyHosts());
}
if (orig.getReadWriteHosts() != null && !orig.getReadWriteHosts().isEmpty()) {
dest.setReadWriteHosts(new StringSet(orig.getReadWriteHosts()));
_logger.info("Read Write Hosts {}", dest.getReadWriteHosts());
}
if (orig.getRootHosts() != null && !orig.getRootHosts().isEmpty()) {
dest.setRootHosts(new StringSet(orig.getRootHosts()));
_logger.info("Root hosts {}", dest.getRootHosts());
}
_logger.info("Dest After {}", dest.toString());
}
@Override
public BiosCommandResult deleteExportRules(StorageSystem storage,
FileDeviceInputOutput args) {
List<ExportRule> allExports = args.getExistingDBExportRules();
String subDir = args.getSubDirectory();
boolean allDirs = args.isAllDir();
VNXeCommandJob job = null;
VNXeFileTaskCompleter completer = null;
boolean isFile = args.getFileOperation();
boolean ifRulePresent = false;
String exportPath;
String subDirExportPath = "";
subDir = args.getSubDirectory();
if (!args.getFileOperation()) {
exportPath = args.getSnapshotPath();
if (subDir != null
&& subDir.length() > 0) {
subDirExportPath = args.getSnapshotPath() + "/"
+ subDir;
}
} else {
exportPath = args.getFs().getPath();
if (subDir != null
&& subDir.length() > 0) {
subDirExportPath = args.getFs().getPath() + "/"
+ subDir;
}
}
_logger.info("exportPath : {}", exportPath);
args.setExportPath(exportPath);
_logger.info("Number of existing exports found {}", allExports.size());
try {
VNXeApiClient apiClient = getVnxeClient(storage);
if (allDirs) {
// ALL EXPORTS
_logger.info(
"Deleting all exports specific to filesystem at device and rules from DB including sub dirs rules and exports");
for (ExportRule rule : allExports) {
FileShareExport fsExport = null;
if (args.getFileObjExports() != null) {
Collection<FileExport> expList = args.getFileObjExports().values();
Iterator<FileExport> it = expList.iterator();
FileExport exp = null;
while (it.hasNext()) {
FileExport export = it.next();
if (export.getPath().equalsIgnoreCase(rule.getExportPath())) {
exp = export;
}
}
fsExport = new FileShareExport(exp);
}
String vnxeShareId = rule.getDeviceExportId();
_logger.info("Delete IsilonExport id {} for path {}",
rule.getDeviceExportId(), rule.getExportPath());
if (isFile) {
String fsId = args.getFs().getNativeId();
job = apiClient.removeNfsShare(vnxeShareId, fsId);
} else {
job = apiClient.deleteNfsShareForSnapshot(vnxeShareId);
}
if (job != null) {
if (isFile) {
completer = new VNXeFileTaskCompleter(FileShare.class, args.getFsId(), args.getOpId());
} else {
completer = new VNXeFileTaskCompleter(Snapshot.class, args.getSnapshotId(), args.getOpId());
}
VNXeUnexportFileSystemJob unexportFSJob = new VNXeUnexportFileSystemJob(job.getId(), storage.getId(),
completer, fsExport, rule.getExportPath(), isFile);
ControllerServiceImpl.enqueueJob(new QueueJob(unexportFSJob));
} else {
_logger.error("No job returned from exportFileSystem");
ServiceError error = DeviceControllerErrors.vnxe.jobFailed("DeleteFileSystem",
"No Job returned from deleteFileSystem");
return BiosCommandResult.createErrorResult(error);
}
}
} else if (subDir != null && !subDir.isEmpty()) {
// Filter for a specific Sub Directory export
_logger.info("Deleting all subdir exports rules at ViPR and sub directory export at device {}", subDir);
FileShareExport fsExport = null;
String vnxeShareId = null;
if (args.getFileObjExports() != null) {
Collection<FileExport> expList = args.getFileObjExports().values();
Iterator<FileExport> it = expList.iterator();
FileExport exp = null;
while (it.hasNext()) {
FileExport export = it.next();
if (export.getPath().equalsIgnoreCase(subDirExportPath)) {
exp = export;
break;
}
}
fsExport = new FileShareExport(exp);
}
for (ExportRule rule : allExports) {
_logger.info("Delete IsilonExport id for path {} f containing subdirectory {}",
rule.getDeviceExportId() + ":" + rule.getExportPath(), subDir);
if (rule.getExportPath().equalsIgnoreCase(subDirExportPath)) {
ifRulePresent = true;
vnxeShareId = rule.getDeviceExportId();
}
}
if (!ifRulePresent) {
if (fsExport != null) {
vnxeShareId = fsExport.getIsilonId();
}
}
_logger.info("Delete IsilonExport id {} for path {}",
vnxeShareId, subDirExportPath);
if (isFile) {
String fsId = args.getFs().getNativeId();
job = apiClient.removeNfsShare(vnxeShareId, fsId);
} else {
job = apiClient.deleteNfsShareForSnapshot(vnxeShareId);
}
if (job != null) {
if (isFile) {
completer = new VNXeFileTaskCompleter(FileShare.class, args.getFsId(), args.getOpId());
} else {
completer = new VNXeFileTaskCompleter(Snapshot.class, args.getSnapshotId(), args.getOpId());
}
VNXeUnexportFileSystemJob unexportFSJob = new VNXeUnexportFileSystemJob(job.getId(), storage.getId(),
completer, fsExport, subDirExportPath, isFile);
ControllerServiceImpl.enqueueJob(new QueueJob(unexportFSJob));
} else {
_logger.error("No job returned from exportFileSystem");
ServiceError error = DeviceControllerErrors.vnxe.jobFailed("DeleteFileSystem", "No Job returned from deleteFileSystem");
return BiosCommandResult.createErrorResult(error);
}
} else {
// Filter for No SUBDIR - main export rules with no sub dirs
_logger.info("Deleting all export rules from DB and export at device not included sub dirs");
FileShareExport fsExport = null;
String vnxeShareId = null;
if (args.getFileObjExports() != null) {
Collection<FileExport> expList = args.getFileObjExports().values();
Iterator<FileExport> it = expList.iterator();
FileExport exp = null;
while (it.hasNext()) {
FileExport export = it.next();
if (export.getPath().equalsIgnoreCase(exportPath)) {
exp = export;
break;
}
}
fsExport = new FileShareExport(exp);
}
for (ExportRule rule : allExports) {
if (rule.getExportPath().equalsIgnoreCase(exportPath)) {
ifRulePresent = true;
vnxeShareId = rule.getDeviceExportId();
}
}
if (!ifRulePresent) {
if (fsExport != null) {
vnxeShareId = fsExport.getIsilonId();
}
}
_logger.info("Delete IsilonExport id {} for path {}",
vnxeShareId, fsExport.getPath());
if (isFile) {
String fsId = args.getFs().getNativeId();
job = apiClient.removeNfsShare(vnxeShareId, fsId);
} else {
job = apiClient.deleteNfsShareForSnapshot(vnxeShareId);
}
if (job != null) {
if (isFile) {
completer = new VNXeFileTaskCompleter(FileShare.class, args.getFsId(), args.getOpId());
} else {
completer = new VNXeFileTaskCompleter(Snapshot.class, args.getSnapshotId(), args.getOpId());
}
VNXeUnexportFileSystemJob unexportFSJob = new VNXeUnexportFileSystemJob(job.getId(), storage.getId(),
completer, fsExport, fsExport.getPath(), isFile);
ControllerServiceImpl.enqueueJob(new QueueJob(unexportFSJob));
} else {
_logger.error("No job returned from exportFileSystem");
ServiceError error = DeviceControllerErrors.vnxe.jobFailed("DeleteFileSystem", "No Job returned from deleteFileSystem");
return BiosCommandResult.createErrorResult(error);
}
}
} catch (VNXeException e) {
_logger.error("Unexport file system got the exception", e);
if (completer != null) {
completer.error(_dbClient, e);
}
return BiosCommandResult.createErrorResult(e);
} catch (Exception ex) {
_logger.error("Delete file system got the exception", ex);
ServiceError error = DeviceControllerErrors.vnxe.jobFailed("DeleteFileSystem", ex.getMessage());
if (completer != null) {
completer.error(_dbClient, error);
}
return BiosCommandResult.createErrorResult(error);
}
if (job != null) {
StringBuilder logMsgBuilder = new StringBuilder(String.format(
"Unexport filesystem job submitted - Array:%s, fileSystem: %s", storage.getSerialNumber(),
args.getFsName()));
_logger.info(logMsgBuilder.toString());
return BiosCommandResult.createPendingResult();
} else {
StringBuilder logMsgBuilder = new StringBuilder(String.format(
"No export found - Array:%s, fileSystem: %s", storage.getSerialNumber(),
args.getFsName()));
_logger.info(logMsgBuilder.toString());
return BiosCommandResult.createSuccessfulResult();
}
}
@Override
public void doTerminateAnyRestoreSessions(StorageSystem storageDevice, URI source, BlockObject snapshot,
TaskCompleter completer) throws Exception {
throw DeviceControllerException.exceptions.blockDeviceOperationNotSupported();
}
@Override
public void doModifyVolumes(StorageSystem storage, StoragePool storagePool, String opId, List<Volume> volumes,
TaskCompleter taskCompleter) throws DeviceControllerException {
// TODO Auto-generated method stub
throw DeviceControllerException.exceptions.blockDeviceOperationNotSupported();
}
@Override
public ExportMaskPolicy getExportMaskPolicy(StorageSystem storage, ExportMask mask) {
// No special policy for this device type yet.
return new ExportMaskPolicy();
}
@Override
public BiosCommandResult doCreateQuotaDirectory(StorageSystem storage,
FileDeviceInputOutput args, QuotaDirectory qd) throws ControllerException {
BiosCommandResult result = new BiosCommandResult();
ServiceError serviceError = DeviceControllerErrors.vnxe.operationNotSupported("Create Quota Directory", "VNXe");
result = BiosCommandResult.createErrorResult(serviceError);
return result;
}
@Override
public BiosCommandResult doDeleteQuotaDirectory(StorageSystem storage,
FileDeviceInputOutput args) throws ControllerException {
BiosCommandResult result = new BiosCommandResult();
ServiceError serviceError = DeviceControllerErrors.vnxe.operationNotSupported("Delete Quota Directory", "VNXe");
result = BiosCommandResult.createErrorResult(serviceError);
return result;
}
@Override
public BiosCommandResult doUpdateQuotaDirectory(StorageSystem storage,
FileDeviceInputOutput args, QuotaDirectory qd) throws ControllerException {
BiosCommandResult result = new BiosCommandResult();
ServiceError serviceError = DeviceControllerErrors.vnxe.operationNotSupported("Update Quota Directory", "VNXe");
result = BiosCommandResult.createErrorResult(serviceError);
return result;
}
@Override
public BiosCommandResult updateShareACLs(StorageSystem storage,
FileDeviceInputOutput args) {
return BiosCommandResult.createErrorResult(
DeviceControllerErrors.vnxe.operationNotSupported("Add or Update CIFS Share ACLs", "VNXe"));
}
@Override
public BiosCommandResult deleteShareACLs(StorageSystem storageObj,
FileDeviceInputOutput args) {
return BiosCommandResult.createErrorResult(
DeviceControllerErrors.vnxe.operationNotSupported("Delete CIFS Share ACLs", "VNXe"));
}
/**
* Get the export rule which are present in array but not in CoprHD Database.
*
* @param storage
* @param args
* @return map with security flavor and export rule
*/
private Map<String, ExportRule> extraExportRuleFromArray(StorageSystem storage, FileDeviceInputOutput args) {
// map to store the export rule grouped by sec flavor
Map<String, ExportRule> exportRuleMap = new HashMap<>();
List<VNXeNfsShare> exportsList = new ArrayList<VNXeNfsShare>();
Set<String> arrayReadOnlyHost = new HashSet<>();
Set<String> arrayReadWriteHost = new HashSet<>();
Set<String> arrayRootHost = new HashSet<>();
Set<String> dbReadOnlyHost = new HashSet<>();
Set<String> dbReadWriteHost = new HashSet<>();
Set<String> dbRootHost = new HashSet<>();
// get all export rule from CoprHD data base
List<ExportRule> existingDBExportRules = args.getExistingDBExportRules();
// get the all the export from the storage system.
VNXeApiClient apiClient = getVnxeClient(storage);
for (ExportRule exportRule : existingDBExportRules) {
if (exportRule.getReadOnlyHosts() != null) {
dbReadOnlyHost.addAll(exportRule.getReadOnlyHosts());
}
if (exportRule.getReadWriteHosts() != null) {
dbReadWriteHost.addAll(exportRule.getReadWriteHosts());
}
if (exportRule.getRootHosts() != null) {
dbRootHost.addAll(exportRule.getRootHosts());
}
String vnxeExportId = exportRule.getDeviceExportId();
if (vnxeExportId != null) {
List<VNXeNfsShare> vnxeExports = null;
vnxeExports = apiClient.getNfsSharesForFileSystem(args.getFs().getNativeId());
exportsList.addAll(vnxeExports);
for (VNXeNfsShare vnXeNfsShare : vnxeExports) {
List<VNXeBase> hostIdReadOnly = vnXeNfsShare.getReadOnlyHosts();
for (VNXeBase vnXeBase : hostIdReadOnly) {
VNXeHost host = apiClient.getHostById(vnXeBase.getId());
arrayReadOnlyHost.add(host.getName());
}
List<VNXeBase> hostIdReadWrite = vnXeNfsShare.getReadWriteHosts();
for (VNXeBase vnXeBase : hostIdReadWrite) {
VNXeHost host = apiClient.getHostById(vnXeBase.getId());
arrayReadWriteHost.add(host.getName());
}
List<VNXeBase> hostIdRootHost = vnXeNfsShare.getRootAccessHosts();
for (VNXeBase vnXeBase : hostIdRootHost) {
VNXeHost host = apiClient.getHostById(vnXeBase.getId());
arrayRootHost.add(host.getName());
}
}
}
// find out the change between array and CoprHD database.
Set<String> arrayExtraReadOnlyHost = Sets.difference(arrayReadOnlyHost, dbReadOnlyHost);
Set<String> arrayExtraReadWriteHost = Sets.difference(arrayReadWriteHost, dbReadWriteHost);
Set<String> arrayExtraRootHost = Sets.difference(arrayRootHost, dbRootHost);
// if change found update the exportRuleMap
if (!arrayExtraReadOnlyHost.isEmpty() || !arrayExtraReadWriteHost.isEmpty() || !arrayExtraRootHost.isEmpty()) {
ExportRule extraRuleFromArray = new ExportRule();
extraRuleFromArray.setDeviceExportId(exportRule.getDeviceExportId());
extraRuleFromArray.setAnon(exportRule.getAnon());
extraRuleFromArray.setSecFlavor(exportRule.getSecFlavor());
extraRuleFromArray.setExportPath(exportRule.getExportPath());
extraRuleFromArray.setReadOnlyHosts(arrayExtraReadOnlyHost);
extraRuleFromArray.setReadWriteHosts(arrayExtraReadWriteHost);
extraRuleFromArray.setRootHosts(arrayExtraRootHost);
exportRuleMap.put(exportRule.getSecFlavor(), extraRuleFromArray);
}
}
return exportRuleMap;
}
@Override
public void doFractureClone(StorageSystem storageDevice, URI source, URI clone,
TaskCompleter completer) {
throw DeviceControllerException.exceptions.blockDeviceOperationNotSupported();
}
@Override
public void doRestoreFromClone(StorageSystem storage, URI cloneVolume,
TaskCompleter taskCompleter) {
throw DeviceControllerException.exceptions.blockDeviceOperationNotSupported();
}
@Override
public void doResyncClone(StorageSystem storage, URI cloneVolume,
TaskCompleter taskCompleter) {
throw DeviceControllerException.exceptions.blockDeviceOperationNotSupported();
}
@Override
public void doCreateGroupClone(StorageSystem storageDevice, List<URI> clones,
Boolean createInactive, TaskCompleter completer) {
throw DeviceControllerException.exceptions.blockDeviceOperationNotSupported();
}
@Override
public void doDetachGroupClone(StorageSystem storage, List<URI> cloneVolume,
TaskCompleter taskCompleter) {
throw DeviceControllerException.exceptions.blockDeviceOperationNotSupported();
}
@Override
public void doEstablishVolumeFullCopyGroupRelation(
StorageSystem storage, URI sourceVolume, URI fullCopy,
TaskCompleter taskCompleter) throws DeviceControllerException {
throw DeviceControllerException.exceptions.blockDeviceOperationNotSupported();
}
@Override
public void doRestoreFromGroupClone(StorageSystem storageSystem,
List<URI> cloneVolume, TaskCompleter taskCompleter) {
throw DeviceControllerException.exceptions.blockDeviceOperationNotSupported();
}
@Override
public void doActivateGroupFullCopy(StorageSystem storageSystem,
List<URI> fullCopy, TaskCompleter completer) {
throw DeviceControllerException.exceptions.blockDeviceOperationNotSupported();
}
@Override
public void doResyncGroupClone(StorageSystem storageDevice,
List<URI> clone, TaskCompleter completer) throws Exception {
throw DeviceControllerException.exceptions.blockDeviceOperationNotSupported();
}
@Override
public Map<URI, Integer> getExportMaskHLUs(StorageSystem storage, ExportMask exportMask) {
return Collections.EMPTY_MAP;
}
@Override
public void doFractureGroupClone(StorageSystem storageDevice,
List<URI> clone, TaskCompleter completer) throws Exception {
throw DeviceControllerException.exceptions.blockDeviceOperationNotSupported();
}
@Override
public void doResyncSnapshot(StorageSystem storage, URI volume, URI snapshot, TaskCompleter taskCompleter)
throws DeviceControllerException {
throw DeviceControllerException.exceptions.blockDeviceOperationNotSupported();
}
@Override
public void doCreateGroupMirrors(StorageSystem storage,
List<URI> mirrorList, Boolean createInactive,
TaskCompleter taskCompleter) throws DeviceControllerException {
throw DeviceControllerException.exceptions.blockDeviceOperationNotSupported();
}
@Override
public void doFractureGroupMirrors(StorageSystem storage,
List<URI> mirrorList, Boolean sync, TaskCompleter taskCompleter)
throws DeviceControllerException {
throw DeviceControllerException.exceptions.blockDeviceOperationNotSupported();
}
@Override
public void doDetachGroupMirrors(StorageSystem storage,
List<URI> mirrorList, Boolean deleteGroup, TaskCompleter taskCompleter)
throws DeviceControllerException {
throw DeviceControllerException.exceptions.blockDeviceOperationNotSupported();
}
@Override
public void doResumeGroupNativeContinuousCopies(StorageSystem storage,
List<URI> mirrorList, TaskCompleter taskCompleter)
throws DeviceControllerException {
throw DeviceControllerException.exceptions.blockDeviceOperationNotSupported();
}
@Override
public void doDeleteGroupMirrors(StorageSystem storage,
List<URI> mirrorList, TaskCompleter taskCompleter)
throws DeviceControllerException {
throw DeviceControllerException.exceptions.blockDeviceOperationNotSupported();
}
@Override
public void doRemoveMirrorFromDeviceMaskingGroup(StorageSystem system,
List<URI> mirrors, TaskCompleter completer)
throws DeviceControllerException {
throw DeviceControllerException.exceptions.blockDeviceOperationNotSupported();
}
@Override
public void doCreateListReplica(StorageSystem storage, List<URI> replicaList, /* String repGroupoName, */Boolean createInactive,
TaskCompleter taskCompleter) throws DeviceControllerException {
throw DeviceControllerException.exceptions.blockDeviceOperationNotSupported();
}
@Override
public void doDetachListReplica(StorageSystem storage, List<URI> replicaList, TaskCompleter taskCompleter)
throws DeviceControllerException {
throw DeviceControllerException.exceptions.blockDeviceOperationNotSupported();
}
@Override
public void doFractureListReplica(StorageSystem storage, List<URI> replicaList, Boolean sync, TaskCompleter taskCompleter)
throws DeviceControllerException {
throw DeviceControllerException.exceptions.blockDeviceOperationNotSupported();
}
@Override
public void doDeleteListReplica(StorageSystem storage, List<URI> replicaList, TaskCompleter taskCompleter)
throws DeviceControllerException {
throw DeviceControllerException.exceptions.blockDeviceOperationNotSupported();
}
@Override
public BiosCommandResult updateNfsACLs(StorageSystem storage, FileDeviceInputOutput args) {
return BiosCommandResult.createErrorResult(
DeviceControllerErrors.vnxe.operationNotSupported("Add or Update NFS Share ACLs", "VNXe"));
}
@Override
public BiosCommandResult deleteNfsACLs(StorageSystem storageObj, FileDeviceInputOutput args) {
return BiosCommandResult.createErrorResult(
DeviceControllerErrors.vnxe.operationNotSupported("Delete NFS Share ACLs", "VNXe"));
}
@Override
public void doUntagVolumes(StorageSystem storageSystem, String opId, List<Volume> volumes,
TaskCompleter taskCompleter) throws DeviceControllerException {
// If this operation is unsupported by default it's not necessarily an error
return;
}
// file mirror related operations
@Override
public void doCreateMirror(StorageSystem storage, URI mirror,
Boolean createInactive, TaskCompleter taskCompleter) throws DeviceControllerException {
throw DeviceControllerException.exceptions.operationNotSupported();
}
public void doDeleteMirror(StorageSystem storage, URI mirror,
Boolean createInactive, TaskCompleter taskCompleter) throws DeviceControllerException {
throw DeviceControllerException.exceptions.operationNotSupported();
}
@Override
public void doCreateSnapshotSession(StorageSystem system, URI snapSessionURI, String groupName, TaskCompleter completer)
throws DeviceControllerException {
throw DeviceControllerException.exceptions.blockDeviceOperationNotSupported();
}
/**
* {@inheritDoc}
*/
@Override
public void doLinkBlockSnapshotSessionTarget(StorageSystem system, URI snapSessionURI, URI snapShotURI,
String copyMode, Boolean targetExists, TaskCompleter completer) throws DeviceControllerException {
throw DeviceControllerException.exceptions.blockDeviceOperationNotSupported();
}
@Override
public void doLinkBlockSnapshotSessionTargetGroup(StorageSystem system, URI snapshotSessionURI, List<URI> snapSessionSnapshotURIs,
String copyMode, Boolean targetsExist, TaskCompleter completer) throws DeviceControllerException {
throw DeviceControllerException.exceptions.blockDeviceOperationNotSupported();
}
/**
* {@inheritDoc}
*/
@Override
public void doRelinkBlockSnapshotSessionTarget(StorageSystem system, URI tgtSnapSessionURI, URI snapshotURI,
TaskCompleter completer) throws DeviceControllerException {
throw DeviceControllerException.exceptions.blockDeviceOperationNotSupported();
}
/**
* {@inheritDoc}
*/
@Override
public void doUnlinkBlockSnapshotSessionTarget(StorageSystem system, URI snapSessionURI, URI snapshotURI,
Boolean deleteTarget, TaskCompleter completer) throws DeviceControllerException {
throw DeviceControllerException.exceptions.blockDeviceOperationNotSupported();
}
/**
* {@inheritDoc}
*/
@Override
public void doRestoreBlockSnapshotSession(StorageSystem system, URI snapSessionURI, TaskCompleter completer)
throws DeviceControllerException {
throw DeviceControllerException.exceptions.blockDeviceOperationNotSupported();
}
/**
* {@inheritDoc}
*/
@Override
public void doDeleteBlockSnapshotSession(StorageSystem system, URI snapSessionURI, String groupName, TaskCompleter completer)
throws DeviceControllerException {
throw DeviceControllerException.exceptions.blockDeviceOperationNotSupported();
}
@Override
public void doAddSnapshotSessionsToConsistencyGroup(StorageSystem storageSystem, URI consistencyGroup, List<URI> addVolumesList,
TaskCompleter taskCompleter) {
throw DeviceControllerException.exceptions.blockDeviceOperationNotSupported();
}
@Override
public BiosCommandResult assignFilePolicy(StorageSystem storageObj, FileDeviceInputOutput args) {
return BiosCommandResult.createErrorResult(
DeviceControllerErrors.vnxe.operationNotSupported("Assign File Policy", "VNXe"));
}
@Override
public BiosCommandResult unassignFilePolicy(StorageSystem storageObj, FileDeviceInputOutput args) {
return BiosCommandResult.createErrorResult(
DeviceControllerErrors.vnxe.operationNotSupported("Unassign File Policy", "VNXe"));
}
@Override
public BiosCommandResult listSanpshotByPolicy(StorageSystem storageObj, FileDeviceInputOutput args) {
return BiosCommandResult.createErrorResult(
DeviceControllerErrors.vnxe.operationNotSupported("List Snapshots by Policy", "VNXe"));
}
@Override
public BiosCommandResult updateStorageSystemFileProtectionPolicy(StorageSystem storageObj, FileDeviceInputOutput args) {
return BiosCommandResult.createErrorResult(
DeviceControllerErrors.vnxe.operationNotSupported("Update storage system protection policy ", "VNXe"));
}
@Override
public void doInitiatorAliasSet(StorageSystem storage, Initiator initiator, String initiatorAlias) throws Exception {
throw DeviceControllerException.exceptions.blockDeviceOperationNotSupported();
}
@Override
public String doInitiatorAliasGet(StorageSystem storage, Initiator initiator) throws Exception {
throw DeviceControllerException.exceptions.blockDeviceOperationNotSupported();
}
@Override
public Map<URI, List<Integer>> doFindHostHLUs(StorageSystem storage, Collection<URI> initiatorURIs)
throws DeviceControllerException {
throw DeviceControllerException.exceptions.blockDeviceOperationNotSupported();
}
@Override
public void doExportAddPaths(StorageSystem storage, URI exportMask, Map<URI, List<URI>> addedPaths,
TaskCompleter taskCompleter) throws DeviceControllerException {
throw DeviceControllerException.exceptions.blockDeviceOperationNotSupported();
}
@Override
public void doExportRemovePaths(StorageSystem storage, URI exportMask, Map<URI, List<URI>> adjustedPaths,
Map<URI, List<URI>> removedPaths,
TaskCompleter taskCompleter) throws DeviceControllerException {
throw DeviceControllerException.exceptions.blockDeviceOperationNotSupported();
}
@Override
public BiosCommandResult doApplyFilePolicy(StorageSystem storageObj, FileDeviceInputOutput args) {
return BiosCommandResult.createErrorResult(
DeviceControllerErrors.vnxe.operationNotSupported("Assign File Policy", "VNXe"));
}
@Override
public BiosCommandResult doUnassignFilePolicy(StorageSystem storage, FileDeviceInputOutput fd) throws ControllerException {
return BiosCommandResult.createErrorResult(
DeviceControllerErrors.vnxe.operationNotSupported("un assign File Policy", "VNXe"));
}
@Override
public BiosCommandResult checkFilePolicyExistsOrCreate(StorageSystem storageObj, FileDeviceInputOutput args) {
return BiosCommandResult.createErrorResult(
DeviceControllerErrors.vnxe.operationNotSupported("Assign File Policy", "VNXe"));
}
@Override
public BiosCommandResult checkFileReplicationPolicyExistsOrCreate(StorageSystem sourceStorageObj, StorageSystem targetStorageObj,
FileDeviceInputOutput sourceSytemArgs, FileDeviceInputOutput targetSytemArgs) {
return BiosCommandResult.createErrorResult(
DeviceControllerErrors.vnxe.operationNotSupported("assign File Policy", "VNXe"));
}
@Override
public BiosCommandResult doStartMirrorLink(StorageSystem system, FileShare source, TaskCompleter completer) {
return BiosCommandResult.createErrorResult(
DeviceControllerErrors.vnxe.operationNotSupported("start the mirror link", "VNXe"));
}
@Override
public BiosCommandResult doRefreshMirrorLink(StorageSystem system, FileShare source) {
return BiosCommandResult.createErrorResult(
DeviceControllerErrors.vnxe.operationNotSupported("start the mirror link", "VNXe"));
}
@Override
public BiosCommandResult doPauseLink(StorageSystem system, FileShare source) {
return BiosCommandResult.createErrorResult(
DeviceControllerErrors.vnxe.operationNotSupported("pause the mirror link", "VNXe"));
}
@Override
public BiosCommandResult doResumeLink(StorageSystem system, FileShare target, TaskCompleter completer) {
return BiosCommandResult.createErrorResult(
DeviceControllerErrors.vnxe.operationNotSupported("resume the mirror link", "VNXe"));
}
@Override
public BiosCommandResult doFailoverLink(StorageSystem system, FileShare target, TaskCompleter completer) {
return BiosCommandResult.createErrorResult(
DeviceControllerErrors.vnxe.operationNotSupported("failover the mirror link", "VNXe"));
}
@Override
public BiosCommandResult checkFilePolicyPathHasResourceLabel(StorageSystem system, FileDeviceInputOutput args) {
return BiosCommandResult.createErrorResult(
DeviceControllerErrors.vnxe.operationNotSupported("failover the mirror link", "VNXe"));
}
@Override
public BiosCommandResult doResyncLink(StorageSystem system, FileShare source, TaskCompleter completer) {
return BiosCommandResult.createErrorResult(
DeviceControllerErrors.vnxe.operationNotSupported("resync the mirror link", "VNXe"));
}
}