/*
* Copyright (c) 2015 EMC Corporation
* All Rights Reserved
*/
package com.emc.storageos.fileorchestrationcontroller;
import java.io.Serializable;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
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.Controller;
import com.emc.storageos.customconfigcontroller.CustomConfigConstants;
import com.emc.storageos.customconfigcontroller.impl.CustomConfigHandler;
import com.emc.storageos.db.client.DbClient;
import com.emc.storageos.db.client.URIUtil;
import com.emc.storageos.db.client.model.DiscoveredDataObject.Type;
import com.emc.storageos.db.client.model.FSExportMap;
import com.emc.storageos.db.client.model.FileExport;
import com.emc.storageos.db.client.model.FileObject;
import com.emc.storageos.db.client.model.FilePolicy;
import com.emc.storageos.db.client.model.FilePolicy.FilePolicyApplyLevel;
import com.emc.storageos.db.client.model.FilePolicy.FilePolicyType;
import com.emc.storageos.db.client.model.FileShare;
import com.emc.storageos.db.client.model.FileShare.PersonalityTypes;
import com.emc.storageos.db.client.model.PhysicalNAS;
import com.emc.storageos.db.client.model.PolicyStorageResource;
import com.emc.storageos.db.client.model.Project;
import com.emc.storageos.db.client.model.SMBFileShare;
import com.emc.storageos.db.client.model.SMBShareMap;
import com.emc.storageos.db.client.model.Snapshot;
import com.emc.storageos.db.client.model.StoragePort;
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.VirtualPool;
import com.emc.storageos.db.client.util.NullColumnValueGetter;
import com.emc.storageos.exceptions.DeviceControllerException;
import com.emc.storageos.fileorchestrationcontroller.FileStorageSystemAssociation.TargetAssociation;
import com.emc.storageos.filereplicationcontroller.FileReplicationDeviceController;
import com.emc.storageos.model.ResourceOperationTypeEnum;
import com.emc.storageos.model.file.CifsShareACLUpdateParams;
import com.emc.storageos.model.file.ExportRule;
import com.emc.storageos.model.file.ExportRules;
import com.emc.storageos.model.file.FileExportUpdateParams;
import com.emc.storageos.model.file.FileNfsACLUpdateParams;
import com.emc.storageos.model.file.MountInfo;
import com.emc.storageos.model.file.NfsACE;
import com.emc.storageos.model.file.ShareACL;
import com.emc.storageos.model.file.ShareACLs;
import com.emc.storageos.model.file.policy.FilePolicyUpdateParam;
import com.emc.storageos.svcs.errorhandling.model.ServiceError;
import com.emc.storageos.svcs.errorhandling.resources.InternalException;
import com.emc.storageos.volumecontroller.ControllerException;
import com.emc.storageos.volumecontroller.ControllerLockingService;
import com.emc.storageos.volumecontroller.FileSMBShare;
import com.emc.storageos.volumecontroller.FileShareExport;
import com.emc.storageos.volumecontroller.TaskCompleter;
import com.emc.storageos.volumecontroller.impl.FileDeviceController;
import com.emc.storageos.volumecontroller.impl.file.CreateMirrorFileSystemsCompleter;
import com.emc.storageos.volumecontroller.impl.file.FileCreateWorkflowCompleter;
import com.emc.storageos.volumecontroller.impl.file.FileDeleteWorkflowCompleter;
import com.emc.storageos.volumecontroller.impl.file.FilePolicyAssignWorkflowCompleter;
import com.emc.storageos.volumecontroller.impl.file.FilePolicyUnAssignWorkflowCompleter;
import com.emc.storageos.volumecontroller.impl.file.FileProtectionPolicyUpdateCompleter;
import com.emc.storageos.volumecontroller.impl.file.FileSnapshotWorkflowCompleter;
import com.emc.storageos.volumecontroller.impl.file.FileSystemAssignPolicyWorkflowCompleter;
import com.emc.storageos.volumecontroller.impl.file.FileWorkflowCompleter;
import com.emc.storageos.volumecontroller.impl.file.MirrorFileFailbackTaskCompleter;
import com.emc.storageos.volumecontroller.impl.file.MirrorFileFailoverTaskCompleter;
import com.emc.storageos.volumecontroller.impl.vnxe.job.VNXeFSSnapshotTaskCompleter;
import com.emc.storageos.workflow.Workflow;
import com.emc.storageos.workflow.WorkflowException;
import com.emc.storageos.workflow.WorkflowService;
public class FileOrchestrationDeviceController implements FileOrchestrationController, Controller {
private static final Logger s_logger = LoggerFactory.getLogger(FileOrchestrationDeviceController.class);
private static DbClient s_dbClient;
private WorkflowService _workflowService;
private static FileDeviceController _fileDeviceController;
private static FileReplicationDeviceController _fileReplicationDeviceController;
private ControllerLockingService _locker;
private CustomConfigHandler customConfigHandler;
static final String CREATE_FILESYSTEMS_WF_NAME = "CREATE_FILESYSTEMS_WORKFLOW";
static final String DELETE_FILESYSTEMS_WF_NAME = "DELETE_FILESYSTEMS_WORKFLOW";
static final String EXPAND_FILESYSTEMS_WF_NAME = "EXPAND_FILESYSTEMS_WORKFLOW";
static final String CHANGE_FILESYSTEMS_VPOOL_WF_NAME = "CHANGE_FILESYSTEMS_VPOOL_WORKFLOW";
static final String CREATE_MIRROR_FILESYSTEMS_WF_NAME = "CREATE_MIRROR_FILESYSTEMS_WORKFLOW";
static final String CREATE_FILESYSTEM_CIFS_SHARE_WF_NAME = "CREATE_FILESYSTEM_CIFS_SHARE_WORKFLOW";
static final String CREATE_FILESYSTEM_NFS_EXPORT_WF_NAME = "CREATE_FILESYSTEM_NFS_EXPORT_WORKFLOW";
static final String UPDATE_FILESYSTEM_EXPORT_RULES_WF_NAME = "UPDATE_FILESYSTEM_EXPORT_RULES_WORKFLOW";
static final String UPDATE_FILESYSTEM_CIFS_SHARE_ACLS_WF_NAME = "UPDATE_FILESYSTEM_CIFS_SHARE_ACLS_WORKFLOW";
static final String CREATE_FILESYSTEM_SNAPSHOT_WF_NAME = "CREATE_FILESYSTEM_SNAPSHOT_WORKFLOW";
static final String DELETE_FILESYSTEM_CIFS_SHARE_WF_NAME = "DELETE_FILESYSTEM_CIFS_SHARE_WORKFLOW";
static final String DELETE_FILESYSTEM_EXPORT_RULES_WF_NAME = "DELETE_FILESYSTEM_EXPORT_RULES_WORKFLOW";
static final String EXPAND_FILESYSTEM_WF_NAME = "EXPAND_FILESYSTEM_WORFLOW";
static final String DELETE_FILESYSTEM_SNAPSHOT_WF_NAME = "DELETE_FILESYSTEM_SNAPSHOT_WORKFLOW";
static final String RESTORE_FILESYSTEM_SNAPSHOT_WF_NAME = "RESTORE_FILESYSTEM_SNAPSHOT_WORFLOW";
static final String DELETE_FILESYSTEM_SHARE_ACLS_WF_NAME = "DELETE_FILESYSTEM_SHARE_ACLS_WORKFLOW";
static final String REPLICATE_QUOTA_DIR_SETTINGS_TO_TARGET_WF_NAME = "REPLICATE_QUOTA_DIR_SETTINGS_TO_TARGET_WORKFLOW";
static final String UNASSIGN_FILE_POLICY_WF_NAME = "UNASSIGN_FILE_POLICY_WORKFLOW";
static final String ASSIGN_FILE_POLICY_WF_NAME = "ASSIGN_FILE_POLICY_WORKFLOW";
static final String UPDATE_FILE_POLICY_WF_NAME = "UPDATE_FILE_POLICY_WORKFLOW";
static final String ASSIGN_FILE_POLICY_TO_FS_WF_NAME = "ASSIGN_FILE_POLICY_TO_FILE_SYSTEM_WORKFLOW";
static final String FAILOVER_FILESYSTEMS_WF_NAME = "FAILOVER_FILESYSTEM_WORKFLOW";
static final String FAILBACK_FILESYSTEMS_WF_NAME = "FAILBACK_FILESYSTEM_WORKFLOW";
static final String REPLICATE_CIFS_SHARES_TO_TARGET_WF_NAME = "REPLICATE_CIFS_SHARES_TO_TARGET_WORKFLOW";
static final String REPLICATE_CIFS_SHARE_ACLS_TO_TARGET_WF_NAME = "REPLICATE_CIFS_SHARE_ACLS_TO_TARGET_WORKFLOW";
static final String REPLICATE_NFS_EXPORT_TO_TARGET_WF_NAME = "REPLICATE_NFS_EXPORT_TO_TARGET_WORFLOW";
static final String REPLICATE_NFS_EXPORT_RULES_TO_TARGET_WF_NAME = "REPLICATE_NFS_EXPORT_RULES_TO_TARGET_WORFLOW";
static final String REPLICATE_NFS_ACLS_TO_TARGET_WF_NAME = "REPLICATE_NFS_ACLS_TO_TARGET_WORKFLOW";
private static final String CREATE_FILESYSTEM_EXPORT_METHOD = "export";
private static final String CREATE_FILESYSTEM_SHARE_METHOD = "share";
private static final String UPDATE_FILESYSTEM_SHARE_ACLS_METHOD = "updateShareACLs";
private static final String UPDATE_FILESYSTEM_NFS_ACL_METHOD = "updateNFSAcl";
private static final String UPDATE_FILESYSTEM_EXPORT_RULES_METHOD = "updateExportRules";
private static final String CREATE_FILESYSTEM_SNAPSHOT_METHOD = "snapshotFS";
private static final String DELETE_FILESYSTEM_SHARE_METHOD = "deleteShare";
private static final String DELETE_FILESYSTEM_EXPORT_RULES = "deleteExportRules";
private static final String MODIFY_FILESYSTEM_METHOD = "modifyFS";
private static final String FAILOVER_FILE_SYSTEM_METHOD = "failoverFileSystem";
private static final String FAILBACK_FILE_SYSTEM_METHOD = "doFailBackMirrorSessionWF";
private static final String FILE_REPLICATION_OPERATIONS_METHOD = "performFileReplicationOperation";
private static final String REPLICATE_FILESYSTEM_DIRECTORY_QUOTA_SETTINGS_METHOD = "addStepsToReplicateDirectoryQuotaSettings";
private static final String REPLICATE_FILESYSTEM_CIFS_SHARES_METHOD = "addStepsToReplicateCIFSShares";
private static final String REPLICATE_FILESYSTEM_CIFS_SHARE_ACLS_METHOD = "addStepsToReplicateCIFSShareACLs";
private static final String REPLICATE_FILESYSTEM_NFS_EXPORT_METHOD = "addStepsToReplicateNFSExports";
private static final String REPLICATE_FILESYSTEM_NFS_EXPORT_RULE_METHOD = "addStepsToReplicateNFSExportRules";
private static final String REPLICATE_FILESYSTEM_NFS_ACLS_METHOD = "addStepsToReplicateNFSACLs";
private static final String RESTORE_FILESYSTEM_SNAPSHOT_METHOD = "restoreFS";
private static final String DELETE_FILESYSTEM_SNAPSHOT_METHOD = "delete";
private static final String DELETE_FILESYSTEM_SHARE_ACLS_METHOD = "deleteShareACLs";
private static final String DELETE_FILESYSTEM_EXPORT_METHOD = "deleteExportRules";
private static final String UNMOUNT_FILESYSTEM_EXPORT_METHOD = "unmountDevice";
private static final String VERIFY_MOUNT_DEPENDENCIES_METHOD = "verifyMountDependencies";
private static final String CHECK_IF_EXPORT_IS_MOUNTED = "CheckIfExportIsMounted";
private static final String APPLY_FILE_POLICY_METHOD = "applyFilePolicy";
private static final String UNASSIGN_FILE_POLICY_METHOD = "unassignFilePolicy";
private static final String ASSIGN_FILE_SNAPSHOT_POLICY_TO_VIRTUAL_POOLS_METHOD = "assignFileSnapshotPolicyToVirtualPools";
private static final String ASSIGN_FILE_SNAPSHOT_POLICY_TO_PROJECTS_METHOD = "assignFileSnapshotPolicyToProjects";
private static final String UPDATE_STORAGE_SYSTEM_FILE_PROTECTION_POLICY_METHOD = "updateStorageSystemFileProtectionPolicy";
private static final String ASSIGN_FILE_REPLICATION_POLICY_TO_VIRTUAL_POOLS_METHOD = "assignFileReplicationPolicyToVirtualPools";
private static final String ASSIGN_FILE_REPLICATION_POLICY_TO_PROJECTS_METHOD = "assignFileReplicationPolicyToProjects";
private static final String CHECK_FILE_POLICY_PATH_HAS_RESOURCE_LABEL_METHOD = "checkFilePolicyPathHasResourceLabel";
public void setCustomConfigHandler(CustomConfigHandler customConfigHandler) {
this.customConfigHandler = customConfigHandler;
}
/*
* (non-Javadoc)
*
* @see com.emc.storageos.fileorchestrationcontroller.FileOrchestrationController#createFileSystems(java.util.List,
* java.lang.String)
*/
/**
* Creates one or more filesystem
* (FileShare, FileMirroring). This method is responsible for creating
* a Workflow and invoking the FileOrchestrationInterface.addStepsForCreateFileSystems
*
* @param fileDescriptors
* @param taskId
* @throws ControllerException
*/
@Override
public void createFileSystems(List<FileDescriptor> fileDescriptors,
String taskId) throws ControllerException {
// Generate the Workflow.
Workflow workflow = null;
List<URI> fsUris = FileDescriptor.getFileSystemURIs(fileDescriptors);
FileCreateWorkflowCompleter completer = new FileCreateWorkflowCompleter(fsUris, taskId, fileDescriptors);
try {
// Generate the Workflow.
workflow = _workflowService.getNewWorkflow(this,
CREATE_FILESYSTEMS_WF_NAME, false, taskId);
String waitFor = null; // the wait for key returned by previous call
s_logger.info("Generating steps for create FileSystem");
// First, call the FileDeviceController to add its methods.
waitFor = _fileDeviceController.addStepsForCreateFileSystems(workflow, waitFor,
fileDescriptors, taskId);
// second, check for policies that has to applied on this file system..
waitFor = addStepsForApplyingPolicies(workflow, waitFor, fileDescriptors);
// Finish up and execute the plan.
// The Workflow will handle the TaskCompleter
String successMessage = "Create filesystems successful for: " + fsUris.toString();
Object[] callbackArgs = new Object[] { fsUris };
workflow.executePlan(completer, successMessage, new WorkflowCallback(), callbackArgs, null, null);
} catch (Exception ex) {
s_logger.error("Could not create filesystems: " + fsUris, ex);
releaseWorkflowLocks(workflow);
String opName = ResourceOperationTypeEnum.CREATE_FILE_SYSTEM.getName();
ServiceError serviceError = DeviceControllerException.errors.createFileSharesFailed(
fsUris.toString(), opName, ex);
completer.error(s_dbClient, _locker, serviceError);
}
}
/*
* (non-Javadoc)
*
* @see
* com.emc.storageos.fileorchestrationcontroller.FileOrchestrationController#changeFileSystemVirtualPool(java.util.
* List,
* java.lang.String)
*/
/**
* Create target filesystems for existing file systems!!
* (FileShare, FileMirroring). This method is responsible for creating
* a Workflow and invoking the FileOrchestrationInterface.addStepsForCreateFileSystems
*
* @param fs
* @param fileDescriptors
* @param taskId
* @throws ControllerException
*/
@Override
public void createTargetsForExistingSource(String fs, List<FileDescriptor> fileDescriptors,
String taskId) throws ControllerException {
// Generate the Workflow.
Workflow workflow = null;
List<URI> fsUris = FileDescriptor.getFileSystemURIs(fileDescriptors);
CreateMirrorFileSystemsCompleter completer = new CreateMirrorFileSystemsCompleter(fsUris, taskId, fileDescriptors);
try {
// Generate the Workflow.
workflow = _workflowService.getNewWorkflow(this,
CREATE_MIRROR_FILESYSTEMS_WF_NAME, false, taskId);
String waitFor = null; // the wait for key returned by previous call
s_logger.info("Generating steps for creating mirror filesystems...");
// First, call the FileDeviceController to add its methods.
// To create target file systems!!
waitFor = _fileDeviceController.addStepsForCreateFileSystems(workflow, waitFor,
fileDescriptors, taskId);
// second, call create replication link or pair
waitFor = _fileReplicationDeviceController.addStepsForCreateFileSystems(workflow, waitFor,
fileDescriptors, taskId);
// Finish up and execute the plan.
// The Workflow will handle the TaskCompleter
String successMessage = "Change filesystems vpool successful for: " + fs;
Object[] callbackArgs = new Object[] { fsUris };
workflow.executePlan(completer, successMessage, new WorkflowCallback(), callbackArgs, null, null);
} catch (Exception ex) {
s_logger.error("Could not change the filesystem vpool: " + fs, ex);
releaseWorkflowLocks(workflow);
String opName = ResourceOperationTypeEnum.CHANGE_FILE_SYSTEM_VPOOL.getName();
ServiceError serviceError = DeviceControllerException.errors.createFileSharesFailed(
fsUris.toString(), opName, ex);
completer.error(s_dbClient, _locker, serviceError);
}
}
/*
* (non-Javadoc)
*
* @see com.emc.storageos.fileorchestrationcontroller.FileOrchestrationController#deleteFileSystems(java.util.List,
* java.lang.String)
*/
/**
* Deletes one or more filesystem.
*
* @param fileDescriptors
* @param taskId
* @throws ControllerException
*/
@Override
public void deleteFileSystems(List<FileDescriptor> fileDescriptors,
String taskId) throws ControllerException {
List<URI> fileShareUris = FileDescriptor.getFileSystemURIs(fileDescriptors);
FileDeleteWorkflowCompleter completer = new FileDeleteWorkflowCompleter(fileShareUris, taskId);
Workflow workflow = null;
try {
// Generate the Workflow.
workflow = _workflowService.getNewWorkflow(this,
DELETE_FILESYSTEMS_WF_NAME, false, taskId);
// call the FileDeviceController to add its delete methods.
_fileDeviceController.addStepsForDeleteFileSystems(workflow, null, fileDescriptors, taskId);
// Finish up and execute the plan.
// The Workflow will handle the TaskCompleter
String successMessage = "Delete FileShares successful for: " + fileShareUris.toString();
Object[] callbackArgs = new Object[] { fileShareUris };
workflow.executePlan(completer, successMessage, new WorkflowCallback(), callbackArgs, null, null);
} catch (Exception ex) {
s_logger.error("Could not delete FileShares: " + fileShareUris, ex);
releaseWorkflowLocks(workflow);
String opName = ResourceOperationTypeEnum.DELETE_FILE_SYSTEM.getName();
ServiceError serviceError = DeviceControllerException.errors.deleteFileSharesFailed(
fileShareUris.toString(), opName, ex);
completer.error(s_dbClient, _locker, serviceError);
}
}
/*
* (non-Javadoc)
*
* @see com.emc.storageos.fileorchestrationcontroller.FileOrchestrationController#expandFileSystem(java.net.URI,
* long, java.lang.String)
*/
/**
* expand one or more filesystem
*
* @param fileDescriptors
* @param taskId
* @throws ControllerException
*/
@Override
public void expandFileSystem(List<FileDescriptor> fileDescriptors,
String taskId) throws ControllerException {
String waitFor = null; // the wait for key returned by previous call
List<URI> fileShareUris = FileDescriptor.getFileSystemURIs(fileDescriptors);
FileWorkflowCompleter completer = new FileWorkflowCompleter(fileShareUris, taskId);
Workflow workflow = null;
try {
// Generate the Workflow.
workflow = _workflowService.getNewWorkflow(this,
EXPAND_FILESYSTEMS_WF_NAME, false, taskId);
// Next, call the FileDeviceController to add its delete methods.
waitFor = _fileDeviceController.addStepsForExpandFileSystems(workflow, waitFor, fileDescriptors, taskId);
// Finish up and execute the plan.
// The Workflow will handle the TaskCompleter
String successMessage = "Expand FileShares successful for: " + fileShareUris.toString();
Object[] callbackArgs = new Object[] { fileShareUris };
workflow.executePlan(completer, successMessage, new WorkflowCallback(), callbackArgs, null, null);
} catch (Exception ex) {
s_logger.error("Could not Expand FileShares: " + fileShareUris, ex);
releaseWorkflowLocks(workflow);
String opName = ResourceOperationTypeEnum.EXPORT_FILE_SYSTEM.getName();
ServiceError serviceError = DeviceControllerException.errors.expandFileShareFailed(fileShareUris.toString(), opName, ex);
completer.error(s_dbClient, _locker, serviceError);
}
}
@SuppressWarnings("serial")
public static class WorkflowCallback implements Workflow.WorkflowCallbackHandler, Serializable {
@Override
public void workflowComplete(Workflow workflow, Object[] args)
throws WorkflowException {
}
}
private void releaseWorkflowLocks(Workflow workflow) {
if (workflow == null) {
return;
}
s_logger.info("Releasing all workflow locks with owner: {}", workflow.getWorkflowURI());
_workflowService.releaseAllWorkflowLocks(workflow);
}
public WorkflowService getWorkflowService() {
return _workflowService;
}
public void setWorkflowService(WorkflowService workflowService) {
this._workflowService = workflowService;
}
public DbClient getDbClient() {
return s_dbClient;
}
public void setDbClient(DbClient dbClient) {
FileOrchestrationDeviceController.s_dbClient = dbClient;
}
public void setLocker(ControllerLockingService locker) {
this._locker = locker;
}
public FileDeviceController getFileDeviceController() {
return _fileDeviceController;
}
public void setFileDeviceController(FileDeviceController fileDeviceController) {
FileOrchestrationDeviceController._fileDeviceController = fileDeviceController;
}
public FileReplicationDeviceController getFileReplicationFileDeviceController() {
return _fileReplicationDeviceController;
}
public void setFileReplicationDeviceController(FileReplicationDeviceController fileReplicationDeviceController) {
FileOrchestrationDeviceController._fileReplicationDeviceController = fileReplicationDeviceController;
}
@Override
public void createCIFSShare(URI storageSystem, URI uri, FileSMBShare smbShare, String taskId) throws ControllerException {
FileObject fileObj = null;
String stepDescription = null;
String successMessage = null;
String opName = null;
TaskCompleter completer = null;
if (URIUtil.isType(uri, FileShare.class)) {
completer = new FileWorkflowCompleter(uri, taskId);
fileObj = s_dbClient.queryObject(FileShare.class, uri);
stepDescription = String.format("Creating CIFS share for file system : %s, share name: %s ", uri, smbShare.getName());
successMessage = String.format("Creating CIFS share for file system : %s, share name: %s finished succesfully.", uri,
smbShare.getName());
opName = ResourceOperationTypeEnum.CREATE_FILE_SYSTEM_SHARE.getName();
} else {
completer = new FileSnapshotWorkflowCompleter(uri, taskId);
fileObj = s_dbClient.queryObject(Snapshot.class, uri);
stepDescription = String.format("Creating CIFS share for file system snapshot : %s, share name: %s ", uri, smbShare.getName());
successMessage = String.format("Creating CIFS share for file system : %s, share name: %s finished succesfully.", uri,
smbShare.getName());
opName = ResourceOperationTypeEnum.CREATE_FILE_SNAPSHOT_SHARE.getName();
}
try {
Workflow workflow = _workflowService.getNewWorkflow(this, CREATE_FILESYSTEM_CIFS_SHARE_WF_NAME, false, taskId, completer);
String shareStep = workflow.createStepId();
Object[] args = new Object[] { storageSystem, uri, smbShare };
_fileDeviceController.createMethod(workflow, null, CREATE_FILESYSTEM_SHARE_METHOD, shareStep, stepDescription, storageSystem,
args);
workflow.executePlan(completer, successMessage);
} catch (Exception ex) {
s_logger.error(String.format("Creating CIFS share for file system : %s, share name: %s failed.", uri,
smbShare.getName()), ex);
ServiceError serviceError = DeviceControllerException.errors.createFileSharesFailed(
fileObj.toString(), opName, ex);
completer.error(s_dbClient, _locker, serviceError);
}
}
@Override
public void createNFSExport(URI storage, URI uri, List<FileShareExport> exports, String opId) throws ControllerException {
FileObject fileObj = null;
String stepDescription = null;
String successMessage = null;
String opName = null;
TaskCompleter completer = null;
if (URIUtil.isType(uri, FileShare.class)) {
completer = new FileWorkflowCompleter(uri, opId);
fileObj = s_dbClient.queryObject(FileShare.class, uri);
stepDescription = String.format("Creating NFS export for file system : %s", uri);
successMessage = String.format("Creating NFS export for file system : %s finished succesfully.", uri);
opName = ResourceOperationTypeEnum.EXPORT_FILE_SYSTEM.getName();
} else {
completer = new FileSnapshotWorkflowCompleter(uri, opId);
fileObj = s_dbClient.queryObject(Snapshot.class, uri);
stepDescription = String.format("Creating NFS export for file system snapshot : %s", uri);
successMessage = String.format("Creating NFS export for file system snapshot : %s finished succesfully.", uri);
opName = ResourceOperationTypeEnum.EXPORT_FILE_SNAPSHOT.getName();
}
try {
Workflow workflow = _workflowService.getNewWorkflow(this, CREATE_FILESYSTEM_NFS_EXPORT_WF_NAME, false, opId, completer);
String exportStep = workflow.createStepId();
Object[] args = new Object[] { storage, uri, exports };
_fileDeviceController.createMethod(workflow, null, CREATE_FILESYSTEM_EXPORT_METHOD, exportStep, stepDescription, storage, args);
workflow.executePlan(completer, successMessage);
} catch (Exception ex) {
s_logger.error(String.format("Creating NFS export for file system/snapshot : %s failed", uri), ex);
ServiceError serviceError = DeviceControllerException.errors.exportFileShareFailed(
fileObj.toString(), opName, ex);
completer.error(s_dbClient, _locker, serviceError);
}
}
@Override
public void updateExportRules(URI storage, URI uri, FileExportUpdateParams param, boolean unmountExport, String opId)
throws ControllerException {
FileObject fileObj = null;
String stepDescription = null;
String successMessage = null;
String opName = null;
TaskCompleter completer = null;
if (URIUtil.isType(uri, FileShare.class)) {
completer = new FileWorkflowCompleter(uri, opId);
fileObj = s_dbClient.queryObject(FileShare.class, uri);
stepDescription = String.format("Updating file system : %s export rules: %s", uri, param.toString());
successMessage = String.format("Updating file system : %s export rules: %s finished successfully.", uri, param.toString());
opName = ResourceOperationTypeEnum.UPDATE_EXPORT_RULES_FILE_SYSTEM.getName();
} else {
completer = new FileSnapshotWorkflowCompleter(uri, opId);
fileObj = s_dbClient.queryObject(Snapshot.class, uri);
stepDescription = String.format("Updating file system : %s export rules: %s", uri, param.toString());
successMessage = String.format("Updating file system : %s export rules: %s finished successfully.", uri, param.toString());
opName = ResourceOperationTypeEnum.UPDATE_EXPORT_RULES_FILE_SNAPSHOT.getName();
}
try {
Workflow workflow = _workflowService.getNewWorkflow(this, UPDATE_FILESYSTEM_EXPORT_RULES_WF_NAME, false, opId, completer);
String waitFor = null;
// Check if the export should be unmounted before deleting
if (unmountExport) {
// get all the mounts and generate steps for unmounting them
List<MountInfo> mountList = _fileDeviceController.getMountedExports(uri, param.getSubDir(), param);
for (MountInfo mount : mountList) {
Object[] args = new Object[] { mount.getHostId(), mount.getFsId(), mount.getMountPath() };
waitFor = _fileDeviceController.createMethod(workflow, waitFor, UNMOUNT_FILESYSTEM_EXPORT_METHOD, null,
"Unmounting path:" + mount.getMountPath(), storage, args);
}
} else if (URIUtil.isType(uri, FileShare.class)) {
// Check if the export rule is mounted and throw an error if mounted
Object[] args = new Object[] { uri, param };
waitFor = _fileDeviceController.createMethod(workflow, waitFor, VERIFY_MOUNT_DEPENDENCIES_METHOD,
null, "Verifying mount dependencies", storage, args);
}
Object[] args = new Object[] { storage, uri, param };
_fileDeviceController.createMethod(workflow, waitFor, UPDATE_FILESYSTEM_EXPORT_RULES_METHOD, null, stepDescription,
storage, args);
workflow.executePlan(completer, successMessage);
} catch (Exception ex) {
s_logger.error(String.format("Updating file system : %s export rules: %s failed.", uri, param.toString()), ex);
ServiceError serviceError = DeviceControllerException.errors.updateFileShareExportRulesFailed(
fileObj.toString(), opName, ex);
completer.error(s_dbClient, _locker, serviceError);
}
}
@Override
public void updateShareACLs(URI storage, URI uri, String shareName, CifsShareACLUpdateParams param, String opId)
throws ControllerException {
FileObject fileObj = null;
String stepDescription = null;
String successMessage = null;
String opName = null;
TaskCompleter completer = null;
if (URIUtil.isType(uri, FileShare.class)) {
completer = new FileWorkflowCompleter(uri, opId);
fileObj = s_dbClient.queryObject(FileShare.class, uri);
stepDescription = String.format("Updating file system : %s share : %s ACLs: %s", uri, shareName, param.toString());
successMessage = String.format("Updating file system : %s share : %s ACLs: %s finished successfully.", uri, shareName,
param.toString());
opName = ResourceOperationTypeEnum.UPDATE_FILE_SYSTEM_SHARE_ACL.getName();
} else {
completer = new FileSnapshotWorkflowCompleter(uri, opId);
fileObj = s_dbClient.queryObject(Snapshot.class, uri);
stepDescription = String.format("Updating file system snapshot : %s share : %s ACLs: %s", uri, shareName, param.toString());
successMessage = String.format("Updating file system snapshot : %s share : %s ACLs: %s finished successfully.", uri,
shareName,
param.toString());
opName = ResourceOperationTypeEnum.UPDATE_FILE_SNAPSHOT_SHARE_ACL.getName();
}
try {
Workflow workflow = _workflowService.getNewWorkflow(this, UPDATE_FILESYSTEM_CIFS_SHARE_ACLS_WF_NAME, false, opId, completer);
String shareACLUpdateStep = workflow.createStepId();
Object[] args = new Object[] { storage, uri, shareName, param };
_fileDeviceController.createMethod(workflow, null, UPDATE_FILESYSTEM_SHARE_ACLS_METHOD, shareACLUpdateStep, stepDescription,
storage,
args);
workflow.executePlan(completer, successMessage);
} catch (Exception ex) {
s_logger.error(String.format("Updating file system : %s share : %s ACLs: %s failed.", uri, shareName, param.toString()), ex);
ServiceError serviceError = DeviceControllerException.errors.updateFileShareCIFSACLsFailed(fileObj.toString(), opName, ex);
completer.error(s_dbClient, _locker, serviceError);
}
}
@Override
public void snapshotFS(URI storage, URI snapshot, URI fsURI, String opId) throws ControllerException {
// Using VNXeFSSnapshotTaskCompleter as it will serve the purpose..
VNXeFSSnapshotTaskCompleter completer = new VNXeFSSnapshotTaskCompleter(Snapshot.class, snapshot, opId);
Workflow workflow = null;
try {
workflow = _workflowService.getNewWorkflow(this, CREATE_FILESYSTEM_SNAPSHOT_WF_NAME, false, opId, completer);
String snapshotFSStep = workflow.createStepId();
String stepDescription = String.format("Creating file system: %s snapshot : %s", fsURI, snapshot);
Object[] args = new Object[] { storage, snapshot, fsURI };
_fileDeviceController.createMethod(workflow, null, CREATE_FILESYSTEM_SNAPSHOT_METHOD, snapshotFSStep, stepDescription, storage,
args);
String successMessage = String.format("Creating file system: %s snapshot : %s finished successfully.", fsURI, snapshot);
workflow.executePlan(completer, successMessage);
} catch (Exception ex) {
s_logger.error(String.format("Creating file system: %s snapshot : %s failed.", fsURI, snapshot), ex);
String opName = ResourceOperationTypeEnum.CREATE_FILE_SYSTEM_SNAPSHOT.getName();
ServiceError serviceError = DeviceControllerException.errors.createFileSystemSnapshotFailed(fsURI.toString(), opName, ex);
completer.error(s_dbClient, _locker, serviceError);
}
}
@Override
public void deleteShare(URI storage, URI uri, FileSMBShare fileSMBShare, String opId) throws ControllerException {
FileObject fileObj = null;
String stepDescription = null;
String successMessage = null;
String opName = null;
TaskCompleter completer = null;
if (URIUtil.isType(uri, FileShare.class)) {
completer = new FileWorkflowCompleter(uri, opId);
fileObj = s_dbClient.queryObject(FileShare.class, uri);
stepDescription = String.format("Deleting file system: %s CIFS share: %s ", uri, fileSMBShare.getName());
successMessage = String.format("Deleting file system: %s CIFS share: %s finished succesfully.", uri, fileSMBShare.getName());
opName = ResourceOperationTypeEnum.DELETE_FILE_SYSTEM_SHARE.getName();
} else {
completer = new FileSnapshotWorkflowCompleter(uri, opId);
fileObj = s_dbClient.queryObject(Snapshot.class, uri);
stepDescription = String.format("Deleting file system snapshot: %s CIFS share: %s ", uri, fileSMBShare.getName());
successMessage = String.format("Deleting file system snapshot: %s CIFS share: %s finished succesfully.", uri,
fileSMBShare.getName());
opName = ResourceOperationTypeEnum.DELETE_FILE_SNAPSHOT_SHARE.getName();
}
try {
Workflow workflow = _workflowService.getNewWorkflow(this, DELETE_FILESYSTEM_CIFS_SHARE_WF_NAME, false, opId, completer);
String sharedeleteStep = workflow.createStepId();
Object[] args = new Object[] { storage, uri, fileSMBShare };
_fileDeviceController.createMethod(workflow, null, DELETE_FILESYSTEM_SHARE_METHOD, sharedeleteStep, stepDescription, storage,
args);
workflow.executePlan(completer, successMessage);
} catch (Exception ex) {
s_logger.error(String.format("Deleting file system snapshot: %s CIFS share: %s failed.", uri, fileSMBShare.getName()), ex);
ServiceError serviceError = DeviceControllerException.errors.deleteCIFSShareFailed(fileObj.toString(), opName, ex);
completer.error(s_dbClient, _locker, serviceError);
}
}
@Override
public void deleteExportRules(URI storage, URI uri, boolean allDirs, String subDirs, boolean unmountExport, String opId)
throws ControllerException {
FileObject fileObj = null;
String stepDescription = null;
String successMessage = null;
String opName = null;
TaskCompleter completer = null;
if (URIUtil.isType(uri, FileShare.class)) {
completer = new FileWorkflowCompleter(uri, opId);
fileObj = s_dbClient.queryObject(FileShare.class, uri);
stepDescription = String.format("Deleting export rules for file system : %s ", uri);
successMessage = String.format("Deleting export rules for file system : %s finished successfully.", uri);
opName = ResourceOperationTypeEnum.UNEXPORT_FILE_SYSTEM.getName();
} else {
completer = new FileSnapshotWorkflowCompleter(uri, opId);
fileObj = s_dbClient.queryObject(Snapshot.class, uri);
stepDescription = String.format("Deleting export rules for file system snapshot : %s ", uri);
successMessage = String.format("Deleting export rules for file system snapshot : %s finished successfully.", uri);
opName = ResourceOperationTypeEnum.UNEXPORT_FILE_SNAPSHOT.getName();
}
try {
Workflow workflow = _workflowService.getNewWorkflow(this, DELETE_FILESYSTEM_EXPORT_RULES_WF_NAME, false, opId, completer);
String waitFor = null;
// Check if the export should be unmounted before deleting
if (unmountExport) {
// get all the mounts and generate steps for unmounting them
List<MountInfo> mountList = _fileDeviceController.getAllMountedExports(uri, subDirs, allDirs);
for (MountInfo mount : mountList) {
Object[] args = new Object[] { mount.getHostId(), mount.getFsId(), mount.getMountPath() };
waitFor = _fileDeviceController.createMethod(workflow, waitFor, UNMOUNT_FILESYSTEM_EXPORT_METHOD, null,
"Unmounting path:" + mount.getMountPath(), storage, args);
}
} else if (URIUtil.isType(uri, FileShare.class)) {
// Check if the export is mounted and throw an error if mounted
Object[] args = new Object[] { uri, subDirs, allDirs };
waitFor = _fileDeviceController.createMethod(workflow, waitFor, CHECK_IF_EXPORT_IS_MOUNTED, null,
"Checking if the export is mounted", storage, args);
}
Object[] args = new Object[] { storage, uri, allDirs, subDirs };
_fileDeviceController.createMethod(workflow, waitFor, DELETE_FILESYSTEM_EXPORT_RULES, null, stepDescription, storage,
args);
workflow.executePlan(completer, successMessage);
} catch (Exception ex) {
s_logger.error(String.format("Deleting export rules for file system snapshot : %s failed. ", uri), ex);
ServiceError serviceError = DeviceControllerException.errors.deleteExportRuleFailed(fileObj.toString(), opName, ex);
completer.error(s_dbClient, _locker, serviceError);
}
}
@Override
public void restoreFS(URI storage, URI fs, URI snapshot, String opId) throws ControllerException {
// Using VNXeFSSnapshotTaskCompleter as it will serve the purpose..
VNXeFSSnapshotTaskCompleter completer = new VNXeFSSnapshotTaskCompleter(Snapshot.class, snapshot, opId);
Workflow workflow = null;
try {
workflow = this._workflowService.getNewWorkflow(this, RESTORE_FILESYSTEM_SNAPSHOT_WF_NAME, false, opId, completer);
String restoreFSStep = workflow.createStepId();
String stepDescription = String.format("Restoring file System : %s from snapshot: %s", fs, snapshot);
Object[] args = new Object[] { storage, fs, snapshot };
_fileDeviceController.createMethod(workflow, null, RESTORE_FILESYSTEM_SNAPSHOT_METHOD, restoreFSStep, stepDescription, storage,
args);
String successMessage = String.format("Restoring file system : %s from snapshot: %s finished successfully.", fs, snapshot);
workflow.executePlan(completer, successMessage);
} catch (Exception ex) {
s_logger.error(String.format("Restoring file system : %s from snapshot: %s failed.", fs, snapshot), ex);
String opName = ResourceOperationTypeEnum.RESTORE_FILE_SNAPSHOT.getName();
ServiceError serviceError = DeviceControllerException.errors.restoreFSFromSnapshotFailed(fs.toString(), opName, ex);
completer.error(s_dbClient, this._locker, serviceError);
}
}
@Override
public void deleteSnapshot(URI storage, URI pool, URI uri, boolean forceDelete, String deleteType, String opId)
throws ControllerException {
Snapshot snap = s_dbClient.queryObject(Snapshot.class, uri);
FileSnapshotWorkflowCompleter completer = new FileSnapshotWorkflowCompleter(uri, opId);
Workflow workflow = null;
try {
workflow = this._workflowService.getNewWorkflow(this, DELETE_FILESYSTEM_SNAPSHOT_WF_NAME, false, opId, completer);
String deleteSnapshotStep = workflow.createStepId();
String stepDescription = String.format("Deleting file System : %s snapshot: %s", snap.getParent(), uri);
Object[] args = new Object[] { storage, pool, uri, forceDelete, deleteType };
_fileDeviceController.createMethod(workflow, null, DELETE_FILESYSTEM_SNAPSHOT_METHOD, deleteSnapshotStep, stepDescription,
storage, args);
String successMessage = String.format("Deleting file System : %s snapshot: %s finished successfully.", snap.getParent(), uri);
workflow.executePlan(completer, successMessage);
} catch (Exception ex) {
s_logger.error(String.format("Deleting file System : %s snapshot: %s failed.", snap.getParent(), uri), ex);
String opName = ResourceOperationTypeEnum.DELETE_FILE_SNAPSHOT.getName();
ServiceError serviceError = DeviceControllerException.errors.deleteFSSnapshotFailed(uri.toString(), opName, ex);
completer.error(s_dbClient, this._locker, serviceError);
}
}
@Override
public void deleteShareACLs(URI storage, URI uri, String shareName, String taskId) throws ControllerException {
String stepDescription = null;
String successMessage = null;
String opName = null;
TaskCompleter completer = null;
if (URIUtil.isType(uri, FileShare.class)) {
completer = new FileWorkflowCompleter(uri, taskId);
stepDescription = String.format("Deleting file system : %s share : %s ACLs", uri, shareName);
successMessage = String.format("Deleting file system : %s share : %s ACLs finished successfully", uri, shareName);
opName = ResourceOperationTypeEnum.DELETE_FILE_SYSTEM_SHARE_ACL.getName();
} else {
completer = new FileSnapshotWorkflowCompleter(uri, taskId);
stepDescription = String.format("Deleting file system snapshot : %s share: %s ACLs", uri, shareName);
successMessage = String.format("Deleting file system snapshot : %s share: %s ACLs: finished successfully", uri, shareName);
opName = ResourceOperationTypeEnum.DELETE_FILE_SNAPSHOT_SHARE_ACL.getName();
}
try {
Workflow workflow = this._workflowService.getNewWorkflow(this, DELETE_FILESYSTEM_SHARE_ACLS_WF_NAME, false, taskId, completer);
String shareACLDeleteStep = workflow.createStepId();
Object[] args = new Object[] { storage, uri, shareName };
_fileDeviceController.createMethod(workflow, null, DELETE_FILESYSTEM_SHARE_ACLS_METHOD, shareACLDeleteStep, stepDescription,
storage, args);
workflow.executePlan(completer, successMessage);
} catch (Exception ex) {
s_logger.error(String.format("Deleting file system snapshot : %s share: %s ACLs failed.", uri, shareName), ex);
ServiceError serviceError = DeviceControllerException.errors.deleteShareACLFailed(uri.toString(), opName, ex);
completer.error(s_dbClient, this._locker, serviceError);
}
}
@Override
public void failbackFileSystem(URI fsURI, StoragePort nfsPort, StoragePort cifsPort, boolean replicateConfiguration, String taskId)
throws ControllerException {
FileWorkflowCompleter completer = new FileWorkflowCompleter(fsURI, taskId);
Workflow workflow = null;
String stepDescription = null;
try {
FileShare sourceFileShare = s_dbClient.queryObject(FileShare.class, fsURI);
List<String> targetfileUris = new ArrayList<String>();
targetfileUris.addAll(sourceFileShare.getMirrorfsTargets());
FileShare targetFileShare = s_dbClient.queryObject(FileShare.class, URI.create(targetfileUris.get(0)));
StorageSystem systemSource = s_dbClient.queryObject(StorageSystem.class, sourceFileShare.getStorageDevice());
workflow = this._workflowService.getNewWorkflow(this, FAILBACK_FILESYSTEMS_WF_NAME, false, taskId, completer);
// Failback from Target File System
s_logger.info("Generating steps for Failback Source File System from Target");
String failbackStep = workflow.createStepId();
stepDescription = String.format("Failback to source file System : %s from target system : %s.", sourceFileShare.getName(),
targetFileShare.getName());
Workflow.Method failbackMethod = new Workflow.Method(FAILBACK_FILE_SYSTEM_METHOD,
systemSource.getId(), sourceFileShare.getId());
String waitForFailback = workflow.createStep(null, stepDescription, null, systemSource.getId(),
systemSource.getSystemType(), getClass(), failbackMethod, null, failbackStep);
// Replicate directory quota setting
stepDescription = String.format(
"Replicating directory quota settings from source file system : %s to file target system : %s",
sourceFileShare.getId(), targetFileShare.getId());
Workflow.Method replicateDirQuotaSettingsMethod = new Workflow.Method(REPLICATE_FILESYSTEM_DIRECTORY_QUOTA_SETTINGS_METHOD,
systemSource.getId(), targetFileShare.getId());
String replicateDirQuotaSettingsStep = workflow.createStepId();
workflow.createStep(null, stepDescription, waitForFailback, systemSource.getId(),
systemSource.getSystemType(), getClass(), replicateDirQuotaSettingsMethod, null, replicateDirQuotaSettingsStep);
if (replicateConfiguration) {
Map<String, List<NfsACE>> sourceNFSACL = FileOrchestrationUtils.queryNFSACL(sourceFileShare, s_dbClient);
Map<String, List<NfsACE>> targetNFSACL = FileOrchestrationUtils.queryNFSACL(targetFileShare, s_dbClient);
if (!sourceNFSACL.isEmpty() || !targetNFSACL.isEmpty()) {
stepDescription = String.format("Replicating NFS ACL from source file system : %s to file target system : %s",
sourceFileShare.getId(), targetFileShare.getId());
Workflow.Method replicateNFSACLsMethod = new Workflow.Method(REPLICATE_FILESYSTEM_NFS_ACLS_METHOD,
systemSource.getId(), targetFileShare.getId());
String replicateNFSACLsStep = workflow.createStepId();
workflow.createStep(null, stepDescription, waitForFailback, systemSource.getId(),
systemSource.getSystemType(), getClass(), replicateNFSACLsMethod, null, replicateNFSACLsStep);
}
// Replicate NFS export and rules to Target Cluster.
FSExportMap targetnfsExportMap = targetFileShare.getFsExports();
FSExportMap sourcenfsExportMap = sourceFileShare.getFsExports();
if (!(targetnfsExportMap == null && sourcenfsExportMap == null)) {
// Both source and target export map shouldn't be null
stepDescription = String.format("Replicating NFS exports from target file system : %s to source file system : %s",
targetFileShare.getId(), sourceFileShare.getId());
Workflow.Method replicateNFSExportMethod = new Workflow.Method(REPLICATE_FILESYSTEM_NFS_EXPORT_METHOD,
systemSource.getId(), targetFileShare.getId(), nfsPort);
String replicateNFSExportStep = workflow.createStepId();
String waitForExport = workflow.createStep(null, stepDescription, waitForFailback, systemSource.getId(),
systemSource.getSystemType(), getClass(), replicateNFSExportMethod, null, replicateNFSExportStep);
stepDescription = String.format("Replicating NFS export rules from target file system : %s to source file system : %s",
targetFileShare.getId(), sourceFileShare.getId());
Workflow.Method replicateNFSExportRulesMethod = new Workflow.Method(REPLICATE_FILESYSTEM_NFS_EXPORT_RULE_METHOD,
systemSource.getId(), targetFileShare.getId());
String replicateNFSExportRulesStep = workflow.createStepId();
workflow.createStep(null, stepDescription, waitForExport, systemSource.getId(), systemSource.getSystemType(),
getClass(), replicateNFSExportRulesMethod, null, replicateNFSExportRulesStep);
}
// Replicate CIFS shares and ACLs from Target File System to Source.
SMBShareMap targetSMBShareMap = targetFileShare.getSMBFileShares();
SMBShareMap sourceSMBShareMap = sourceFileShare.getSMBFileShares();
if (!(targetSMBShareMap == null && sourceSMBShareMap == null)) {
// Both source and target share map shouldn't be null
stepDescription = String.format("Replicating CIFS shares from target file system : %s to file source system : %s",
targetFileShare.getId(), sourceFileShare.getId());
Workflow.Method replicateCIFSShareMethod = new Workflow.Method(REPLICATE_FILESYSTEM_CIFS_SHARES_METHOD,
systemSource.getId(), targetFileShare.getId(), cifsPort);
String replicateCIFSShareStep = workflow.createStepId();
String waitForShare = workflow.createStep(null, stepDescription, waitForFailback, systemSource.getId(),
systemSource.getSystemType(), getClass(), replicateCIFSShareMethod, null,
replicateCIFSShareStep);
stepDescription = String.format("Replicating CIFS share ACLs from target file system : %s to source file system : %s",
targetFileShare.getId(), sourceFileShare.getId());
Workflow.Method replicateCIFSShareACLsMethod = new Workflow.Method(REPLICATE_FILESYSTEM_CIFS_SHARE_ACLS_METHOD,
systemSource.getId(), targetFileShare.getId());
String replicateCIFSShareACLsStep = workflow.createStepId();
workflow.createStep(null, stepDescription, waitForShare, systemSource.getId(), systemSource.getSystemType(),
getClass(), replicateCIFSShareACLsMethod, null, replicateCIFSShareACLsStep);
}
}
String successMessage = "Failback FileSystem successful for: " + sourceFileShare.getLabel();
workflow.executePlan(completer, successMessage);
} catch (Exception ex) {
s_logger.error("Could not failback filesystems: " + fsURI, ex);
String opName = ResourceOperationTypeEnum.FILE_PROTECTION_ACTION_FAILBACK.getName();
ServiceError serviceError = DeviceControllerException.errors.createFileSharesFailed(
fsURI.toString(), opName, ex);
completer.error(s_dbClient, this._locker, serviceError);
}
}
@Override
public void failoverFileSystem(URI fsURI, StoragePort nfsPort, StoragePort cifsPort, boolean replicateConfiguration, String taskId)
throws ControllerException {
FileWorkflowCompleter completer = new FileWorkflowCompleter(fsURI, taskId);
Workflow workflow = null;
String stepDescription = null;
MirrorFileFailoverTaskCompleter failoverCompleter = null;
try {
FileShare sourceFileShare = s_dbClient.queryObject(FileShare.class, fsURI);
List<String> targetfileUris = new ArrayList<String>();
targetfileUris.addAll(sourceFileShare.getMirrorfsTargets());
FileShare targetFileShare = s_dbClient.queryObject(FileShare.class, URI.create(targetfileUris.get(0)));
StorageSystem systemTarget = s_dbClient.queryObject(StorageSystem.class, targetFileShare.getStorageDevice());
workflow = this._workflowService.getNewWorkflow(this, FAILOVER_FILESYSTEMS_WF_NAME, false, taskId, completer);
// Failover File System to Target
s_logger.info("Generating steps for Failover File System to Target");
String failoverStep = workflow.createStepId();
List<URI> combined = Arrays.asList(sourceFileShare.getId(), targetFileShare.getId());
failoverCompleter = new MirrorFileFailoverTaskCompleter(FileShare.class, combined, failoverStep);
stepDescription = String.format("Failover Source File System %s to Target System.", sourceFileShare.getLabel());
Object[] args = new Object[] { systemTarget.getId(), targetFileShare.getId(), failoverCompleter };
String waitForFailover = _fileDeviceController.createMethod(workflow, null,
FAILOVER_FILE_SYSTEM_METHOD, failoverStep, stepDescription, systemTarget.getId(), args);
// Replicate quota setting
stepDescription = String.format(
"Replicating directory quota settings from source file system : %s to file target system : %s",
sourceFileShare.getId(), targetFileShare.getId());
Workflow.Method replicateDirQuotaSettingsMethod = new Workflow.Method(REPLICATE_FILESYSTEM_DIRECTORY_QUOTA_SETTINGS_METHOD,
systemTarget.getId(), fsURI);
String replicateDirQuotaSettingsStep = workflow.createStepId();
workflow.createStep(null, stepDescription, waitForFailover, systemTarget.getId(),
systemTarget.getSystemType(), getClass(), replicateDirQuotaSettingsMethod, null, replicateDirQuotaSettingsStep);
if (replicateConfiguration) {
Map<String, List<NfsACE>> sourceNFSACL = FileOrchestrationUtils.queryNFSACL(sourceFileShare, s_dbClient);
Map<String, List<NfsACE>> targetNFSACL = FileOrchestrationUtils.queryNFSACL(targetFileShare, s_dbClient);
if (!sourceNFSACL.isEmpty() || !targetNFSACL.isEmpty()) {
stepDescription = String.format("Replicating NFS ACL from source file system : %s to file target system : %s",
sourceFileShare.getId(), targetFileShare.getId());
Workflow.Method replicateNFSACLsMethod = new Workflow.Method(REPLICATE_FILESYSTEM_NFS_ACLS_METHOD,
systemTarget.getId(), fsURI);
String replicateNFSACLsStep = workflow.createStepId();
workflow.createStep(null, stepDescription, waitForFailover, systemTarget.getId(),
systemTarget.getSystemType(), getClass(), replicateNFSACLsMethod, null, replicateNFSACLsStep);
}
SMBShareMap sourceSMBShareMap = sourceFileShare.getSMBFileShares();
SMBShareMap targetSMBShareMap = targetFileShare.getSMBFileShares();
if (sourceSMBShareMap != null || targetSMBShareMap != null) {
// Both source and target share map shouldn't be null
stepDescription = String.format("Replicating CIFS shares from source file system : %s to target file system : %s",
sourceFileShare.getId(), targetFileShare.getId());
Workflow.Method replicateCIFSShareMethod = new Workflow.Method(REPLICATE_FILESYSTEM_CIFS_SHARES_METHOD,
systemTarget.getId(), fsURI, cifsPort);
String replicateCIFSShareStep = workflow.createStepId();
String waitForShare = workflow.createStep(null, stepDescription, waitForFailover, systemTarget.getId(),
systemTarget.getSystemType(), getClass(), replicateCIFSShareMethod, null, replicateCIFSShareStep);
stepDescription = String.format("Replicating CIFS share ACLs from source file system : %s to file target system : %s",
sourceFileShare.getId(), targetFileShare.getId());
Workflow.Method replicateCIFSShareACLsMethod = new Workflow.Method(REPLICATE_FILESYSTEM_CIFS_SHARE_ACLS_METHOD,
systemTarget.getId(), fsURI);
String replicateCIFSShareACLsStep = workflow.createStepId();
workflow.createStep(null, stepDescription, waitForShare, systemTarget.getId(),
systemTarget.getSystemType(), getClass(), replicateCIFSShareACLsMethod, null, replicateCIFSShareACLsStep);
}
// Replicate NFS export and rules to Target Cluster.
FSExportMap sourceNFSExportMap = sourceFileShare.getFsExports();
FSExportMap targetNFSExportMap = targetFileShare.getFsExports();
if (sourceNFSExportMap != null || targetNFSExportMap != null) {
// Both source and target export map shouldn't be null
stepDescription = String.format("Replicating NFS exports from source file system : %s to target file system : %s",
sourceFileShare.getId(), targetFileShare.getId());
Workflow.Method replicateNFSExportMethod = new Workflow.Method(REPLICATE_FILESYSTEM_NFS_EXPORT_METHOD,
systemTarget.getId(), fsURI, nfsPort);
String replicateNFSExportStep = workflow.createStepId();
String waitForExport = workflow.createStep(null, stepDescription, waitForFailover, systemTarget.getId(),
systemTarget.getSystemType(), getClass(), replicateNFSExportMethod, null, replicateNFSExportStep);
stepDescription = String.format("Replicating NFS export rules from source file system : %s to target file system : %s",
sourceFileShare.getId(), targetFileShare.getId());
Workflow.Method replicateNFSExportRulesMethod = new Workflow.Method(REPLICATE_FILESYSTEM_NFS_EXPORT_RULE_METHOD,
systemTarget.getId(), fsURI);
String replicateNFSExportRulesStep = workflow.createStepId();
workflow.createStep(null, stepDescription, waitForExport, systemTarget.getId(), systemTarget.getSystemType(),
getClass(), replicateNFSExportRulesMethod, null, replicateNFSExportRulesStep);
}
}
String successMessage = "Failover FileSystem successful for: " + sourceFileShare.getLabel();
workflow.executePlan(completer, successMessage);
} catch (Exception ex) {
s_logger.error("Could not failover filesystems: " + fsURI, ex);
String opName = ResourceOperationTypeEnum.FILE_PROTECTION_ACTION_FAILOVER.getName();
ServiceError serviceError = DeviceControllerException.errors.createFileSharesFailed(
fsURI.toString(), opName, ex);
completer.error(s_dbClient, this._locker, serviceError);
}
}
/**
* Child workflow for replicating source file system CIFS shares to target.
*
* @param systemTarget
* - URI of target StorageSystem where source CIFS shares has to be replicated.
* @param fsURI
* -URI of the source FileSystem
* @param cifsPort
* -StoragePort, CIFS port of target File System where new shares has to be created.
* @param taskId
*/
public void addStepsToReplicateCIFSShares(URI systemTarget, URI fsURI, StoragePort cifsPort, String taskId) {
s_logger.info("Generating steps for Replicating CIFS shares to Target Cluster");
FileWorkflowCompleter completer = new FileWorkflowCompleter(fsURI, taskId);
Workflow workflow = null;
FileShare targetFileShare = null;
try {
FileShare sourceFileShare = s_dbClient.queryObject(FileShare.class, fsURI);
if (sourceFileShare.getPersonality().equals(PersonalityTypes.SOURCE.name())) {
List<String> targetfileUris = new ArrayList<String>();
targetfileUris.addAll(sourceFileShare.getMirrorfsTargets());
targetFileShare = s_dbClient.queryObject(FileShare.class, URI.create(targetfileUris.get(0)));
} else {
targetFileShare = s_dbClient.queryObject(FileShare.class, sourceFileShare.getParentFileShare());
}
workflow = this._workflowService.getNewWorkflow(this, REPLICATE_CIFS_SHARES_TO_TARGET_WF_NAME, false, taskId, completer);
SMBShareMap sourceSMBShareMap = sourceFileShare.getSMBFileShares();
SMBShareMap targetSMBShareMap = targetFileShare.getSMBFileShares();
if (sourceSMBShareMap == null && targetSMBShareMap != null) {
// source file system don't have any CIFS share but target do have share.
List<SMBFileShare> targetSMBShares = new ArrayList<SMBFileShare>(targetSMBShareMap.values());
deleteCIFSShareFromTarget(workflow, systemTarget, targetSMBShares, targetFileShare);
} else if (targetSMBShareMap == null && sourceSMBShareMap != null) {
// target file system don't have any CIFS share but source do have share
List<SMBFileShare> sourceSMBShares = new ArrayList<SMBFileShare>(sourceSMBShareMap.values());
createCIFSShareOnTarget(workflow, systemTarget, sourceSMBShares, cifsPort, targetFileShare, sourceFileShare);
} else if (targetSMBShareMap != null && sourceSMBShareMap != null) {
// both source and target file system do have some shares..
List<SMBFileShare> targetSMBSharestoDelete = new ArrayList<SMBFileShare>();
List<SMBFileShare> targetSMBSharestoCreate = new ArrayList<SMBFileShare>();
for (String sourceSMBSharesName : sourceSMBShareMap.keySet()) {
if (targetSMBShareMap.get(sourceSMBSharesName) == null) {
targetSMBSharestoCreate.add(sourceSMBShareMap.get(sourceSMBSharesName));
}
}
for (String targetSMBSharesName : targetSMBShareMap.keySet()) {
if (sourceSMBShareMap.get(targetSMBSharesName) == null) {
targetSMBSharestoDelete.add(targetSMBShareMap.get(targetSMBSharesName));
}
}
if (!targetSMBSharestoCreate.isEmpty()) {
createCIFSShareOnTarget(workflow, systemTarget, targetSMBSharestoCreate, cifsPort, targetFileShare, sourceFileShare);
}
if (!targetSMBSharestoDelete.isEmpty()) {
deleteCIFSShareFromTarget(workflow, systemTarget, targetSMBSharestoDelete, targetFileShare);
}
}
String successMessage = String.format(
"Replicating source File System : %s, CIFS Shares to Target System finished successfully", sourceFileShare.getLabel());
workflow.executePlan(completer, successMessage);
} catch (Exception ex) {
s_logger.error("Could not replicate source filesystem CIFS shares: " + fsURI, ex);
String opName = ResourceOperationTypeEnum.FILE_PROTECTION_ACTION_FAILOVER.getName();
ServiceError serviceError = DeviceControllerException.errors.createFileSharesFailed(
fsURI.toString(), opName, ex);
completer.error(s_dbClient, this._locker, serviceError);
}
}
/**
* Child workflow for replicating source file system CIFS ACLs to target system.
*
* @param systemTarget
* - URI of target StorageSystem where source CIFS shares has to be replicated.
* @param fsURI
* -URI of the source FileSystem
* @param taskId
*/
public void addStepsToReplicateCIFSShareACLs(URI systemTarget, URI fsURI, String taskId) {
s_logger.info("Generating steps for Replicating CIFS share ACLs to Target Cluster");
CifsShareACLUpdateParams params;
FileWorkflowCompleter completer = new FileWorkflowCompleter(fsURI, taskId);
FileShare targetFileShare = null;
Workflow workflow = null;
try {
FileShare sourceFileShare = s_dbClient.queryObject(FileShare.class, fsURI);
if (sourceFileShare.getPersonality().equals(PersonalityTypes.SOURCE.name())) {
List<String> targetfileUris = new ArrayList<String>();
targetfileUris.addAll(sourceFileShare.getMirrorfsTargets());
targetFileShare = s_dbClient.queryObject(FileShare.class, URI.create(targetfileUris.get(0)));
} else {
targetFileShare = s_dbClient.queryObject(FileShare.class, sourceFileShare.getParentFileShare());
}
workflow = this._workflowService.getNewWorkflow(this, REPLICATE_CIFS_SHARE_ACLS_TO_TARGET_WF_NAME, false, taskId, completer);
SMBShareMap sourceSMBShareMap = sourceFileShare.getSMBFileShares();
if (sourceSMBShareMap != null) {
List<SMBFileShare> sourceSMBShares = new ArrayList<SMBFileShare>(sourceSMBShareMap.values());
for (SMBFileShare sourceSMBShare : sourceSMBShares) {
List<ShareACL> sourceShareACLs = FileOrchestrationUtils.queryShareACLs(sourceSMBShare.getName(),
sourceFileShare.getId(), s_dbClient);
List<ShareACL> targetShareACLs = FileOrchestrationUtils.queryShareACLs(sourceSMBShare.getName(),
targetFileShare.getId(), s_dbClient);
if (!sourceShareACLs.isEmpty() && targetShareACLs.isEmpty()) {
// target share doesn't have any ACLs but corresponding share on source does have ACL
params = new CifsShareACLUpdateParams();
ShareACLs shareACLs = new ShareACLs();
shareACLs.setShareACLs(sourceShareACLs);
params.setAclsToAdd(shareACLs);
updateCIFSShareACLOnTarget(workflow, systemTarget, targetFileShare, sourceSMBShare, params);
} else if (!targetShareACLs.isEmpty() && sourceShareACLs.isEmpty()) {
// source share doesn't have any ACLs but corresponding share on target does have ACL
params = new CifsShareACLUpdateParams();
ShareACLs shareACLs = new ShareACLs();
shareACLs.setShareACLs(targetShareACLs);
// TO FIX COP-26361 DU case
// params.setAclsToDelete(shareACLs);
updateCIFSShareACLOnTarget(workflow, systemTarget, targetFileShare, sourceSMBShare, params);
} else if (!targetShareACLs.isEmpty() && !sourceShareACLs.isEmpty()) {
// both source and target share have some ACL
List<ShareACL> shareACLsToAdd = new ArrayList<ShareACL>();
List<ShareACL> shareACLsToDelete = new ArrayList<ShareACL>();
List<ShareACL> shareACLsToModify = new ArrayList<ShareACL>();
HashMap<String, ShareACL> sourceShareACLMap = FileOrchestrationUtils.getShareACLMap(sourceShareACLs);
HashMap<String, ShareACL> targetShareACLMap = FileOrchestrationUtils.getShareACLMap(targetShareACLs);
// ACLs To Add
for (String sourceACLName : sourceShareACLMap.keySet()) {
if (targetShareACLMap.get(sourceACLName) == null) {
ShareACL shareACL = sourceShareACLMap.get(sourceACLName);
shareACL.setFileSystemId(targetFileShare.getId());
shareACLsToAdd.add(shareACL);
}
}
// ACLs To Delete
for (String targetACLName : targetShareACLMap.keySet()) {
if (sourceShareACLMap.get(targetACLName) == null) {
shareACLsToDelete.add(targetShareACLMap.get(targetACLName));
}
}
// ACLs to Modify
targetShareACLs.removeAll(shareACLsToDelete);
sourceShareACLs.removeAll(shareACLsToAdd);
sourceShareACLMap = FileOrchestrationUtils.getShareACLMap(sourceShareACLs);
targetShareACLMap = FileOrchestrationUtils.getShareACLMap(targetShareACLs);
for (String sourceACLName : sourceShareACLMap.keySet()) {
if (targetShareACLMap.get(sourceACLName) != null && !targetShareACLMap.get(sourceACLName).getPermission()
.equals(sourceShareACLMap.get(sourceACLName).getPermission())) {
ShareACL shareACL = targetShareACLMap.get(sourceACLName);
shareACL.setPermission(sourceShareACLMap.get(sourceACLName).getPermission());
shareACLsToModify.add(shareACL);
}
}
params = new CifsShareACLUpdateParams();
if (!shareACLsToAdd.isEmpty()) {
ShareACLs addShareACLs = new ShareACLs();
addShareACLs.setShareACLs(shareACLsToAdd);
params.setAclsToAdd(addShareACLs);
}
if (!shareACLsToDelete.isEmpty()) {
ShareACLs deleteShareACLs = new ShareACLs();
deleteShareACLs.setShareACLs(shareACLsToDelete);
// TO FIX COP-26361 DU case
// params.setAclsToDelete(deleteShareACLs);
}
if (!shareACLsToModify.isEmpty()) {
ShareACLs modifyShareACLs = new ShareACLs();
modifyShareACLs.setShareACLs(shareACLsToModify);
params.setAclsToModify(modifyShareACLs);
}
if (params.retrieveAllACLs() != null && !params.retrieveAllACLs().isEmpty()) {
updateCIFSShareACLOnTarget(workflow, systemTarget, targetFileShare, sourceSMBShare, params);
}
}
}
}
String successMessage = String.format(
"Replicating source File System : %s, CIFS Shares ACLs to Target System finished successfully",
sourceFileShare.getLabel());
workflow.executePlan(completer, successMessage);
} catch (Exception ex) {
s_logger.error("Could not replicate source filesystem CIFS shares ACLs : " + fsURI, ex);
String opName = ResourceOperationTypeEnum.FILE_PROTECTION_ACTION_FAILOVER.getName();
ServiceError serviceError = DeviceControllerException.errors.updateFileShareCIFSACLsFailed(
fsURI.toString(), opName, ex);
completer.error(s_dbClient, this._locker, serviceError);
}
}
/**
* Child workflow for replicating source file system NFS export to target.
*
* @param systemTarget
* - URI of target StorageSystem where source NFS shares has to be replicated.
* @param fsURI
* -URI of the source FileSystem
* @param nfsPort
* -StoragePort, NFS port of target File System where new export has to be created.
* @param taskId
*/
public void addStepsToReplicateNFSExports(URI systemTarget, URI fsURI, StoragePort nfsPort, String taskId) {
s_logger.info("Generating steps for Replicating NFS exports to Target Cluster");
FileWorkflowCompleter completer = new FileWorkflowCompleter(fsURI, taskId);
Workflow workflow = null;
FileShare targetFileShare = null;
try {
FileShare sourceFileShare = s_dbClient.queryObject(FileShare.class, fsURI);
if (sourceFileShare.getPersonality().equals(PersonalityTypes.SOURCE.name())) {
List<String> targetfileUris = new ArrayList<String>();
targetfileUris.addAll(sourceFileShare.getMirrorfsTargets());
targetFileShare = s_dbClient.queryObject(FileShare.class, URI.create(targetfileUris.get(0)));
} else {
targetFileShare = s_dbClient.queryObject(FileShare.class, sourceFileShare.getParentFileShare());
}
workflow = this._workflowService.getNewWorkflow(this, REPLICATE_NFS_EXPORT_TO_TARGET_WF_NAME, false, taskId, completer);
FSExportMap sourceNFSExportMap = sourceFileShare.getFsExports();
FSExportMap targetNFSExportMap = targetFileShare.getFsExports();
if (targetNFSExportMap == null && sourceNFSExportMap != null) {
// No export on target i.e create all source export on target
List<FileExport> sourceNFSExports = new ArrayList<FileExport>(sourceNFSExportMap.values());
createNFSExportOnTarget(workflow, systemTarget, sourceNFSExports, nfsPort, targetFileShare, sourceFileShare);
} else if (sourceNFSExportMap != null && targetNFSExportMap != null) {
// both source and target have some exports
List<FileExport> sourceNFSExports = new ArrayList<FileExport>(sourceNFSExportMap.values());
List<FileExport> targetNFSExports = new ArrayList<FileExport>(targetNFSExportMap.values());
List<FileExport> targetNFSExportstoCreate = new ArrayList<FileExport>();
// Creating new map since FSExportMap key contains path+sec+user
HashMap<String, FileExport> sourceFileExportMap = FileOrchestrationUtils.getFileExportMap(sourceNFSExports);
HashMap<String, FileExport> targetFileExportMap = FileOrchestrationUtils.getFileExportMap(targetNFSExports);
String waitFor = null;
// Check for export to create on target
for (String exportPath : sourceFileExportMap.keySet()) {
if (exportPath.equals(sourceFileShare.getPath())) {
if (targetFileExportMap.get(targetFileShare.getPath()) == null) {
targetNFSExportstoCreate.add(sourceFileExportMap.get(exportPath));
}
} else {
ArrayList<String> subdirName = new ArrayList<String>();
subdirName.add(exportPath.split(sourceFileShare.getPath())[1]);
if (targetFileExportMap.get(targetFileShare.getPath() + subdirName.get(0)) == null) {
targetNFSExportstoCreate.add(sourceFileExportMap.get(exportPath));
}
}
}
if (!targetNFSExportstoCreate.isEmpty()) {
waitFor = createNFSExportOnTarget(workflow, systemTarget, targetNFSExportstoCreate, nfsPort, targetFileShare,
sourceFileShare);
}
// Check for export to delete on target
for (String exportPath : targetFileExportMap.keySet()) {
String stepDescription = String.format("deleting NFS export : %s", exportPath);
String exportdeletionStep = workflow.createStepId();
if (exportPath.equals(targetFileShare.getPath())) {
if (sourceFileExportMap.get(sourceFileShare.getPath()) == null) {
Object[] args = new Object[] { systemTarget, targetFileShare.getId(), false, null };
waitFor = _fileDeviceController.createMethod(workflow, waitFor, DELETE_FILESYSTEM_EXPORT_METHOD,
exportdeletionStep, stepDescription, systemTarget, args);
}
} else {
ArrayList<String> subdirName = new ArrayList<String>();
subdirName.add(exportPath.split(targetFileShare.getPath())[1]);
if (sourceFileExportMap.get(sourceFileShare.getPath() + subdirName.get(0)) == null) {
Object[] args = new Object[] { systemTarget, targetFileShare.getId(), false, subdirName.get(0).substring(1) };
waitFor = _fileDeviceController.createMethod(workflow, waitFor, DELETE_FILESYSTEM_EXPORT_METHOD,
exportdeletionStep, stepDescription, systemTarget, args);
}
}
}
}
String successMessage = String.format(
"Replicating source File System : %s NFS Exports to Target System finished successfully", sourceFileShare.getId());
workflow.executePlan(completer, successMessage);
} catch (Exception ex) {
s_logger.error("Could not replicate source filesystem NFS Exports : " + fsURI, ex);
String opName = ResourceOperationTypeEnum.FILE_PROTECTION_ACTION_FAILOVER.getName();
ServiceError serviceError = DeviceControllerException.errors.updateFileShareExportRulesFailed(
fsURI.toString(), opName, ex);
completer.error(s_dbClient, this._locker, serviceError);
}
}
/**
* Child workflow for replicating source file system NFS export Rules to target.
*
* @param systemTarget
* - URI of target StorageSystem where source NFS shares has to be replicated.
* @param fsURI
* -URI of the source FileSystem
* @param taskId
*/
public void addStepsToReplicateNFSExportRules(URI systemTarget, URI fsURI, String taskId) {
s_logger.info("Generating steps for Replicating NFS export rules to Target Cluster");
FileWorkflowCompleter completer = new FileWorkflowCompleter(fsURI, taskId);
Workflow workflow = null;
FileShare targetFileShare = null;
try {
FileShare sourceFileShare = s_dbClient.queryObject(FileShare.class, fsURI);
if (sourceFileShare.getPersonality().equals(PersonalityTypes.SOURCE.name())) {
List<String> targetfileUris = new ArrayList<String>();
targetfileUris.addAll(sourceFileShare.getMirrorfsTargets());
targetFileShare = s_dbClient.queryObject(FileShare.class, URI.create(targetfileUris.get(0)));
} else {
targetFileShare = s_dbClient.queryObject(FileShare.class, sourceFileShare.getParentFileShare());
}
workflow = this._workflowService.getNewWorkflow(this, REPLICATE_NFS_EXPORT_RULES_TO_TARGET_WF_NAME, false, taskId, completer);
FSExportMap sourceFSExportMap = sourceFileShare.getFsExports();
FSExportMap targetFSExportMap = targetFileShare.getFsExports();
if (sourceFSExportMap == null && targetFSExportMap != null) {
// There are no export rule on source but there are on target!!
List<ExportRule> exportRulesToDelete;
HashMap<String, List<ExportRule>> targetExportRuleMap = FileOrchestrationUtils.getFSExportRuleMap(targetFileShare,
s_dbClient);
for (String exportPath : targetExportRuleMap.keySet()) {
FileExportUpdateParams params = new FileExportUpdateParams();
if (exportPath.equals(targetFileShare.getPath())) {
// File system export rules....
exportRulesToDelete = targetExportRuleMap.get(targetFileShare.getPath());
} else {
// Sub directory export rules....
String subDir = exportPath.split(targetFileShare.getPath())[1];
exportRulesToDelete = targetExportRuleMap.get(targetFileShare.getPath() + subDir);
params.setSubDir(subDir.substring(1));
}
ExportRules deleteExportRules = new ExportRules();
deleteExportRules.setExportRules(exportRulesToDelete);
params.setExportRulesToDelete(deleteExportRules);
updateFSExportRulesOnTarget(workflow, systemTarget, targetFileShare, exportPath, params);
}
} else if (targetFSExportMap != null && sourceFSExportMap != null) {
// Both source and target have export rules!!
HashMap<String, List<ExportRule>> sourceExportRuleMap = FileOrchestrationUtils.getFSExportRuleMap(sourceFileShare,
s_dbClient);
HashMap<String, List<ExportRule>> targetExportRuleMap = FileOrchestrationUtils.getFSExportRuleMap(targetFileShare,
s_dbClient);
for (String exportPath : sourceExportRuleMap.keySet()) {
FileExportUpdateParams params = new FileExportUpdateParams();
List<ExportRule> exportRulesToAdd = new ArrayList<ExportRule>();
List<ExportRule> exportRulesToDelete = new ArrayList<ExportRule>();
List<ExportRule> exportRulesToModify = new ArrayList<ExportRule>();
List<ExportRule> sourceExportRules;
List<ExportRule> targetExportRules;
HashMap<String, ExportRule> srcExportRuleSecFlvMap;
HashMap<String, ExportRule> trgtExportRuleSecFlvMap;
if (exportPath.equals(sourceFileShare.getPath())) {
// File system export rules....
sourceExportRules = sourceExportRuleMap.get(exportPath);
targetExportRules = targetExportRuleMap.get(targetFileShare.getPath());
} else {
// Sub directory export rules....
sourceExportRules = sourceExportRuleMap.get(exportPath);
String subDir = exportPath.split(sourceFileShare.getPath())[1];
targetExportRules = targetExportRuleMap.get(targetFileShare.getPath() + subDir);
params.setSubDir(subDir.substring(1));
}
if (sourceExportRules != null && targetExportRules != null) {
srcExportRuleSecFlvMap = FileOrchestrationUtils.getExportRuleSecFlvMap(sourceExportRules);
trgtExportRuleSecFlvMap = FileOrchestrationUtils.getExportRuleSecFlvMap(targetExportRules);
FileOrchestrationUtils.checkForExportRuleToAdd(sourceFileShare, targetFileShare, srcExportRuleSecFlvMap,
trgtExportRuleSecFlvMap, exportRulesToAdd);
FileOrchestrationUtils.checkForExportRuleToDelete(srcExportRuleSecFlvMap, trgtExportRuleSecFlvMap,
exportRulesToDelete);
sourceExportRules.removeAll(exportRulesToAdd);
targetExportRules.removeAll(exportRulesToDelete);
srcExportRuleSecFlvMap = FileOrchestrationUtils.getExportRuleSecFlvMap(sourceExportRules);
trgtExportRuleSecFlvMap = FileOrchestrationUtils.getExportRuleSecFlvMap(targetExportRules);
FileOrchestrationUtils.checkForExportRuleToModify(srcExportRuleSecFlvMap, trgtExportRuleSecFlvMap,
exportRulesToModify);
if (!exportRulesToAdd.isEmpty()) {
ExportRules addExportRules = new ExportRules();
addExportRules.setExportRules(exportRulesToAdd);
params.setExportRulesToAdd(addExportRules);
}
if (!exportRulesToDelete.isEmpty()) {
ExportRules deleteExportRules = new ExportRules();
deleteExportRules.setExportRules(exportRulesToDelete);
params.setExportRulesToDelete(deleteExportRules);
}
if (!exportRulesToModify.isEmpty()) {
ExportRules modifyExportRules = new ExportRules();
modifyExportRules.setExportRules(exportRulesToModify);
params.setExportRulesToModify(modifyExportRules);
}
if (params.retrieveAllExports() != null && !params.retrieveAllExports().isEmpty()) {
updateFSExportRulesOnTarget(workflow, systemTarget, targetFileShare, exportPath, params);
}
}
}
}
String successMessage = String.format(
"Replicating source File System : %s, NFS Exports Rules to Target System finished successfully",
sourceFileShare.getLabel());
workflow.executePlan(completer, successMessage);
} catch (Exception ex) {
s_logger.error("Could not replicate source filesystem NFS Exports Rules : " + fsURI, ex);
String opName = ResourceOperationTypeEnum.FILE_PROTECTION_ACTION_FAILOVER.getName();
ServiceError serviceError = DeviceControllerException.errors.updateFileShareExportRulesFailed(fsURI.toString(), opName, ex);
completer.error(s_dbClient, this._locker, serviceError);
}
}
private static String createNFSExportOnTarget(Workflow workflow, URI systemTarget, List<FileExport> nfsExportsToCreate,
StoragePort nfsPort, FileShare targetFileShare, FileShare sourceFileShare) {
String waitFor = null;
for (FileExport nfsExport : nfsExportsToCreate) {
FileShareExport fileNFSExport = new FileShareExport(nfsExport.getClients(), nfsExport.getSecurityType(),
nfsExport.getPermissions(), nfsExport.getRootUserMapping(),
nfsExport.getProtocol(), nfsPort.getPortName(), nfsPort.getPortNetworkId(), null);
if (!sourceFileShare.getPath().equals(nfsExport.getPath())) {
ArrayList<String> subdirName = new ArrayList<String>();
subdirName.add(nfsExport.getPath().split(sourceFileShare.getPath())[1]);
fileNFSExport.setMountPath(targetFileShare.getMountPath() + subdirName.get(0));
fileNFSExport.setPath(targetFileShare.getMountPath() + subdirName.get(0));
} else {
fileNFSExport.setMountPath(targetFileShare.getMountPath());
fileNFSExport.setPath(targetFileShare.getMountPath());
}
String stepDescription = String.format("creating NFS export : %s", fileNFSExport.getMountPath());
String exportCreationStep = workflow.createStepId();
Object[] args = new Object[] { systemTarget, targetFileShare.getId(), Arrays.asList(fileNFSExport) };
waitFor = _fileDeviceController.createMethod(workflow, waitFor, CREATE_FILESYSTEM_EXPORT_METHOD, exportCreationStep,
stepDescription, systemTarget, args);
}
return waitFor;
}
private static void createCIFSShareOnTarget(Workflow workflow, URI systemTarget, List<SMBFileShare> smbShares, StoragePort cifsPort,
FileShare targetFileShare, FileShare sourceFileShare) {
for (SMBFileShare smbShare : smbShares) {
FileSMBShare fileSMBShare = new FileSMBShare(smbShare);
fileSMBShare.setStoragePortName(cifsPort.getPortName());
fileSMBShare.setStoragePortNetworkId(cifsPort.getPortNetworkId());
if (fileSMBShare.isSubDirPath()) {
fileSMBShare.setPath(targetFileShare.getPath() + fileSMBShare.getPath().split(sourceFileShare.getPath())[1]);
} else {
fileSMBShare.setPath(targetFileShare.getPath());
}
String shareCreationStep = workflow.createStepId();
String stepDescription = String.format("creating CIFS Share : %s, path : %s", fileSMBShare.getName(),
fileSMBShare.getPath());
Object[] args = new Object[] { systemTarget, targetFileShare.getId(), fileSMBShare };
_fileDeviceController.createMethod(workflow, null, CREATE_FILESYSTEM_SHARE_METHOD, shareCreationStep, stepDescription,
systemTarget, args);
}
}
private static void deleteCIFSShareFromTarget(Workflow workflow, URI systemTarget, List<SMBFileShare> smbShares,
FileShare targetFileShare) {
for (SMBFileShare smbShare : smbShares) {
FileSMBShare fileSMBShare = new FileSMBShare(smbShare);
String stepDescription = String.format("deleting CIFS share : %s, path : %s", fileSMBShare.getName(), fileSMBShare.getPath());
String sharedeleteStep = workflow.createStepId();
Object[] args = new Object[] { systemTarget, targetFileShare.getId(), fileSMBShare };
_fileDeviceController.createMethod(workflow, null, DELETE_FILESYSTEM_SHARE_METHOD, sharedeleteStep,
stepDescription, systemTarget, args);
}
}
private static void updateCIFSShareACLOnTarget(Workflow workflow, URI systemTarget, FileShare targetFileShare,
SMBFileShare sourceSMBShare, CifsShareACLUpdateParams params) {
String stepDescription = String.format(
"updating CIFS share : %s, ACLs : %s", sourceSMBShare.getName(), params.toString());
String shareACLUpdateStep = workflow.createStepId();
Object[] args = new Object[] { systemTarget, targetFileShare.getId(), sourceSMBShare.getName(), params };
_fileDeviceController.createMethod(workflow, null, UPDATE_FILESYSTEM_SHARE_ACLS_METHOD, shareACLUpdateStep,
stepDescription, systemTarget, args);
}
private static void updateFSExportRulesOnTarget(Workflow workflow, URI systemTarget, FileShare targetFileShare, String exportPath,
FileExportUpdateParams params) {
String stepDescription = String.format("updating NFS export rules for path : %s, %s", exportPath, params.toString());
String exportRuleUpdateStep = workflow.createStepId();
Object[] args = new Object[] { systemTarget, targetFileShare.getId(), params };
_fileDeviceController.createMethod(workflow, null, UPDATE_FILESYSTEM_EXPORT_RULES_METHOD, exportRuleUpdateStep,
stepDescription, systemTarget, args);
}
private static void updateNFSACLOnTarget(Workflow workflow, URI systemTarget, FileShare targetFileShare,
FileNfsACLUpdateParams params) {
String stepDescription = String.format(
"Updating NFS ACL of file system: %s", targetFileShare.getName(), params.toString());
String updateNFSACLStep = workflow.createStepId();
Object[] args = new Object[] { systemTarget, targetFileShare.getId(), params };
_fileDeviceController.createMethod(workflow, null, UPDATE_FILESYSTEM_NFS_ACL_METHOD, updateNFSACLStep,
stepDescription, systemTarget, args);
}
/**
* Child workflow for replicating source file system NFS ACL to target system.
*
* @param systemTarget
* - URI of target StorageSystem where source CIFS shares has to be replicated.
* @param fsURI
* -URI of the source FileSystem
* @param taskId
*/
public void addStepsToReplicateNFSACLs(URI systemTarget, URI fsURI, String taskId) {
s_logger.info("Generating steps for Replicating NFS ACLs to Target Cluster");
FileNfsACLUpdateParams params = null;
FileWorkflowCompleter completer = new FileWorkflowCompleter(fsURI, taskId);
FileShare targetFileShare = null;
Workflow workflow = null;
try {
FileShare sourceFileShare = s_dbClient.queryObject(FileShare.class, fsURI);
if (sourceFileShare.getPersonality().equals(PersonalityTypes.SOURCE.name())) {
List<String> targetfileUris = new ArrayList<String>();
targetfileUris.addAll(sourceFileShare.getMirrorfsTargets());
targetFileShare = s_dbClient.queryObject(FileShare.class, URI.create(targetfileUris.get(0)));
} else {
targetFileShare = s_dbClient.queryObject(FileShare.class, sourceFileShare.getParentFileShare());
}
workflow = this._workflowService.getNewWorkflow(this, REPLICATE_NFS_ACLS_TO_TARGET_WF_NAME, false, taskId, completer);
Map<String, List<NfsACE>> sourceFSACLMap = FileOrchestrationUtils.queryNFSACL(sourceFileShare, s_dbClient);
Map<String, List<NfsACE>> targetFSACLMap = FileOrchestrationUtils.queryNFSACL(targetFileShare, s_dbClient);
if (!sourceFSACLMap.isEmpty() && targetFSACLMap.isEmpty()) {
// target share doesn't have any ACLs but corresponding share on source does have ACL
s_logger.info("Target NFS doesn't have any ACL but corresponding NFS on source does have ACL.");
for (String fsPath : sourceFSACLMap.keySet()) {
List<NfsACE> aclToAdd = null;
params = FileOrchestrationUtils.getFileNfsACLUpdateParamWithSubDir(fsPath, sourceFileShare);
aclToAdd = sourceFSACLMap.get(fsPath);
params.setAcesToAdd(aclToAdd);
s_logger.info("Invoking updateNFSACL on FS: {}, with {}", targetFileShare.getName(), params);
updateNFSACLOnTarget(workflow, systemTarget, targetFileShare, params);
}
} else if (!targetFSACLMap.isEmpty() && sourceFSACLMap.isEmpty()) {
s_logger.info("Source NFS doesn't have any ACL but corresponding NFS on target has ACL.");
for (String fsPath : targetFSACLMap.keySet()) {
List<NfsACE> aclToDelete = null;
params = FileOrchestrationUtils.getFileNfsACLUpdateParamWithSubDir(fsPath, targetFileShare);
aclToDelete = targetFSACLMap.get(fsPath);
// TO FIX COP-26361 DU case
// params.setAcesToDelete(aclToDelete);
s_logger.info("Invoking updateNFSACL on FS: {}, with {}", targetFileShare.getName(), params);
updateNFSACLOnTarget(workflow, systemTarget, targetFileShare, params);
}
} else if (!sourceFSACLMap.isEmpty() && !targetFSACLMap.isEmpty()) {
// both source and target FS have some ACL
for (String sourceFSACLPath : sourceFSACLMap.keySet()) {
List<NfsACE> aclToAdd = new ArrayList<NfsACE>();
List<NfsACE> aclToDelete = new ArrayList<NfsACE>();
List<NfsACE> aclToModify = new ArrayList<NfsACE>();
// Segregate source and target NFS ACL
params = FileOrchestrationUtils.getFileNfsACLUpdateParamWithSubDir(sourceFSACLPath, sourceFileShare);
List<NfsACE> sourceNFSACL = sourceFSACLMap.get(sourceFSACLPath);
if (sourceNFSACL == null) {
sourceNFSACL = new ArrayList<NfsACE>();
}
String subDir = params.getSubDir();
String targetFSACLPath = targetFileShare.getPath();
if (subDir != null) {
targetFSACLPath += "/" + subDir;
}
List<NfsACE> targetNFSACL = targetFSACLMap.get(targetFSACLPath);
if (targetNFSACL == null) {
targetNFSACL = new ArrayList<NfsACE>();
}
HashMap<String, NfsACE> sourceUserToNFSACLMap = FileOrchestrationUtils
.getUserToNFSACEMap(sourceNFSACL);
HashMap<String, NfsACE> targetUserToNFSACLMap = FileOrchestrationUtils
.getUserToNFSACEMap(targetNFSACL);
// ACL To Add
for (String sourceACEUser : sourceUserToNFSACLMap.keySet()) {
if (targetUserToNFSACLMap.get(sourceACEUser) == null) {
NfsACE nfsACE = sourceUserToNFSACLMap.get(sourceACEUser);
aclToAdd.add(nfsACE);
}
}
// ACL To Delete
for (String targetACEUser : targetUserToNFSACLMap.keySet()) {
if (sourceUserToNFSACLMap.get(targetACEUser) == null) {
aclToDelete.add(targetUserToNFSACLMap.get(targetACEUser));
}
}
// ACL to Modify
targetNFSACL.removeAll(aclToDelete);
sourceNFSACL.removeAll(aclToAdd);
sourceUserToNFSACLMap = FileOrchestrationUtils.getUserToNFSACEMap(sourceNFSACL);
targetUserToNFSACLMap = FileOrchestrationUtils.getUserToNFSACEMap(targetNFSACL);
for (String sourceACEUser : sourceUserToNFSACLMap.keySet()) {
NfsACE targetACE = targetUserToNFSACLMap.get(sourceACEUser);
NfsACE sourceACE = sourceUserToNFSACLMap.get(sourceACEUser);
if (targetACE != null &&
(!targetACE.getPermissions().equals(sourceACE.getPermissions()) ||
!targetACE.getPermissionType().equals(sourceACE.getPermissionType()))) {
targetACE.setPermissions(sourceACE.getPermissions());
targetACE.setPermissionType(sourceACE.getPermissionType());
aclToModify.add(targetACE);
}
}
if (!aclToAdd.isEmpty()) {
params.setAcesToAdd(aclToAdd);
}
if (!aclToDelete.isEmpty()) {
// TO FIX COP-26361 DU case
// params.setAcesToDelete(aclToDelete);
}
if (!aclToModify.isEmpty()) {
params.setAcesToModify(aclToModify);
}
if (!params.retrieveAllACL().isEmpty()) {
s_logger.info("Invoking updateNFSACL on FS: {}, with {}", targetFileShare.getName(), params);
updateNFSACLOnTarget(workflow, systemTarget, targetFileShare, params);
}
}
}
String successMessage = String.format(
"Replicating source file system : %s, NFS ACL to target file system finished successfully",
sourceFileShare.getLabel());
workflow.executePlan(completer, successMessage);
} catch (Exception ex) {
s_logger.error("Could not replicate source filesystem NFS ACL : " + fsURI, ex);
String opName = ResourceOperationTypeEnum.FILE_PROTECTION_ACTION_FAILOVER.getName();
ServiceError serviceError = DeviceControllerException.errors.updateFileShareNFSACLFailed(
fsURI.toString(), opName, ex);
completer.error(s_dbClient, this._locker, serviceError);
}
}
private static void updateTargetFileSystem(Workflow workflow, URI systemTarget, FileShare targetFileShare) {
String stepDescription = String.format(
"Updating target file system: %s with new directory quota settings.", targetFileShare.getName());
String updateQuotaDirStep = workflow.createStepId();
Object[] args = new Object[] { systemTarget, targetFileShare.getPool(), targetFileShare.getId() };
_fileDeviceController.createMethod(workflow, null, MODIFY_FILESYSTEM_METHOD, updateQuotaDirStep,
stepDescription, systemTarget, args);
}
/**
* Child workflow for replicating source file system directory quota settings to target system.
*
* @param systemTarget
* - URI of target StorageSystem where source quota directory settings have to be replicated.
* @param fsURI
* -URI of the source FileSystem
* @param taskId
*/
public void addStepsToReplicateDirectoryQuotaSettings(URI systemTarget, URI fsURI, String taskId) {
s_logger.info("Generating steps for replicating directory quota settings to target cluster.");
FileWorkflowCompleter completer = new FileWorkflowCompleter(fsURI, taskId);
FileShare targetFileShare = null;
Workflow workflow = null;
try {
FileShare sourceFileShare = s_dbClient.queryObject(FileShare.class, fsURI);
if (sourceFileShare.getPersonality().equals(PersonalityTypes.SOURCE.name())) {
List<String> targetfileUris = new ArrayList<String>();
targetfileUris.addAll(sourceFileShare.getMirrorfsTargets());
targetFileShare = s_dbClient.queryObject(FileShare.class, URI.create(targetfileUris.get(0)));
} else {
targetFileShare = s_dbClient.queryObject(FileShare.class, sourceFileShare.getParentFileShare());
}
targetFileShare.setSoftGracePeriod(sourceFileShare.getSoftGracePeriod());
targetFileShare.setSoftLimit(sourceFileShare.getSoftLimit());
targetFileShare.setNotificationLimit(sourceFileShare.getNotificationLimit());
s_dbClient.updateObject(targetFileShare);
workflow = this._workflowService.getNewWorkflow(this, REPLICATE_QUOTA_DIR_SETTINGS_TO_TARGET_WF_NAME, false, taskId, completer);
updateTargetFileSystem(workflow, systemTarget, targetFileShare);
String successMessage = String.format(
"Replicating source file system : %s, directory quota settings to target file system finished successfully.",
sourceFileShare.getLabel());
workflow.executePlan(completer, successMessage);
} catch (Exception ex) {
s_logger.error("Could not replicate source filesystem directory quota settings: " + fsURI, ex);
String opName = ResourceOperationTypeEnum.FILE_PROTECTION_ACTION_FAILOVER.getName();
ServiceError serviceError = DeviceControllerException.errors.unableToUpdateFileSystem(opName, ex);
completer.error(s_dbClient, this._locker, serviceError);
}
}
public String addStepsForApplyingPolicies(Workflow workflow, String waitFor, List<FileDescriptor> fileDescriptors) {
FileDescriptor sourceDescriptors = FileDescriptor
.filterByType(fileDescriptors, FileDescriptor.Type.FILE_DATA, FileDescriptor.Type.FILE_MIRROR_SOURCE).get(0);
FileShare sourceFS = s_dbClient.queryObject(FileShare.class, sourceDescriptors.getFsURI());
StorageSystem system = s_dbClient.queryObject(StorageSystem.class, sourceFS.getStorageDevice());
// applying policy is only supported by isilon
if (system != null && system.getSystemType().equalsIgnoreCase(Type.isilon.toString())) {
URI nasServer = null;
if (sourceFS.getVirtualNAS() != null) {
nasServer = sourceFS.getVirtualNAS();
} else {
// Get the physical NAS for the storage system!!
PhysicalNAS pNAS = FileOrchestrationUtils.getSystemPhysicalNAS(s_dbClient, system);
if (pNAS != null) {
nasServer = pNAS.getId();
}
}
if (nasServer == null) {
s_logger.error(
String.format("Adding steps to apply policies failed : No Nas server found on system {}", system.getLabel()));
throw DeviceControllerException.exceptions.noNasServerFoundToAddStepsToApplyPolicy(system.getLabel());
}
VirtualPool vpool = s_dbClient.queryObject(VirtualPool.class, sourceFS.getVirtualPool());
List<FilePolicy> fileVpoolPolicies = new ArrayList<FilePolicy>();
waitFor = setVpoolLevelPolicesToCreate(workflow, vpool,
sourceFS.getStorageDevice(),
nasServer, fileVpoolPolicies, waitFor);
if (fileVpoolPolicies != null && !fileVpoolPolicies.isEmpty()) {
for (FilePolicy fileVpoolPolicy : fileVpoolPolicies) {
String stepDescription = String.format("creating file policy : %s at : %s level", fileVpoolPolicy.getId(),
vpool.getLabel());
String applyFilePolicyStep = workflow.createStepId();
Object[] args = new Object[] { sourceFS.getStorageDevice(), sourceFS.getId(), fileVpoolPolicy.getId() };
waitFor = _fileDeviceController.createMethod(workflow, waitFor, APPLY_FILE_POLICY_METHOD, applyFilePolicyStep,
stepDescription, system.getId(), args);
}
}
Project project = s_dbClient.queryObject(Project.class, sourceFS.getProject());
List<FilePolicy> fileProjectPolicies = new ArrayList<FilePolicy>();
waitFor = setAllProjectLevelPolices(workflow, project, vpool,
sourceFS.getStorageDevice(), nasServer, fileProjectPolicies, waitFor);
if (fileProjectPolicies != null && !fileProjectPolicies.isEmpty()) {
for (FilePolicy fileProjectPolicy : fileProjectPolicies) {
String stepDescription = String.format("creating file policy : %s at : %s level", fileProjectPolicy.getId(),
project.getLabel());
String applyFilePolicyStep = workflow.createStepId();
Object[] args = new Object[] { sourceFS.getStorageDevice(), sourceFS.getId(), fileProjectPolicy.getId() };
waitFor = _fileDeviceController.createMethod(workflow, waitFor, APPLY_FILE_POLICY_METHOD, applyFilePolicyStep,
stepDescription, system.getId(), args);
}
}
}
return waitFor;
}
@Override
public void unassignFilePolicy(URI policy, Set<URI> unassignFrom, String taskId) throws InternalException {
FilePolicy filePolicy = s_dbClient.queryObject(FilePolicy.class, policy);
FilePolicyUnAssignWorkflowCompleter completer = new FilePolicyUnAssignWorkflowCompleter(policy, unassignFrom, taskId);
try {
Workflow workflow = _workflowService.getNewWorkflow(this, UNASSIGN_FILE_POLICY_WF_NAME, false, taskId, completer);
completer.setWorkFlowId(workflow.getWorkflowURI());
s_logger.info("Generating steps for unassigning file policy {} from resources", policy);
Set<String> policyResources = filePolicy.getPolicyStorageResources();
if (policyResources != null && !policyResources.isEmpty()) {
for (URI uri : unassignFrom) {
for (String policyResource : policyResources) {
PolicyStorageResource policyStorage = s_dbClient.queryObject(PolicyStorageResource.class,
URI.create(policyResource));
if (policyStorage.getAppliedAt().toString().equals(uri.toString())) {
StorageSystem storageSystem = s_dbClient.queryObject(StorageSystem.class, policyStorage.getStorageSystem());
String stepId = workflow.createStepId();
String stepDes = String.format("unassigning file policy : %s, from resource: %s,", filePolicy.getId(), uri);
Object[] args = new Object[] { storageSystem.getId(), policy, policyStorage.getId() };
_fileDeviceController.createMethod(workflow, null, UNASSIGN_FILE_POLICY_METHOD, stepId, stepDes,
storageSystem.getId(), args);
}
}
}
} else {
s_logger.info("file policy {} is not applied to any storage system", policy);
for (URI uri : unassignFrom) {
filePolicy.removeAssignedResources(uri);
FileOrchestrationUtils.updateUnAssignedResource(filePolicy, uri, s_dbClient);
}
// If no other resources are assigned to replication policy
// Remove the replication topology from the policy
FileOrchestrationUtils.removeTopologyInfo(filePolicy, s_dbClient);
s_dbClient.updateObject(filePolicy);
s_logger.info("Unassigning file policy: {} from resources: {} finished successfully", policy.toString(),
unassignFrom.toString());
}
String successMessage = String.format("unassigning file policy : %s, from resources: %s finsihed successfully,",
filePolicy.getId(), unassignFrom);
workflow.executePlan(completer, successMessage);
} catch (Exception ex) {
s_logger.error(String.format("unassigning file policy : %s, from resource: %s failed,", filePolicy.getId(), unassignFrom), ex);
ServiceError serviceError = DeviceControllerException.errors.unassignFilePolicyFailed(policy.toString(), ex);
completer.error(s_dbClient, _locker, serviceError);
}
}
@Override
public void assignFileSnapshotPolicyToVirtualPools(Map<URI, List<URI>> vpoolToStorageSystemMap, URI filePolicyToAssign, String taskId)
throws InternalException {
FilePolicy filePolicy = s_dbClient.queryObject(FilePolicy.class, filePolicyToAssign);
FilePolicyAssignWorkflowCompleter completer = new FilePolicyAssignWorkflowCompleter(filePolicyToAssign,
vpoolToStorageSystemMap.keySet(), null, taskId);
try {
String waitFor = null;
Workflow workflow = _workflowService.getNewWorkflow(this, ASSIGN_FILE_POLICY_WF_NAME, false, taskId, completer);
completer.setWorkFlowId(workflow.getWorkflowURI());
String usePhysicalNASForProvisioning = customConfigHandler.getComputedCustomConfigValue(
CustomConfigConstants.USE_PHYSICAL_NAS_FOR_PROVISIONING, "isilon", null);
Boolean usePhysicalNAS = Boolean.valueOf(usePhysicalNASForProvisioning);
for (URI vpoolURI : vpoolToStorageSystemMap.keySet()) {
s_logger.info("Generating steps for assigning file policy {} to vpool: {}.", filePolicyToAssign, vpoolURI);
List<URI> storageSystemURIList = vpoolToStorageSystemMap.get(vpoolURI);
if (storageSystemURIList != null && !storageSystemURIList.isEmpty()) {
for (URI storageSystemURI : storageSystemURIList) {
List<URI> vNASURIList = FileOrchestrationUtils
.getVNASServersOfStorageSystemAndVarrayOfVpool(s_dbClient, storageSystemURI, vpoolURI, null);
if (vNASURIList != null && !vNASURIList.isEmpty()) {
for (URI vNASURI : vNASURIList) {
String stepId = workflow.createStepId();
String stepDes = String
.format("Assigning file policy: %s, to vpool: %s on storage system: %s", filePolicy.getId(),
vpoolURI,
storageSystemURI);
Object[] args = new Object[] { storageSystemURI, vNASURI, filePolicyToAssign, vpoolURI };
// Let the all workflow steps be executed
// workflow completer should handle the unsuccessful steps
_fileDeviceController.createMethod(workflow, waitFor,
ASSIGN_FILE_SNAPSHOT_POLICY_TO_VIRTUAL_POOLS_METHOD,
stepId,
stepDes,
storageSystemURI, args);
}
}
StorageSystem storagesystem = s_dbClient.queryObject(StorageSystem.class, storageSystemURI);
if (storagesystem.getSystemType().equals(Type.isilon.toString())) {
if (usePhysicalNAS) {
s_logger.info("Generating step for assigning file policy {} to vpool on physical NAS server: {}.",
filePolicyToAssign, vpoolURI);
String stepId = workflow.createStepId();
String stepDes = String
.format("Assigning file policy: %s, to vpool: %s on storage system: %s", filePolicy.getId(),
vpoolURI,
storageSystemURI);
Object[] args = new Object[] { storageSystemURI, null, filePolicyToAssign, vpoolURI };
// Let the all workflow steps be executed
// workflow completer should handle the unsuccessful steps
_fileDeviceController.createMethod(workflow, waitFor,
ASSIGN_FILE_SNAPSHOT_POLICY_TO_VIRTUAL_POOLS_METHOD,
stepId,
stepDes,
storageSystemURI, args);
}
}
}
} else {
s_logger.info("No storage system(s) present for vpool: {}", vpoolURI);
}
}
String successMessage = String.format("Assigning file policy : %s, to vpool(s) successful.",
filePolicy.getId(), vpoolToStorageSystemMap);
workflow.executePlan(completer, successMessage);
} catch (Exception ex) {
s_logger.error(String.format("Assigning file policy : %s to vpool(s) failed", filePolicy.getId()), ex);
ServiceError serviceError = DeviceControllerException.errors
.assignFilePolicyFailed(filePolicyToAssign.toString(), FilePolicyApplyLevel.vpool.name(), ex);
completer.error(s_dbClient, _locker, serviceError);
}
}
@Override
public void assignFileSnapshotPolicyToProjects(Map<URI, List<URI>> vpoolToStorageSystemMap, List<URI> projectURIs,
URI filePolicyToAssign, String taskId) {
FilePolicy filePolicy = s_dbClient.queryObject(FilePolicy.class, filePolicyToAssign);
String opName = ResourceOperationTypeEnum.ASSIGN_FILE_POLICY.getName();
URI projectVpool = null;
if (vpoolToStorageSystemMap != null && !vpoolToStorageSystemMap.isEmpty()) {
Set<URI> vpoolUris = vpoolToStorageSystemMap.keySet();
// For project assignment, there would be a single vpool!!
projectVpool = vpoolUris.toArray(new URI[vpoolUris.size()])[0];
}
FilePolicyAssignWorkflowCompleter completer = new FilePolicyAssignWorkflowCompleter(filePolicyToAssign, projectURIs, projectVpool,
taskId);
try {
String waitFor = null;
Workflow workflow = _workflowService.getNewWorkflow(this, ASSIGN_FILE_POLICY_WF_NAME, false, taskId, completer);
completer.setWorkFlowId(workflow.getWorkflowURI());
String usePhysicalNASForProvisioning = customConfigHandler.getComputedCustomConfigValue(
CustomConfigConstants.USE_PHYSICAL_NAS_FOR_PROVISIONING, "isilon", null);
Boolean usePhysicalNAS = Boolean.valueOf(usePhysicalNASForProvisioning);
for (URI vpoolURI : vpoolToStorageSystemMap.keySet()) {
s_logger.info("Generating steps for assigning file policy {} to project: {}.", filePolicyToAssign, vpoolURI);
List<URI> storageSystemURIList = vpoolToStorageSystemMap.get(vpoolURI);
if (storageSystemURIList != null && !storageSystemURIList.isEmpty()) {
for (URI storageSystemURI : storageSystemURIList) {
if (projectURIs != null && !projectURIs.isEmpty()) {
for (URI projectURI : projectURIs) {
// Get the eligible nas server for given project from the storage system!!!
List<URI> vNASURIList = FileOrchestrationUtils.getVNASServersOfStorageSystemAndVarrayOfVpool(s_dbClient,
storageSystemURI, vpoolURI, projectURI);
if (vNASURIList != null && !vNASURIList.isEmpty()) {
for (URI vNASURI : vNASURIList) {
String stepId = workflow.createStepId();
String stepDes = String
.format("Assigning file policy: %s, to project: %s on storage system: %s",
filePolicy.getId(),
vpoolURI,
storageSystemURI);
Object[] args = new Object[] { storageSystemURI, vNASURI, filePolicyToAssign, vpoolURI,
projectURI };
// Let the all workflow steps be executed
// workflow completer should handle the unsuccessful steps
_fileDeviceController.createMethod(workflow, waitFor,
ASSIGN_FILE_SNAPSHOT_POLICY_TO_PROJECTS_METHOD,
stepId,
stepDes,
storageSystemURI, args);
}
}
StorageSystem storagesystem = s_dbClient.queryObject(StorageSystem.class, storageSystemURI);
// Create policy, if physical nas is eligible for provisioning!!
if (storagesystem.getSystemType().equals(Type.isilon.toString())) {
if (usePhysicalNAS) {
s_logger.info(
"Generating step for assigning file policy {} to project on physical NAS server: {}.",
filePolicyToAssign, vpoolURI);
String stepId = workflow.createStepId();
String stepDes = String
.format("Assigning file policy: %s, to project: %s on storage system: %s",
filePolicy.getId(),
projectURI,
storageSystemURI);
Object[] args = new Object[] { storageSystemURI, null, filePolicyToAssign, vpoolURI, projectURI };
// Let the all workflow steps be executed
// workflow completer should handle the unsuccessful steps
_fileDeviceController.createMethod(workflow, waitFor,
ASSIGN_FILE_SNAPSHOT_POLICY_TO_PROJECTS_METHOD,
stepId,
stepDes,
storageSystemURI, args);
}
}
}
}
}
} else {
s_logger.info("No storage system(s) present for vpool: {}", vpoolURI);
}
}
String successMessage = String.format("Assigning file policy : %s, to project(s) successful.",
filePolicy.getId(), vpoolToStorageSystemMap);
workflow.executePlan(completer, successMessage);
} catch (Exception ex) {
s_logger.error(String.format("Assigning file policy : %s to vpool(s) failed", filePolicy.getId()), ex);
ServiceError serviceError = DeviceControllerException.errors
.assignFilePolicyFailed(filePolicyToAssign.toString(), FilePolicyApplyLevel.project.name(), ex);
completer.error(s_dbClient, _locker, serviceError);
}
}
@Override
public void updateFileProtectionPolicy(URI policy, FilePolicyUpdateParam param, String taskId) {
FilePolicy filePolicy = s_dbClient.queryObject(FilePolicy.class, policy);
String opName = ResourceOperationTypeEnum.UPDATE_FILE_PROTECTION_POLICY.getName();
FileProtectionPolicyUpdateCompleter completer = new FileProtectionPolicyUpdateCompleter(policy, taskId);
try {
String waitFor = null;
Workflow workflow = _workflowService.getNewWorkflow(this, UPDATE_FILE_POLICY_WF_NAME, false, taskId, completer);
completer.setWorkFlowId(workflow.getWorkflowURI());
// Get the file policy storage resources!!!
List<PolicyStorageResource> policyStorageResources = FileOrchestrationUtils.getFilePolicyStorageResources(s_dbClient,
filePolicy);
if (policyStorageResources != null && !policyStorageResources.isEmpty()) {
s_logger.info("Generating steps for updating file policy {} ", filePolicy.getFilePolicyName());
for (PolicyStorageResource policyStorageRes : policyStorageResources) {
StorageSystem system = s_dbClient.queryObject(StorageSystem.class, policyStorageRes.getStorageSystem());
String stepId = workflow.createStepId();
String stepDes = String
.format("Updating policy on storage system %s, at path: %s",
system.getLabel(),
policyStorageRes.getResourcePath());
Object[] args = new Object[] { policyStorageRes.getStorageSystem(), policy, policyStorageRes.getId(), param };
// Try to update all storage system policies
// Dont use waitFor for next step!!!
_fileDeviceController.createMethod(workflow, waitFor,
UPDATE_STORAGE_SYSTEM_FILE_PROTECTION_POLICY_METHOD,
stepId,
stepDes,
policyStorageRes.getStorageSystem(), args);
}
String successMessage = String.format("Updating file policy {} is successful.", filePolicy.getFilePolicyName());
workflow.executePlan(completer, successMessage);
} else {
s_logger.info("No File Policy Storage resource for policy {} to update", filePolicy.getFilePolicyName());
}
} catch (Exception ex) {
s_logger.error(String.format("Updating file protection policy {} failed", filePolicy.getFilePolicyName()), ex);
ServiceError serviceError = DeviceControllerException.errors
.updateFilePolicyFailed(filePolicy.toString(), ex);
completer.error(s_dbClient, _locker, serviceError);
}
}
private Map<URI, List<FileStorageSystemAssociation>>
getAssociationsPerAssignedResource(List<FileStorageSystemAssociation> associations) {
Map<URI, List<FileStorageSystemAssociation>> resAssociations = new HashMap<URI, List<FileStorageSystemAssociation>>();
for (FileStorageSystemAssociation association : associations) {
List<FileStorageSystemAssociation> recs = resAssociations.get(association.getAppliedAtResource());
if (recs == null) {
recs = new ArrayList<FileStorageSystemAssociation>();
resAssociations.put(association.getAppliedAtResource(), recs);
}
recs.add(association);
}
return resAssociations;
}
private boolean checkRecommendationsWithManySourceToOneTarget(List<FileStorageSystemAssociation> associations) {
StringSet targets = new StringSet();
for (Map.Entry<URI, List<FileStorageSystemAssociation>> entry : getAssociationsPerAssignedResource(associations).entrySet()) {
// Verify more recommnedations are pointing to same target!!!
if (entry.getValue() != null && entry.getValue().size() < 2) {
continue;
}
for (FileStorageSystemAssociation association : entry.getValue()) {
StorageSystem system = s_dbClient.queryObject(StorageSystem.class, association.getSourceSystem());
if (system != null && system.getSystemType().equalsIgnoreCase(Type.isilon.toString()) &&
association.getTargets() != null && !association.getTargets().isEmpty()) {
for (TargetAssociation target : association.getTargets()) {
StringBuffer targetKey = new StringBuffer();
if (target.getStorageSystemURI() != null) {
targetKey.append(target.getStorageSystemURI().toString());
}
if (target.getvNASURI() != null) {
targetKey.append(target.getvNASURI().toString());
}
if (!targetKey.toString().isEmpty()) {
if (targets.contains(targetKey.toString())) {
s_logger.info("Found same taget for different source recommendations");
return true;
}
targets.add(targetKey.toString());
}
}
}
}
}
return false;
}
private void verifyClusterNameInPathForManyToOneRecommendations(List<FileStorageSystemAssociation> associations,
FilePolicy filePolicy) {
if (checkRecommendationsWithManySourceToOneTarget(associations)) {
StringMap scope = new StringMap();
scope.put("systemType", "isilon");
String customConfig = customConfigHandler.getCustomConfigValue(CustomConfigConstants.ISILON_PATH_CUSTOMIZATION,
scope);
if (customConfig != null && !customConfig.isEmpty() && !customConfig.contains("isilon_cluster_name")) {
s_logger.error(
"Conflicting taget path for different sources , Please configure cluster name in directory path defination");
throw DeviceControllerException.exceptions.assignFilePolicyFailed(filePolicy.getFilePolicyName(),
filePolicy.getApplyAt(),
"Conflicting taget path for different sources , Please configure cluster name in directory path defination");
}
}
}
@Override
public void assignFileReplicationPolicyToVirtualPools(List<FileStorageSystemAssociation> associations,
List<URI> vpoolURIs, URI filePolicyToAssign, String taskId) {
FilePolicy filePolicy = s_dbClient.queryObject(FilePolicy.class, filePolicyToAssign);
FilePolicyAssignWorkflowCompleter completer = new FilePolicyAssignWorkflowCompleter(filePolicyToAssign, vpoolURIs, null, taskId);
try {
String waitFor = null;
String stepId = null;
String stepDes = null;
Workflow workflow = _workflowService.getNewWorkflow(this, ASSIGN_FILE_POLICY_WF_NAME, false, taskId, completer);
completer.setWorkFlowId(workflow.getWorkflowURI());
String usePhysicalNASForProvisioning = customConfigHandler.getComputedCustomConfigValue(
CustomConfigConstants.USE_PHYSICAL_NAS_FOR_PROVISIONING, "isilon", null);
Boolean usePhysicalNAS = Boolean.valueOf(usePhysicalNASForProvisioning);
// Verify the associations have many to one storage system relation.
// If so, inform the user to configure cluster name in provisioning path!!
verifyClusterNameInPathForManyToOneRecommendations(associations, filePolicy);
s_logger.info("Generating steps for assigning file replication policy to vpool: {}.", filePolicyToAssign);
for (FileStorageSystemAssociation association : associations) {
StorageSystem sourceStoragesystem = s_dbClient.queryObject(StorageSystem.class, association.getSourceSystem());
URI vpoolURI = association.getAppliedAtResource();
List<TargetAssociation> targetAssociations = association.getTargets();
if (targetAssociations != null && !targetAssociations.isEmpty()) {
for (Iterator<TargetAssociation> iterator = targetAssociations.iterator(); iterator.hasNext();) {
TargetAssociation targetAssociation = iterator.next();
URI targetVNASURI = targetAssociation.getvNASURI();
URI targetStorage = targetAssociation.getStorageSystemURI();
URI targetVArray = targetAssociation.getvArrayURI();
if (targetVNASURI != null && association.getSourceVNAS() != null) {
stepId = workflow.createStepId();
stepDes = String.format("Assigning file policy: %s, to vpool: %s on storage system: %s",
filePolicy.getId(),
vpoolURI, association.getSourceSystem());
Object[] args = new Object[] { association.getSourceSystem(), targetStorage,
association.getSourceVNAS(), targetVArray, targetVNASURI, filePolicyToAssign, vpoolURI };
_fileDeviceController.createMethod(workflow, waitFor,
ASSIGN_FILE_REPLICATION_POLICY_TO_VIRTUAL_POOLS_METHOD,
stepId,
stepDes,
association.getSourceSystem(), args);
} else {
if (sourceStoragesystem.getSystemType().equals(Type.isilon.toString())) {
if (usePhysicalNAS) {
stepId = workflow.createStepId();
stepDes = String.format("Assigning file policy: %s, to vpool: %s on storage system: %s",
filePolicy.getId(),
vpoolURI, association.getSourceSystem());
// Let the all workflow steps be executed
// workflow completer should handle the unsuccessful steps
Object[] args = new Object[] { association.getSourceSystem(), targetStorage,
association.getSourceVNAS(), targetVArray, null, filePolicyToAssign, vpoolURI };
_fileDeviceController.createMethod(workflow, waitFor,
ASSIGN_FILE_REPLICATION_POLICY_TO_VIRTUAL_POOLS_METHOD,
stepId,
stepDes,
association.getSourceSystem(), args);
}
}
}
}
}
}
String successMessage = String.format("Assigning file policy : %s, to vpool(s) successful.",
filePolicy.getId());
workflow.executePlan(completer, successMessage);
} catch (Exception ex) {
// If no other resources are assigned to replication policy
// Remove the replication topology from the policy
FileOrchestrationUtils.removeTopologyInfo(filePolicy, s_dbClient);
s_logger.error(String.format("Assigning file policy : %s to vpool(s) failed", filePolicy.getId()), ex);
ServiceError serviceError = DeviceControllerException.errors
.assignFilePolicyFailed(filePolicyToAssign.toString(), filePolicy.getApplyAt(), ex);
completer.error(s_dbClient, _locker, serviceError);
}
}
@Override
public void assignFileReplicationPolicyToProjects(List<FileStorageSystemAssociation> associations, URI vpoolURI, List<URI> projectURIs,
URI filePolicyToAssign,
String taskId) {
FilePolicy filePolicy = s_dbClient.queryObject(FilePolicy.class, filePolicyToAssign);
FilePolicyAssignWorkflowCompleter completer = new FilePolicyAssignWorkflowCompleter(filePolicyToAssign, projectURIs, vpoolURI,
taskId);
try {
String waitFor = null;
String stepId = null;
String stepDes = null;
Workflow workflow = _workflowService.getNewWorkflow(this, ASSIGN_FILE_POLICY_WF_NAME, false, taskId, completer);
completer.setWorkFlowId(workflow.getWorkflowURI());
String usePhysicalNASForProvisioning = customConfigHandler.getComputedCustomConfigValue(
CustomConfigConstants.USE_PHYSICAL_NAS_FOR_PROVISIONING, "isilon", null);
Boolean usePhysicalNAS = Boolean.valueOf(usePhysicalNASForProvisioning);
// Verify the associations have many to one storage system relation.
// If so, inform the user to configure cluster name in provisioning path!!
verifyClusterNameInPathForManyToOneRecommendations(associations, filePolicy);
s_logger.info("Generating steps for assigning file policy {} to project.", filePolicyToAssign);
for (FileStorageSystemAssociation association : associations) {
StorageSystem sourceStoragesystem = s_dbClient.queryObject(StorageSystem.class, association.getSourceSystem());
URI projectURI = association.getAppliedAtResource();
URI vPoolURI = association.getProjectvPool();
List<TargetAssociation> targetAssociations = association.getTargets();
if (targetAssociations != null && !targetAssociations.isEmpty()) {
for (Iterator<TargetAssociation> iterator = targetAssociations.iterator(); iterator.hasNext();) {
TargetAssociation targetAssociation = iterator.next();
URI targetVNASURI = targetAssociation.getvNASURI();
URI targetStorage = targetAssociation.getStorageSystemURI();
URI targetVArray = targetAssociation.getvArrayURI();
if (targetVNASURI != null && association.getSourceVNAS() != null) {
stepId = workflow.createStepId();
stepDes = String.format("Assigning file policy: %s, to project: %s on storage system: %s",
filePolicy.getId(),
projectURI, association.getSourceSystem());
// Let the all workflow steps be executed
// workflow completer should handle the unsuccessful steps
Object[] args = new Object[] { association.getSourceSystem(), targetStorage,
association.getSourceVNAS(), targetVArray, targetVNASURI, filePolicyToAssign, vPoolURI, projectURI };
_fileDeviceController.createMethod(workflow, waitFor,
ASSIGN_FILE_REPLICATION_POLICY_TO_PROJECTS_METHOD,
stepId,
stepDes,
association.getSourceSystem(), args);
} else {
if (sourceStoragesystem.getSystemType().equals(Type.isilon.toString())) {
if (usePhysicalNAS) {
stepId = workflow.createStepId();
stepDes = String.format("Assigning file policy: %s, to project: %s on storage system: %s",
filePolicy.getId(),
projectURI, association.getSourceSystem());
// Let the all workflow steps be executed
// workflow completer should handle the unsuccessful steps
Object[] args = new Object[] { association.getSourceSystem(), targetStorage,
association.getSourceVNAS(), targetVArray, null, filePolicyToAssign, vPoolURI, projectURI };
_fileDeviceController.createMethod(workflow, waitFor,
ASSIGN_FILE_REPLICATION_POLICY_TO_PROJECTS_METHOD,
stepId,
stepDes,
association.getSourceSystem(), args);
}
}
}
}
}
}
String successMessage = String.format("Assigning file policy : %s, to project(s) successful.",
filePolicy.getId());
workflow.executePlan(completer, successMessage);
} catch (Exception ex) {
// If no other resources are assigned to replication policy
// Remove the replication topology from the policy
FileOrchestrationUtils.removeTopologyInfo(filePolicy, s_dbClient);
s_logger.error(String.format("Assigning file policy : %s to project(s) failed", filePolicy.getId()), ex);
ServiceError serviceError = DeviceControllerException.errors
.assignFilePolicyFailed(filePolicyToAssign.toString(), filePolicy.getApplyAt(), ex);
completer.error(s_dbClient, _locker, serviceError);
}
}
@Override
public void assignFilePolicyToFileSystem(FilePolicy filePolicy, List<FileDescriptor> fileDescriptors,
String taskId) throws ControllerException {
FileShare sourceFS = null;
Workflow workflow = null;
List<URI> fsURIs = FileDescriptor.getFileSystemURIs(fileDescriptors);
FileSystemAssignPolicyWorkflowCompleter completer = new FileSystemAssignPolicyWorkflowCompleter(filePolicy.getId(), fsURIs, taskId);
try {
workflow = _workflowService.getNewWorkflow(this, ASSIGN_FILE_POLICY_TO_FS_WF_NAME, false, taskId);
String waitFor = null;
s_logger.info("Generating steps for creating mirror filesystems...");
for (FileDescriptor fileDescriptor : fileDescriptors) {
if (fileDescriptor.getType().toString().equals(FileDescriptor.Type.FILE_EXISTING_MIRROR_SOURCE.name())
|| fileDescriptor.getType().toString().equals(FileDescriptor.Type.FILE_EXISTING_SOURCE.name())) {
sourceFS = s_dbClient.queryObject(FileShare.class, fileDescriptor.getFsURI());
break;
}
}
// 1. If policy to be applied is of type replication and source file system doesn't have any target,
// then we have to create mirror file system first..
if (filePolicy.getFilePolicyType().equals(FilePolicyType.file_replication.name())) {
waitFor = _fileDeviceController.addStepsForCreateFileSystems(workflow, waitFor, fileDescriptors, taskId);
}
// 2. Apply the file protection policy
String stepDescription = String.format("applying file policy : %s for file system : %s",
filePolicy.getId(), sourceFS.getId());
String applyFilePolicyStep = workflow.createStepId();
Object[] args = new Object[] { sourceFS.getStorageDevice(), sourceFS.getId(), filePolicy.getId() };
_fileDeviceController.createMethod(workflow, waitFor, APPLY_FILE_POLICY_METHOD, applyFilePolicyStep,
stepDescription, sourceFS.getStorageDevice(), args);
// Finish up and execute the plan.
String successMessage = String.format("Assigning file policy : %s, to file system: %s successful.",
filePolicy.getId(), sourceFS.getId());
workflow.executePlan(completer, successMessage);
} catch (Exception ex) {
s_logger.error(String.format("Assigning file policy : %s to file system : %s failed", filePolicy.getId(),
sourceFS.getId()), ex);
ServiceError serviceError = DeviceControllerException.errors.assignFilePolicyFailed(filePolicy.toString(),
FilePolicyApplyLevel.file_system.name(), ex);
completer.error(s_dbClient, _locker, serviceError);
}
}
private static String setVpoolLevelPolicesToCreate(Workflow workflow, VirtualPool vpool, URI storageSystem, URI nasServer,
List<FilePolicy> filePoliciesToCreate, String waitFor) {
StringSet fileVpoolPolicies = vpool.getFilePolicies();
if (fileVpoolPolicies != null && !fileVpoolPolicies.isEmpty()) {
for (String fileVpoolPolicy : fileVpoolPolicies) {
FilePolicy filePolicy = s_dbClient.queryObject(FilePolicy.class, URIUtil.uri(fileVpoolPolicy));
filePoliciesToCreate.add(filePolicy);
StringSet policyStrRes = filePolicy.getPolicyStorageResources();
if (policyStrRes != null && !policyStrRes.isEmpty()) {
for (String policyStrRe : policyStrRes) {
PolicyStorageResource strRes = s_dbClient.queryObject(PolicyStorageResource.class, URIUtil.uri(policyStrRe));
if (strRes.getAppliedAt().toString().equals(vpool.getId().toString())
&& strRes.getStorageSystem().toString().equals(storageSystem.toString())
&& strRes.getNasServer().toString().equalsIgnoreCase(nasServer.toString())) {
s_logger.info("File Policy {} is already exists for vpool {} , storage system {} and nas server {}",
filePolicy.getFilePolicyName(), vpool.getLabel(), storageSystem.toString(), strRes);
/*
* 1. Generate file policy path
* 2. Check if vpool name is part of the policy path
* 3. If not, throw error.
*/
String stepDescription = String.format("Step to check if vpool {} is part of file policy path...",
vpool.getLabel());
String stepId = workflow.createStepId();
Object[] args = new Object[] { storageSystem, URIUtil.uri(fileVpoolPolicy), nasServer, vpool.getId(), null };
waitFor = _fileDeviceController.createMethod(workflow, waitFor,
CHECK_FILE_POLICY_PATH_HAS_RESOURCE_LABEL_METHOD, stepId, stepDescription,
storageSystem,
args);
filePoliciesToCreate.remove(filePolicy);
break;
}
}
}
}
}
return waitFor;
}
private static String setAllProjectLevelPolices(Workflow workflow, Project project, VirtualPool vpool,
URI storageSystem, URI nasServer, List<FilePolicy> filePoliciesToCreate, String waitFor) {
StringSet fileProjectPolicies = project.getFilePolicies();
if (fileProjectPolicies != null && !fileProjectPolicies.isEmpty()) {
for (String fileProjectPolicy : fileProjectPolicies) {
FilePolicy filePolicy = s_dbClient.queryObject(FilePolicy.class, URIUtil.uri(fileProjectPolicy));
if (NullColumnValueGetter.isNullURI(filePolicy.getFilePolicyVpool())
|| !filePolicy.getFilePolicyVpool().toString().equals(vpool.getId().toString())) {
continue;
}
filePoliciesToCreate.add(filePolicy);
StringSet policyStrRes = filePolicy.getPolicyStorageResources();
if (policyStrRes != null && !policyStrRes.isEmpty()) {
for (String policyStrRe : policyStrRes) {
PolicyStorageResource strRes = s_dbClient.queryObject(PolicyStorageResource.class, URIUtil.uri(policyStrRe));
if (strRes != null && strRes.getAppliedAt().toString().equals(project.getId().toString())
&& strRes.getStorageSystem().toString().equals(storageSystem.toString())
&& strRes.getNasServer().toString().equalsIgnoreCase(nasServer.toString())) {
s_logger.info("File Policy {} is already exists for project {} , storage system {} and nas server {}",
filePolicy.getFilePolicyName(), project.getLabel(), storageSystem.toString(), strRes);
/*
* 1. Generate file policy path
* 2. Check if project name is part of the policy path
* 3. If not, throw error.
*/
String stepDescription = String.format("Step to check if vpool {} is part of file policy path...",
vpool.getLabel());
String stepId = workflow.createStepId();
Object[] args = new Object[] { storageSystem, URIUtil.uri(fileProjectPolicy), nasServer, vpool.getId(),
project.getId() };
waitFor = _fileDeviceController.createMethod(workflow, waitFor,
CHECK_FILE_POLICY_PATH_HAS_RESOURCE_LABEL_METHOD, stepId, stepDescription,
storageSystem,
args);
filePoliciesToCreate.remove(filePolicy);
break;
}
}
}
}
}
return waitFor;
}
/**
* Child Workflow for failback
*
* @param systemURI
* @param fsURI source FS URI
* @param taskId
*/
public void doFailBackMirrorSessionWF(URI systemURI, URI fsURI, String taskId) {
TaskCompleter taskCompleter = null;
String stepDescription;
String stepId;
Object[] args;
try {
FileShare sourceFS = s_dbClient.queryObject(FileShare.class, fsURI);
StorageSystem primarysystem = s_dbClient.queryObject(StorageSystem.class, systemURI);
StringSet targets = sourceFS.getMirrorfsTargets();
List<URI> targetFSURI = new ArrayList<>();
for (String target : targets) {
targetFSURI.add(URI.create(target));
}
FileShare targetFS = s_dbClient.queryObject(FileShare.class, targetFSURI.get(0));
StorageSystem secondarySystem = s_dbClient.queryObject(StorageSystem.class, targetFS.getStorageDevice());
taskCompleter = new MirrorFileFailbackTaskCompleter(FileShare.class, sourceFS.getId(), taskId);
Workflow workflow = _workflowService.getNewWorkflow(this,
FAILBACK_FILE_SYSTEM_METHOD, false, taskId, taskCompleter);
s_logger.info("Generating steps for failback to source file share: {} from target file share: {}", fsURI, targetFS.getId());
/*
* Step 1. Creates a mirror replication policy for the secondary cluster i.e Resync-prep on primary cluster , this will disable
* primary cluster replication policy.
*/
stepDescription = String.format("source resync-prep : creating mirror policy on target system: %s", secondarySystem.getId());
stepId = workflow.createStepId();
args = new Object[] { primarysystem.getId(), sourceFS.getId(), "resync" };
String waitFor = _fileDeviceController.createMethod(workflow, null, FILE_REPLICATION_OPERATIONS_METHOD, stepId,
stepDescription, primarysystem.getId(), args);
/*
* Step 2. Start the mirror replication policy manually, this will replicate new data (written during failover) from secondary
* cluster to primary cluster.
*/
stepDescription = String.format("start mirror policy: replicate target file share: %s, data to source file share:%s",
targetFS.getId(), sourceFS.getId());
stepId = workflow.createStepId();
args = new Object[] { secondarySystem.getId(), targetFS.getId(), "start" };
waitFor = _fileDeviceController.createMethod(workflow, waitFor, FILE_REPLICATION_OPERATIONS_METHOD, stepId,
stepDescription, secondarySystem.getId(), args);
/*
* Step 3. Allow Write on Primary Cluster local target after replication from step 2
* i.e Fail over to Primary Cluster
*/
stepDescription = String.format("failover on source file system : allow write on source file share: %s", sourceFS.getId());
stepId = workflow.createStepId();
List<URI> combined = Arrays.asList(sourceFS.getId(), targetFS.getId());
MirrorFileFailoverTaskCompleter failoverCompleter = new MirrorFileFailoverTaskCompleter(FileShare.class, combined, stepId);
args = new Object[] { primarysystem.getId(), sourceFS.getId(), failoverCompleter };
waitFor = _fileDeviceController.createMethod(workflow, waitFor, FAILOVER_FILE_SYSTEM_METHOD, stepId,
stepDescription, primarysystem.getId(), args);
/*
* Step 4. Resync-Prep on secondary cluster , same as step 1 but will be executed on secondary cluster instead of primary
* cluster.
*/
stepDescription = String.format(" target resync-prep : disabling mirror policy on target system: %s", secondarySystem.getId());
stepId = workflow.createStepId();
args = new Object[] { secondarySystem.getId(), targetFS.getId(), "resync" };
_fileDeviceController.createMethod(workflow, waitFor, FILE_REPLICATION_OPERATIONS_METHOD, stepId,
stepDescription, secondarySystem.getId(), args);
String successMsg = String.format("Failback of %s to %s successful", sourceFS.getId(), targetFS.getId());
workflow.executePlan(taskCompleter, successMsg);
} catch (Exception ex) {
s_logger.error("Could not replicate source filesystem CIFS shares: " + fsURI, ex);
String opName = ResourceOperationTypeEnum.FILE_PROTECTION_ACTION_FAILBACK.getName();
ServiceError serviceError = DeviceControllerException.errors.createFileSharesFailed(
fsURI.toString(), opName, ex);
taskCompleter.error(s_dbClient, this._locker, serviceError);
}
}
}