Gilad Chaplik has uploaded a new change for review. Change subject: db: Affinity Groups database support ......................................................................
db: Affinity Groups database support * Create affinity groups and members tables * Add affinity group view (join of affinity group and members) * Add CRUD stored procedure for affinity groups, the procedures will control both of the tables, i.e. insert affinity group, will fill its members as well. * Stored procedures for fetching Affinty Groups: * by id * by cluster id * by vm id For more information please refer to: http://www.ovirt.org/Features/VM-Affinity Change-Id: Ib09c50cae8d9a23a08a9e723d0e0498ea2016e6a Bug-Url: https://bugzilla.redhat.com/1036638 Signed-off-by: Gilad Chaplik <gchap...@redhat.com> --- M backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dal/dbbroker/DbFacade.java M backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/BaseDAODbFacade.java M backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/DiskImageDAODbFacadeImpl.java A backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/scheduling/AffinityGroupDao.java A backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/scheduling/AffinityGroupDaoImpl.java M backend/manager/modules/dal/src/main/jdbc-resources/engine-daos.properties A packaging/dbscripts/affinity_groups_sp.sql M packaging/dbscripts/create_views.sql A packaging/dbscripts/upgrade/03_04_0300_create_affinity_group_tables.sql 9 files changed, 275 insertions(+), 11 deletions(-) git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/14/22714/1 diff --git a/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dal/dbbroker/DbFacade.java b/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dal/dbbroker/DbFacade.java index 3a0c04e..a9da479 100644 --- a/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dal/dbbroker/DbFacade.java +++ b/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dal/dbbroker/DbFacade.java @@ -46,7 +46,6 @@ import org.ovirt.engine.core.common.job.Step; import org.ovirt.engine.core.compat.Guid; import org.ovirt.engine.core.dao.ActionGroupDAO; -import org.ovirt.engine.core.dao.DbGroupDAO; import org.ovirt.engine.core.dao.AsyncTaskDAO; import org.ovirt.engine.core.dao.AuditLogDAO; import org.ovirt.engine.core.dao.BaseDAODbFacade; @@ -55,6 +54,7 @@ import org.ovirt.engine.core.dao.BusinessEntitySnapshotDAO; import org.ovirt.engine.core.dao.DAO; import org.ovirt.engine.core.dao.DaoFactory; +import org.ovirt.engine.core.dao.DbGroupDAO; import org.ovirt.engine.core.dao.DbUserDAO; import org.ovirt.engine.core.dao.DiskDao; import org.ovirt.engine.core.dao.DiskImageDAO; @@ -118,6 +118,7 @@ import org.ovirt.engine.core.dao.network.VnicProfileDao; import org.ovirt.engine.core.dao.network.VnicProfileViewDao; import org.ovirt.engine.core.dao.provider.ProviderDao; +import org.ovirt.engine.core.dao.scheduling.AffinityGroupDao; import org.ovirt.engine.core.dao.scheduling.ClusterPolicyDao; import org.ovirt.engine.core.dao.scheduling.PolicyUnitDao; import org.ovirt.engine.core.utils.linq.LinqUtils; @@ -952,6 +953,15 @@ } /** + * Returns the singleton instance of {@link AffinityGroupDao}. + * + * @return the dao instance + */ + public AffinityGroupDao getAffinityGroupDao() { + return getDao(AffinityGroupDao.class); + } + + /** * This call will populate a translation table of OS Ids to they're name * The translation table shall be in use by DWH * diff --git a/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/BaseDAODbFacade.java b/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/BaseDAODbFacade.java index 7a9af36..bf2a1ef 100644 --- a/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/BaseDAODbFacade.java +++ b/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/BaseDAODbFacade.java @@ -2,8 +2,11 @@ import java.sql.ResultSet; import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Arrays; import java.util.UUID; +import org.apache.commons.lang.StringUtils; import org.ovirt.engine.core.compat.Guid; import org.ovirt.engine.core.dal.dbbroker.CustomMapSqlParameterSource; import org.ovirt.engine.core.dal.dbbroker.DbEngineDialect; @@ -13,6 +16,7 @@ import org.springframework.jdbc.core.RowMapper; public abstract class BaseDAODbFacade { + protected static final String SEPARATOR = ","; protected JdbcTemplate jdbcTemplate; protected DbEngineDialect dialect; @@ -167,4 +171,12 @@ protected static Guid getGuidDefaultNewGuid(ResultSet resultSet, String columnName) throws SQLException { return getGuid(resultSet, columnName, Guid.newGuid()); } + + protected static ArrayList<String> split(String str) { + if (StringUtils.isEmpty(str)) { + return null; + } + + return new ArrayList<String>(Arrays.asList(str.split(SEPARATOR))); + } } diff --git a/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/DiskImageDAODbFacadeImpl.java b/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/DiskImageDAODbFacadeImpl.java index 592556f..e517b55 100644 --- a/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/DiskImageDAODbFacadeImpl.java +++ b/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/DiskImageDAODbFacadeImpl.java @@ -180,16 +180,6 @@ return new DiskImage(); } - private static final String SEPARATOR = ","; - - private ArrayList<String> split(String str) { - if (StringUtils.isEmpty(str)) { - return null; - } - - return new ArrayList<String>(Arrays.asList(str.split(SEPARATOR))); - } - /** * since quota can be null, we need to preserve null in the list * diff --git a/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/scheduling/AffinityGroupDao.java b/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/scheduling/AffinityGroupDao.java new file mode 100644 index 0000000..3583757 --- /dev/null +++ b/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/scheduling/AffinityGroupDao.java @@ -0,0 +1,13 @@ +package org.ovirt.engine.core.dao.scheduling; + +import java.util.List; + +import org.ovirt.engine.core.common.scheduling.AffinityGroup; +import org.ovirt.engine.core.compat.Guid; +import org.ovirt.engine.core.dao.GenericDao; + +public interface AffinityGroupDao extends GenericDao<AffinityGroup, Guid> { + List<AffinityGroup> getAllAffinityGroupsByClusterId(Guid clusterId); + + List<AffinityGroup> getAllAffinityGroupsByVmId(Guid vmId); +} diff --git a/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/scheduling/AffinityGroupDaoImpl.java b/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/scheduling/AffinityGroupDaoImpl.java new file mode 100644 index 0000000..03ee746 --- /dev/null +++ b/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/scheduling/AffinityGroupDaoImpl.java @@ -0,0 +1,84 @@ +package org.ovirt.engine.core.dao.scheduling; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; + +import org.apache.commons.lang.StringUtils; +import org.ovirt.engine.core.common.scheduling.AffinityGroup; +import org.ovirt.engine.core.common.scheduling.enums.AffinityEnforcementType; +import org.ovirt.engine.core.common.scheduling.enums.AffinityPolarity; +import org.ovirt.engine.core.compat.Guid; +import org.ovirt.engine.core.dao.DefaultGenericDaoDbFacade; +import org.ovirt.engine.core.utils.GuidUtils; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; + +public class AffinityGroupDaoImpl extends DefaultGenericDaoDbFacade<AffinityGroup, Guid> implements AffinityGroupDao { + + public AffinityGroupDaoImpl() { + super("AffinityGroup"); + } + + @Override + public List<AffinityGroup> getAllAffinityGroupsByClusterId(Guid clusterId) { + return getCallsHandler().executeReadList("getAllAffinityGroupsByClusterId", + createEntityRowMapper(), + getCustomMapSqlParameterSource().addValue("cluster_id", clusterId)); + } + + @Override + public List<AffinityGroup> getAllAffinityGroupsByVmId(Guid vmId) { + return getCallsHandler().executeReadList("getAllAffinityGroupsByVmId", + createEntityRowMapper(), + getCustomMapSqlParameterSource().addValue("vm_id", vmId)); + } + + @Override + public void save(AffinityGroup entity) { + getCallsHandler().executeModification("InsertAffinityGroupWithMembers", createFullParametersMapper(entity)); + } + + @Override + public void update(AffinityGroup entity) { + getCallsHandler().executeModification("UpdateAffinityGroupWithMembers", createFullParametersMapper(entity)); + } + + @Override + protected MapSqlParameterSource createFullParametersMapper(AffinityGroup entity) { + return createIdParameterMapper(entity.getId()) + .addValue("name", entity.getName()) + .addValue("description", entity.getDescription()) + .addValue("cluster_id", entity.getClusterId()) + .addValue("polarity", entity.getPolarity()) + .addValue("enforcement_type", entity.getEnforcementType()) + .addValue("vm_ids", + entity.getVmIds() == null ? StringUtils.EMPTY : StringUtils.join(entity.getVmIds(), SEPARATOR)); + } + + @Override + protected MapSqlParameterSource createIdParameterMapper(Guid id) { + return getCustomMapSqlParameterSource().addValue("id", id); + } + + @Override + protected RowMapper<AffinityGroup> createEntityRowMapper() { + return new RowMapper<AffinityGroup>() { + + @Override + public AffinityGroup mapRow(ResultSet rs, int arg1) throws SQLException { + AffinityGroup affinityGroup = new AffinityGroup(); + affinityGroup.setId(getGuid(rs, "id")); + affinityGroup.setName(rs.getString("name")); + affinityGroup.setDescription(rs.getString("description")); + affinityGroup.setClusterId(getGuid(rs, "cluster_id")); + affinityGroup.setPolarity(AffinityPolarity.forValue(rs.getInt("polarity"))); + affinityGroup.setEnforcementType(AffinityEnforcementType.forValue(rs.getInt("enforcement_type"))); + affinityGroup.setVmIds(GuidUtils.getGuidListFromString(rs.getString("vm_ids"))); + affinityGroup.setVmNames(split(rs.getString("vm_names"))); + + return affinityGroup; + } + }; + } +} diff --git a/backend/manager/modules/dal/src/main/jdbc-resources/engine-daos.properties b/backend/manager/modules/dal/src/main/jdbc-resources/engine-daos.properties index 60ead40..906d13c 100644 --- a/backend/manager/modules/dal/src/main/jdbc-resources/engine-daos.properties +++ b/backend/manager/modules/dal/src/main/jdbc-resources/engine-daos.properties @@ -70,3 +70,4 @@ PolicyUnitDao=org.ovirt.engine.core.dao.scheduling.PolicyUnitDaoImpl ClusterPolicyDao=org.ovirt.engine.core.dao.scheduling.ClusterPolicyDaoImpl DwhHistoryTimekeepingDao=org.ovirt.engine.core.dao.dwh.DwhHistoryTimekeepingDaoDbFacadeImpl +AffinityGroupDao=org.ovirt.engine.core.dao.scheduling.AffinityGroupDaoImpl diff --git a/packaging/dbscripts/affinity_groups_sp.sql b/packaging/dbscripts/affinity_groups_sp.sql new file mode 100644 index 0000000..31b5e08 --- /dev/null +++ b/packaging/dbscripts/affinity_groups_sp.sql @@ -0,0 +1,112 @@ +-- Affinity Groups Stored Procedures script file + +-- get All Affinity Groups with members by vm id +Create or replace FUNCTION getAllAffinityGroupsByVmId(v_vm_id UUID) RETURNS SETOF affinity_groups_view STABLE +AS $procedure$ +BEGIN + RETURN QUERY + SELECT affinity_groups_view.* + FROM affinity_groups_view + JOIN affinity_group_members ON v_vm_id = affinity_group_members.vm_id + AND affinity_group_members.affinity_group_id = affinity_groups_view.id; +END; $procedure$ +LANGUAGE plpgsql; + +-- get All Affinity Groups with members by cluster id +Create or replace FUNCTION getAllAffinityGroupsByClusterId(v_cluster_id UUID) RETURNS SETOF affinity_groups_view STABLE +AS $procedure$ +BEGIN + RETURN QUERY + SELECT * + FROM affinity_groups_view + WHERE cluster_id = v_cluster_id; +END; $procedure$ +LANGUAGE plpgsql; + +-- get Affinity Group with members by id +Create or replace FUNCTION GetAffinityGroupByAffinityGroupId(v_id UUID) RETURNS SETOF affinity_groups_view STABLE +AS $procedure$ +BEGIN + RETURN QUERY + SELECT * + FROM affinity_groups_view + WHERE id = v_id; +END; $procedure$ +LANGUAGE plpgsql; + +-- Insert Affinity Group with members +Create or replace FUNCTION InsertAffinityGroupWithMembers( + v_id UUID, + v_name VARCHAR(128), + v_description VARCHAR(4000), + v_cluster_id UUID, + v_polarity SMALLINT, + v_enforcement_type SMALLINT, + v_vm_ids VARCHAR(4000) +) +RETURNS VOID +AS $procedure$ +DECLARE + iter_id UUID; +BEGIN + INSERT INTO affinity_groups( + id, + name, + description, + cluster_id, + polarity, + enforcement_type) + VALUES( + v_id, + v_name, + v_description, + v_cluster_id, + v_polarity, + v_enforcement_type); + FOR iter_id IN (SELECT * FROM fnsplitteruuid(v_vm_ids)) + LOOP + INSERT INTO affinity_group_members( + affinity_group_id, + vm_id) + VALUES( + v_id, + iter_id); + END LOOP; +END; $procedure$ +LANGUAGE plpgsql; + +-- Delete Affinity Group (uses cascade to remove members) +Create or replace FUNCTION DeleteAffinityGroup(v_id UUID) +RETURNS VOID +AS $procedure$ +BEGIN + DELETE + FROM affinity_groups + WHERE id = v_id; +END; $procedure$ +LANGUAGE plpgsql; + +-- Update Affinity Group (implemeted using Delete and Insert SPs) +Create or replace FUNCTION UpdateAffinityGroupWithMembers( + v_id UUID, + v_name VARCHAR(128), + v_description VARCHAR(4000), + v_cluster_id UUID, + v_polarity SMALLINT, + v_enforcement_type SMALLINT, + v_vm_ids VARCHAR(4000) +) +RETURNS VOID +AS $procedure$ +BEGIN + PERFORM DeleteAffinityGroup(v_id); + PERFORM InsertAffinityGroupWithMembers( + v_id, + v_name, + v_description, + v_cluster_id, + v_polarity, + v_enforcement_type, + v_vm_ids); +END; $procedure$ +LANGUAGE plpgsql; diff --git a/packaging/dbscripts/create_views.sql b/packaging/dbscripts/create_views.sql index 253dfc8..bcf535d 100644 --- a/packaging/dbscripts/create_views.sql +++ b/packaging/dbscripts/create_views.sql @@ -1642,3 +1642,14 @@ vds_static.vds_name AS server_name FROM gluster_server_hooks INNER JOIN vds_static ON gluster_server_hooks.server_id = vds_static.vds_id; + +-- Affinity Groups view, including members +CREATE OR REPLACE VIEW affinity_groups_view +AS +SELECT affinity_groups.*, + array_to_string(array_agg(affinity_group_members.vm_id), ',') as vm_ids, + array_to_string(array_agg(vm_static.vm_name), ',') as vm_names +FROM affinity_groups +LEFT JOIN affinity_group_members ON affinity_group_members.affinity_group_id = affinity_groups.id +LEFT JOIN vm_static ON vm_static.vm_guid = affinity_group_members.vm_id +GROUP BY affinity_groups.id; diff --git a/packaging/dbscripts/upgrade/03_04_0300_create_affinity_group_tables.sql b/packaging/dbscripts/upgrade/03_04_0300_create_affinity_group_tables.sql new file mode 100644 index 0000000..7060eb9 --- /dev/null +++ b/packaging/dbscripts/upgrade/03_04_0300_create_affinity_group_tables.sql @@ -0,0 +1,31 @@ +CREATE OR REPLACE FUNCTION __temp_Upgrade_AddAffinityGroupsTables() +RETURNS void +AS $function$ +BEGIN + IF EXISTS (SELECT * FROM information_schema.tables WHERE table_name ILIKE 'affinity_groups') THEN + RETURN; + END IF; + -- create affinity_groups table + CREATE TABLE affinity_groups + ( + id UUID NOT NULL CONSTRAINT affinity_group_pk PRIMARY KEY, + name VARCHAR(128) NOT NULL, + description VARCHAR(4000), + cluster_id UUID NOT NULL CONSTRAINT affinity_group_cluster_id_fk REFERENCES vds_groups(vds_group_id) ON DELETE CASCADE, + polarity SMALLINT NOT NULL, + enforcement_type SMALLINT NOT NULL + ); + -- create affinity_groups members table + CREATE TABLE affinity_group_members + ( + affinity_group_id UUID NOT NULL CONSTRAINT affinity_group_member_affinity_id_fk REFERENCES affinity_groups(id) ON DELETE CASCADE, + vm_id UUID NOT NULL CONSTRAINT affinity_group_member_vm_id_fk REFERENCES vm_static(vm_guid) ON DELETE CASCADE + ); + +END; $function$ +LANGUAGE plpgsql; + +SELECT * FROM __temp_Upgrade_AddAffinityGroupsTables(); + +DROP FUNCTION __temp_Upgrade_AddAffinityGroupsTables(); + -- To view, visit http://gerrit.ovirt.org/22714 To unsubscribe, visit http://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ib09c50cae8d9a23a08a9e723d0e0498ea2016e6a Gerrit-PatchSet: 1 Gerrit-Project: ovirt-engine Gerrit-Branch: master Gerrit-Owner: Gilad Chaplik <gchap...@redhat.com> _______________________________________________ Engine-patches mailing list Engine-patches@ovirt.org http://lists.ovirt.org/mailman/listinfo/engine-patches