package org.ovirt.engine.core.dao.scheduling; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import javax.inject.Inject; import javax.inject.Named; import javax.inject.Singleton; import javax.validation.constraints.NotNull; 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.utils.Pair; import org.ovirt.engine.core.compat.Guid; import org.ovirt.engine.core.dao.DefaultGenericDao; import org.ovirt.engine.core.utils.SerializationFactory; import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; @Named @Singleton public class ClusterPolicyDaoImpl extends DefaultGenericDao<ClusterPolicy, Guid> implements ClusterPolicyDao { @Inject private PolicyUnitDao policyUnitDao; public ClusterPolicyDaoImpl() { super("ClusterPolicy"); } @Override public void save(ClusterPolicy clusterPolicy) { super.save(clusterPolicy); List<ClusterPolicyUnit> clusterPolicyUnits = getclusterPolicyUnit(clusterPolicy); if (clusterPolicyUnits != null) { clusterPolicyUnits.forEach(this::saveClusterPolicyUnit); } } @Override public void update(ClusterPolicy clusterPolicy) { super.update(clusterPolicy); getCallsHandler().executeModification("DeleteClusterPolicyUnitsByClusterPolicyId", getCustomMapSqlParameterSource().addValue("id", clusterPolicy.getId())); List<ClusterPolicyUnit> clusterPolicyUnits = getclusterPolicyUnit(clusterPolicy); if (clusterPolicyUnits != null) { clusterPolicyUnits.forEach(this::saveClusterPolicyUnit); } } @Override public List<ClusterPolicy> getAll(@NotNull Map<Guid, PolicyUnitType> internalUnitTypes) { List<ClusterPolicy> clusterPolicies = super.getAll(); Map<Guid, ClusterPolicy> map = new HashMap<>(); for (ClusterPolicy clusterPolicy : clusterPolicies) { map.put(clusterPolicy.getId(), clusterPolicy); } List<ClusterPolicyUnit> clusterPolicyUnits = getCallsHandler().executeReadList("GetAllFromClusterPolicyUnits", createClusterPolicyUnitRowMapper(), getCustomMapSqlParameterSource()); fillClusterPolicy(map, clusterPolicyUnits, Collections.unmodifiableMap(internalUnitTypes)); return clusterPolicies; } @Override public ClusterPolicy get(Guid id, @NotNull Map<Guid, PolicyUnitType> internalUnitTypes) { ClusterPolicy clusterPolicy = super.get(id); if (clusterPolicy == null) { return null; } List<ClusterPolicyUnit> clusterPolicyUnits = getCallsHandler().executeReadList("GetClusterPolicyUnitsByClusterPolicyId", createClusterPolicyUnitRowMapper(), createIdParameterMapper(id)); Map<Guid, ClusterPolicy> map = new HashMap<>(); map.put(clusterPolicy.getId(), clusterPolicy); fillClusterPolicy(map, clusterPolicyUnits, Collections.unmodifiableMap(internalUnitTypes)); return clusterPolicy; } private void fillClusterPolicy(Map<Guid, ClusterPolicy> map, List<ClusterPolicyUnit> clusterPolicyUnits, @NotNull Map<Guid, PolicyUnitType> internalUnitTypes) { Map<Guid, PolicyUnitType> policyUnitTypeMap = new HashMap<>(internalUnitTypes); for (PolicyUnit policyUnit : policyUnitDao.getAll()) { policyUnitTypeMap.put(policyUnit.getId(), policyUnit.getPolicyUnitType()); } for (ClusterPolicyUnit clusterPolicyUnit : clusterPolicyUnits) { ClusterPolicy clusterPolicy = map.get(clusterPolicyUnit.getClusterPolicyId()); if (policyUnitTypeMap.get(clusterPolicyUnit.getPolicyUnitId()) == PolicyUnitType.FILTER) { if (clusterPolicy.getFilters() == null) { clusterPolicy.setFilters(new ArrayList<>()); } clusterPolicy.getFilters().add(clusterPolicyUnit.getPolicyUnitId()); if (clusterPolicyUnit.getFilterSequence() != 0) { if (clusterPolicy.getFilterPositionMap() == null) { clusterPolicy.setFilterPositionMap(new HashMap<>()); } clusterPolicy.getFilterPositionMap().put(clusterPolicyUnit.getPolicyUnitId(), clusterPolicyUnit.getFilterSequence()); } } if (policyUnitTypeMap.get(clusterPolicyUnit.getPolicyUnitId()) == PolicyUnitType.WEIGHT) { if(clusterPolicy.getFunctions() == null){ clusterPolicy.setFunctions(new ArrayList<>()); } clusterPolicy.getFunctions().add(new Pair<>(clusterPolicyUnit.getPolicyUnitId(), clusterPolicyUnit.getFactor())); } if (policyUnitTypeMap.get(clusterPolicyUnit.getPolicyUnitId()) == PolicyUnitType.LOAD_BALANCING) { clusterPolicy.setBalance(clusterPolicyUnit.getPolicyUnitId()); } } } private List<ClusterPolicyUnit> getclusterPolicyUnit(ClusterPolicy entity) { Map<Guid, ClusterPolicyUnit> map = new HashMap<>(); ClusterPolicyUnit unit; if (entity.getFilters() != null) { for (Guid policyUnitId : entity.getFilters()) { unit = getClusterPolicyUnit(entity, policyUnitId, map); if (entity.getFilterPositionMap() != null) { Integer position = entity.getFilterPositionMap().get(policyUnitId); unit.setFilterSequence(position != null ? position : 0); } } } if (entity.getFunctions() != null) { for (Pair<Guid, Integer> pair : entity.getFunctions()) { unit = getClusterPolicyUnit(entity, pair.getFirst(), map); unit.setFactor(pair.getSecond()); } } if (entity.getBalance() != null) { getClusterPolicyUnit(entity, entity.getBalance(), map); } return new ArrayList<>(map.values()); } private void saveClusterPolicyUnit(ClusterPolicyUnit clusterPolicyUnit) { getCallsHandler().executeModification("InsertClusterPolicyUnit", getClusterPolicyUnitParameterMap(clusterPolicyUnit)); } private MapSqlParameterSource getClusterPolicyUnitParameterMap(ClusterPolicyUnit clusterPolicyUnit) { return getCustomMapSqlParameterSource().addValue("cluster_policy_id", clusterPolicyUnit.getClusterPolicyId()) .addValue("policy_unit_id", clusterPolicyUnit.getPolicyUnitId()) .addValue("filter_sequence", clusterPolicyUnit.getFilterSequence()) .addValue("factor", clusterPolicyUnit.getFactor()); } protected RowMapper<ClusterPolicyUnit> createClusterPolicyUnitRowMapper() { return (rs, arg1) -> { ClusterPolicyUnit unit = new ClusterPolicyUnit(); unit.setClusterPolicyId(getGuid(rs, "cluster_policy_id")); unit.setPolicyUnitId(getGuid(rs, "policy_unit_id")); unit.setFilterSequence(rs.getInt("filter_sequence")); unit.setFactor(rs.getInt("factor")); return unit; }; } private ClusterPolicyUnit getClusterPolicyUnit(ClusterPolicy clusterPolicy, Guid policyUnitId, Map<Guid, ClusterPolicyUnit> map) { ClusterPolicyUnit clusterPolicyUnit = map.get(policyUnitId); if (clusterPolicyUnit == null) { clusterPolicyUnit = new ClusterPolicyUnit(clusterPolicy.getId(), policyUnitId); map.put(policyUnitId, clusterPolicyUnit); } return clusterPolicyUnit; } @Override protected MapSqlParameterSource createFullParametersMapper(ClusterPolicy entity) { return createIdParameterMapper(entity.getId()) .addValue("name", entity.getName()) .addValue("description", entity.getDescription()) .addValue("is_locked", entity.isLocked()) .addValue("is_default", entity.isDefaultPolicy()) .addValue("custom_properties", SerializationFactory.getSerializer().serialize(entity.getParameterMap())); } @Override protected MapSqlParameterSource createIdParameterMapper(Guid id) { return getCustomMapSqlParameterSource().addValue("id", id); } @Override protected RowMapper<ClusterPolicy> createEntityRowMapper() { return (rs, arg1) -> { ClusterPolicy clusterPolicy = new ClusterPolicy(); clusterPolicy.setId(getGuid(rs, "id")); clusterPolicy.setName(rs.getString("name")); clusterPolicy.setDescription(rs.getString("description")); clusterPolicy.setLocked(rs.getBoolean("is_locked")); clusterPolicy.setDefaultPolicy(rs.getBoolean("is_default")); clusterPolicy.setParameterMap(SerializationFactory.getDeserializer() .deserializeOrCreateNew(rs.getString("custom_properties"), LinkedHashMap.class)); return clusterPolicy; }; } /** * Helper class for cluster's policy units. this class is hidden from users of this dao. mapped into cluster policy * class. */ private static class ClusterPolicyUnit { Guid clusterPolicyId; Guid policyUnitId; int filterSequence; int factor; public ClusterPolicyUnit() { } public ClusterPolicyUnit(Guid clusterPolicyId, Guid policyUnitId) { this.clusterPolicyId = clusterPolicyId; this.policyUnitId = policyUnitId; } public Guid getClusterPolicyId() { return clusterPolicyId; } public void setClusterPolicyId(Guid clusterPolicyId) { this.clusterPolicyId = clusterPolicyId; } public Guid getPolicyUnitId() { return policyUnitId; } public void setPolicyUnitId(Guid policyUnitId) { this.policyUnitId = policyUnitId; } public int getFilterSequence() { return filterSequence; } public void setFilterSequence(int filterSequence) { this.filterSequence = filterSequence; } public int getFactor() { return factor; } public void setFactor(int factor) { this.factor = factor; } } }