/** * Copyright (c) 2009 - 2012 Red Hat, Inc. * * This software is licensed to you under the GNU General Public License, * version 2 (GPLv2). There is NO WARRANTY for this software, express or * implied, including the implied warranties of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2 * along with this software; if not, see * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. * * Red Hat trademarks are not licensed under GPLv2. No permission is * granted to use or replicate Red Hat trademarks that are incorporated * in this software or its documentation. */ package org.candlepin.policy.criteria; import org.candlepin.common.config.Configuration; import org.candlepin.model.Consumer; import org.candlepin.model.ConsumerCurator; import org.candlepin.model.Pool; import org.candlepin.model.PoolFilterBuilder; import com.google.inject.Inject; import org.hibernate.criterion.Criterion; import org.hibernate.criterion.DetachedCriteria; import org.hibernate.criterion.Projections; import org.hibernate.criterion.Restrictions; import org.hibernate.criterion.Subqueries; import java.util.LinkedList; import java.util.List; /** * CriteriaRules * * A class used to generate database criteria for filtering out rules that are not applicable for a * consumer before running them through a rules check. */ public class CriteriaRules { protected Configuration config; protected ConsumerCurator consumerCurator; @Inject public CriteriaRules(Configuration config, ConsumerCurator consumerCurator) { this.config = config; this.consumerCurator = consumerCurator; } /** * Create a List of JPA criterion that can filter out pools that are not * applicable to consumer. Helps to scale down large numbers of pools * specifically with virt_limit subscriptions. * * @param consumer The consumer we are filtering pools for * @return List of Criterion */ @SuppressWarnings("checkstyle:indentation") public List<Criterion> availableEntitlementCriteria(Consumer consumer) { // avoid passing in a consumerCurator just to get the host // consumer UUID Consumer hostConsumer = null; if (consumer.getFact("virt.uuid") != null) { hostConsumer = consumerCurator.getHost(consumer.getFact("virt.uuid"), consumer.getOwner()); } List<Criterion> criteriaFilters = new LinkedList<Criterion>(); // Don't load virt_only pools if this consumer isn't a guest // or a manifest consumer if (consumer.isManifestDistributor()) { DetachedCriteria requiresHost = DetachedCriteria.forClass(Pool.class, "pool2") .createAlias("pool2.attributes", "attrib") .add(Restrictions.eqProperty("pool2.id", "id")) .add(Restrictions.eq("attrib.indicies", Pool.Attributes.REQUIRES_HOST)) .setProjection(Projections.id()); // we do want everything else criteriaFilters.add(Subqueries.notExists(requiresHost)); } else if (!consumer.isGuest()) { PoolFilterBuilder filterBuilder = new PoolFilterBuilder(); filterBuilder.addAttributeFilter("virt_only", "true"); criteriaFilters.add(Restrictions.not(filterBuilder.getCriteria())); } else { // we are a virt guest // add criteria for filtering out pools that are not for this guest if (consumer.hasFact("virt.uuid")) { String hostUuid = ""; // need a default value in case there is no host if (hostConsumer != null) { hostUuid = hostConsumer.getUuid(); } // Note: looking for pools that are not for this guest // we do want everything else DetachedCriteria wrongRequiresHost = DetachedCriteria.forClass(Pool.class, "pool2") .createAlias("pool2.attributes", "attrib") .add(Restrictions.eqProperty("pool2.id", "id")) .add(Restrictions.eq("attrib.indicies", Pool.Attributes.REQUIRES_HOST)) .add(Restrictions.ne("attrib.elements", hostUuid).ignoreCase()) .setProjection(Projections.id()); criteriaFilters.add(Subqueries.notExists(wrongRequiresHost)); } // no virt.uuid, we can't try to filter } return criteriaFilters; } }