use of org.candlepin.policy.js.RuleExecutionException in project candlepin by candlepin.
the class QuantityRules method getSuggestedQuantities.
/**
* Calculates the suggested quantities for many pools in one call. This allows for
* performant list pools queries with large numbers of pools and a large amount of
* entitlements to serialize.
*
* Map returned will map each pool ID to the suggested quantities for it. Every pool
* provided should have it's ID present in the result.
*
* @param pools
* @param c
* @param date
* @return suggested quantities for all pools requested
*/
@SuppressWarnings("checkstyle:indentation")
public Map<String, SuggestedQuantity> getSuggestedQuantities(List<Pool> pools, Consumer c, Date date) {
JsonJsContext args = new JsonJsContext(mapper);
Stream<PoolDTO> poolStream = pools == null ? Stream.empty() : pools.stream().map(this.translator.getStreamMapper(Pool.class, PoolDTO.class));
Stream<EntitlementDTO> entStream = c.getEntitlements() == null ? Stream.empty() : c.getEntitlements().stream().filter(ent -> ent.isValidOnDate(date)).map(this.translator.getStreamMapper(Entitlement.class, EntitlementDTO.class));
args.put("pools", poolStream.collect(Collectors.toSet()));
args.put("consumer", this.translator.translate(c, ConsumerDTO.class));
args.put("validEntitlements", entStream.collect(Collectors.toSet()));
args.put("log", log, false);
args.put("guestIds", c.getGuestIds());
String json = jsRules.runJsFunction(String.class, "get_suggested_quantities", args);
Map<String, SuggestedQuantity> resultMap;
TypeReference<Map<String, SuggestedQuantity>> typeref = new TypeReference<Map<String, SuggestedQuantity>>() {
};
try {
resultMap = mapper.toObject(json, typeref);
} catch (Exception e) {
throw new RuleExecutionException(e);
}
return resultMap;
}
use of org.candlepin.policy.js.RuleExecutionException in project candlepin by candlepin.
the class EntitlementRules method filterPools.
@Override
@SuppressWarnings("checkstyle:indentation")
public List<Pool> filterPools(Consumer consumer, List<Pool> pools, boolean showAll) {
JsonJsContext args = new JsonJsContext(objectMapper);
Map<String, ValidationResult> resultMap = new HashMap<>();
ConsumerType ctype = this.consumerTypeCurator.getConsumerType(consumer);
if (!ctype.isType(ConsumerTypeEnum.SHARE)) {
Stream<PoolDTO> poolStream = pools == null ? Stream.empty() : pools.stream().map(this.translator.getStreamMapper(Pool.class, PoolDTO.class));
Stream<EntitlementDTO> entStream = consumer.getEntitlements() == null ? Stream.empty() : consumer.getEntitlements().stream().map(this.translator.getStreamMapper(Entitlement.class, EntitlementDTO.class));
args.put("consumer", this.translator.translate(consumer, ConsumerDTO.class));
args.put("hostConsumer", this.translator.translate(getHost(consumer, pools), ConsumerDTO.class));
args.put("consumerEntitlements", entStream.collect(Collectors.toSet()));
args.put("standalone", config.getBoolean(ConfigProperties.STANDALONE));
args.put("pools", poolStream.collect(Collectors.toSet()));
args.put("caller", CallerType.LIST_POOLS.getLabel());
args.put("log", log, false);
String json = jsRules.runJsFunction(String.class, "validate_pools_list", args);
TypeReference<Map<String, ValidationResult>> typeref = new TypeReference<Map<String, ValidationResult>>() {
};
try {
resultMap = objectMapper.toObject(json, typeref);
} catch (Exception e) {
throw new RuleExecutionException(e);
}
}
List<Pool> filteredPools = new LinkedList<>();
for (Pool pool : pools) {
ValidationResult result;
if (ctype.isType(ConsumerTypeEnum.SHARE)) {
result = new ValidationResult();
resultMap.put(pool.getId(), result);
validatePoolSharingEligibility(result, pool);
} else {
result = resultMap.get(pool.getId());
}
finishValidation(result, pool, 1);
if (result.isSuccessful() && (!result.hasWarnings() || showAll)) {
filteredPools.add(pool);
} else if (log.isDebugEnabled()) {
log.debug("Omitting pool due to failed rules: " + pool.getId());
if (result.hasErrors()) {
log.debug("\tErrors: " + result.getErrors());
}
if (result.hasWarnings()) {
log.debug("\tWarnings: " + result.getWarnings());
}
}
}
return filteredPools;
}
use of org.candlepin.policy.js.RuleExecutionException in project candlepin by candlepin.
the class EntitlementRules method preEntitlement.
@Override
@SuppressWarnings("checkstyle:indentation")
public Map<String, ValidationResult> preEntitlement(Consumer consumer, Consumer host, Collection<PoolQuantity> entitlementPoolQuantities, CallerType caller) {
Map<String, ValidationResult> resultMap = new HashMap<>();
ConsumerType ctype = this.consumerTypeCurator.getConsumerType(consumer);
/* This document describes the java script portion of the pre entitlement rules check:
* http://www.candlepinproject.org/docs/candlepin/pre_entitlement_rules_check.html
* As described in the document, none of the checks are related to share binds, so we
* skip that step for share consumers.
*/
if (!ctype.isType(ConsumerTypeEnum.SHARE)) {
Stream<EntitlementDTO> entStream = consumer.getEntitlements() == null ? Stream.empty() : consumer.getEntitlements().stream().map(this.translator.getStreamMapper(Entitlement.class, EntitlementDTO.class));
JsonJsContext args = new JsonJsContext(objectMapper);
args.put("consumer", this.translator.translate(consumer, ConsumerDTO.class));
args.put("hostConsumer", this.translator.translate(host, ConsumerDTO.class));
args.put("consumerEntitlements", entStream.collect(Collectors.toSet()));
args.put("standalone", config.getBoolean(ConfigProperties.STANDALONE));
args.put("poolQuantities", entitlementPoolQuantities);
args.put("caller", caller.getLabel());
args.put("log", log, false);
String json = jsRules.runJsFunction(String.class, "validate_pools_batch", args);
TypeReference<Map<String, ValidationResult>> typeref = new TypeReference<Map<String, ValidationResult>>() {
};
try {
resultMap = objectMapper.toObject(json, typeref);
for (PoolQuantity poolQuantity : entitlementPoolQuantities) {
if (!resultMap.containsKey(poolQuantity.getPool().getId())) {
resultMap.put(poolQuantity.getPool().getId(), new ValidationResult());
log.info("no result returned for pool: {}", poolQuantity.getPool());
}
}
} catch (Exception e) {
throw new RuleExecutionException(e);
}
}
for (PoolQuantity poolQuantity : entitlementPoolQuantities) {
if (ctype.isType(ConsumerTypeEnum.SHARE)) {
ValidationResult result = new ValidationResult();
resultMap.put(poolQuantity.getPool().getId(), result);
validatePoolSharingEligibility(result, poolQuantity.getPool());
}
finishValidation(resultMap.get(poolQuantity.getPool().getId()), poolQuantity.getPool(), poolQuantity.getQuantity());
}
return resultMap;
}
use of org.candlepin.policy.js.RuleExecutionException in project candlepin by candlepin.
the class AutobindRules method selectBestPools.
public List<PoolQuantity> selectBestPools(Consumer consumer, String[] productIds, List<Pool> pools, ComplianceStatus compliance, String serviceLevelOverride, Set<String> exemptLevels, boolean considerDerived) {
List<PoolQuantity> bestPools = new ArrayList<>();
int poolsBeforeContentFilter = pools.size();
pools = filterPoolsForV1Certificates(consumer, pools);
log.debug("pools.size() before V1 certificate filter: {}, after: {}", poolsBeforeContentFilter, pools.size());
if (pools.size() == 0) {
if (compliance.getReasons().size() == 0) {
log.info("Consumer is compliant and does not require more entitlements.");
} else {
logProducts("No pools available to complete compliance for the set of products: {}" + " and consumer installed products: {}", productIds, consumer, false);
}
return bestPools;
}
if (log.isDebugEnabled()) {
logProducts("Selecting best entitlement pool for products: {}" + "and consumer installed products: {}", productIds, consumer, true);
if (poolsBeforeContentFilter != pools.size()) {
log.debug("{} pools filtered due to too much content", (poolsBeforeContentFilter - pools.size()));
}
}
List<PoolDTO> poolDTOs = new ArrayList<>();
for (Pool pool : pools) {
poolDTOs.add(this.translator.translate(pool, PoolDTO.class));
}
// Provide objects for the script:
JsonJsContext args = new JsonJsContext(mapper);
args.put("consumer", this.translator.translate(consumer, ConsumerDTO.class));
Owner owner = ownerCurator.findOwnerById(consumer.getOwnerId());
args.put("owner", this.translator.translate(owner, OwnerDTO.class));
args.put("serviceLevelOverride", serviceLevelOverride);
args.put("pools", poolDTOs.toArray());
args.put("products", productIds);
args.put("log", log, false);
args.put("compliance", compliance);
args.put("exemptList", exemptLevels);
args.put("considerDerived", considerDerived);
args.put("guestIds", consumer.getGuestIds());
// Convert the JSON returned into a Map object:
Map<String, Integer> result = null;
try {
String json = jsRules.invokeMethod(SELECT_POOL_FUNCTION, args);
result = mapper.toObject(json, Map.class);
if (log.isDebugEnabled()) {
log.debug("Executed javascript rule: {}", SELECT_POOL_FUNCTION);
}
} catch (NoSuchMethodException e) {
log.warn("No method found: {}", SELECT_POOL_FUNCTION);
log.warn("Resorting to default pool selection behavior.");
return selectBestPoolDefault(pools);
} catch (RhinoException e) {
throw new RuleExecutionException(e);
}
if (pools.size() > 0 && (result == null || result.isEmpty())) {
logProducts("Rules did not select a pool for products: {} and consumer installed products: {}", productIds, consumer, false);
return bestPools;
}
for (Pool p : pools) {
for (Entry<String, Integer> entry : result.entrySet()) {
if (p.getId().equals(entry.getKey())) {
log.debug("Best pool: {}", p);
int quantity = entry.getValue();
bestPools.add(new PoolQuantity(p, quantity));
}
}
}
return bestPools;
}
use of org.candlepin.policy.js.RuleExecutionException in project candlepin by candlepin.
the class ComplianceRules method getStatus.
/**
* Check compliance status for a consumer on a specific date.
*
* @param consumer Consumer to check.
* @param date Date to check compliance status for.
* @param calculateCompliantUntil calculate how long the system will remain compliant (expensive)
* @param updateConsumer whether or not to use consumerCurator.update
* @param calculateProductComplianceDateRanges calculate the individual compliance ranges for each product
* (also expensive)
* @return Compliance status.
*/
@SuppressWarnings("checkstyle:indentation")
public ComplianceStatus getStatus(Consumer consumer, Collection<Entitlement> newEntitlements, Date date, boolean calculateCompliantUntil, boolean updateConsumer, boolean calculateProductComplianceDateRanges, boolean currentCompliance) {
if (date == null) {
date = new Date();
}
if (currentCompliance) {
updateEntsOnStart(consumer);
}
Stream<EntitlementDTO> entStream = Stream.concat(newEntitlements != null ? newEntitlements.stream() : Stream.empty(), consumer.getEntitlements() != null ? consumer.getEntitlements().stream() : Stream.empty()).map(this.translator.getStreamMapper(Entitlement.class, EntitlementDTO.class));
// Do not calculate compliance status for distributors and shares. It is prohibitively
// expensive and meaningless
ConsumerType ctype = this.consumerTypeCurator.getConsumerType(consumer);
if (ctype != null && (ctype.isManifest() || ctype.isType(ConsumerTypeEnum.SHARE))) {
return new ComplianceStatus(new Date());
}
JsonJsContext args = new JsonJsContext(mapper);
args.put("consumer", this.translator.translate(consumer, ConsumerDTO.class));
args.put("entitlements", entStream.collect(Collectors.toSet()));
args.put("ondate", date);
args.put("calculateCompliantUntil", calculateCompliantUntil);
args.put("calculateProductComplianceDateRanges", calculateProductComplianceDateRanges);
args.put("log", log, false);
args.put("guestIds", consumer.getGuestIds());
// Convert the JSON returned into a ComplianceStatus object:
String json = jsRules.runJsFunction(String.class, "get_status", args);
try {
ComplianceStatus status = mapper.toObject(json, ComplianceStatus.class);
for (ComplianceReason reason : status.getReasons()) {
generator.setMessage(consumer, reason, status.getDate());
}
if (currentCompliance) {
applyStatus(consumer, status, updateConsumer);
}
return status;
} catch (Exception e) {
throw new RuleExecutionException(e);
}
}
Aggregations