Search in sources :

Example 6 with Pool

use of org.candlepin.model.Pool in project candlepin by candlepin.

the class CandlepinPoolManager method refreshPoolsForMasterPool.

@Transactional
void refreshPoolsForMasterPool(Pool pool, boolean updateStackDerived, boolean lazy, Map<String, Product> changedProducts) {
    // These don't all necessarily belong to this owner
    List<Pool> subscriptionPools;
    if (pool.getSubscriptionId() != null) {
        subscriptionPools = this.poolCurator.getPoolsBySubscriptionId(pool.getSubscriptionId()).list();
    } else {
        // If we don't have a subscription ID, this *is* the master pool, but we need to use
        // the original, hopefully unmodified pool
        subscriptionPools = pool.getId() != null ? Collections.<Pool>singletonList(this.poolCurator.find(pool.getId())) : Collections.<Pool>singletonList(pool);
    }
    log.debug("Found {} pools for subscription {}", subscriptionPools.size(), pool.getSubscriptionId());
    if (log.isDebugEnabled()) {
        for (Pool p : subscriptionPools) {
            log.debug("    owner={} - {}", p.getOwner().getKey(), p);
        }
    }
    // TODO: Should this be performed by poolRules? Seems like that should be a thing.
    for (Pool subPool : subscriptionPools) {
        Product product = subPool.getProduct();
        if (product != null) {
            Product update = changedProducts.get(product.getId());
            if (update != null) {
                subPool.setProduct(update);
            }
        }
        product = subPool.getDerivedProduct();
        if (product != null) {
            Product update = changedProducts.get(product.getId());
            if (update != null) {
                subPool.setDerivedProduct(update);
            }
        }
    }
    // Cleans up pools on other owners who have migrated subs away
    removeAndDeletePoolsOnOtherOwners(subscriptionPools, pool);
    // capture the original quantity to check for updates later
    Long originalQuantity = pool.getQuantity();
    // BZ 1012386: This will regenerate master/derived for bonus scenarios if only one of the
    // pair still exists.
    createAndEnrichPools(pool, subscriptionPools);
    // don't update floating here, we'll do that later so we don't update anything twice
    Set<String> updatedMasterPools = updatePoolsForMasterPool(subscriptionPools, pool, originalQuantity, updateStackDerived, changedProducts);
    regenerateCertificatesByEntIds(updatedMasterPools, lazy);
}
Also used : Product(org.candlepin.model.Product) Pool(org.candlepin.model.Pool) Transactional(com.google.inject.persist.Transactional)

Example 7 with Pool

use of org.candlepin.model.Pool in project candlepin by candlepin.

the class CandlepinPoolManager method getBestPoolsForHost.

/**
 * Here we pick uncovered products from the guest where no virt-only
 * subscriptions exist, and have the host bind non-zero virt_limit
 * subscriptions in order to generate pools for the guest to bind later.
 *
 * @param guest whose products we want to provide
 * @param host to bind entitlements to
 * @param entitleDate
 * @param owner
 * @param serviceLevelOverride
 * @return PoolQuantity list to attempt to attach
 * @throws EntitlementRefusedException if unable to bind
 */
@Override
@SuppressWarnings("checkstyle:methodlength")
public List<PoolQuantity> getBestPoolsForHost(Consumer guest, Consumer host, Date entitleDate, String ownerId, String serviceLevelOverride, Collection<String> fromPools) throws EntitlementRefusedException {
    Map<String, ValidationResult> failedResults = new HashMap<>();
    log.debug("Looking up best pools for host: {}", host);
    boolean tempLevel = false;
    if (StringUtils.isEmpty(host.getServiceLevel())) {
        host.setServiceLevel(guest.getServiceLevel());
        tempLevel = true;
    }
    Date activePoolDate = entitleDate;
    if (entitleDate == null) {
        activePoolDate = new Date();
    }
    PoolFilterBuilder poolFilter = new PoolFilterBuilder();
    poolFilter.addIdFilters(fromPools);
    List<Pool> allOwnerPools = this.listAvailableEntitlementPools(host, null, ownerId, null, null, activePoolDate, false, poolFilter, null, false, false, null).getPageData();
    log.debug("Found {} total pools in org.", allOwnerPools.size());
    logPools(allOwnerPools);
    List<Pool> allOwnerPoolsForGuest = this.listAvailableEntitlementPools(guest, null, ownerId, null, null, activePoolDate, false, poolFilter, null, false, false, null).getPageData();
    log.debug("Found {} total pools already available for guest", allOwnerPoolsForGuest.size());
    logPools(allOwnerPoolsForGuest);
    for (Entitlement ent : host.getEntitlements()) {
        // filter out pools that are attached, there is no need to
        // complete partial stacks, as they are already granting
        // virtual pools
        log.debug("Removing pool host is already entitled to: {}", ent.getPool());
        allOwnerPools.remove(ent.getPool());
    }
    List<Pool> filteredPools = new LinkedList<>();
    ComplianceStatus guestCompliance = complianceRules.getStatus(guest, entitleDate, false);
    Set<String> tmpSet = new HashSet<>();
    // we only want to heal red products, not yellow
    tmpSet.addAll(guestCompliance.getNonCompliantProducts());
    log.debug("Guest's non-compliant products: {}", Util.collectionToString(tmpSet));
    /*Do not attempt to create subscriptions for products that
          already have virt_only pools available to the guest */
    Set<String> productsToRemove = getProductsToRemove(allOwnerPoolsForGuest, tmpSet);
    log.debug("Guest already will have virt-only pools to cover: {}", Util.collectionToString(productsToRemove));
    tmpSet.removeAll(productsToRemove);
    String[] productIds = tmpSet.toArray(new String[] {});
    if (log.isDebugEnabled()) {
        log.debug("Attempting host autobind for guest products: {}", Util.collectionToString(tmpSet));
    }
    // Bulk fetch our provided and derived provided product IDs so we're not hitting the DB
    // several times for this lookup.
    Map<String, Set<String>> providedProductIds = this.poolCurator.getProvidedProductIds(allOwnerPools);
    Map<String, Set<String>> derivedProvidedProductIds = this.poolCurator.getDerivedProvidedProductIds(allOwnerPools);
    for (Pool pool : allOwnerPools) {
        boolean providesProduct = false;
        // and we only need to check that it's non-zero
        if (pool.getProduct().hasAttribute(Product.Attributes.VIRT_LIMIT) && !pool.getProduct().getAttributeValue(Product.Attributes.VIRT_LIMIT).equals("0")) {
            Map<String, Set<String>> providedProductMap;
            String baseProductId;
            // Determine which set of provided products we should use...
            if (pool.getDerivedProduct() != null) {
                providedProductMap = derivedProvidedProductIds;
                baseProductId = pool.getDerivedProduct().getId();
            } else {
                providedProductMap = providedProductIds;
                baseProductId = pool.getProduct().getId();
            }
            // Add the base product to the list of derived provided products...
            Set<String> poolProvidedProductIds = providedProductMap.get(pool.getId());
            if (baseProductId != null) {
                if (poolProvidedProductIds != null) {
                    poolProvidedProductIds.add(baseProductId);
                } else {
                    poolProvidedProductIds = Collections.<String>singleton(baseProductId);
                }
            }
            // Check if the pool provides any of the specified products
            if (poolProvidedProductIds != null) {
                for (String productId : productIds) {
                    // provides anything for the guest, otherwise we use the parent.
                    if (poolProvidedProductIds.contains(productId)) {
                        log.debug("Found virt_limit pool providing product {}: {}", productId, pool);
                        providesProduct = true;
                        break;
                    }
                }
            }
        }
        if (providesProduct) {
            ValidationResult result = enforcer.preEntitlement(host, pool, 1, CallerType.BEST_POOLS);
            if (result.hasErrors() || result.hasWarnings()) {
                // Just keep the last one around, if we need it
                failedResults.put(pool.getId(), result);
                if (log.isDebugEnabled()) {
                    log.debug("Pool filtered from candidates due to failed rule(s): {}", pool);
                    log.debug("  warnings: {}", Util.collectionToString(result.getWarnings()));
                    log.debug("  errors: {}", Util.collectionToString(result.getErrors()));
                }
            } else {
                filteredPools.add(pool);
            }
        }
    }
    // Only throw refused exception if we actually hit the rules:
    if (filteredPools.size() == 0 && !failedResults.isEmpty()) {
        throw new EntitlementRefusedException(failedResults);
    }
    ComplianceStatus hostCompliance = complianceRules.getStatus(host, entitleDate, false);
    log.debug("Host pools being sent to rules: {}", filteredPools.size());
    logPools(filteredPools);
    List<PoolQuantity> enforced = autobindRules.selectBestPools(host, productIds, filteredPools, hostCompliance, serviceLevelOverride, poolCurator.retrieveServiceLevelsForOwner(ownerId, true), true);
    if (log.isDebugEnabled()) {
        log.debug("Host selectBestPools returned {} pools: ", enforced.size());
        for (PoolQuantity poolQuantity : enforced) {
            log.debug("  " + poolQuantity.getPool());
        }
    }
    if (tempLevel) {
        host.setServiceLevel("");
        // complianceRules.getStatus may have persisted the host with the temp service level,
        // so we need to be certain we undo that.
        consumerCurator.update(host);
    }
    return enforced;
}
Also used : PoolQuantity(org.candlepin.model.PoolQuantity) Set(java.util.Set) HashSet(java.util.HashSet) HashMap(java.util.HashMap) ComplianceStatus(org.candlepin.policy.js.compliance.ComplianceStatus) EntitlementRefusedException(org.candlepin.policy.EntitlementRefusedException) ValidationResult(org.candlepin.policy.ValidationResult) Date(java.util.Date) LinkedList(java.util.LinkedList) PoolFilterBuilder(org.candlepin.model.PoolFilterBuilder) Pool(org.candlepin.model.Pool) Entitlement(org.candlepin.model.Entitlement) HashSet(java.util.HashSet)

Example 8 with Pool

use of org.candlepin.model.Pool in project candlepin by candlepin.

the class CandlepinPoolManager method createAndEnrichPools.

public List<Pool> createAndEnrichPools(Subscription sub, List<Pool> existingPools) {
    List<Pool> pools = poolRules.createAndEnrichPools(sub, existingPools);
    log.debug("Creating {} pools for subscription: {}", pools.size(), sub);
    for (Pool pool : pools) {
        createPool(pool);
    }
    return pools;
}
Also used : Pool(org.candlepin.model.Pool)

Example 9 with Pool

use of org.candlepin.model.Pool in project candlepin by candlepin.

the class CandlepinPoolManager method revokeEntitlements.

/**
 * Revokes the given set of entitlements.
 *
 * @param entsToRevoke entitlements to revoke
 * @param alreadyDeletedPools pools to skip deletion as they have already been deleted
 * @param regenCertsAndStatuses if this revocation should also trigger regeneration of certificates
 * and recomputation of statuses. For performance reasons some callers might
 * choose to set this to false.
 */
@Transactional
@Traceable
public void revokeEntitlements(List<Entitlement> entsToRevoke, Set<String> alreadyDeletedPools, boolean regenCertsAndStatuses) {
    if (CollectionUtils.isEmpty(entsToRevoke)) {
        return;
    }
    log.debug("Starting batch revoke of {} entitlements", entsToRevoke.size());
    if (log.isTraceEnabled()) {
        log.trace("Entitlements IDs: {}", getEntIds(entsToRevoke));
    }
    Set<Pool> poolsToDelete = this.poolCurator.listBySourceEntitlements(entsToRevoke);
    log.debug("Found {} additional pools to delete from source entitlements", poolsToDelete.size());
    if (log.isTraceEnabled()) {
        log.trace("Additional pool IDs: {}", getPoolIds(poolsToDelete));
    }
    List<Pool> poolsToLock = new ArrayList<>();
    poolsToLock.addAll(poolsToDelete);
    for (Entitlement ent : entsToRevoke) {
        poolsToLock.add(ent.getPool());
        // associated pool as well.
        if (ent.getPool() != null && ent.getPool().isDevelopmentPool()) {
            poolsToDelete.add(ent.getPool());
        }
    }
    poolCurator.lockAndLoad(poolsToLock);
    log.info("Batch revoking {} entitlements", entsToRevoke.size());
    entsToRevoke = new ArrayList<>(entsToRevoke);
    for (Pool pool : poolsToDelete) {
        for (Entitlement ent : pool.getEntitlements()) {
            ent.setDeletedFromPool(true);
            entsToRevoke.add(ent);
        }
    }
    log.debug("Adjusting consumed quantities on pools");
    List<Pool> poolsToSave = new ArrayList<>();
    Set<String> entIdsToRevoke = new HashSet<>();
    for (Entitlement ent : entsToRevoke) {
        // or just continue silently ignoring them?
        if (ent == null || ent.getId() == null) {
            continue;
        }
        // Collect the entitlement IDs to revoke seeing as we are iterating over them anyway.
        entIdsToRevoke.add(ent.getId());
        // We need to trigger lazy load of provided products
        // to have access to those products later in this method.
        Pool pool = ent.getPool();
        int entQuantity = ent.getQuantity() != null ? ent.getQuantity() : 0;
        pool.setConsumed(pool.getConsumed() - entQuantity);
        Consumer consumer = ent.getConsumer();
        ConsumerType ctype = this.consumerTypeCurator.getConsumerType(consumer);
        if (ctype != null) {
            if (ctype.isManifest()) {
                pool.setExported(pool.getExported() - entQuantity);
            } else if (ctype.isType(ConsumerTypeEnum.SHARE)) {
                pool.setShared(pool.getShared() - entQuantity);
            }
        }
        consumer.setEntitlementCount(consumer.getEntitlementCount() - entQuantity);
        consumerCurator.update(consumer);
        poolsToSave.add(pool);
    }
    poolCurator.updateAll(poolsToSave, false, false);
    /*
         * Before deleting the entitlements, we need to find out if there are any
         * modifier entitlements that need to have their certificates regenerated
         */
    if (regenCertsAndStatuses) {
        log.debug("Marking dependent entitlements as dirty...");
        int update = this.entitlementCurator.markDependentEntitlementsDirty(entIdsToRevoke);
        log.debug("{} dependent entitlements marked dirty.", update);
    }
    log.info("Starting batch delete of pools");
    poolCurator.batchDelete(poolsToDelete, alreadyDeletedPools);
    log.info("Starting batch delete of entitlements");
    entitlementCurator.batchDelete(entsToRevoke);
    log.info("Starting delete flush");
    entitlementCurator.flush();
    log.info("All deletes flushed successfully");
    Map<Consumer, List<Entitlement>> consumerSortedEntitlements = entitlementCurator.getDistinctConsumers(entsToRevoke);
    filterAndUpdateStackingEntitlements(consumerSortedEntitlements, alreadyDeletedPools);
    // post unbind actions
    for (Entitlement ent : entsToRevoke) {
        enforcer.postUnbind(ent.getConsumer(), this, ent);
    }
    if (!regenCertsAndStatuses) {
        log.info("Regeneration and status computation was not requested finishing batch revoke");
        sendDeletedEvents(entsToRevoke);
        return;
    }
    log.info("Recomputing status for {} consumers.", consumerSortedEntitlements.size());
    int i = 1;
    for (Consumer consumer : consumerSortedEntitlements.keySet()) {
        if (i++ % 1000 == 0) {
            consumerCurator.flush();
        }
        complianceRules.getStatus(consumer);
    }
    consumerCurator.flush();
    log.info("All statuses recomputed.");
    sendDeletedEvents(entsToRevoke);
}
Also used : ArrayList(java.util.ArrayList) Consumer(org.candlepin.model.Consumer) Pool(org.candlepin.model.Pool) List(java.util.List) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) Entitlement(org.candlepin.model.Entitlement) ConsumerType(org.candlepin.model.ConsumerType) HashSet(java.util.HashSet) Traceable(org.candlepin.util.Traceable) Transactional(com.google.inject.persist.Transactional)

Example 10 with Pool

use of org.candlepin.model.Pool in project candlepin by candlepin.

the class CandlepinPoolManager method getProductsToRemove.

/**
 * Do not attempt to create subscriptions for products that
 * already have virt_only pools available to the guest
 */
private Set<String> getProductsToRemove(List<Pool> allOwnerPoolsForGuest, Set<String> tmpSet) {
    Set<String> productsToRemove = new HashSet<>();
    // Bulk fetch our provided product IDs so we're not hitting the DB several times
    // for this lookup.
    Map<String, Set<String>> providedProductIds = this.poolCurator.getProvidedProductIds(allOwnerPoolsForGuest);
    for (Pool pool : allOwnerPoolsForGuest) {
        if (pool.getProduct() != null && (pool.getProduct().hasAttribute(Product.Attributes.VIRT_ONLY) || pool.hasAttribute(Pool.Attributes.VIRT_ONLY))) {
            Set<String> poolProvidedProductIds = providedProductIds.get(pool.getId());
            String poolProductId = pool.getProduct().getId();
            if (poolProductId != null) {
                // Add the base product to our list of "provided" products
                if (poolProvidedProductIds != null) {
                    poolProvidedProductIds.add(poolProductId);
                } else {
                    poolProvidedProductIds = Collections.singleton(poolProductId);
                }
            }
            if (poolProvidedProductIds != null) {
                for (String prodId : tmpSet) {
                    if (poolProvidedProductIds.contains(prodId)) {
                        productsToRemove.add(prodId);
                    }
                }
            }
        }
    }
    return productsToRemove;
}
Also used : Set(java.util.Set) HashSet(java.util.HashSet) Pool(org.candlepin.model.Pool) HashSet(java.util.HashSet)

Aggregations

Pool (org.candlepin.model.Pool)508 Test (org.junit.Test)358 Product (org.candlepin.model.Product)217 Entitlement (org.candlepin.model.Entitlement)125 Consumer (org.candlepin.model.Consumer)115 ValidationResult (org.candlepin.policy.ValidationResult)111 ArrayList (java.util.ArrayList)100 LinkedList (java.util.LinkedList)100 Owner (org.candlepin.model.Owner)80 HashSet (java.util.HashSet)76 HashMap (java.util.HashMap)67 PoolQuantity (org.candlepin.model.PoolQuantity)66 Date (java.util.Date)65 ConsumerInstalledProduct (org.candlepin.model.ConsumerInstalledProduct)62 Subscription (org.candlepin.model.dto.Subscription)60 List (java.util.List)48 ConsumerType (org.candlepin.model.ConsumerType)48 SourceSubscription (org.candlepin.model.SourceSubscription)47 ActivationKey (org.candlepin.model.activationkeys.ActivationKey)38 Matchers.anyString (org.mockito.Matchers.anyString)30