Search in sources :

Example 6 with EntitlementRefusedException

use of org.candlepin.policy.EntitlementRefusedException in project candlepin by candlepin.

the class EntitlerJob method toExecute.

@Override
public void toExecute(JobExecutionContext ctx) throws JobExecutionException {
    try {
        JobDataMap map = ctx.getMergedJobDataMap();
        String uuid = (String) map.get(JobStatus.TARGET_ID);
        PoolIdAndQuantity[] poolQuantities = (PoolIdAndQuantity[]) map.get("pool_and_quantities");
        Map<String, Integer> poolMap = new HashMap<>();
        for (PoolIdAndQuantity poolIdAndQuantity : poolQuantities) {
            poolMap.put(poolIdAndQuantity.getPoolId(), poolIdAndQuantity.getQuantity());
        }
        List<Entitlement> ents = entitler.bindByPoolQuantities(uuid, poolMap);
        entitler.sendEvents(ents);
        PoolIdAndQuantity[] consumed = new PoolIdAndQuantity[ents.size()];
        for (int i = 0; i < ents.size(); i++) {
            consumed[i] = new PoolIdAndQuantity(ents.get(i).getPool().getId(), ents.get(i).getQuantity());
        }
        ctx.setResult(Arrays.asList(consumed));
        poolCurator.clear();
    } catch (EntitlementRefusedException e) {
        log.error("EntitlerJob encountered a problem, translating errors", e);
        Map<String, ValidationResult> validationResults = e.getResults();
        EntitlementRulesTranslator translator = new EntitlementRulesTranslator(i18n);
        List<PoolIdAndErrors> poolErrors = new ArrayList<>();
        for (Pool pool : poolCurator.listAllByIds(validationResults.keySet())) {
            List<String> errorMessages = new ArrayList<>();
            for (ValidationError error : validationResults.get(pool.getId()).getErrors()) {
                errorMessages.add(translator.poolErrorToMessage(pool, error));
            }
            poolErrors.add(new PoolIdAndErrors(pool.getId(), errorMessages));
        }
        ctx.setResult(poolErrors);
    }// so that the job will be properly cleaned up on failure.
     catch (Exception e) {
        log.error("EntitlerJob encountered a problem.", e);
        throw new JobExecutionException(e.getMessage(), e, false);
    }
}
Also used : JobDataMap(org.quartz.JobDataMap) PoolIdAndQuantity(org.candlepin.model.dto.PoolIdAndQuantity) PoolIdAndErrors(org.candlepin.model.dto.PoolIdAndErrors) HashMap(java.util.HashMap) EntitlementRefusedException(org.candlepin.policy.EntitlementRefusedException) SchedulerException(org.quartz.SchedulerException) EntitlementRefusedException(org.candlepin.policy.EntitlementRefusedException) JobExecutionException(org.quartz.JobExecutionException) JobExecutionException(org.quartz.JobExecutionException) ArrayList(java.util.ArrayList) List(java.util.List) Pool(org.candlepin.model.Pool) ValidationError(org.candlepin.policy.ValidationError) Entitlement(org.candlepin.model.Entitlement) EntitlementRulesTranslator(org.candlepin.policy.js.entitlement.EntitlementRulesTranslator) HashMap(java.util.HashMap) Map(java.util.Map) JobDataMap(org.quartz.JobDataMap)

Example 7 with EntitlementRefusedException

use of org.candlepin.policy.EntitlementRefusedException in project candlepin by candlepin.

the class Entitler method bindByPoolQuantity.

public List<Entitlement> bindByPoolQuantity(Consumer consumer, String poolId, Integer quantity) {
    Map<String, Integer> poolMap = new HashMap<>();
    poolMap.put(poolId, quantity);
    try {
        return bindByPoolQuantities(consumer, poolMap);
    } catch (EntitlementRefusedException e) {
        // TODO: Could be multiple errors, but we'll just report the first
        // one for now
        Pool pool = poolCurator.find(poolId);
        throw new ForbiddenException(messageTranslator.poolErrorToMessage(pool, e.getResults().get(poolId).getErrors().get(0)));
    }
}
Also used : ForbiddenException(org.candlepin.common.exceptions.ForbiddenException) HashMap(java.util.HashMap) EntitlementRefusedException(org.candlepin.policy.EntitlementRefusedException) Pool(org.candlepin.model.Pool)

Example 8 with EntitlementRefusedException

use of org.candlepin.policy.EntitlementRefusedException in project candlepin by candlepin.

the class Entitler method getDryRun.

/**
 * Entitles the given Consumer to the given Product. Will seek out pools
 * which provide access to this product, either directly or as a child, and
 * select the best one based on a call to the rules engine.
 *
 * @param consumer The consumer being entitled.
 * @return List of Entitlements
 */
public List<PoolQuantity> getDryRun(Consumer consumer, Owner owner, String serviceLevelOverride) {
    List<PoolQuantity> result = new ArrayList<>();
    try {
        if (consumer.isDev()) {
            if (config.getBoolean(ConfigProperties.STANDALONE) || !poolCurator.hasActiveEntitlementPools(consumer.getOwnerId(), null)) {
                throw new ForbiddenException(i18n.tr("Development units may only be used on hosted servers" + " and with orgs that have active subscriptions."));
            }
            // Look up the dev pool for this consumer, and if not found
            // create one. If a dev pool already exists, remove it and
            // create a new one.
            String sku = consumer.getFact("dev_sku");
            Pool devPool = poolCurator.findDevPool(consumer);
            if (devPool != null) {
                poolManager.deletePool(devPool);
            }
            devPool = poolManager.createPool(assembleDevPool(consumer, owner, sku));
            result.add(new PoolQuantity(devPool, 1));
        } else {
            result = poolManager.getBestPools(consumer, null, null, owner.getId(), serviceLevelOverride, null);
        }
        log.debug("Created Pool Quantity list: {}", result);
    } catch (EntitlementRefusedException e) {
        // to the process
        if (log.isDebugEnabled()) {
            log.debug("consumer {} dry-run errors:", consumer.getUuid());
            for (Entry<String, ValidationResult> entry : e.getResults().entrySet()) {
                log.debug("errors for pool id: {}", entry.getKey());
                for (ValidationError error : entry.getValue().getErrors()) {
                    log.debug(error.getResourceKey());
                }
            }
        }
    }
    return result;
}
Also used : PoolQuantity(org.candlepin.model.PoolQuantity) ForbiddenException(org.candlepin.common.exceptions.ForbiddenException) Entry(java.util.Map.Entry) EntitlementRefusedException(org.candlepin.policy.EntitlementRefusedException) ArrayList(java.util.ArrayList) Pool(org.candlepin.model.Pool) ValidationError(org.candlepin.policy.ValidationError)

Example 9 with EntitlementRefusedException

use of org.candlepin.policy.EntitlementRefusedException in project candlepin by candlepin.

the class CandlepinPoolManager method getBestPools.

@Override
public List<PoolQuantity> getBestPools(Consumer consumer, String[] productIds, Date entitleDate, String ownerId, String serviceLevelOverride, Collection<String> fromPools) throws EntitlementRefusedException {
    Map<String, ValidationResult> failedResults = new HashMap<>();
    Date activePoolDate = entitleDate;
    if (entitleDate == null) {
        activePoolDate = new Date();
    }
    PoolFilterBuilder poolFilter = new PoolFilterBuilder();
    poolFilter.addIdFilters(fromPools);
    List<Pool> allOwnerPools = this.listAvailableEntitlementPools(consumer, null, ownerId, null, null, activePoolDate, false, poolFilter, null, false, false, null).getPageData();
    List<Pool> filteredPools = new LinkedList<>();
    // We have to check compliance status here so we can replace an empty
    // array of product IDs with the array the consumer actually needs. (i.e. during
    // a healing request)
    ComplianceStatus compliance = complianceRules.getStatus(consumer, entitleDate, false);
    if (productIds == null || productIds.length == 0) {
        log.debug("No products specified for bind, checking compliance to see what is needed.");
        Set<String> tmpSet = new HashSet<>();
        tmpSet.addAll(compliance.getNonCompliantProducts());
        tmpSet.addAll(compliance.getPartiallyCompliantProducts().keySet());
        productIds = tmpSet.toArray(new String[] {});
    }
    if (log.isDebugEnabled()) {
        log.debug("Attempting for products on date: {}", entitleDate);
        for (String productId : productIds) {
            log.debug("  {}", productId);
        }
    }
    // 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(allOwnerPools);
    for (Pool pool : allOwnerPools) {
        boolean providesProduct = false;
        // We want to complete partial stacks if possible, even if they do not provide any products
        Product poolProduct = pool.getProduct();
        String stackingId = poolProduct.getAttributeValue(Product.Attributes.STACKING_ID);
        if (stackingId != null && compliance.getPartialStacks().containsKey(stackingId)) {
            providesProduct = true;
        } else {
            Set<String> poolProvidedProductIds = providedProductIds.get(pool.getId());
            String poolProductId = pool.getProduct() != null ? pool.getProduct().getId() : null;
            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 productId : productIds) {
                    if (poolProvidedProductIds.contains(productId)) {
                        providesProduct = true;
                        break;
                    }
                }
            }
        }
        if (providesProduct) {
            ValidationResult result = enforcer.preEntitlement(consumer, pool, 1, CallerType.BEST_POOLS);
            if (result.hasErrors() || result.hasWarnings()) {
                failedResults.put(pool.getId(), result);
                log.debug("Pool filtered from candidates due to rules failure: {}", pool.getId());
            } else {
                filteredPools.add(pool);
            }
        }
    }
    // Only throw refused exception if we actually hit the rules:
    if (filteredPools.size() == 0 && !failedResults.isEmpty()) {
        throw new EntitlementRefusedException(failedResults);
    }
    List<PoolQuantity> enforced = autobindRules.selectBestPools(consumer, productIds, filteredPools, compliance, serviceLevelOverride, poolCurator.retrieveServiceLevelsForOwner(ownerId, true), false);
    // Sort the resulting pools to avoid deadlocks
    Collections.sort(enforced);
    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) Product(org.candlepin.model.Product) ValidationResult(org.candlepin.policy.ValidationResult) Date(java.util.Date) LinkedList(java.util.LinkedList) PoolFilterBuilder(org.candlepin.model.PoolFilterBuilder) Pool(org.candlepin.model.Pool) HashSet(java.util.HashSet)

Example 10 with EntitlementRefusedException

use of org.candlepin.policy.EntitlementRefusedException in project candlepin by candlepin.

the class CandlepinPoolManager method adjustEntitlementQuantity.

@Override
@Transactional
public /*
     * NOTE: please refer to the comment on create entitlements with respect to locking.
     */
Entitlement adjustEntitlementQuantity(Consumer consumer, Entitlement entitlement, Integer quantity) throws EntitlementRefusedException {
    int change = quantity - entitlement.getQuantity();
    if (change == 0) {
        return entitlement;
    }
    // Because there are several paths to this one place where entitlements
    // are updated, we cannot be positive the caller obtained a lock on the
    // pool when it was read. As such we're going to reload it with a lock
    // before starting this process.
    log.debug("Updating entitlement, Locking pool: {}", entitlement.getPool().getId());
    Pool pool = poolCurator.lockAndLoad(entitlement.getPool());
    if (pool == null) {
        throw new RuntimeException("Unable to lock pool for entitlement: " + entitlement);
    }
    log.debug("Locked pool: {} consumed: {}", pool, pool.getConsumed());
    ValidationResult result = enforcer.update(consumer, entitlement, change);
    if (!result.isSuccessful()) {
        log.warn("Entitlement not updated: {} for pool: {}", result.getErrors().toString(), pool.getId());
        Map<String, ValidationResult> errorMap = new HashMap<>();
        errorMap.put(pool.getId(), result);
        throw new EntitlementRefusedException(errorMap);
    }
    /*
         * Grab an exclusive lock on the consumer to prevent deadlock.
         */
    consumer = consumerCurator.lockAndLoad(consumer);
    ConsumerType ctype = this.consumerTypeCurator.getConsumerType(consumer);
    // Persist the entitlement after it has been updated.
    log.info("Processing entitlement and persisting.");
    entitlement.setQuantity(entitlement.getQuantity() + change);
    entitlementCurator.merge(entitlement);
    pool.setConsumed(pool.getConsumed() + change);
    if (ctype != null && ctype.isManifest()) {
        pool.setExported(pool.getExported() + change);
    }
    poolCurator.merge(pool);
    consumer.setEntitlementCount(consumer.getEntitlementCount() + change);
    Map<String, Entitlement> entMap = new HashMap<>();
    entMap.put(pool.getId(), entitlement);
    Map<String, PoolQuantity> poolQuantityMap = new HashMap<>();
    poolQuantityMap.put(pool.getId(), new PoolQuantity(pool, change));
    Owner owner = ownerCurator.find(consumer.getOwnerId());
    // the only thing we do here is decrement bonus pool quantity
    enforcer.postEntitlement(this, consumer, owner, entMap, new ArrayList<>(), true, poolQuantityMap);
    // we might have changed the bonus pool quantities, revoke ents if needed.
    checkBonusPoolQuantities(consumer.getOwnerId(), entMap);
    // if shared ents, update shared pool quantity
    if (ctype != null && ctype.isType(ConsumerTypeEnum.SHARE)) {
        pool.setShared(pool.getShared() + change);
        List<Pool> sharedPools = poolCurator.listBySourceEntitlement(entitlement).list();
        for (Pool p : sharedPools) {
            setPoolQuantity(p, entitlement.getQuantity().longValue());
        }
    } else {
        this.entitlementCurator.markEntitlementsDirty(Arrays.asList(entitlement.getId()));
    }
    /*
         * If the consumer is not a distributor or share, check consumer's new compliance
         * status and save. the getStatus call does that internally.
         * all consumer's entitlement count are updated though, so we need to update irrespective
         * of the consumer type.
         */
    complianceRules.getStatus(consumer, null, false, false);
    consumerCurator.update(consumer);
    poolCurator.flush();
    return entitlement;
}
Also used : PoolQuantity(org.candlepin.model.PoolQuantity) Owner(org.candlepin.model.Owner) HashMap(java.util.HashMap) EntitlementRefusedException(org.candlepin.policy.EntitlementRefusedException) ValidationResult(org.candlepin.policy.ValidationResult) Pool(org.candlepin.model.Pool) ConsumerType(org.candlepin.model.ConsumerType) Entitlement(org.candlepin.model.Entitlement) Transactional(com.google.inject.persist.Transactional)

Aggregations

EntitlementRefusedException (org.candlepin.policy.EntitlementRefusedException)16 Pool (org.candlepin.model.Pool)13 HashMap (java.util.HashMap)10 ValidationResult (org.candlepin.policy.ValidationResult)8 Entitlement (org.candlepin.model.Entitlement)7 PoolQuantity (org.candlepin.model.PoolQuantity)7 ArrayList (java.util.ArrayList)5 ForbiddenException (org.candlepin.common.exceptions.ForbiddenException)4 Transactional (com.google.inject.persist.Transactional)3 Date (java.util.Date)3 HashSet (java.util.HashSet)3 LinkedList (java.util.LinkedList)3 List (java.util.List)3 Set (java.util.Set)3 Consumer (org.candlepin.model.Consumer)3 Owner (org.candlepin.model.Owner)3 PoolFilterBuilder (org.candlepin.model.PoolFilterBuilder)3 Product (org.candlepin.model.Product)3 ValidationError (org.candlepin.policy.ValidationError)3 ComplianceStatus (org.candlepin.policy.js.compliance.ComplianceStatus)3