com.abiquo.server.core.infrastructure.RackDAO.java Source code

Java tutorial

Introduction

Here is the source code for com.abiquo.server.core.infrastructure.RackDAO.java

Source

/**
 * Abiquo community edition
 * cloud management application for hybrid clouds
 * Copyright (C) 2008-2010 - Abiquo Holdings S.L.
 *
 * This application is free software; you can redistribute it and/or
 * modify it under the terms of the GNU LESSER GENERAL PUBLIC
 * LICENSE as published by the Free Software Foundation under
 * version 3 of the License
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * LESSER GENERAL PUBLIC LICENSE v.3 for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

package com.abiquo.server.core.infrastructure;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.EntityManager;

import org.apache.commons.lang.StringUtils;
import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Repository;

import com.abiquo.model.enumerator.MachineState;
import com.abiquo.server.core.common.persistence.DefaultDAOBase;
import com.softwarementors.bzngine.entities.PersistentEntity;

@Repository("jpaRackDAO")
/* package */class RackDAO extends DefaultDAOBase<Integer, Rack> {

    public RackDAO() {
        super(Rack.class);
    }

    public RackDAO(final EntityManager entityManager) {
        super(Rack.class, entityManager);
    }

    private static Criterion sameDatacenter(final Datacenter datacenter) {
        assert datacenter != null;

        return Restrictions.eq(Rack.DATACENTER_PROPERTY, datacenter);
    }

    private static Criterion equalName(final String name) {
        assert !StringUtils.isEmpty(name);

        return Restrictions.eq(Rack.NAME_PROPERTY, name);
    }

    public List<Rack> findRacks(final Datacenter datacenter) {
        return findRacks(datacenter, null);
    }

    private final static String QUERY_GET_FILTERED_RACKS = //
            "SELECT  r.idRack, r.idDataCenter, r.name, r.shortDescription, r.largeDescription, r.vlan_id_min, r.vlan_id_max, "
                    + "r.vlans_id_avoided, r.vlan_per_vdc_expected, r.nrsq, r.haEnabled, r.version_c FROM " //
                    + "rack r LEFT OUTER JOIN datacenter dc ON r.idDatacenter = dc.idDatacenter "
                    + "WHERE dc.idDatacenter = :idDatacenter " //
                    + "AND (r.name like :filter "
                    + "OR r.idRack in (SELECT pms.idRack FROM physicalmachine pms LEFT OUTER JOIN enterprise ent ON pms.idEnterprise = ent.idEnterprise "
                    + "WHERE ent.name like :filter OR pms.name like :filter ) " + ")";

    public List<Rack> findRacks(final Datacenter datacenter, final String filter) {
        assert datacenter != null;
        assert isManaged2(datacenter);

        if (filter != null && !filter.isEmpty()) {
            Query query = getSession().createSQLQuery(QUERY_GET_FILTERED_RACKS);
            query.setParameter("idDatacenter", datacenter.getId());
            query.setString("filter", "%" + filter + "%");

            List<Rack> racks = getSQLQueryResults(getSession(), query, Rack.class, 0);
            return racks;

        }
        Criteria criteria = createCriteria(sameDatacenter(datacenter));
        criteria.addOrder(Order.asc(Rack.NAME_PROPERTY));
        List<Rack> result = getResultList(criteria);
        return result;
    }

    @SuppressWarnings("unchecked")
    private <T> List<T> getSQLQueryResults(final Session session, final Query query, final Class<T> objectClass,
            final int idFieldPosition) {
        List<T> result = new ArrayList<T>();
        List<Object[]> sqlResult = query.list();

        if (sqlResult != null && !sqlResult.isEmpty()) {
            for (Object[] res : sqlResult) {
                T obj = (T) session.get(objectClass, (Integer) res[idFieldPosition]);
                result.add(obj);
            }
        }

        return result;
    }

    public List<Rack> findRacksWithHAEnabled(final Datacenter datacenter) {
        Criteria criteria = createCriteria(sameDatacenter(datacenter));
        criteria.add(Restrictions.eq(Rack.HAENABLED_PROPERTY, true));
        criteria.addOrder(Order.asc(Rack.NAME_PROPERTY));

        List<Rack> result = getResultList(criteria);

        return result;
    }

    public boolean existsAnyWithDatacenterAndName(final Datacenter datacenter, final String name) {
        assert datacenter != null;
        assert !StringUtils.isEmpty(name);

        return existsAnyByCriterions(sameDatacenter(datacenter), equalName(name));
    }

    public boolean existsAnyOtherWithDatacenterAndName(final Rack rack, final String name) {
        assert rack != null;
        assert !StringUtils.isEmpty(name);

        return existsAnyOtherByCriterions(rack, sameDatacenter(rack.getDatacenter()), equalName(name));
    }

    private final static String SQL_RACK_IDS_BY_MIN_VLAN_COUNT = //
            //
            "SELECT rack_filtered_dc.idRack FROM " + //
                    "(SELECT r.idRack, r.idDatacenter, r.vlan_id_min, r.vlan_id_max, r.vlan_per_vdc_expected, r.nrsq, count(vn.id) as vlans_used "
                    + //
                    "FROM rack r LEFT JOIN vlan_network_assignment vn ON r.idRack = vn.idRack GROUP BY r.idRack ) as rack_filtered_dc "
                    + //
                    "WHERE rack_filtered_dc.idDataCenter = :idDatacenter AND rack_filtered_dc.vlans_used + rack_filtered_dc.vlan_per_vdc_expected + (((rack_filtered_dc.vlan_id_max - rack_filtered_dc.vlan_id_min +1 ) * (rack_filtered_dc.nrsq)) / 100) <= ((rack_filtered_dc.vlan_id_max - rack_filtered_dc.vlan_id_min) + 1) "
                    + //
                    "ORDER BY rack_filtered_dc.vlans_used + rack_filtered_dc.vlan_per_vdc_expected ASC";

    private final static String SQL_RACK_IDS_BY_MIN_VLAN_COUNT_LITE = //
            //
            "SELECT r.idRack " + //
                    "FROM rack r, virtualapp va, virtualdatacenter vdc, datacenter dc " + //
                    "WHERE va.idVirtualApp = :idVApp " + //
                    "AND vdc.idVirtualDataCenter = va.idVirtualDataCenter " + //
                    "AND vdc.idDataCenter = r.idDatacenter";//

    /**
     * Obtains the racks (prefiltered by target datacenter and virtualdatacenter) with minimal VLANS
     * // and with vms deployed
     */
    public List<Integer> getRackIdByMinVLANCount(final int idDatacenter) {
        SQLQuery query = getSession().createSQLQuery(SQL_RACK_IDS_BY_MIN_VLAN_COUNT);
        query.setInteger("idDatacenter", idDatacenter);

        return query.list();
    }

    private final static String COUNT_DEPLOYED_VLA = //
            "SELECT COUNT(vn.id) " + //
                    "FROM NetworkAssignment vn WHERE " + //
                    "vn.rack.id = :idRack";

    public Long getNumberOfDeployedVlanNetworks(final Integer rackId) {
        Query query = getSession().createQuery(COUNT_DEPLOYED_VLA);
        query.setInteger("idRack", rackId);

        Long numberOfDeployedNetworks = (Long) query.uniqueResult();

        return numberOfDeployedNetworks;
    }

    /**
     * Return the Rack by datacenter id and rack id.
     * 
     * @param datacenterId
     * @param rackId
     * @return
     */
    public Rack findByIds(final Integer datacenterId, final Integer rackId) {
        return findUniqueByCriterions(Restrictions.eq("datacenter.id", datacenterId),
                Restrictions.eq(PersistentEntity.ID_PROPERTY, rackId));
    }

    private final static String HQL_NOT_MANAGED_RACKS_BY_DATACENTER = //
            "SELECT nmr " + //
                    "FROM Rack nmr WHERE " + //
                    "nmr.datacenter.id = :idDatacenter and nmr.class = " + Rack.class.getName();

    /**
     * Returns all not managed racks.
     * 
     * @param datacenter
     * @return List<Rack>
     */
    public List<Rack> findAllNotManagedRacksByDatacenter(final Integer datacenterId) {
        return findAllNotManagedRacksByDatacenter(datacenterId, null);
    }

    public List<Rack> findAllNotManagedRacksByDatacenter(final Integer datacenterId, final String filter) {
        String hql = HQL_NOT_MANAGED_RACKS_BY_DATACENTER;
        if (filter != null && !filter.isEmpty()) {
            hql += " AND nmr.name like :filter";
        }

        Query q = getSession().createQuery(hql);
        q.setInteger("idDatacenter", datacenterId);
        if (filter != null && !filter.isEmpty()) {
            q.setString("filter", "%" + filter + "%");
        }

        return q.list();
    }

    private final String QUERY_USED_VDRP = "SELECT vm.vdrpPort " + //
            "FROM com.abiquo.server.core.cloud.VirtualMachine vm " + //
            "WHERE vm.hypervisor.machine.rack = :rack ";

    @SuppressWarnings("unchecked")
    public List<Integer> findUsedVrdpPorts(final Rack rack) {
        Query query = getSession().createQuery(QUERY_USED_VDRP);
        query.setParameter("rack", rack);
        return query.list();
    }

    private final static String HQL_EMPTY_OFF_MACHINES_IN_RACK = "select m from Machine m where m.rack.id = :rackId and m.state = "
            + MachineState.HALTED_FOR_SAVE.ordinal()
            + " order by (case when exists (select n from Hypervisor n where n.machine = m) then 0 else 1 end)";

    private final static String HQL_EMPTY_ON_MACHINES_IN_RACK = "select m from Machine m where m.rack.id = :rackId and m.state = "
            + MachineState.MANAGED.ordinal()
            + " and not exists (select vm from VirtualMachine vm where vm.hypervisor.machine = m)";

    /**
     * Return all machines in a rack that are empty of VM and powered off.
     * 
     * @param rackId rack.
     * @return Integer
     */
    public Integer getEmptyOffMachines(final Integer rackId) {
        Query q = getSession().createQuery(HQL_EMPTY_OFF_MACHINES_IN_RACK).setInteger("rackId", rackId);
        return q.list().size();
    }

    /**
     * Return all machines in a rack that are empty of VM.
     * 
     * @param rackId rack.
     * @return Integer
     */
    public Integer getEmptyOnMachines(final Integer rackId) {
        Query q = getSession().createQuery(HQL_EMPTY_ON_MACHINES_IN_RACK).setInteger("rackId", rackId);
        return q.list().size();
    }

    /**
     * Returns any machine that is in the rack in HALTED_FOR_SAVE. If howMany <= 0 an empty list is
     * returned.
     * 
     * @param rackId rack.
     * @return Machine
     */
    public List<Machine> getRandomMachinesToStartFromRack(final Integer rackId, final Integer howMany) {
        if (howMany <= 0) {
            return new ArrayList<Machine>();
        }
        Query q = getSession().createQuery(HQL_EMPTY_OFF_MACHINES_IN_RACK).setInteger("rackId", rackId);

        List<Machine> machines = q.setMaxResults(howMany).list();
        return machines;
    }

    /**
     * Returns any machine that is in the rack in MANAGED. If howMany <= 0 an empty list is
     * returned.
     * 
     * @param rackId rack.
     * @return Machine
     */
    public List<Machine> getRandomMachinesToShutDownFromRack(final Integer rackId, final Integer howMany) {
        if (howMany <= 0) {
            return new ArrayList<Machine>();
        }
        Query q = getSession().createQuery(HQL_EMPTY_ON_MACHINES_IN_RACK).setInteger("rackId", rackId);

        List<Machine> machines = q.setMaxResults(howMany).list();
        return machines;
    }

    /**
     * Returns all machine that is in the rack in MANAGED.
     * 
     * @param rackId rack.
     * @return Machine
     */
    public List<Machine> getAllMachinesToShutDownFromRack(final Integer rackId) {
        Query q = getSession().createQuery(HQL_EMPTY_ON_MACHINES_IN_RACK).setInteger("rackId", rackId);

        return q.list();
    }
}