/**
* 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.appslibrary;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import javax.persistence.EntityManager;
import org.apache.commons.collections.CollectionUtils;
import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.hibernate.sql.JoinFragment;
import org.springframework.stereotype.Repository;
import com.abiquo.model.enumerator.ConversionState;
import com.abiquo.model.enumerator.DiskFormatType;
import com.abiquo.model.enumerator.HypervisorType;
import com.abiquo.model.enumerator.StatefulInclusion;
import com.abiquo.model.enumerator.VolumeState;
import com.abiquo.server.core.cloud.VirtualDatacenter;
import com.abiquo.server.core.cloud.VirtualMachine;
import com.abiquo.server.core.common.persistence.DefaultDAOBase;
import com.abiquo.server.core.enterprise.Enterprise;
import com.abiquo.server.core.infrastructure.Datacenter;
import com.abiquo.server.core.infrastructure.management.RasdManagement;
import com.abiquo.server.core.infrastructure.storage.StorageDevice;
import com.abiquo.server.core.infrastructure.storage.StoragePool;
import com.abiquo.server.core.infrastructure.storage.VolumeManagement;
@Repository("jpaVirtualMachineTemplateDAO")
/* package */class VirtualMachineTemplateDAO extends
DefaultDAOBase<Integer, VirtualMachineTemplate>
{
private final String FIND_ICONS_BY_ENTERPRISE = " SELECT distinct vtd.iconUrl "//
+ "FROM com.abiquo.server.core.appslibrary.VirtualMachineTemplate vtd "//
+ "WHERE vtd.enterprise.id = :enterpriseId";
public VirtualMachineTemplateDAO()
{
super(VirtualMachineTemplate.class);
}
public VirtualMachineTemplateDAO(final EntityManager entityManager)
{
super(VirtualMachineTemplate.class, entityManager);
}
public List<VirtualMachineTemplate> findByEnterprise(final Enterprise enterprise)
{
Criteria criteria = createCriteria(sameEnterpriseOrShared(enterprise));
criteria.addOrder(Order.asc(VirtualMachine.NAME_PROPERTY));
return getResultList(criteria);
}
public List<VirtualMachineTemplate> findByEnterpriseAndRepository(final Enterprise enterprise,
final com.abiquo.server.core.infrastructure.Repository repository)
{
Criteria criteria = createCriteria(sameEnterpriseOrSharedInRepo(enterprise, repository));
criteria.addOrder(Order.asc(VirtualMachine.NAME_PROPERTY));
return getResultList(criteria);
}
public List<VirtualMachineTemplate> findImportedByEnterprise(final Enterprise enterprise)
{
Criteria criteria = createCriteria(importedVirtualMachineTemplate(enterprise));
criteria.addOrder(Order.asc(VirtualMachine.NAME_PROPERTY));
return getResultList(criteria);
}
public List<VirtualMachineTemplate> findBy(final Enterprise enterprise,
final com.abiquo.server.core.infrastructure.Repository repository, final Category category,
final HypervisorType hypervisor)
{
Criteria criteria = createCriteria(sameEnterpriseOrSharedInRepo(enterprise, repository));
if (category != null)
{
criteria.add(sameCategory(category));
}
if (hypervisor != null)
{
criteria.add(compatibleOrConversions(hypervisor, criteria));
}
// TODO
// criteria.setProjection(Projections.distinct(Projections.id()));
// criteria.setResultTransformer(DistinctResultTransformer.INSTANCE);
criteria.addOrder(Order.asc(VirtualMachineTemplate.NAME_PROPERTY));
List<VirtualMachineTemplate> result = getResultList(criteria);
return distinct(result);
}
public List<VirtualMachineTemplate> findBy(final Category category)
{
Criteria criteria = createCriteria(sameCategory(category));
criteria.addOrder(Order.asc(VirtualMachineTemplate.NAME_PROPERTY));
List<VirtualMachineTemplate> result = getResultList(criteria);
return result;
}
private List<VirtualMachineTemplate> distinct(final List<VirtualMachineTemplate> ins)
{
List<VirtualMachineTemplate> outs = new LinkedList<VirtualMachineTemplate>();
Set<Integer> ids = new HashSet<Integer>();
for (VirtualMachineTemplate in : ins)
{
if (!ids.contains(in.getId()))
{
ids.add(in.getId());
outs.add(in);
}
}
return outs;
}
public List<VirtualMachineTemplate> findImportedBy(final Enterprise enterprise,
final Category category, final HypervisorType hypervisor)
{
Criteria criteria = createCriteria(importedVirtualMachineTemplate(enterprise));
if (category != null)
{
criteria.add(sameCategory(category));
}
if (hypervisor != null)
{
criteria.add(compatibleOrConversions(hypervisor, criteria));
}
criteria.addOrder(Order.asc(VirtualMachine.NAME_PROPERTY));
List<VirtualMachineTemplate> result = getResultList(criteria);
return result;
}
private Criterion importedVirtualMachineTemplate(final Enterprise enterprise)
{
return Restrictions.and(sameEnterprise(enterprise), repositoryNull());
}
/** Virtual Machine Template compatible or some conversion compatible. */
private Criterion compatibleOrConversions(final HypervisorType hypervisorType,
final Criteria criteria)
{
return Restrictions.or(compatible(hypervisorType.compatibleFormats), //
compatibleConversions(hypervisorType.compatibleFormats, criteria));
}
/** Virtual Machine Template is compatible. */
private Criterion compatible(final Collection<DiskFormatType> types)
{
return Restrictions.in(VirtualMachineTemplate.DISKFORMAT_TYPE_PROPERTY, types);
}
/**
* If (finished) conversions check some compatible. Left join to {@link VirtualImageConversion}
*/
private Criterion compatibleConversions(final Collection<DiskFormatType> types,
final Criteria criteria)
{
criteria.createAlias(VirtualMachineTemplate.CONVERSIONS_PROPERTY, "conversions",
JoinFragment.LEFT_OUTER_JOIN);
Criterion finished =
Restrictions.eq("conversions." + VirtualImageConversion.STATE_PROPERTY,
ConversionState.FINISHED);
Criterion compatible =
Restrictions.in("conversions." + VirtualImageConversion.TARGET_TYPE_PROPERTY, types);
return Restrictions.and(finished, compatible);
}
/** ######### */
public VirtualMachineTemplate findByName(final String name)
{
return findUniqueByProperty(VirtualMachineTemplate.NAME_PROPERTY, name);
}
public VirtualMachineTemplate findByPath(final Enterprise enterprise,
final com.abiquo.server.core.infrastructure.Repository repository, final String path)
{
Criteria criteria =
createCriteria(sameEnterpriseOrSharedInRepo(enterprise, repository, path));
criteria.addOrder(Order.asc(VirtualMachine.NAME_PROPERTY));
return getSingleResult(criteria);
}
public boolean existWithSamePath(final Enterprise enterprise,
final com.abiquo.server.core.infrastructure.Repository repository, final String path)
{
Criteria criteria =
createCriteria(sameEnterpriseOrSharedInRepo(enterprise, repository, path));
criteria.addOrder(Order.asc(VirtualMachine.NAME_PROPERTY));
List<VirtualMachineTemplate> result = getResultList(criteria);
return CollectionUtils.isEmpty(result) ? false : true;
}
public List<VirtualMachineTemplate> findStatefuls()
{
Criteria criteria = createCriteria();
criteria.add(statefulVirtualMachineTemplate(StatefulInclusion.ALL, criteria));
criteria.addOrder(Order.asc(VirtualMachine.NAME_PROPERTY));
return getResultList(criteria);
}
public List<VirtualMachineTemplate> findStatefulsByDatacenter(final Datacenter datacenter,
final StatefulInclusion stateful)
{
return findStatefulsByDatacenter(datacenter, null, stateful);
}
public List<VirtualMachineTemplate> findStatefulsByDatacenter(final Datacenter datacenter,
final VirtualDatacenter vdc, final StatefulInclusion stateful)
{
Criteria crit = criteriaWithStatefulNavigation();
crit.add(statefulVirtualMachineTemplate(stateful, crit));
crit.add(sameStatefulDatacenter(datacenter));
if (vdc != null)
{
crit.add(sameStatefulVirtualDatacenter(vdc));
}
crit.addOrder(Order.asc(VirtualMachineTemplate.NAME_PROPERTY));
return getResultList(crit);
}
public List<VirtualMachineTemplate> findStatefulsByCategoryAndDatacenter(
final Category category, final Datacenter datacenter, final StatefulInclusion stateful)
{
return findStatefulsByCategoryAndDatacenter(category, datacenter, null, stateful);
}
public List<VirtualMachineTemplate> findStatefulsByCategoryAndDatacenter(
final Category category, final Datacenter datacenter, final VirtualDatacenter vdc,
final StatefulInclusion stateful)
{
Criteria crit = criteriaWithStatefulNavigation();
crit.add(statefulVirtualMachineTemplate(stateful, crit));
crit.add(sameCategory(category));
crit.add(sameStatefulDatacenter(datacenter));
if (vdc != null)
{
crit.add(sameStatefulVirtualDatacenter(vdc));
}
crit.addOrder(Order.asc(VirtualMachineTemplate.NAME_PROPERTY));
return getResultList(crit);
}
public List<VirtualMachineTemplate> findByMaster(final VirtualMachineTemplate master)
{
Criteria criteria = createCriteria(sameMaster(master));
return getResultList(criteria);
}
public boolean isMaster(final VirtualMachineTemplate vmtemplate)
{
Criteria criteria = createCriteria(sameMaster(vmtemplate));
return CollectionUtils.isEmpty(getResultList(criteria)) ? false : true;
}
private static Criterion sameCategory(final Category category)
{
return Restrictions.eq(VirtualMachineTemplate.CATEGORY_PROPERTY, category);
}
private static Criterion sameEnterprise(final Enterprise enterprise)
{
return Restrictions.eq(VirtualMachineTemplate.ENTERPRISE_PROPERTY, enterprise);
}
private static Criterion sameRepositoryAndNotStatefull(
final com.abiquo.server.core.infrastructure.Repository repository)
{
// return Restrictions.and(Restrictions.eq(VirtualMachineTemplate.STATEFUL_PROPERTY, false),
// Restrictions.eq(VirtualMachineTemplate.REPOSITORY_PROPERTY, repository));
return Restrictions.eq(VirtualMachineTemplate.REPOSITORY_PROPERTY, repository);
}
private static Criterion repositoryNull()
{
return Restrictions.isNull(VirtualMachineTemplate.REPOSITORY_PROPERTY);
}
private static Criterion sharedVirtualMachineTemplate()
{
return Restrictions.eq(VirtualMachineTemplate.SHARED_PROPERTY, true);
}
private static Criterion statefulVirtualMachineTemplate(final StatefulInclusion stateful,
final Criteria criteria)
{
Criterion cri = Restrictions.eq(VirtualMachineTemplate.STATEFUL_PROPERTY, true);
switch (stateful)
{
case ALL:
Restrictions.and(cri,
Restrictions.isNotNull(VirtualMachineTemplate.VOLUME_PROPERTY));
break;
case USED:
// use function criteriaWithStatefulNavigation before
return Restrictions.and(cri,
Restrictions.eq("vl." + VolumeManagement.STATE_PROPERTY, VolumeState.ATTACHED));
case NOTUSED:
// use function criteriaWithStatefulNavigation before
return Restrictions.and(cri,
Restrictions.eq("vl." + VolumeManagement.STATE_PROPERTY, VolumeState.DETACHED));
}
return cri;
}
private static Criterion sameEnterpriseOrShared(final Enterprise enterprise)
{
return Restrictions.or(sameEnterprise(enterprise), sharedVirtualMachineTemplate());
}
private static Criterion sameEnterpriseOrSharedInRepo(final Enterprise enterprise,
final com.abiquo.server.core.infrastructure.Repository repository)
{
return Restrictions.and(sameRepositoryAndNotStatefull(repository),
Restrictions.or(sameEnterprise(enterprise), sharedVirtualMachineTemplate()));
}
private static Criterion sameEnterpriseOrSharedInRepo(final Enterprise enterprise,
final com.abiquo.server.core.infrastructure.Repository repository, final String path)
{
Criterion sameEnterpriseOrSharedInRepo =
Restrictions.and(sameRepositoryAndNotStatefull(repository),
Restrictions.or(sameEnterprise(enterprise), sharedVirtualMachineTemplate()));
return Restrictions.and(Restrictions.eq(VirtualMachineTemplate.PATH_PROPERTY, path),
sameEnterpriseOrSharedInRepo);
}
private static Criterion sameMaster(final VirtualMachineTemplate vmtemplate)
{
return Restrictions.eq(VirtualMachineTemplate.MASTER_PROPERTY, vmtemplate);
}
private static Criterion sameStatefulDatacenter(final Datacenter datacenter)
{
return Restrictions.eq("device." + StorageDevice.DATACENTER_PROPERTY, datacenter);
}
private static Criterion sameStatefulVirtualDatacenter(final VirtualDatacenter virtualDatacenter)
{
return Restrictions.eq("vl." + RasdManagement.VIRTUAL_DATACENTER_PROPERTY,
virtualDatacenter);
}
public List<String> findIconsByEnterprise(final Integer enterpriseId)
{
Query query = getSession().createQuery(FIND_ICONS_BY_ENTERPRISE);
return query.setParameter("enterpriseId", enterpriseId).list();
}
private Criteria criteriaWithStatefulNavigation()
{
Criteria crit = createCriteria();
crit.createAlias(VirtualMachineTemplate.VOLUME_PROPERTY, "vl");
crit.createAlias("vl." + VolumeManagement.STORAGE_POOL_PROPERTY, "pool");
crit.createAlias("pool." + StoragePool.DEVICE_PROPERTY, "device");
return crit;
}
}