use of org.candlepin.model.ConsumerType in project candlepin by candlepin.
the class EntitlementRules method update.
@Override
public ValidationResult update(Consumer consumer, Entitlement entitlement, Integer change) {
ValidationResult result = new ValidationResult();
ConsumerType ctype = this.consumerTypeCurator.getConsumerType(consumer);
if (!ctype.isManifest() && !ctype.isType(ConsumerTypeEnum.SHARE)) {
Pool pool = entitlement.getPool();
// multi ent check
if (!"yes".equalsIgnoreCase(pool.getProductAttributeValue(Pool.Attributes.MULTI_ENTITLEMENT)) && entitlement.getQuantity() + change > 1) {
result.addError(new ValidationError(EntitlementRulesTranslator.PoolErrorKeys.MULTI_ENTITLEMENT_UNSUPPORTED));
}
if (!consumer.isGuest()) {
String multiplier = pool.getProductAttributeValue(Product.Attributes.INSTANCE_MULTIPLIER);
if (multiplier != null) {
int instanceMultiplier = Integer.parseInt(multiplier);
// quantity should be divisible by multiplier
if ((entitlement.getQuantity() + change) % instanceMultiplier != 0) {
result.addError(new ValidationError(EntitlementRulesTranslator.PoolErrorKeys.QUANTITY_MISMATCH));
}
}
}
}
finishValidation(result, entitlement.getPool(), change);
return result;
}
use of org.candlepin.model.ConsumerType 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.model.ConsumerType in project candlepin by candlepin.
the class AutobindRules method consumerIsCertV3Capable.
/**
* Checks if the specified consumer is capable of using v3 certificates
*
* @param consumer
* The consumer to check
*
* @return
* true if the consumer is capable of using v3 certificates; false otherwise
*/
private boolean consumerIsCertV3Capable(Consumer consumer) {
if (consumer == null) {
throw new IllegalArgumentException("consumer is null");
}
ConsumerType type = this.consumerTypeCurator.getConsumerType(consumer);
if (type.isManifest()) {
for (ConsumerCapability capability : consumer.getCapabilities()) {
if ("cert_v3".equals(capability.getName())) {
return true;
}
}
return false;
} else if (type.isType(ConsumerTypeEnum.HYPERVISOR)) {
// Hypervisors in this context don't use content, so V3 is allowed
return true;
}
// Consumer isn't a special type, check their certificate_version fact
String entitlementVersion = consumer.getFact("system.certificate_version");
return entitlementVersion != null && entitlementVersion.startsWith("3.");
}
use of org.candlepin.model.ConsumerType in project candlepin by candlepin.
the class CandlepinPoolManager method handlePostEntitlement.
public void handlePostEntitlement(PoolManager manager, Consumer consumer, Owner owner, Map<String, Entitlement> entitlements, Map<String, PoolQuantity> poolQuantityMap) {
Set<String> stackIds = new HashSet<>();
for (Entitlement entitlement : entitlements.values()) {
if (entitlement.getPool().isStacked()) {
stackIds.add(entitlement.getPool().getStackId());
}
}
ConsumerType ctype = this.consumerTypeCurator.getConsumerType(consumer);
List<Pool> subPoolsForStackIds = null;
// Therefore, we do not need to check if any stack derived pools need updating
if (!stackIds.isEmpty() && !ctype.isType(ConsumerTypeEnum.SHARE) && !ctype.isManifest()) {
subPoolsForStackIds = poolCurator.getSubPoolForStackIds(consumer, stackIds);
if (CollectionUtils.isNotEmpty(subPoolsForStackIds)) {
poolRules.updatePoolsFromStack(consumer, subPoolsForStackIds, false);
poolCurator.mergeAll(subPoolsForStackIds, false);
}
} else {
subPoolsForStackIds = new ArrayList<>();
}
enforcer.postEntitlement(manager, consumer, owner, entitlements, subPoolsForStackIds, false, poolQuantityMap);
}
use of org.candlepin.model.ConsumerType 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;
}
Aggregations