package org.ovirt.engine.ui.uicommonweb.models.configure.scheduling; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; import java.util.Map.Entry; import org.ovirt.engine.core.common.action.VdcActionType; import org.ovirt.engine.core.common.scheduling.ClusterPolicy; import org.ovirt.engine.core.common.scheduling.PolicyUnit; import org.ovirt.engine.core.common.scheduling.PolicyUnitType; import org.ovirt.engine.core.common.scheduling.parameters.ClusterPolicyCRUDParameters; import org.ovirt.engine.core.common.utils.Pair; import org.ovirt.engine.core.compat.Guid; import org.ovirt.engine.ui.frontend.Frontend; import org.ovirt.engine.ui.uicommonweb.UICommand; import org.ovirt.engine.ui.uicommonweb.help.HelpTag; import org.ovirt.engine.ui.uicommonweb.models.EntityModel; import org.ovirt.engine.ui.uicommonweb.models.IModel; import org.ovirt.engine.ui.uicommonweb.models.ListModel; import org.ovirt.engine.ui.uicommonweb.models.Model; import org.ovirt.engine.ui.uicommonweb.models.configure.roles_ui.RoleListModel.CommandType; import org.ovirt.engine.ui.uicommonweb.models.vms.key_value.KeyValueModel; import org.ovirt.engine.ui.uicommonweb.validation.AsciiNameValidation; import org.ovirt.engine.ui.uicommonweb.validation.AsciiOrNoneValidation; import org.ovirt.engine.ui.uicommonweb.validation.IValidation; import org.ovirt.engine.ui.uicommonweb.validation.LengthValidation; import org.ovirt.engine.ui.uicommonweb.validation.NotEmptyValidation; import org.ovirt.engine.ui.uicompat.ConstantsManager; import org.ovirt.engine.ui.uicompat.Event; import org.ovirt.engine.ui.uicompat.EventArgs; import org.ovirt.engine.ui.uicompat.EventDefinition; public class NewClusterPolicyModel extends Model { public static final Guid NONE_POLICY_UNIT = new Guid("38440000-8cf0-14bd-c43e-10b96e4ef00a"); //$NON-NLS-1$ private static final EventDefinition FILTERS_CHANGED_EVENT_DEFINITION = new EventDefinition("FiltersChanged", //$NON-NLS-1$ NewClusterPolicyModel.class); private static final EventDefinition FUNCTIONS_CHANGED_EVENT_DEFINITION = new EventDefinition("FiltersChanged", //$NON-NLS-1$ NewClusterPolicyModel.class); public static NewClusterPolicyModel createModel(CommandType commandType, ClusterPolicy clusterPolicy, IModel sourceModel, ArrayList<PolicyUnit> policyUnits) { NewClusterPolicyModel clusterPolicyModel = new NewClusterPolicyModel(commandType, clusterPolicy, sourceModel, policyUnits); clusterPolicyModel.init(); return clusterPolicyModel; } private void init() { initTitle(); initModels(); initCommands(); } private void initModels() { getName().setEntity(clusterPolicy.getName()); getName().setIsChangeable(!clusterPolicy.isLocked()); getDescription().setEntity(clusterPolicy.getDescription()); getDescription().setIsChangeable(!clusterPolicy.isLocked()); initFilters(); initFunctions(); initLoadBalance(); initCustomPropertySheet(); } private void initCustomPropertySheet() { setCustomPropertySheet(new KeyValueModel()); if (clusterPolicy.getParameterMap() != null) { getCustomProperties().putAll(clusterPolicy.getParameterMap()); } getCustomPropertySheet().setIsChangeable(!clusterPolicy.isLocked()); customPropertiesInitialized = true; refreshCustomProperties(null, false); } private void refreshCustomProperties(PolicyUnit toRemove, boolean reset) { if (!customPropertiesInitialized) { return; } Map<String, String> policyProperties = new HashMap<>(); Map<Guid, PolicyUnit> allPolicyUnits = new HashMap<>(); for (PolicyUnit policyUnit : getUsedFilters()) { allPolicyUnits.put(policyUnit.getId(), policyUnit); } for (Pair<PolicyUnit, Integer> pair : getUsedFunctions()) { allPolicyUnits.put(pair.getFirst().getId(), pair.getFirst()); } if (toRemove != null && !allPolicyUnits.containsKey(toRemove.getId())) { if (toRemove.getParameterRegExMap() != null) { for (Entry<String, String> entry : toRemove.getParameterRegExMap().entrySet()) { getCustomProperties().remove(entry.getKey()); } } } PolicyUnit selectedItem = loadBalanceList.getSelectedItem(); allPolicyUnits.put(selectedItem.getId(), selectedItem); for (PolicyUnit policyUnit : allPolicyUnits.values()) { if (policyUnit.getParameterRegExMap() != null) { policyProperties.putAll(policyUnit.getParameterRegExMap()); } } Map<String, String> defaultMap = new HashMap<>(getCustomProperties()); if(!reset) { defaultMap.putAll(KeyValueModel.convertProperties(getCustomPropertySheet().serialize())); } getCustomPropertySheet().setKeyValueMap(policyProperties); getCustomPropertySheet().deserialize(KeyValueModel.convertProperties(defaultMap)); } private void initFilters() { getUsedFilters().clear(); getUnusedFilters().clear(); if (clusterPolicy.getFilters() == null) { getUnusedFilters().addAll(getFilterPolicyUnits(policyUnits)); return; } HashMap<Guid, PolicyUnit> map = (HashMap<Guid, PolicyUnit>) ((HashMap<Guid, PolicyUnit>) policyUnitsMap).clone(); for (Guid policyUnitId : clusterPolicy.getFilters()) { map.remove(policyUnitId); getUsedFilters().add(policyUnitsMap.get(policyUnitId)); } initFilterPositions(); getUnusedFilters().addAll(getFilterPolicyUnits(new ArrayList<>(map.values()))); } private void initFilterPositions() { if (clusterPolicy.getFilterPositionMap() != null) { for (Entry<Guid, Integer> entry : clusterPolicy.getFilterPositionMap().entrySet()) { getFilterPositionMap().put(entry.getKey(), entry.getValue()); } } } private void initFunctions() { getUsedFunctions().clear(); getUnusedFunctions().clear(); if (clusterPolicy.getFunctions() == null) { getUnusedFunctions().addAll(getFunctionPolicyUnits(policyUnits)); return; } HashMap<Guid, PolicyUnit> map = (HashMap<Guid, PolicyUnit>) ((HashMap<Guid, PolicyUnit>) policyUnitsMap).clone(); for (Pair<Guid, Integer> pair : clusterPolicy.getFunctions()) { map.remove(pair.getFirst()); getUsedFunctions().add(new Pair<>(policyUnitsMap.get(pair.getFirst()), pair.getSecond())); } getUnusedFunctions().addAll(getFunctionPolicyUnits(new ArrayList<>(map.values()))); } private void initLoadBalance() { ArrayList<PolicyUnit> balancePolicyUnits = getBalancePolicyUnits(policyUnits); getLoadBalanceList().setItems(balancePolicyUnits); if (clusterPolicy.getBalance() != null) { currentLoadBalance = policyUnitsMap.get(clusterPolicy.getBalance()); } else { currentLoadBalance = policyUnitsMap.get(NONE_POLICY_UNIT); } getLoadBalanceList().setIsChangeable(!clusterPolicy.isLocked()); getLoadBalanceList().setSelectedItem(currentLoadBalance); getLoadBalanceList().getSelectedItemChangedEvent().addListener((ev, sender, args) -> { refreshCustomProperties(currentLoadBalance, false); currentLoadBalance = getLoadBalanceList().getSelectedItem(); }); } private ArrayList<PolicyUnit> getBalancePolicyUnits(ArrayList<PolicyUnit> list) { if (list == null || list.size() == 0) { return new ArrayList<>(); } ArrayList<PolicyUnit> balancePolicyUnits = new ArrayList<>(); for (PolicyUnit policyUnit : list) { if (policyUnit.getPolicyUnitType() == PolicyUnitType.LOAD_BALANCING) { balancePolicyUnits.add(policyUnit); } } return balancePolicyUnits; } private ArrayList<PolicyUnit> getFilterPolicyUnits(ArrayList<PolicyUnit> list) { if (list == null || list.size() == 0) { return new ArrayList<>(); } ArrayList<PolicyUnit> filterPolicyUnits = new ArrayList<>(); for (PolicyUnit policyUnit : list) { if (policyUnit.getPolicyUnitType() == PolicyUnitType.FILTER) { filterPolicyUnits.add(policyUnit); } } return filterPolicyUnits; } private ArrayList<PolicyUnit> getFunctionPolicyUnits(ArrayList<PolicyUnit> list) { if (list == null || list.size() == 0) { return new ArrayList<>(); } ArrayList<PolicyUnit> functionPolicyUnits = new ArrayList<>(); for (PolicyUnit policyUnit : list) { if (policyUnit.getPolicyUnitType() == PolicyUnitType.WEIGHT) { functionPolicyUnits.add(policyUnit); } } return functionPolicyUnits; } private void initCommands() { if (!clusterPolicy.isLocked() || commandType == CommandType.Clone) { UICommand onSaveCommand = UICommand.createDefaultOkUiCommand("OnSave", this); //$NON-NLS-1$ getCommands().add(onSaveCommand); UICommand onResetCommand = new UICommand("OnReset", this); //$NON-NLS-1$ onResetCommand.setTitle(ConstantsManager.getInstance().getConstants().resetTitle()); getCommands().add(onResetCommand); } UICommand cancelCommand = new UICommand("Cancel", this); //$NON-NLS-1$ cancelCommand.setTitle(!clusterPolicy.isLocked() ? ConstantsManager.getInstance().getConstants().cancel() : ConstantsManager.getInstance().getConstants().close()); cancelCommand.setIsCancel(true); getCommands().add(cancelCommand); } private void initTitle() { switch (commandType) { case New: setTitle(ConstantsManager.getInstance().getConstants().newClusterPolicyTitle()); setHelpTag(HelpTag.new_cluster_policy); setHashName("new_cluster_policy"); //$NON-NLS-1$ break; case Edit: setTitle(ConstantsManager.getInstance().getConstants().editClusterPolicyTitle()); setHelpTag(HelpTag.edit_cluster_policy); setHashName("edit_cluster_policy"); //$NON-NLS-1$ break; case Clone: setTitle(ConstantsManager.getInstance().getConstants().copyClusterPolicyTitle()); setHelpTag(HelpTag.copy_cluster_policy); setHashName("copy_cluster_policy"); //$NON-NLS-1$ break; } } private boolean customPropertiesInitialized = false; private Event<EventArgs> filtersChangedEvent; private Event<EventArgs> functionsChangedEvent; private final IModel sourceModel; private final ClusterPolicy clusterPolicy; private final CommandType commandType; private final Map<Guid, PolicyUnit> policyUnitsMap; private final ArrayList<PolicyUnit> policyUnits; private final ArrayList<PolicyUnit> usedFilters; private final ArrayList<PolicyUnit> unusedFilters; private final ArrayList<Pair<PolicyUnit, Integer>> usedFunctions; private final ArrayList<PolicyUnit> unusedFunctions; private final Map<Guid, Integer> filterPositionMap; private KeyValueModel customPropertySheet; private final Map<String, String> customProperties; private EntityModel<String> name; private EntityModel<String> description; private ListModel filterList; private ListModel functionList; private ListModel<PolicyUnit> loadBalanceList; private PolicyUnit currentLoadBalance; public NewClusterPolicyModel(CommandType commandType, ClusterPolicy clusterPolicy, IModel sourceModel, ArrayList<PolicyUnit> policyUnits) { this.commandType = commandType; this.clusterPolicy = clusterPolicy; this.sourceModel = sourceModel; this.policyUnits = policyUnits; policyUnitsMap = new HashMap<>(); for (PolicyUnit policyUnit : policyUnits) { policyUnitsMap.put(policyUnit.getId(), policyUnit); } usedFilters = new ArrayList<>(); unusedFilters = new ArrayList<>(); usedFunctions = new ArrayList<>(); unusedFunctions = new ArrayList<>(); filterPositionMap = new HashMap<>(); customProperties = new LinkedHashMap<>(); setName(new EntityModel<String>()); setDescription(new EntityModel<String>()); setFilterList(new ListModel()); setFunctionList(new ListModel()); setLoadBalanceList(new ListModel<PolicyUnit>()); setFiltersChangedEvent(new Event<>(FILTERS_CHANGED_EVENT_DEFINITION)); setFunctionsChangedEvent(new Event<>(FUNCTIONS_CHANGED_EVENT_DEFINITION)); } public EntityModel<String> getName() { return name; } public void setName(EntityModel<String> name) { this.name = name; } public EntityModel<String> getDescription() { return description; } public void setDescription(EntityModel<String> description) { this.description = description; } public ListModel getFilterList() { return filterList; } public void setFilterList(ListModel filterList) { this.filterList = filterList; } public ListModel getFunctionList() { return functionList; } public void setFunctionList(ListModel functionList) { this.functionList = functionList; } public ListModel<PolicyUnit> getLoadBalanceList() { return loadBalanceList; } public void setLoadBalanceList(ListModel<PolicyUnit> loadBalanceList) { this.loadBalanceList = loadBalanceList; } public ClusterPolicy getClusterPolicy() { return clusterPolicy; } public CommandType getCommandType() { return commandType; } public ArrayList<PolicyUnit> getPolicyUnits() { return policyUnits; } public Map<Guid, PolicyUnit> getPolicyUnitsMap() { return policyUnitsMap; } public ArrayList<PolicyUnit> getUsedFilters() { return usedFilters; } public ArrayList<PolicyUnit> getUnusedFilters() { return unusedFilters; } public ArrayList<Pair<PolicyUnit, Integer>> getUsedFunctions() { return usedFunctions; } public ArrayList<PolicyUnit> getUnusedFunctions() { return unusedFunctions; } public Map<Guid, Integer> getFilterPositionMap() { return filterPositionMap; } public Event<EventArgs> getFiltersChangedEvent() { return filtersChangedEvent; } public void setFiltersChangedEvent(Event<EventArgs> filtersChangedEvent) { this.filtersChangedEvent = filtersChangedEvent; } public KeyValueModel getCustomPropertySheet() { return customPropertySheet; } public void setCustomPropertySheet(KeyValueModel customPropertySheet) { this.customPropertySheet = customPropertySheet; } public Map<String, String> getCustomProperties() { return customProperties; } public Event<EventArgs> getFunctionsChangedEvent() { return functionsChangedEvent; } public void setFunctionsChangedEvent(Event<EventArgs> functionsChangedEvent) { this.functionsChangedEvent = functionsChangedEvent; } @Override public void executeCommand(UICommand command) { super.executeCommand(command); if (command.getName().equals("Cancel")) { // $NON-NLS-1$ cancel(); } else if (command.getName().equals("OnSave")) { //$NON-NLS-1$ save(); } else if (command.getName().equals("OnReset")) { //$NON-NLS-1$ reset(); } } public void addFilter(PolicyUnit policyUnit, boolean used, int position) { if (position != 0) { Guid removeEntry = null; for (Entry<Guid, Integer> entry : getFilterPositionMap().entrySet()) { if (entry.getValue().equals(position)) { removeEntry = entry.getKey(); break; } } if (removeEntry != null) { getFilterPositionMap().remove(removeEntry); } } getFilterPositionMap().put(policyUnit.getId(), position); if (!used) { usedFilters.add(policyUnit); for (int i = 0; i < unusedFilters.size(); i++) { if (unusedFilters.get(i).getId().equals(policyUnit.getId())) { unusedFilters.remove(policyUnit); break; } } } refreshCustomProperties(null, false); getFiltersChangedEvent().raise(this, EventArgs.EMPTY); } public void removeFilter(PolicyUnit policyUnit) { unusedFilters.add(policyUnit); for (int i = 0; i < usedFilters.size(); i++) { if (usedFilters.get(i).getId().equals(policyUnit.getId())) { usedFilters.remove(i); break; } } refreshCustomProperties(policyUnit, false); getFiltersChangedEvent().raise(this, EventArgs.EMPTY); } public void addFunction(PolicyUnit policyUnit) { usedFunctions.add(new Pair<>(policyUnit, 1)); for (int i = 0; i < unusedFunctions.size(); i++) { if (unusedFunctions.get(i).getId().equals(policyUnit.getId())) { unusedFunctions.remove(policyUnit); break; } } refreshCustomProperties(null, false); getFunctionsChangedEvent().raise(this, EventArgs.EMPTY); } public void removeFunction(PolicyUnit policyUnit) { unusedFunctions.add(policyUnit); for (int i = 0; i < usedFunctions.size(); i++) { if (usedFunctions.get(i).getFirst().getId().equals(policyUnit.getId())) { usedFunctions.remove(i); break; } } refreshCustomProperties(policyUnit, false); getFunctionsChangedEvent().raise(this, EventArgs.EMPTY); } public void updateFactor(PolicyUnit policyUnit, Integer factor) { for (int i = 0; i < usedFunctions.size(); i++) { if (usedFunctions.get(i).getFirst().getId().equals(policyUnit.getId())) { usedFunctions.get(i).setSecond(factor); break; } } } private void cancel() { sourceModel.setWindow(null); } private void save() { if (getProgress() != null) { return; } if (!validate()) { return; } startProgress(); ClusterPolicy policy = new ClusterPolicy(); policy.setId(clusterPolicy.getId()); policy.setName(getName().getEntity()); policy.setDescription(getDescription().getEntity()); ArrayList<Guid> keys = new ArrayList<>(); for (PolicyUnit clusterPolicy : getUsedFilters()) { keys.add(clusterPolicy.getId()); } policy.setFilters(keys); policy.setFilterPositionMap(getFilterPositionMap()); ArrayList<Pair<Guid, Integer>> pairs = new ArrayList<>(); for (Pair<PolicyUnit, Integer> pair : getUsedFunctions()) { pairs.add(new Pair<>(pair.getFirst().getId(), pair.getSecond())); } policy.setFunctions(pairs); policy.setBalance(getLoadBalanceList().getSelectedItem().getId()); policy.setParameterMap(KeyValueModel.convertProperties(getCustomPropertySheet().serialize())); Frontend.getInstance().runAction(commandType == CommandType.Edit ? VdcActionType.EditClusterPolicy : VdcActionType.AddClusterPolicy, new ClusterPolicyCRUDParameters(policy.getId(), policy), result -> { NewClusterPolicyModel.this.stopProgress(); if (result.getReturnValue().getSucceeded()) { NewClusterPolicyModel.this.cancel(); } }); } private boolean validate() { getName().validateEntity(new IValidation[] { new NotEmptyValidation(), new LengthValidation(50), new AsciiNameValidation() }); getDescription().validateEntity(new IValidation[] { new LengthValidation(400), new AsciiOrNoneValidation() }); return getName().getIsValid() && getDescription().getIsValid() && getCustomPropertySheet().validate(); } private void reset() { getName().setEntity(clusterPolicy.getName()); getDescription().setEntity(clusterPolicy.getDescription()); initFilters(); initFunctions(); if (clusterPolicy.getBalance() != null) { getLoadBalanceList().setSelectedItem(policyUnitsMap.get(clusterPolicy.getBalance())); } getFiltersChangedEvent().raise(this, EventArgs.EMPTY); getFunctionsChangedEvent().raise(this, EventArgs.EMPTY); customProperties.clear(); if (clusterPolicy.getParameterMap() != null) { customProperties.putAll(clusterPolicy.getParameterMap()); } refreshCustomProperties(null, true); } @Override public void cleanup() { cleanupEvents(getFiltersChangedEvent(), getFunctionsChangedEvent()); super.cleanup(); } }