/**
* Copyright (C) 2008 - Abiquo Holdings S.L. All rights reserved.
*
* Please see /opt/abiquo/tomcat/webapps/legal/ on Abiquo server
* or contact contact@abiquo.com for licensing information.
*/
package com.abiquo.server.core.appslibrary;
import java.util.Collection;
import java.util.List;
import javax.persistence.EntityManager;
import org.apache.commons.collections.CollectionUtils;
import org.hibernate.Criteria;
import org.hibernate.NonUniqueObjectException;
import org.hibernate.Query;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Restrictions;
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.VMTemplateState;
import com.abiquo.server.core.cloud.Hypervisor;
import com.abiquo.server.core.cloud.NodeVirtualImage;
import com.abiquo.server.core.common.persistence.DefaultDAOBase;
@Repository("jpaVirtualImageConversionDAO")
public class VirtualImageConversionDAO extends DefaultDAOBase<Integer, VirtualImageConversion>
{
public VirtualImageConversionDAO()
{
super(VirtualImageConversion.class);
}
public VirtualImageConversionDAO(final EntityManager entityManager)
{
super(VirtualImageConversion.class, entityManager);
}
private static Criterion sameImage(final VirtualMachineTemplate image)
{
return Restrictions.eq(VirtualImageConversion.VIRTUAL_MACHINE_TEMPLATE_PROPERTY, image);
}
private static Criterion sameImageAndSourcePath(final VirtualImageConversion conversion)
{
final Criterion sameimage =
Restrictions.eq(VirtualImageConversion.VIRTUAL_MACHINE_TEMPLATE_PROPERTY,
conversion.getVirtualMachineTemplate());
final Criterion samesourcepath =
Restrictions
.eq(VirtualImageConversion.SOURCE_PATH_PROPERTY, conversion.getSourcePath());
return Restrictions.and(sameimage, samesourcepath);
}
private static Criterion sameSourceFormat(final VirtualImageConversion image)
{
return Restrictions.eq(VirtualImageConversion.SOURCE_TYPE_PROPERTY, image.getSourceType());
}
private static Criterion sameTargetFormat(final VirtualImageConversion image)
{
return sameTargetFormat(image.getTargetType());
}
private static Criterion sameTargetFormat(final DiskFormatType targetFormat)
{
return Restrictions.eq(VirtualImageConversion.TARGET_TYPE_PROPERTY, targetFormat);
}
private static Criterion sameState(final ConversionState state)
{
return Restrictions.eq(VirtualImageConversion.STATE_PROPERTY, state);
}
private static Criterion targetFormatIn(final DiskFormatType... formats)
{
return Restrictions.in(VirtualImageConversion.TARGET_TYPE_PROPERTY, formats);
}
private static Criterion sourceFormatNull()
{
return Restrictions.isNull(VirtualImageConversion.SOURCE_TYPE_PROPERTY);
}
/**
* Get all the provided hypervisor compatible {@link VirtualImageConversion} for a given
* {@link HypervisorType}
* <p>
* Before calling this method assure the virtualImage format IS NOT the hypervisorType base
* format or compatible (conversion not needed). @see
* {@link VirtualMachineServicePremium#shouldFindConversion}
*
* @return the list of all compatible {@link VirtualImageConversion} in <b>ANY state</b>.
* {@link VirtualMachineServicePremium#selectConversion} will check the state and pick
* the most suitable format.
*/
@SuppressWarnings("unchecked")
public List<VirtualImageConversion> compatilbeConversions(
final VirtualMachineTemplate virtualImage, final HypervisorType hypervisorType)
{
final Criterion compat =
Restrictions.and(sameImage(virtualImage),
targetFormatIn(hypervisorType.compatibilityTable));
return createCriteria(compat).list();
}
/**
* @param hypervisorType, optionally specify only compatible conversions with this hypervisor
* @param state, optionally specify the desired state of the conversions
*/
public List<VirtualImageConversion> getConversionsOptionalHypervisorTypeAndState(
final VirtualMachineTemplate virtualImage, final HypervisorType hypervisorType,
final ConversionState state)
{
Criterion criterion = sameImage(virtualImage);
if (hypervisorType != null)
{
criterion =
Restrictions.and(criterion, targetFormatIn(hypervisorType.compatibilityTable));
}
if (state != null)
{
criterion = Restrictions.and(criterion, sameState(state));
}
return createCriteria(criterion).list();
}
/**
* Returns a list of {@link HypervisorType} from all hypervisors in a datacenter.
*/
private final String QUERY_IMAGE_CONVERTED = "SELECT count(vic) " + //
"FROM com.abiquo.server.core.appslibrary.VirtualImageConversion vic " + //
"WHERE vic.virtualImage.id = :idVirtualImage";
/**
* List of {@link HypervisorType} from all hypervisors in a datacenter.
*
* @param datacenterId {@link Hypervisor} machines datacenter.
* @return list of {@link HypervisorType} from all hypervisors in a datacenter.
*/
public boolean isVirtualImageConverted(final Integer vImageId, final DiskFormatType format)
{
Query query = getSession().createQuery(QUERY_IMAGE_CONVERTED);
query.setParameter("idVirtualImage", vImageId);
return (Long) query.uniqueResult() > 0;
}
@Deprecated
// use selectConversion TODO delthis
@SuppressWarnings("unchecked")
public VirtualImageConversion getUnbundledConversion(final VirtualMachineTemplate image,
final DiskFormatType format)
{
// There can be no images
List<VirtualImageConversion> conversions =
createCriteria(sameImage(image)).add(targetFormatIn(format)).add(sourceFormatNull())
.list();
// Are there any?
if (conversions != null && !conversions.isEmpty())
{
// This function should be returning the only object
if (conversions.size() > 1)
{
throw new NonUniqueObjectException("There is more than one conversion!",
image.getId(),
VirtualImageConversion.class.getSimpleName());
}
return conversions.get(0);
}
return null;
}
public boolean isConverted(final VirtualMachineTemplate image, final DiskFormatType targetType)
{
final Criterion compat = Restrictions.and(sameImage(image), targetFormatIn(targetType));
return !createCriteria(compat).list().isEmpty();
}
public List<VirtualImageConversion> findByVirtualImage(final VirtualMachineTemplate virtualImage)
{
final Criteria criteria = createCriteria().add(sameImage(virtualImage));
return criteria.list();
}
private final String VIRTUALIMAGECONVERSION_BY_NODEVIRTUALIMAGE = "SELECT "
+ "vic FROM com.abiquo.server.core.appslibrary.VirtualImageConversion vic, "
+ "com.abiquo.server.core.cloud.NodeVirtualImage nvi "
+ "WHERE nvi.id = :idVirtualImageConversion AND nvi.virtualImage.id = vic.virtualImage.id";
public Collection<VirtualImageConversion> findByVirtualImageConversionByNodeVirtualImage(
final NodeVirtualImage nodeVirtualImage)
{
Query query = getSession().createQuery(VIRTUALIMAGECONVERSION_BY_NODEVIRTUALIMAGE);
query.setParameter("idVirtualImageConversion", nodeVirtualImage.getId());
return query.list();
}
private final String DATACENTERUUID_BY_VIRTUALIMAGECONVERSION =
"select distinct(dc.uuid) from virtualimage_conversions vic left outer join virtualimage vi on vic.idImage = vi.idImage left outer join repository rep on vi.idRepository = rep.idRepository left outer join datacenter dc on rep.idDataCenter = dc.idDatacenter where vic.id = :idVirtualImageConversion";
public String getDatacenterUUIDByVirtualImageConversionID(final Integer idVirtualImageConversion)
{
Query query = getSession().createSQLQuery(DATACENTERUUID_BY_VIRTUALIMAGECONVERSION);
query.setParameter("idVirtualImageConversion", idVirtualImageConversion);
return (String) query.uniqueResult();
}
public boolean existDuplicatedConversion(final VirtualImageConversion conversion)
{
Criterion cri =
Restrictions.and(sameImageAndSourcePath(conversion), sameSourceFormat(conversion));
cri = Restrictions.and(cri, sameTargetFormat(conversion));
return existsAnyByCriterions(cri);
}
/**
* @return null if the conversion doesn't exist for the provided target disk format type and
* virtual machine template
*/
public VirtualImageConversion getConversionByTemplateAndFormat(
final VirtualMachineTemplate virtualMachineTemplate, final DiskFormatType targetFormat)
{
Criteria cri =
createCriteria(Restrictions.and(sameImage(virtualMachineTemplate),
sameTargetFormat(targetFormat)));
Collection<VirtualImageConversion> convs = getResultList(cri);
return CollectionUtils.isEmpty(convs) ? null : convs.iterator().next();
}
}