/* * Copyright (c) 2016 EMC Corporation * All Rights Reserved */ package controllers.arrays; import static com.emc.vipr.client.core.util.ResourceUtils.uri; import static util.BourneUtil.getViprClient; import java.net.URI; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import jobs.vipr.TenantsCall; import models.datatable.ScheculePoliciesDataTable; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang.StringUtils; import play.Logger; import play.data.binding.As; import play.data.validation.MaxSize; import play.data.validation.MinSize; import play.data.validation.Required; import play.data.validation.Validation; import play.mvc.Util; import play.mvc.With; import util.MessagesUtils; import util.StringOption; import util.TenantUtils; import util.VirtualPoolUtils; import util.builders.ACLUpdateBuilder; import util.datatable.DataTablesSupport; 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.FilePolicy.FileReplicationType; import com.emc.storageos.model.DataObjectRestRep; import com.emc.storageos.model.NamedRelatedResourceRep; import com.emc.storageos.model.RelatedResourceRep; import com.emc.storageos.model.TaskResourceRep; import com.emc.storageos.model.auth.ACLEntry; import com.emc.storageos.model.file.policy.FilePolicyAssignParam; import com.emc.storageos.model.file.policy.FilePolicyCreateParam; import com.emc.storageos.model.file.policy.FilePolicyCreateResp; import com.emc.storageos.model.file.policy.FilePolicyListRestRep; import com.emc.storageos.model.file.policy.FilePolicyParam; import com.emc.storageos.model.file.policy.FilePolicyProjectAssignParam; import com.emc.storageos.model.file.policy.FilePolicyRestRep; import com.emc.storageos.model.file.policy.FilePolicyRestRep.ReplicationSettingsRestRep; import com.emc.storageos.model.file.policy.FilePolicyRestRep.SnapshotSettingsRestRep; import com.emc.storageos.model.file.policy.FilePolicyScheduleParams; import com.emc.storageos.model.file.policy.FilePolicyUnAssignParam; import com.emc.storageos.model.file.policy.FilePolicyUpdateParam; import com.emc.storageos.model.file.policy.FilePolicyVpoolAssignParam; import com.emc.storageos.model.file.policy.FileReplicationPolicyParam; import com.emc.storageos.model.file.policy.FileReplicationTopologyParam; import com.emc.storageos.model.file.policy.FileReplicationTopologyRestRep; import com.emc.storageos.model.file.policy.FileSnapshotPolicyExpireParam; import com.emc.storageos.model.file.policy.FileSnapshotPolicyParam; import com.emc.storageos.model.project.ProjectRestRep; import com.emc.storageos.model.varray.VirtualArrayRestRep; import com.emc.storageos.model.vpool.FileVirtualPoolProtectionParam; import com.emc.storageos.model.vpool.FileVirtualPoolRestRep; import com.emc.vipr.client.core.ACLResources; import com.emc.vipr.client.core.util.ResourceUtils; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import controllers.Common; import controllers.deadbolt.Restrict; import controllers.deadbolt.Restrictions; import controllers.util.FlashException; import controllers.util.Models; import controllers.util.ViprResourceController; @With(Common.class) @Restrictions({ @Restrict("PROJECT_ADMIN"), @Restrict("TENANT_ADMIN"), @Restrict("SYSTEM_ADMIN"), @Restrict("RESTRICTED_SYSTEM_ADMIN") }) public class FileProtectionPolicies extends ViprResourceController { protected static final String UNKNOWN = "schedule.policies.unknown"; protected static final String vPoolLevelSnapshotPattern = "{Cluster}_{vNas}_{VPool}_{Policy_TemplateName}_%Y-%m-%d-_%H-%M"; public static void list() { ScheculePoliciesDataTable dataTable = new ScheculePoliciesDataTable(); render(dataTable); } @FlashException(value = "list", keep = true) public static void listJson() { FilePolicyListRestRep viprSchedulePolicies = getViprClient().fileProtectionPolicies().listFilePolicies(); List<ScheculePoliciesDataTable.FileProtectionPolicy> scheculePolicies = Lists.newArrayList(); for (NamedRelatedResourceRep policy : viprSchedulePolicies.getFilePolicies()) { scheculePolicies.add(new ScheculePoliciesDataTable.FileProtectionPolicy( getViprClient().fileProtectionPolicies().getFilePolicy(policy.getId()))); } renderJSON(DataTablesSupport.createJSON(scheculePolicies, params)); } public static void details(String id) { FilePolicyRestRep filePolicyRestRep = getViprClient().fileProtectionPolicies().get(uri(id)); if (filePolicyRestRep == null) { renderJSON(""); } renderJSON(filePolicyRestRep); } @FlashException(value = "list", keep = true) public static void create() { SchedulePolicyForm schedulePolicy = new SchedulePolicyForm(); schedulePolicy.tenantId = Models.currentAdminTenant(); addRenderArgs(); addDateTimeRenderArgs(); addTenantOptionsArgs(); addRenderApplyPolicysAt(); addNumWorkerThreadsArgs(); render("@edit", schedulePolicy); } @FlashException(value = "list", keep = true) public static void edit(String id) { FilePolicyRestRep filePolicyRestRep = getViprClient().fileProtectionPolicies().get(uri(id)); if (filePolicyRestRep != null) { SchedulePolicyForm schedulePolicy = new SchedulePolicyForm().form(filePolicyRestRep); addRenderArgs(); addDateTimeRenderArgs(); addTenantOptionsArgs(); addRenderApplyPolicysAt(); addNumWorkerThreadsArgs(); render(schedulePolicy); } else { flash.error(MessagesUtils.get(UNKNOWN, id)); list(); } } @FlashException(value = "list", keep = true) public static void assign(String ids) { FilePolicyRestRep filePolicyRestRep = getViprClient().fileProtectionPolicies().get(uri(ids)); if (filePolicyRestRep != null) { AssignPolicyForm assignPolicy = new AssignPolicyForm().form(filePolicyRestRep); addRenderApplyPolicysAt(); addProjectArgs(filePolicyRestRep); addVpoolArgs(filePolicyRestRep); render(assignPolicy); } else { flash.error(MessagesUtils.get(UNKNOWN, ids)); list(); } } @FlashException(value = "list", keep = true) public static void unassign(String ids) { FilePolicyRestRep filePolicyRestRep = getViprClient().fileProtectionPolicies().get(uri(ids)); if (filePolicyRestRep != null) { AssignPolicyForm assignPolicy = new AssignPolicyForm().form(filePolicyRestRep); addRenderApplyPolicysAt(); addAssignedProjectArgs(filePolicyRestRep); addAssignedVPoolArgs(filePolicyRestRep); render(assignPolicy); } else { flash.error(MessagesUtils.get(UNKNOWN, ids)); list(); } } @Util private static void addRenderArgs() { List<StringOption> policyTypeOptions = Lists.newArrayList(); policyTypeOptions.add(new StringOption("file_snapshot", MessagesUtils.get("schedulePolicy.snapshot"))); policyTypeOptions.add(new StringOption("file_replication", MessagesUtils.get("schedulePolicy.replication"))); renderArgs.put("policyTypeOptions", policyTypeOptions); List<StringOption> replicationTypeOptions = Lists.newArrayList(); replicationTypeOptions.add(new StringOption("REMOTE", MessagesUtils.get("schedulePolicy.replicationRemote"))); replicationTypeOptions.add(new StringOption("LOCAL", MessagesUtils.get("schedulePolicy.replicationLocal"))); renderArgs.put("replicationTypeOptions", replicationTypeOptions); List<StringOption> replicationCopyTypeOptions = Lists.newArrayList(); replicationCopyTypeOptions.add(new StringOption("ASYNC", MessagesUtils.get("schedulePolicy.replicationAsync"))); renderArgs.put("replicationCopyTypeOptions", replicationCopyTypeOptions); List<StringOption> policyPriorityOptions = Lists.newArrayList(); policyPriorityOptions.add(new StringOption("Normal", MessagesUtils.get("schedulePolicy.priorityNormal"))); policyPriorityOptions.add(new StringOption("High", MessagesUtils.get("schedulePolicy.priorityHigh"))); renderArgs.put("policyPriorityOptions", policyPriorityOptions); } private static void addDateTimeRenderArgs() { // Days of the Week Map<String, String> daysOfWeek = Maps.newLinkedHashMap(); for (int i = 1; i <= 7; i++) { String num = String.valueOf(i); daysOfWeek.put(MessagesUtils.get("datetime.daysOfWeek." + num).toLowerCase(), MessagesUtils.get("datetime.daysOfWeek." + num)); } renderArgs.put("daysOfWeek", daysOfWeek); // Days of the Month Map<String, String> daysOfMonth = Maps.newLinkedHashMap(); for (int i = 1; i <= 31; i++) { String num = String.valueOf(i); daysOfMonth.put(num, num); } renderArgs.put("daysOfMonth", daysOfMonth); List<StringOption> expirationTypeOptions = Lists.newArrayList(); expirationTypeOptions.add(new StringOption("hours", MessagesUtils.get("schedulePolicy.hours"))); expirationTypeOptions.add(new StringOption("days", MessagesUtils.get("schedulePolicy.days"))); expirationTypeOptions.add(new StringOption("weeks", MessagesUtils.get("schedulePolicy.weeks"))); expirationTypeOptions.add(new StringOption("months", MessagesUtils.get("schedulePolicy.months"))); renderArgs.put("expirationTypeOptions", expirationTypeOptions); String[] hoursOptions = new String[24]; for (int i = 0; i < 24; i++) { String num = ""; if (i < 10) { num = "0" + String.valueOf(i); } else { num = String.valueOf(i); } hoursOptions[i] = num; } String[] minutesOptions = new String[60]; for (int i = 0; i < 60; i++) { String num = ""; if (i < 10) { num = "0" + String.valueOf(i); } else { num = String.valueOf(i); } minutesOptions[i] = num; } renderArgs.put("hours", StringOption.options(hoursOptions)); renderArgs.put("minutes", StringOption.options(minutesOptions)); } private static void addNumWorkerThreadsArgs() { // Number of worker threads!! Map<String, String> numWorkerThreads = Maps.newLinkedHashMap(); for (int i = 3; i <= 10; i++) { String num = String.valueOf(i); numWorkerThreads.put(num, num); } renderArgs.put("numWorkerThreadsOptions", numWorkerThreads); } private static void addTenantOptionsArgs() { if (TenantUtils.canReadAllTenants() && VirtualPoolUtils.canUpdateACLs()) { addDataObjectOptions("tenantOptions", new TenantsCall().asPromise()); } } private static void addRenderApplyPolicysAt() { List<StringOption> applyPolicyAtOptions = Lists.newArrayList(); applyPolicyAtOptions.add(new StringOption(FilePolicyApplyLevel.vpool.name(), MessagesUtils.get("assignPolicy.applyAtVPool"))); applyPolicyAtOptions.add(new StringOption(FilePolicyApplyLevel.project.name(), MessagesUtils.get("assignPolicy.applyAtProject"))); applyPolicyAtOptions.add(new StringOption(FilePolicyApplyLevel.file_system.name(), MessagesUtils.get("assignPolicy.applyAtFs"))); renderArgs.put("applyPolicyOptions", applyPolicyAtOptions); } private static List<StringOption> createResourceOptions(Collection<? extends DataObjectRestRep> values) { List<StringOption> options = Lists.newArrayList(); for (DataObjectRestRep value : values) { options.add(new StringOption(value.getId().toString(), value.getName())); } return options; } private static List<StringOption> getFileVirtualPoolsOptions(FilePolicyRestRep policy) { Collection<FileVirtualPoolRestRep> virtualPools; virtualPools = getViprClient().fileVpools().getAll(); Collection<FileVirtualPoolRestRep> vPools = Lists.newArrayList(); for (FileVirtualPoolRestRep vpool : virtualPools) { // first level filter based on the protection is enabled or not FileVirtualPoolProtectionParam protectParam =vpool.getProtection(); if (protectParam == null) { continue; } // 2nde level filter based on the applied level of policy and the pool if (FilePolicyApplyLevel.project.name().equalsIgnoreCase(policy.getAppliedAt()) && !protectParam.getAllowFilePolicyAtProjectLevel()) { continue; } if (FilePolicyApplyLevel.file_system.name().equalsIgnoreCase(policy.getAppliedAt()) && !protectParam.getAllowFilePolicyAtFSLevel()) { continue; } // now add pool into list if matches protection type with policy if (FilePolicyType.file_snapshot.name().equalsIgnoreCase(policy.getType()) && protectParam.getScheduleSnapshots()) { vPools.add(vpool); } else if (FilePolicyType.file_replication.name().equalsIgnoreCase(policy.getType()) && protectParam.getReplicationSupported()) { vPools.add(vpool); } } return createResourceOptions(vPools); } /** * Get list the pool which is already assigned to a protection policy. * * @param id * @return */ private static List<StringOption> getAssignedResourceOptions(FilePolicyRestRep policy, FilePolicyApplyLevel applyAt) { List<StringOption> options = Lists.newArrayList(); // Filter the vpools based on policy type!!! if (applyAt.name().equalsIgnoreCase(policy.getAppliedAt())) { List<NamedRelatedResourceRep> existingResource = policy.getAssignedResources(); for (NamedRelatedResourceRep value : existingResource) { options.add(new StringOption(value.getId().toString(), value.getName())); } } return options; } /** * Get vpool associated with is assigned to a protection policy at project level. * * @param id * @return list ,currently only one */ private static List<StringOption> getVPoolForAssignedProjectOptions(FilePolicyRestRep policy) { List<StringOption> options = Lists.newArrayList(); // get the vpool for which projects are assigned. if (FilePolicyApplyLevel.project.name().equalsIgnoreCase(policy.getAppliedAt())) { NamedRelatedResourceRep vpool = policy.getVpool(); if (vpool != null) { options.add(new StringOption(vpool.getId().toString(), vpool.getName())); } } return options; } private static List<StringOption> getFileProjectOptions(URI tenantId) { Collection<ProjectRestRep> projects = getViprClient().projects().getByTenant(tenantId); return createResourceOptions(projects); } private static void addProjectArgs(FilePolicyRestRep policy) { renderArgs.put("projectOptions", getFileProjectOptions(uri(Models.currentAdminTenant()))); } private static void addVpoolArgs(FilePolicyRestRep policy) { renderArgs.put("vPoolOptions", getFileVirtualPoolsOptions(policy)); } private static void addAssignedProjectArgs(FilePolicyRestRep policy) { renderArgs.put("projectVpoolOptions", getVPoolForAssignedProjectOptions(policy)); renderArgs.put("projectOptions", getAssignedResourceOptions(policy, FilePolicyApplyLevel.project)); } private static void addAssignedVPoolArgs(FilePolicyRestRep policy) { renderArgs.put("vPoolOptions", getAssignedResourceOptions(policy, FilePolicyApplyLevel.vpool)); renderArgs.put("virtualArrayOptions", getAllVarrays()); } private static List<StringOption> getAllVarrays() { List<StringOption> varrayList = Lists.newArrayList(); List<NamedRelatedResourceRep> allVarrays = getViprClient().varrays().list(); for (NamedRelatedResourceRep varray : allVarrays) { varrayList.add(new StringOption(varray.getId().toString(), varray.getName())); } return varrayList; } public static void getVarraysAssociatedWithPools(String id) { List<VirtualArrayRestRep> varrayList = Lists.newArrayList(); Set<String> varraySet = Sets.newHashSet(); FileVirtualPoolRestRep vpool = getViprClient().fileVpools().get(uri(id)); List<RelatedResourceRep> varrays = vpool.getVirtualArrays(); for (RelatedResourceRep varray : varrays) { varraySet.add(varray.getId().toString()); } for (String varrayId : varraySet) { VirtualArrayRestRep varray = getViprClient().varrays().get(uri(varrayId)); varrayList.add(varray); } renderJSON(varrayList); } /** * This call return the pool or pools which can be associated with policy. * Currently this does not check vpool is assigned to another policy. * As we do not have direct reference of policy in file vpool and looping all * policy and then its assigned resource to figure out it is assign or not * is causing slowness in GUI.Will address this in future release * * @param id */ public static void getVpoolForProtectionPolicy(String id) { Collection<FileVirtualPoolRestRep> vPools = Lists.newArrayList(); FilePolicyRestRep policy = getViprClient().fileProtectionPolicies().get(uri(id)); // check if policy is already assigned then return only assigned pool. if (policy.getAssignedResources() != null && !policy.getAssignedResources().isEmpty()) { NamedRelatedResourceRep vpoolNameRes = null; // get the first vpool and return it. if (policy.getAppliedAt().equalsIgnoreCase(FilePolicyApplyLevel.vpool.name())) { vpoolNameRes = policy.getAssignedResources().get(0); } else if (policy.getAppliedAt().equalsIgnoreCase(FilePolicyApplyLevel.project.name())) { vpoolNameRes = policy.getVpool(); } if (vpoolNameRes != null) { FileVirtualPoolRestRep vpolRestep = getViprClient().fileVpools().get(vpoolNameRes.getId()); vPools.add(vpolRestep); renderJSON(vPools); return; } } List<FileVirtualPoolRestRep> virtualPools = getViprClient().fileVpools().getAll(); for (FileVirtualPoolRestRep vpool : virtualPools) { // first level filter based on the protection is enabled or not FileVirtualPoolProtectionParam protectParam = vpool.getProtection(); if (protectParam == null) { continue; } // 2nde level filter based on the applied level of policy and the pool if (FilePolicyApplyLevel.project.name().equalsIgnoreCase(policy.getAppliedAt()) && !protectParam.getAllowFilePolicyAtProjectLevel()) { continue; } if (FilePolicyApplyLevel.file_system.name().equalsIgnoreCase(policy.getAppliedAt()) && !protectParam.getAllowFilePolicyAtFSLevel()) { continue; } // now add pool into list if matches protection type with policy if (FilePolicyType.file_snapshot.name().equalsIgnoreCase(policy.getType()) && protectParam.getScheduleSnapshots()) { vPools.add(vpool); } else if (FilePolicyType.file_replication.name().equalsIgnoreCase(policy.getType()) && protectParam.getReplicationSupported()) { vPools.add(vpool); } } renderJSON(vPools); } @FlashException(keep = true, referrer = { "create", "edit" }) public static void save(SchedulePolicyForm schedulePolicy) { if (schedulePolicy == null) { Logger.error("No policy parameters passed"); badRequest("No policy parameters passed"); return; } schedulePolicy.validate("schedulePolicy"); if (Validation.hasErrors()) { Common.handleError(); } schedulePolicy.id = params.get("id"); URI policyId = null; if (schedulePolicy.isNew()) { schedulePolicy.tenantId = Models.currentAdminTenant(); FilePolicyCreateParam policyParam = new FilePolicyCreateParam(); updatePolicyParam(schedulePolicy, policyParam, null); policyParam.setPolicyType(schedulePolicy.policyType); if (schedulePolicy.description != null && !schedulePolicy.description.isEmpty()) { policyParam.setPolicyDescription(schedulePolicy.description); } FilePolicyCreateResp createdPolicy = getViprClient().fileProtectionPolicies().create(policyParam); policyId = createdPolicy.getId(); } else { FilePolicyRestRep schedulePolicyRestRep = getViprClient().fileProtectionPolicies().get(uri(schedulePolicy.id)); FilePolicyUpdateParam input = new FilePolicyUpdateParam(); updatePolicyParam(schedulePolicy, input, schedulePolicyRestRep.getType()); getViprClient().fileProtectionPolicies().update(schedulePolicyRestRep.getId(), input); policyId = schedulePolicyRestRep.getId(); } // Update the ACLs com.emc.vipr.client.core.FileProtectionPolicies filePolicies = getViprClient().fileProtectionPolicies(); schedulePolicy.saveTenantACLs(filePolicies, policyId); flash.success(MessagesUtils.get("schedulepolicies.saved", schedulePolicy.policyName)); if (StringUtils.isNotBlank(schedulePolicy.referrerUrl)) { redirect(schedulePolicy.referrerUrl); } else { list(); } } @FlashException(keep = true, referrer = { "assign" }) public static void saveAssignPolicy(AssignPolicyForm assignPolicy) { if (assignPolicy == null) { Logger.error("No assign policy parameters passed"); badRequest("No assign policy parameters passed"); return; } assignPolicy.validate("assignPolicy"); if (Validation.hasErrors()) { Common.handleError(); } assignPolicy.id = params.get("id"); FilePolicyRestRep policy = getViprClient().fileProtectionPolicies().getFilePolicy(uri(assignPolicy.id)); if (policy.getAppliedAt().equalsIgnoreCase(FilePolicyApplyLevel.file_system.name())) { list(); } FilePolicyAssignParam assignPolicyParam = new FilePolicyAssignParam(); if (assignPolicy.topologiesString == null || assignPolicy.topologiesString.equalsIgnoreCase("[]")) { if (policy.getReplicationSettings() != null && policy.getReplicationSettings().getType().equalsIgnoreCase(FileReplicationType.REMOTE.name())) { flash.error("No source and target varry parameters passed", policy.getName()); if (StringUtils.isNotBlank(assignPolicy.referrerUrl)) { redirect(assignPolicy.referrerUrl); } else { list(); } } } try { updateAssignPolicyParam(assignPolicy, assignPolicyParam); TaskResourceRep taskRes = getViprClient().fileProtectionPolicies().assignPolicy(uri(assignPolicy.id), assignPolicyParam); if (isTaskSuccessful(assignPolicy.id, taskRes)) { flash.success(MessagesUtils.get("assignPolicy.request.saved", assignPolicy.policyName)); } } catch (Exception ex) { flash.error(ex.getMessage(), assignPolicy.policyName); } if (StringUtils.isNotBlank(assignPolicy.referrerUrl)) { redirect(assignPolicy.referrerUrl); } else { list(); } } @FlashException(keep = true, referrer = { "unassign" }) public static void saveUnAssignPolicy(AssignPolicyForm assignPolicy) { if (assignPolicy == null) { Logger.error("No Unassign policy parameters passed"); badRequest("No Unassign policy parameters passed"); return; } assignPolicy.validate("UnassignPolicy"); if (Validation.hasErrors()) { Common.handleError(); } assignPolicy.id = params.get("id"); FilePolicyUnAssignParam unAssignPolicyParam = new FilePolicyUnAssignParam(); try { if (updateUnAssignPolicyParam(assignPolicy, unAssignPolicyParam)) { TaskResourceRep taskRes = getViprClient().fileProtectionPolicies().unassignPolicy(uri(assignPolicy.id), unAssignPolicyParam); if (isTaskSuccessful(assignPolicy.id, taskRes)) { flash.success(MessagesUtils.get("unAssignPolicy.request.saved", assignPolicy.policyName)); } } } catch (Exception ex) { flash.error(ex.getMessage(), assignPolicy.policyName); } if (StringUtils.isNotBlank(assignPolicy.referrerUrl)) { redirect(assignPolicy.referrerUrl); } else { list(); } } private static boolean isTaskSuccessful(String policyId, TaskResourceRep taskRes) { try { FilePolicyRestRep resp = getViprClient().fileProtectionPolicies().getTask(uri(policyId), taskRes.getId()).get(); return true; } catch (Exception ex) { flash.error(ex.getMessage(), policyId); return false; } } private static Set<FileReplicationTopologyParam> getFileReplicationTopologyParamSet(List<FileReplicationTopology> replicationTopologies) { Set<FileReplicationTopologyParam> topologyParamSet = new HashSet<FileReplicationTopologyParam>(); for (FileReplicationTopology replicationTopology : replicationTopologies) { FileReplicationTopologyParam param = new FileReplicationTopologyParam(); param.setSourceVArray((uri(replicationTopology.sourceVArray))); Set<URI> targetVArrays = new HashSet<URI>(); targetVArrays.add((uri(replicationTopology.targetVArray))); param.setTargetVArrays(targetVArrays); topologyParamSet.add(param); } return topologyParamSet; } private static FilePolicyParam updatePolicyParam(SchedulePolicyForm schedulePolicy, FilePolicyParam param, String policyType) { param.setPolicyName(schedulePolicy.policyName); if (schedulePolicy.appliedAt != null) { param.setApplyAt(schedulePolicy.appliedAt); } if (schedulePolicy.description != null && !schedulePolicy.description.isEmpty()) { param.setPolicyDescription(schedulePolicy.description); } if (policyType == null) { policyType = schedulePolicy.policyType; } FilePolicyScheduleParams scheduleParam = new FilePolicyScheduleParams(); if (policyType.equalsIgnoreCase("file_snapshot") || policyType.equalsIgnoreCase("file_replication")) { scheduleParam.setScheduleTime(schedulePolicy.scheduleHour + ":" + schedulePolicy.scheduleMin); scheduleParam.setScheduleFrequency(schedulePolicy.frequency); scheduleParam.setScheduleRepeat(schedulePolicy.repeat); if (schedulePolicy.frequency != null && "weeks".equals(schedulePolicy.frequency)) { if (schedulePolicy.scheduleDayOfWeek != null) { scheduleParam.setScheduleDayOfWeek(schedulePolicy.scheduleDayOfWeek); } } else if (schedulePolicy.frequency != null && "months".equals(schedulePolicy.frequency)) { scheduleParam.setScheduleDayOfMonth(schedulePolicy.scheduleDayOfMonth); } } if (policyType.equalsIgnoreCase("file_snapshot")) { FileSnapshotPolicyParam snapshotParam = new FileSnapshotPolicyParam(); snapshotParam.setSnapshotNamePattern(schedulePolicy.snapshotNamePattern); snapshotParam.setPolicySchedule(scheduleParam); FileSnapshotPolicyExpireParam snapExpireParam = new FileSnapshotPolicyExpireParam(); if (schedulePolicy.expiration != null && !"NEVER".equals(schedulePolicy.expiration)) { snapExpireParam.setExpireType(schedulePolicy.expireType); snapExpireParam.setExpireValue(schedulePolicy.expireValue); snapshotParam.setSnapshotExpireParams(snapExpireParam); param.setSnapshotPolicyPrams(snapshotParam); } if ("NEVER".equals(schedulePolicy.expiration)) { snapExpireParam.setExpireType("never"); snapshotParam.setSnapshotExpireParams(snapExpireParam); param.setSnapshotPolicyPrams(snapshotParam); } } else if (policyType.equalsIgnoreCase("file_replication")) { FileReplicationPolicyParam replicationPolicyParams = new FileReplicationPolicyParam(); replicationPolicyParams.setReplicationCopyMode(schedulePolicy.replicationCopyType); replicationPolicyParams.setReplicationType(schedulePolicy.replicationType); replicationPolicyParams.setPolicySchedule(scheduleParam); param.setPriority(schedulePolicy.priority); param.setNumWorkerThreads(schedulePolicy.numWorkerThreads); param.setReplicationPolicyParams(replicationPolicyParams); } return param; } @FlashException("list") public static void delete(@As(",") String[] ids) { if (ids != null && ids.length > 0) { for (String id : ids) { getViprClient().fileProtectionPolicies().delete(uri(id)); } flash.success(MessagesUtils.get("schedulepolicies.deleted")); } list(); } // Suppressing sonar violation for need of accessor methods. Accessor methods are not needed and we use public variables @SuppressWarnings("ClassVariableVisibilityCheck") public static class SchedulePolicyForm { public String id; public String tenantId; @Required @MaxSize(128) @MinSize(2) // Schedule policy name public String policyName; // Schedule policy description public String description; // Type of the policy public String policyType; // File Policy schedule type - daily, weekly, monthly. public String frequency = "days"; // Policy execution repeats on public Long repeat = 1L; // Time when policy run public String scheduleTime; // week day when policy run public String scheduleDayOfWeek; // Day of the month public Long scheduleDayOfMonth; public String snapshotNamePattern = vPoolLevelSnapshotPattern; // Schedule Snapshot expire type e.g hours, days, weeks, months and never public String expireType; // Schedule Snapshot expire after public int expireValue = 2; public String expiration = "EXPIRE_TIME"; // if true policy has assigned resource . public boolean isAssigned; public String referrerUrl; public String scheduleHour; public String scheduleMin; public String appliedAt; public boolean enableTenants; public String tenants; // Replication policy specific fields // Replication type local / remote public String replicationType; // Replication copy type - sync / async / demi-sync public String replicationCopyType; // Replication policy priority normal / high public String priority; public int numWorkerThreads = 3; public SchedulePolicyForm form(FilePolicyRestRep restRep) { this.id = restRep.getId().toString(); // this.tenantId = restRep.getTenant().getId().toString(); this.policyType = restRep.getType(); this.policyName = restRep.getName(); this.frequency = restRep.getSchedule().getFrequency(); if (restRep.getAssignedResources() != null && !restRep.getAssignedResources().isEmpty()) { this.isAssigned = true; } if (restRep.getDescription() != null && !restRep.getDescription().isEmpty()) { this.description = restRep.getDescription(); } if (restRep.getSchedule().getDayOfMonth() != null) { this.scheduleDayOfMonth = restRep.getSchedule().getDayOfMonth(); } if (restRep.getSchedule().getDayOfWeek() != null) { this.scheduleDayOfWeek = restRep.getSchedule().getDayOfWeek(); } if (restRep.getSnapshotSettings() != null) { SnapshotSettingsRestRep snapshotSettings = restRep.getSnapshotSettings(); if (snapshotSettings.getSnapshotNamePattern() != null) { this.snapshotNamePattern = snapshotSettings.getSnapshotNamePattern(); } if (snapshotSettings.getExpiryType() != null) { this.expireType = snapshotSettings.getExpiryType(); } if (snapshotSettings.getExpiryTime() != null) { this.expireValue = snapshotSettings.getExpiryTime().intValue(); } } if (restRep.getSchedule() != null) { this.repeat = restRep.getSchedule().getRepeat(); } if (restRep.getSchedule() != null && restRep.getSchedule().getTime() != null) { this.scheduleTime = restRep.getSchedule().getTime(); String[] hoursMin = this.scheduleTime.split(":"); if (hoursMin.length > 1) { if (restRep.getSchedule().getTime().contains("PM")) { int hour = Integer.valueOf(hoursMin[0]); hour += 12; this.scheduleHour = Integer.toString(hour); } else { this.scheduleHour = hoursMin[0]; } String[] minWithStrings = hoursMin[1].split(" "); if (minWithStrings.length > 0) { this.scheduleMin = minWithStrings[0]; } } } if (this.expireType == null || "never".equals(this.expireType)) { this.expiration = "NEVER"; } else { this.expiration = "EXPIRE_TIME"; } if (restRep.getPriority() != null) { this.priority = restRep.getPriority(); } if (restRep.getNumWorkerThreads() != null && restRep.getNumWorkerThreads() > 0) { this.numWorkerThreads = restRep.getNumWorkerThreads().intValue(); } if (restRep.getAppliedAt() != null) { this.appliedAt = restRep.getAppliedAt(); } // Update replication fileds if (restRep.getReplicationSettings() != null) { ReplicationSettingsRestRep replSetting = restRep.getReplicationSettings(); if (replSetting.getMode() != null) { this.replicationCopyType = replSetting.getMode(); } if (replSetting.getType() != null) { this.replicationType = replSetting.getType(); } } // Get the ACLs com.emc.vipr.client.core.FileProtectionPolicies fileProtectionPolicies = getViprClient().fileProtectionPolicies(); loadTenantACLs(fileProtectionPolicies); return this; } public boolean isNew() { return StringUtils.isBlank(id); } public void validate(String formName) { Validation.valid(formName, this); Validation.required(formName + ".policyName", policyName); if (policyName == null || policyName.isEmpty()) { Validation.addError(formName + ".policyName", MessagesUtils.get("schedulePolicy.policyName.error.required")); } } /** * Loads the tenant ACL information from the provided ACLResources. * * @param resources * the resources from which to load the ACLs. */ protected void loadTenantACLs(ACLResources resources) { this.tenants = ""; URI policyId = ResourceUtils.uri(id); if (policyId != null) { for (ACLEntry acl : resources.getACLs(policyId)) { if (StringUtils.isNotBlank(acl.getTenant())) { this.tenants = acl.getTenant(); break; } } } this.enableTenants = !tenants.isEmpty(); } /** * Saves the tenant ACL information using the provided ACLResources. * * @param resources * the resources on which to save the tenant ACLs. */ protected void saveTenantACLs(ACLResources resources, URI policyId) { // Only allow a user than can read all tenants and update ACLs do this if (TenantUtils.canReadAllTenants() && VirtualPoolUtils.canUpdateACLs()) { if (policyId != null) { Set<String> tenantIds = Sets.newHashSet(); if (isTrue(enableTenants) && (tenants != null)) { tenantIds.add(tenants); } ACLUpdateBuilder builder = new ACLUpdateBuilder(resources.getACLs(policyId)); builder.setTenants(tenantIds); resources.updateACLs(policyId, builder.getACLUpdate()); } } } } private static Boolean updateAssignPolicyParam(AssignPolicyForm assignPolicy, FilePolicyAssignParam param) { Boolean policyAssignment = false; FilePolicyRestRep existingPolicy = getViprClient().fileProtectionPolicies().get(URI.create(assignPolicy.id)); param.setApplyOnTargetSite(assignPolicy.applyOnTargetSite); // Get source and target varrays if (FilePolicyType.file_replication.name().equalsIgnoreCase(existingPolicy.getType())) { List<FileReplicationTopology> replicationTopologies = null; if (assignPolicy.topologiesString != null && !assignPolicy.topologiesString.isEmpty()) { GsonBuilder builder = new GsonBuilder(); Gson gson = builder.create(); replicationTopologies = Arrays .asList((gson.fromJson(assignPolicy.topologiesString, FileReplicationTopology[].class))); } Set<FileReplicationTopologyParam> toploSet = getFileReplicationTopologyParamSet(replicationTopologies); param.setFileReplicationtopologies(toploSet); } if (FilePolicyApplyLevel.project.name().equalsIgnoreCase(existingPolicy.getAppliedAt())) { FilePolicyProjectAssignParam projectAssignParams = new FilePolicyProjectAssignParam(); projectAssignParams.setVpool(uri(assignPolicy.vpool)); List<String> existingProjects = stringRefIds(existingPolicy.getAssignedResources()); List<String> projects = Lists.newArrayList(); if (assignPolicy.projects != null) { projects = assignPolicy.projects; } Set<String> add = Sets.newHashSet(CollectionUtils.subtract(projects, existingProjects)); // Assign new projects Set<URI> assignProjects = new HashSet<URI>(); if (!add.isEmpty()) { for (String project : add) { assignProjects.add(uri(project)); } policyAssignment = true; } projectAssignParams.setAssigntoProjects(assignProjects); param.setProjectAssignParams(projectAssignParams); } else if (FilePolicyApplyLevel.vpool.name().equalsIgnoreCase(existingPolicy.getAppliedAt())) { FilePolicyVpoolAssignParam vpoolAssignParams = new FilePolicyVpoolAssignParam(); List<String> existingvPools = stringRefIds(existingPolicy.getAssignedResources()); List<String> vPools = Lists.newArrayList(); if (assignPolicy.vpool != null) { vPools.add(assignPolicy.vpool); } if (FilePolicyType.file_snapshot.name().equalsIgnoreCase(existingPolicy.getType()) && assignPolicy.virtualPools != null) { vPools.addAll(assignPolicy.virtualPools); } Set<String> add = Sets.newHashSet(CollectionUtils.subtract(vPools, existingvPools)); Set<URI> assignVpools = new HashSet<URI>(); if (!add.isEmpty()) { for (String vpool : add) { assignVpools.add(uri(vpool)); } policyAssignment = true; } vpoolAssignParams.setAssigntoVpools(assignVpools); param.setVpoolAssignParams(vpoolAssignParams); } return policyAssignment; } private static Boolean updateUnAssignPolicyParam(AssignPolicyForm assignPolicy, FilePolicyUnAssignParam param) { Boolean policyUnAssignment = false; FilePolicyRestRep existingPolicy = getViprClient().fileProtectionPolicies().get(URI.create(assignPolicy.id)); if (FilePolicyApplyLevel.project.name().equalsIgnoreCase(existingPolicy.getAppliedAt())) { List<String> projects = Lists.newArrayList(); if (assignPolicy.unassignedProjects != null) { projects = assignPolicy.unassignedProjects; } List<String> remove = projects; // removed projects Set<URI> unAssingRes = new HashSet<URI>(); if (!remove.isEmpty()) { for (String project : remove) { unAssingRes.add(uri(project)); } policyUnAssignment = true; } param.setUnassignfrom(unAssingRes); } else if (FilePolicyApplyLevel.vpool.name().equalsIgnoreCase(existingPolicy.getAppliedAt())) { List<String> vPools = Lists.newArrayList(); if (assignPolicy.unassignedVirtualPools != null) { vPools = assignPolicy.unassignedVirtualPools; } List<String> remove = vPools; // removed vpools Set<URI> unAssingRes = new HashSet<URI>(); if (!remove.isEmpty()) { for (String vpool : remove) { unAssingRes.add(uri(vpool)); } policyUnAssignment = true; } param.setUnassignfrom(unAssingRes); } return policyUnAssignment; } // Suppressing sonar violation for need of accessor methods. Accessor methods are not needed and we use public variables @SuppressWarnings("ClassVariableVisibilityCheck") public static class AssignPolicyForm { public String id; public String tenantId; @Required @MaxSize(128) @MinSize(2) // Schedule policy name public String policyName; // Type of the policy public String policyType; public String vpool; public List<String> projects; public List<String> virtualPools; // Currently same form is used for assigned and unassigned need to separate it in future public List<String> unassignedProjects; public List<String> unassignedVirtualPools; public boolean applyOnTargetSite; // if true policy already has assigned resource . public boolean isAssigned; public String appliedAt; public List<FileReplicationTopology> topologies; public String topologiesString; public String referrerUrl; public String replicationType; public AssignPolicyForm form(FilePolicyRestRep restRep) { this.id = restRep.getId().toString(); // this.tenantId = restRep.getTenant().getId().toString(); this.policyType = restRep.getType(); this.policyName = restRep.getName(); if (restRep.getAssignedResources() != null && !restRep.getAssignedResources().isEmpty()) { // if it does not have already assigned resource this.isAssigned = true; } this.appliedAt = restRep.getAppliedAt(); this.applyOnTargetSite = false; if (restRep.getApplyOnTargetSite() != null) { this.applyOnTargetSite = restRep.getApplyOnTargetSite(); } if (restRep.getReplicationSettings() != null) { this.replicationType = restRep.getReplicationSettings().getType(); List<FileReplicationTopologyRestRep> topologyRestReps = restRep.getReplicationSettings().getReplicationTopologies(); if (topologyRestReps != null && !topologyRestReps.isEmpty()) { List<FileReplicationTopology> replicationTopologies = new ArrayList<FileReplicationTopology>(); for (FileReplicationTopologyRestRep repTopology : topologyRestReps) { FileReplicationTopology fileTopology = new FileReplicationTopology(); if (repTopology.getSourceVArray() != null) { fileTopology.sourceVArray = repTopology.getSourceVArray().toString(); } if (repTopology.getTargetVArrays() != null && !repTopology.getTargetVArrays().isEmpty()) { fileTopology.targetVArray = repTopology.getTargetVArrays().iterator().next().toString(); } replicationTopologies.add(fileTopology); } if (!replicationTopologies.isEmpty()) { this.topologies = replicationTopologies; } } } // Load project applicable fields this.vpool = ResourceUtils.stringId(restRep.getVpool()); if (FilePolicyApplyLevel.project.name().equalsIgnoreCase(restRep.getAppliedAt())) { this.projects = ResourceUtils.stringRefIds(restRep.getAssignedResources()); } else if (FilePolicyApplyLevel.vpool.name().equalsIgnoreCase(restRep.getAppliedAt())) { this.virtualPools = ResourceUtils.stringRefIds(restRep.getAssignedResources()); } return this; } public boolean isNew() { return StringUtils.isBlank(id); } public void validate(String formName) { Validation.valid(formName, this); Validation.required(formName + ".policyName", policyName); if (policyName == null || policyName.isEmpty()) { Validation.addError(formName + ".policyName", MessagesUtils.get("schedulePolicy.policyName.error.required")); } } } }