/**
* 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.enterprise;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceException;
import javax.persistence.Query;
import javax.validation.constraints.NotNull;
import org.apache.commons.lang.StringUtils;
import org.hibernate.Criteria;
import org.hibernate.SQLQuery;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Disjunction;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import com.abiquo.server.core.common.DefaultEntityCurrentUsed;
import com.abiquo.server.core.common.persistence.DefaultDAOBase;
import com.abiquo.server.core.common.persistence.JPAConfiguration;
import com.abiquo.server.core.infrastructure.network.IpPoolManagement;
import com.abiquo.server.core.infrastructure.network.IpPoolManagementDAO;
import com.abiquo.server.core.infrastructure.network.VLANNetwork;
import com.abiquo.server.core.infrastructure.network.VLANNetworkDAO;
import com.abiquo.server.core.pricing.PricingTemplate;
import com.abiquo.server.core.util.PagedList;
import com.softwarementors.bzngine.entities.PersistentEntity;
@Repository("jpaEnterpriseDAO")
class EnterpriseDAO extends DefaultDAOBase<Integer, Enterprise>
{
@Autowired
private VLANNetworkDAO vlanNetDAO;
@Autowired
private IpPoolManagementDAO ipPoolDao;
public EnterpriseDAO()
{
super(Enterprise.class);
}
public EnterpriseDAO(final EntityManager entityManager)
{
super(Enterprise.class, entityManager);
this.vlanNetDAO = new VLANNetworkDAO(entityManager);
this.ipPoolDao = new IpPoolManagementDAO(entityManager);
}
@Override
public List<Enterprise> findAll()
{
return createCriteria().list();
}
public List<Enterprise> findAll(Integer firstElem, final Integer numResults, final int idScope)
{
try
{
// Check if the page requested is bigger than the last one
Criteria criteria = createCriteria();
if (!Scope.DEFAULT_SCOPE_ID.equals(idScope))
{
JPAConfiguration.enableScopeFilter(getEntityManager(), idScope);
}
Number total = count();
if (firstElem >= total.intValue())
{
firstElem = total.intValue() - numResults;
}
criteria.setFirstResult(firstElem);
criteria.setMaxResults(numResults);
List<Enterprise> result = getResultList(criteria);
PagedList<Enterprise> page = new PagedList<Enterprise>(result);
page.setCurrentElement(firstElem);
page.setPageSize(numResults);
page.setTotalResults(total.intValue());
return page;
}
finally
{
JPAConfiguration.disableScopeFilter(getEntityManager());
}
}
public List<Enterprise> findByNameAnywhere(final String name, final int idScope)
{
try
{
assert name != null;
Criteria criteria = createCriteria(nameLikeAnywhere(name));
criteria.addOrder(Order.asc(Enterprise.NAME_PROPERTY));
if (!Scope.DEFAULT_SCOPE_ID.equals(idScope))
{
JPAConfiguration.enableScopeFilter(getEntityManager(), idScope);
}
List<Enterprise> result = getResultList(criteria);
return result;
}
finally
{
JPAConfiguration.disableScopeFilter(getEntityManager());
}
}
public List<Enterprise> findByPricingTemplate(Integer firstElem, final PricingTemplate pt,
final boolean included, final String filterName, final Integer numResults,
final Integer idEnterprise, final int idScope)
{
// Check if the page requested is bigger than the last one
try
{
Criteria criteria = createCriteria(pt, included, filterName, idEnterprise);
Number total = count(criteria);
if (firstElem >= total.intValue())
{
firstElem = total.intValue() - numResults;
}
criteria = createCriteria(pt, included, filterName, idEnterprise);
if (!Scope.DEFAULT_SCOPE_ID.equals(idScope))
{
JPAConfiguration.enableScopeFilter(getEntityManager(), idScope);
}
criteria.setFirstResult(firstElem);
criteria.setMaxResults(numResults);
List<Enterprise> result = getResultList(criteria);
PagedList<Enterprise> page = new PagedList<Enterprise>();
page.addAll(result);
page.setCurrentElement(firstElem);
page.setPageSize(numResults);
page.setTotalResults(total.intValue());
return page;
}
finally
{
JPAConfiguration.disableScopeFilter(getEntityManager());
}
}
private static Criterion nameLikeAnywhere(final String name)
{
assert name != null;
if (StringUtils.isEmpty(name))
{
return null;
}
return Restrictions.ilike(Enterprise.NAME_PROPERTY, name, MatchMode.ANYWHERE);
}
@Override
public void persist(final Enterprise enterprise)
{
assert enterprise != null;
assert !isManaged(enterprise);
assert !existsAnyWithName(enterprise.getName());
super.persist(enterprise);
}
public boolean existsAnyWithName(final String name)
{
assert !StringUtils.isEmpty(name);
return existsAnyByCriterions(nameEqual(name));
}
private Criterion nameEqual(final String name)
{
assert name != null;
return Restrictions.eq(Enterprise.NAME_PROPERTY, name);
}
public boolean existsAnyOtherWithName(final Enterprise enterprise, final String name)
{
assert enterprise != null;
assert isManaged(enterprise);
assert !StringUtils.isEmpty(name);
return existsAnyOtherByCriterions(enterprise, nameEqual(name));
}
private Criterion differentPricingTemplateOrNull(final PricingTemplate pricingTemplate)
{
Disjunction filterDisjunction = Restrictions.disjunction();
filterDisjunction.add(Restrictions.ne(Enterprise.PRICING_PROPERTY, pricingTemplate));
filterDisjunction.add(Restrictions.isNull(Enterprise.PRICING_PROPERTY));
return filterDisjunction;
// return Restrictions.eq(Enterprise.PRICING_PROPERTY, pricingTemplate);
}
private Criterion samePricingTemplate(final PricingTemplate pricingTemplate)
{
Disjunction filterDisjunction = Restrictions.disjunction();
filterDisjunction.add(Restrictions.eq(Enterprise.PRICING_PROPERTY, pricingTemplate));
return filterDisjunction;
// return Restrictions.eq(Enterprise.PRICING_PROPERTY, pricingTemplate);
}
private Criterion withPricingTemplate()
{
Disjunction filterDisjunction = Restrictions.disjunction();
filterDisjunction.add(Restrictions.isNotNull(Enterprise.PRICING_PROPERTY));
return filterDisjunction;
}
private Criterion withoutPricingTemplate()
{
Disjunction filterDisjunction = Restrictions.disjunction();
filterDisjunction.add(Restrictions.isNull(Enterprise.PRICING_PROPERTY));
return filterDisjunction;
}
private Criterion filterBy(final String filter)
{
Disjunction filterDisjunction = Restrictions.disjunction();
filterDisjunction.add(Restrictions.like(Role.NAME_PROPERTY, '%' + filter + '%'));
return filterDisjunction;
}
private static final String SUM_VM_RESOURCES =
"select sum(vm.cpu), sum(vm.ram), sum(vm.hd) from virtualmachine vm, hypervisor hy, physicalmachine pm "
+ " where hy.id = vm.idHypervisor and pm.idPhysicalMachine = hy.idPhysicalMachine "// and
// pm.idState
// !=
// 7"
// //
// not
// HA_DISABLED
+ " and vm.idEnterprise = :enterpriseId and vm.state != 'NOT_ALLOCATED' and vm.idHypervisor is not null and vm.temporal is null";
private static final String SUM_EXTRA_HD_RESOURCES =
"select sum(r.limitResource) from rasd r, rasd_management rm, virtualdatacenter vdc, virtualmachine vm where r.instanceID = rm.idResource "
+ "and rm.idResourceType = '17' and rm.idVirtualDatacenter = vdc.idVirtualDatacenter and vdc.idEnterprise=:enterpriseId "
+ "and rm.idVM = vm.idVM and vm.state != 'NOT_ALLOCATED' and vm.idHypervisor is not null";
private static final String SUM_STORAGE_RESOURCES = "select sum(r.limitResource) "
+ "from volume_management vm, rasd_management rm, virtualdatacenter vdc, rasd r "
+ "where vm.idManagement = rm.idManagement "//
+ "and rm.idResource = r.instanceID " //
+ "and rm.idVirtualDataCenter = vdc.idVirtualDataCenter " //
+ "and vdc.idEnterprise = :enterpriseId";
public DefaultEntityCurrentUsed getEnterpriseResourceUsage(final int enterpriseId)
{
Object[] vmResources =
(Object[]) getSession().createSQLQuery(SUM_VM_RESOURCES)
.setParameter("enterpriseId", enterpriseId).uniqueResult();
Long cpu = vmResources[0] == null ? 0 : ((BigDecimal) vmResources[0]).longValue();
Long ram = vmResources[1] == null ? 0 : ((BigDecimal) vmResources[1]).longValue();
Long hd = vmResources[2] == null ? 0 : ((BigDecimal) vmResources[2]).longValue();
BigDecimal extraHd =
(BigDecimal) getSession().createSQLQuery(SUM_EXTRA_HD_RESOURCES)
.setParameter("enterpriseId", enterpriseId).uniqueResult();
Long hdTot = extraHd == null ? hd : hd + extraHd.longValue() * 1024 * 1024;
Long storage = getStorageUsage(enterpriseId) * 1024 * 1024; // Storage usage is stored in MB
Long publiIp = getPublicIPUsage(enterpriseId);
Long vlanCount = getVLANUsage(enterpriseId);
// TODO repository
// XXX checking null resource utilization (if any resource allocated)
DefaultEntityCurrentUsed used = new DefaultEntityCurrentUsed(cpu.intValue(), ram, hdTot);
used.setStorage(storage);
used.setPublicIp(publiIp);
used.setVlanCount(vlanCount);
return used;
}
/**
* Gets the storage usage for the given enterprise.
*
* @param idEnterprise The enterprise being checked.
* @return The amount of used storage.
* @throws PersistenceException If an error occurs.
*/
public Long getStorageUsage(final Integer idEnterprise)
{
// [ABICLOUDPREMIUM-4172] A SQL query must be used here, to avoid taking into account the
// objects in the Hibernate session that can have been already modified.
// This is the case of volume resize, when this method is called with the object modified in
// the session (but still not flushed)
BigDecimal storageInDB =
(BigDecimal) getSession().createSQLQuery(SUM_STORAGE_RESOURCES)
.setParameter("enterpriseId", idEnterprise).uniqueResult();
return storageInDB == null ? 0L : storageInDB.longValue();
}
/**
* Gets the vlan usage for the given enterprise.
*
* @param idEnterprise The enterprise being checked.
* @return The amount of used vlans.
* @throws PersistenceException If an error occurs.
*/
private Long getVLANUsage(final Integer idEnterprise)
{
final List<VLANNetwork> vlans = vlanNetDAO.findByEnterprise(idEnterprise);
// TODO count
return Long.valueOf(vlans.size());
}
/**
* Gets the public IP usage for the given enterprise.
*
* @param idEnterprise The enterprise being checked.
* @return The amount of used public IPs.
* @throws PersistenceException If an error occurs.
*/
private Long getPublicIPUsage(final Integer idEnterprise)
{
final List<IpPoolManagement> publicIPs =
ipPoolDao.getPublicNetworkPoolPurchasedByEnterprise(idEnterprise);
return Long.valueOf(publicIPs.size());
}
/**
* Gets the repository usage for the given enterprise.
*
* @param idEnterprise The enterprise being checked.
* @return The amount of used repository space.
* @throws PersistenceException If an error occurs.
*/
private Long getRepositoryUsage(final Integer idEnterprise)
{
// TODO unimplemented
return 0l;
// @Autowired
// DatacenterRep datacenterRep;
//
// @Autowired
// RemoteServiceDAO remoteServiceDao;
// long repoUsed = 0L;
//
// final List<Datacenter> datacenters = datacenterRep.findAll();
//
// for (final Datacenter dc : datacenters)
// {
//
// try
// {
// final String amUrl =
// remoteServiceDao.getRemoteServiceUri(dc, RemoteServiceType.APPLIANCE_MANAGER);
//
// final EnterpriseRepositoryDto repoData =
// amStub.getRepository(am.getUri(), String.valueOf(idEnterprise));
//
// repoUsed += repoData.getRepositoryEnterpriseUsedMb();
//
// }
// catch (Exception e) // am not defined on this datacenter
// {
//
// }
// }
//
// return repoUsed;
}
public boolean existAnyEnterpriseWithPricingTemplate(final PricingTemplate pricingTemplate)
{
return existsAnyByCriterions(samePricingTemplate(pricingTemplate));
}
private Criteria createCriteria(final PricingTemplate pricingTemplate, final boolean included,
final String filter, final Integer enterpriseId)
{
Criteria criteria = createCriteria();
if (included && pricingTemplate != null)
{
criteria.add(samePricingTemplate(pricingTemplate));
}
else if (included && pricingTemplate == null)
{
criteria.add(withPricingTemplate());
}
else if (!included && pricingTemplate != null)
{
criteria.add(differentPricingTemplateOrNull(pricingTemplate));
}
else if (!included && pricingTemplate == null)
{
criteria.add(withoutPricingTemplate());
}
if (enterpriseId != null)
{
criteria.add(Restrictions.eq(PersistentEntity.ID_PROPERTY, enterpriseId));
}
if (!StringUtils.isEmpty(filter))
{
criteria.add(filterBy(filter));
}
return criteria;
}
public static final String NAMED_QUERY_COUNT_ID_NAME_BY_SCOPE =
"select count(*) from Enterprise e where e.name like :name";
public Collection<Enterprise> findByScope(
final int idScope,
Integer startwith,
final @NotNull(message = "EnterpriseDAO.findByScope filter name cannot be null") String filterName,
final Integer numResults)
{
try
{
Query q =
getEntityManager().createNamedQuery(Enterprise.NAMED_QUERY_FIND_ID_NAME_BY_SCOPE);
q.setParameter("name", "%" + filterName + "%");
q.setFirstResult(startwith);
q.setMaxResults(numResults);
if (!Scope.DEFAULT_SCOPE_ID.equals(idScope))
{
JPAConfiguration.enableScopeFilter(getEntityManager(), idScope);
}
// This not initialize the collection (also is same as projection).
int total =
((Long) getSession().createQuery(NAMED_QUERY_COUNT_ID_NAME_BY_SCOPE)
.setString("name", "%" + filterName + "%").iterate().next()).intValue();
if (startwith >= total)
{
startwith = total - numResults;
}
List<Enterprise> result = q.getResultList();
PagedList<Enterprise> page = new PagedList<Enterprise>();
page.addAll(result);
page.setCurrentElement(startwith);
page.setPageSize(numResults);
page.setTotalResults(total);
return page;
}
finally
{
if (!Scope.DEFAULT_SCOPE_ID.equals(idScope))
{
JPAConfiguration.disableScopeFilter(getEntityManager());
}
}
}
@Override
public Enterprise findById(final Integer id)
{
Criteria criteria = createCriteria();
criteria.add(Restrictions.eq(PersistentEntity.ID_PROPERTY, id));
return (Enterprise) criteria.uniqueResult();
}
public boolean isEnterpriseWithinUserScope(final String userName, final Integer idEnt)
{
SQLQuery query = getSession().createSQLQuery(USER_DEFAULT_SCOPE);
query.setParameter("username", userName);
List result = query.list();
// check if the scope is the global then the enterprise is allowed
if (!result.isEmpty())
{
return true;
}
// in other case we have to check if enterprise is in scope
query = getSession().createSQLQuery(ENTERPRISE_WITHIN_USER_SCOPE);
query.setParameter("username", userName);
query.setParameter("identerprise", idEnt);
result = query.list();
return !(result == null || result.isEmpty());
}
private static final String USER_DEFAULT_SCOPE =
"select 1 FROM user u, role r ,scope s where u.user=:username and u.idRole=r.idRole and (r.idScope ='1' or(r.idScope=s.id and s.name='Global scope')) ";
private static final String ENTERPRISE_WITHIN_USER_SCOPE =
"select 1 FROM user u, role r,enterprise e, scope_resource s where e.idEnterprise=:identerprise and e.idEnterprise=s.idResource and u.user=:username and u.idRole=r.idRole and r.idScope =s.idScope and s.resourceType='ENTERPRISE'";
}