package com.emc.storageos.db.client.upgrade.callbacks; import java.net.URI; import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.emc.storageos.db.client.DbClient; import com.emc.storageos.db.client.URIUtil; 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.NASServer; import com.emc.storageos.db.client.model.PhysicalNAS; import com.emc.storageos.db.client.model.PolicyStorageResource; import com.emc.storageos.db.client.model.SchedulePolicy; import com.emc.storageos.db.client.model.StorageSystem; import com.emc.storageos.db.client.model.StringSet; import com.emc.storageos.db.client.model.VirtualNAS; import com.emc.storageos.db.client.model.VirtualPool; import com.emc.storageos.db.client.upgrade.BaseCustomMigrationCallback; import com.emc.storageos.svcs.errorhandling.resources.MigrationCallbackException; /** * File snapshot policy to file policy migration * */ public class FileSnapshotPolicyMigration extends BaseCustomMigrationCallback { private static final Logger logger = LoggerFactory.getLogger(FileSnapshotPolicyMigration.class); public static final String FILE_STORAGE_RESOURCE = "FILESTORAGERESOURCE"; public static final String FILE_STORAGE_DEVICE_TYPE = "ISILON"; @Override public void process() throws MigrationCallbackException { logger.info("File snapshot schedule policy to file policy migration START"); DbClient dbClient = getDbClient(); try { List<URI> schedulePolicyURIs = dbClient.queryByType(SchedulePolicy.class, true); Iterator<SchedulePolicy> schedulePolicies = dbClient.queryIterativeObjects(SchedulePolicy.class, schedulePolicyURIs, true); List<FilePolicy> filePolicies = new ArrayList<FilePolicy>(); List<VirtualPool> modifiedVpools = new ArrayList<VirtualPool>(); while (schedulePolicies.hasNext()) { SchedulePolicy schedulePolicy = schedulePolicies.next(); FilePolicy fileSnapshotPolicy = new FilePolicy(); VirtualPool associatedVP = new VirtualPool(); fileSnapshotPolicy.setId(URIUtil.createId(FilePolicy.class)); if (schedulePolicy.getAssignedResources() != null && !schedulePolicy.getAssignedResources().isEmpty()) { for (String assignedResource : schedulePolicy.getAssignedResources()) { logger.info("assigning resource to fileSnapshotPolicy from schedulePolicy : {}", schedulePolicy.getAssignedResources()); fileSnapshotPolicy.addAssignedResources(resourceURI(assignedResource)); logger.info("Assigned resources from fileSnapshotPolicy : {}", fileSnapshotPolicy.getAssignedResources()); } } fileSnapshotPolicy.setFilePolicyDescription( "Policy created from Schedule Policy " + schedulePolicy.getLabel() + " while system upgrade"); String polName = schedulePolicy.getLabel() + "_File_Snapshot_Policy"; fileSnapshotPolicy.setLabel(polName); fileSnapshotPolicy.setFilePolicyName(schedulePolicy.getLabel()); fileSnapshotPolicy.setFilePolicyType(FilePolicyType.file_snapshot.name()); fileSnapshotPolicy.setScheduleFrequency(schedulePolicy.getScheduleFrequency()); fileSnapshotPolicy.setScheduleRepeat(schedulePolicy.getScheduleRepeat()); fileSnapshotPolicy.setScheduleTime(schedulePolicy.getScheduleTime()); fileSnapshotPolicy.setScheduleDayOfWeek(schedulePolicy.getScheduleDayOfWeek()); fileSnapshotPolicy.setScheduleDayOfMonth(schedulePolicy.getScheduleDayOfMonth()); fileSnapshotPolicy.setSnapshotExpireTime(schedulePolicy.getSnapshotExpireTime()); fileSnapshotPolicy.setSnapshotExpireType(schedulePolicy.getSnapshotExpireType()); // snapshot policy apply at file system level fileSnapshotPolicy.setApplyAt(FilePolicyApplyLevel.file_system.name()); if (schedulePolicy.getAssignedResources() != null && !schedulePolicy.getAssignedResources().isEmpty()) { List<URI> fileShareURIs = getAssignedResourcesURIs(schedulePolicy.getAssignedResources()); for (URI fsURI : fileShareURIs) { FileShare fs = dbClient.queryObject(FileShare.class, fsURI); if (!fs.getInactive()) { StorageSystem system = dbClient.queryObject(StorageSystem.class, fs.getStorageDevice()); updatePolicyStorageResouce(system, fileSnapshotPolicy, fs); // Remove the existing schedule policy from fs // add new file policy to fs!! StringSet fsExistingPolicies = fs.getFilePolicies(); if (fsExistingPolicies != null && !fsExistingPolicies.isEmpty()) { Set<String> snapSchedulesToRemove = new HashSet<String>(); for (String existingSnapPolicyId : fsExistingPolicies) { if (URIUtil.isType(URI.create(existingSnapPolicyId), SchedulePolicy.class)) { snapSchedulesToRemove.add(existingSnapPolicyId); } } if (!snapSchedulesToRemove.isEmpty()) { /* * StringSet.removeAll() does not work if the set has only one entry. * Hence the logic below */ if (fsExistingPolicies.size() == 1 && snapSchedulesToRemove.size() == 1) { fsExistingPolicies.clear(); } else { fsExistingPolicies.removeAll(snapSchedulesToRemove); } } } else { fsExistingPolicies = new StringSet(); } fsExistingPolicies.add(fileSnapshotPolicy.getId().toString()); fs.setFilePolicies(fsExistingPolicies); dbClient.updateObject(fs); URI associatedVPId = fs.getVirtualPool(); associatedVP = dbClient.queryObject(VirtualPool.class, associatedVPId); associatedVP.setAllowFilePolicyAtFSLevel(true); modifiedVpools.add(associatedVP); } } } filePolicies.add(fileSnapshotPolicy); } // Update DB if (!filePolicies.isEmpty()) { logger.info("Created {} file snapshot policies", filePolicies.size()); dbClient.createObject(filePolicies); } if (!modifiedVpools.isEmpty()) { logger.info("Modified {} vpools ", modifiedVpools.size()); dbClient.updateObject(modifiedVpools); } } catch (Exception ex) { logger.error("Exception occured while migrating file replication policy for Virtual pools"); logger.error(ex.getMessage(), ex); } } private URI resourceURI(String assignedResource) { URI resURI = URI.create(assignedResource); return resURI; } private List<URI> getAssignedResourcesURIs(StringSet assignedResources) { List<URI> resourceURIs = new ArrayList<URI>(); if (!assignedResources.isEmpty()) { for (String resource : assignedResources) { URI resourceURI = URI.create(resource); resourceURIs.add(resourceURI); } } return resourceURIs; } private String generateNativeGuidForFilePolicyResource(StorageSystem system, String nasServer, String filePolicyType, String path) { return String.format("%s+%s+%s+%s+%s+%s", FILE_STORAGE_DEVICE_TYPE, system.getSerialNumber(), FILE_STORAGE_RESOURCE, nasServer, filePolicyType, path); } private PhysicalNAS getSystemPhysicalNAS(StorageSystem system) { List<URI> nasServers = dbClient.queryByType(PhysicalNAS.class, true); List<PhysicalNAS> phyNasServers = dbClient.queryObject(PhysicalNAS.class, nasServers); for (PhysicalNAS nasServer : phyNasServers) { if (nasServer.getStorageDeviceURI().toString().equalsIgnoreCase(system.getId().toString())) { return nasServer; } } return null; } private void updatePolicyStorageResouce(StorageSystem system, FilePolicy fileSnapshotPolicy, FileShare fs) { logger.info("Creating policy storage resource for storage {} fs {} and policy {} ", system.getLabel(), fs.getLabel(), fileSnapshotPolicy.getFilePolicyName()); PolicyStorageResource policyStorageResource = new PolicyStorageResource(); policyStorageResource.setId(URIUtil.createId(PolicyStorageResource.class)); policyStorageResource.setFilePolicyId(fileSnapshotPolicy.getId()); policyStorageResource.setStorageSystem(system.getId()); policyStorageResource.setPolicyNativeId(fileSnapshotPolicy.getFilePolicyName() + "_" + fs.getName()); policyStorageResource.setAppliedAt(fs.getId()); policyStorageResource.setResourcePath(fs.getNativeId()); NASServer nasServer = null; if (fs.getVirtualNAS() != null) { nasServer = dbClient.queryObject(VirtualNAS.class, fs.getVirtualNAS()); } else { // Get the physical NAS for the storage system!! PhysicalNAS pNAS = getSystemPhysicalNAS(system); if (pNAS != null) { nasServer = pNAS; } } if (nasServer != null) { logger.info("Found NAS server {} ", nasServer.getNasName()); policyStorageResource.setNasServer(nasServer.getId()); policyStorageResource.setNativeGuid(generateNativeGuidForFilePolicyResource(system, nasServer.getNasName(), fileSnapshotPolicy.getFilePolicyType(), fs.getNativeId())); } dbClient.createObject(policyStorageResource); fileSnapshotPolicy.addPolicyStorageResources(policyStorageResource.getId()); fileSnapshotPolicy.addAssignedResources(fs.getId()); logger.info("PolicyStorageResource object created successfully for {} ", system.getLabel() + policyStorageResource.getAppliedAt()); } }