use of org.candlepin.policy.ValidationResult 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;
}
use of org.candlepin.policy.ValidationResult in project candlepin by candlepin.
the class PoolManagerTest method testCleanup.
@Test
public void testCleanup() throws Exception {
Pool p = createPoolWithEntitlements();
when(mockPoolCurator.lockAndLoad(any(Pool.class))).thenReturn(p);
when(mockPoolCurator.entitlementsIn(p)).thenReturn(new ArrayList<>(p.getEntitlements()));
PreUnbindHelper preHelper = mock(PreUnbindHelper.class);
ValidationResult result = new ValidationResult();
when(preHelper.getResult()).thenReturn(result);
manager.deletePool(p);
// And the pool should be deleted:
verify(mockPoolCurator).delete(p);
// Check that appropriate events were sent out:
verify(eventFactory).poolDeleted(p);
verify(mockEventSink, times(1)).queueEvent((Event) any());
}
use of org.candlepin.policy.ValidationResult in project candlepin by candlepin.
the class PoolManagerTest method testRevokeAllEntitlements.
@Test
public void testRevokeAllEntitlements() {
Consumer c = TestUtil.createConsumer(owner);
Entitlement e1 = new Entitlement(pool, c, owner, 1);
Entitlement e2 = new Entitlement(pool, c, owner, 1);
List<Entitlement> entitlementList = new ArrayList<>();
entitlementList.add(e1);
entitlementList.add(e2);
when(entitlementCurator.listByConsumer(eq(c))).thenReturn(entitlementList);
when(mockPoolCurator.lockAndLoad(any(Pool.class))).thenReturn(pool);
PreUnbindHelper preHelper = mock(PreUnbindHelper.class);
ValidationResult result = new ValidationResult();
when(preHelper.getResult()).thenReturn(result);
int total = manager.revokeAllEntitlements(c);
assertEquals(2, total);
verify(entitlementCurator, times(1)).markDependentEntitlementsDirty(any(List.class));
// TODO assert batch revokes have been called
}
use of org.candlepin.policy.ValidationResult in project candlepin by candlepin.
the class PoolManagerTest method testRefreshPoolsRemovesOtherOwnerPoolsForSameSub.
@Test
public void testRefreshPoolsRemovesOtherOwnerPoolsForSameSub() {
PreUnbindHelper preHelper = mock(PreUnbindHelper.class);
Owner other = new Owner("otherkey", "othername");
List<Subscription> subscriptions = new ArrayList<>();
Owner owner = this.getOwner();
Product product = TestUtil.createProduct();
product.setLocked(true);
Subscription sub = TestUtil.createSubscription(owner, product);
sub.setId("123");
subscriptions.add(sub);
mockSubsList(subscriptions);
List<Pool> pools = new ArrayList<>();
Pool p = TestUtil.copyFromSub(sub);
p.setOwner(other);
p.setSourceSubscription(new SourceSubscription(sub.getId(), "master"));
p.setConsumed(1L);
pools.add(p);
when(mockPoolCurator.lockAndLoad(any(Pool.class))).thenReturn(p);
mockPoolsList(pools);
List<Entitlement> poolEntitlements = new ArrayList<>();
Entitlement ent = TestUtil.createEntitlement();
ent.setPool(p);
ent.setQuantity(1);
poolEntitlements.add(ent);
when(mockPoolCurator.entitlementsIn(eq(p))).thenReturn(poolEntitlements);
ValidationResult result = new ValidationResult();
when(preHelper.getResult()).thenReturn(result);
when(mockOwnerCurator.lookupByKey(owner.getKey())).thenReturn(owner);
this.mockProducts(owner, product);
this.mockProductImport(owner, product);
this.mockContentImport(owner, new Content[] {});
CandlepinQuery<Pool> cqmock = mock(CandlepinQuery.class);
when(cqmock.list()).thenReturn(pools);
when(cqmock.iterator()).thenReturn(pools.iterator());
when(mockPoolCurator.listByOwnerAndType(eq(owner), any(PoolType.class))).thenReturn(cqmock);
this.manager.getRefresher(mockSubAdapter, mockOwnerAdapter).add(owner).run();
// The pool left over from the pre-migrated subscription should be deleted
// and granted entitlements should be revoked
List<Entitlement> entsToDelete = Arrays.asList(ent);
verify(mockPoolCurator).delete(eq(p));
verify(entitlementCurator).batchDelete(eq(entsToDelete));
// Make sure pools that don't match the owner were removed from the list
// They shouldn't cause us to attempt to update existing pools when we
// haven't created them in the first place
ArgumentCaptor<Pool> argPool = ArgumentCaptor.forClass(Pool.class);
verify(poolRulesMock).createAndEnrichPools(argPool.capture(), any(List.class));
TestUtil.assertPoolsAreEqual(TestUtil.copyFromSub(sub), argPool.getValue());
}
use of org.candlepin.policy.ValidationResult in project candlepin by candlepin.
the class PoolManagerTest method testDeleteExcessEntitlementsBatch.
@Test
public void testDeleteExcessEntitlementsBatch() throws EntitlementRefusedException {
ConsumerType ctype = this.mockConsumerType(TestUtil.createConsumerType());
Consumer consumer = TestUtil.createConsumer(ctype, owner);
Subscription sub = TestUtil.createSubscription(owner, product);
sub.setId("testing-subid");
pool.setSourceSubscription(new SourceSubscription(sub.getId(), "master"));
final Pool derivedPool = TestUtil.createPool(owner, product, 1);
derivedPool.setAttribute(Pool.Attributes.DERIVED_POOL, "true");
derivedPool.setSourceSubscription(new SourceSubscription(sub.getId(), "der"));
derivedPool.setConsumed(3L);
derivedPool.setId("derivedPool");
Entitlement masterEnt = new Entitlement(pool, consumer, owner, 5);
Entitlement derivedEnt = new Entitlement(derivedPool, consumer, owner, 1);
derivedEnt.setId("1");
Entitlement derivedEnt2 = new Entitlement(derivedPool, consumer, owner, 1);
derivedEnt2.setId("2");
final Pool derivedPool2 = TestUtil.createPool(owner, product, 1);
derivedPool2.setAttribute(Pool.Attributes.DERIVED_POOL, "true");
derivedPool2.setSourceSubscription(new SourceSubscription(sub.getId(), "der"));
derivedPool2.setConsumed(2L);
derivedPool2.setId("derivedPool2");
Entitlement derivedEnt3 = new Entitlement(derivedPool2, consumer, owner, 1);
derivedEnt3.setId("3");
Set<Entitlement> ents = new HashSet<>();
ents.add(derivedEnt);
ents.add(derivedEnt2);
derivedPool.setEntitlements(ents);
Set<Entitlement> ents2 = new HashSet<>();
ents2.add(derivedEnt3);
derivedPool2.setEntitlements(ents2);
Pool derivedPool3 = TestUtil.createPool(owner, product, 1);
derivedPool3.setAttribute(Pool.Attributes.DERIVED_POOL, "true");
derivedPool3.setSourceSubscription(new SourceSubscription(sub.getId(), "der"));
derivedPool3.setConsumed(2L);
derivedPool3.setId("derivedPool3");
// before
assertEquals(3, derivedPool.getConsumed().intValue());
assertEquals(2, derivedPool2.getConsumed().intValue());
assertEquals(2, derivedPool3.getConsumed().intValue());
when(mockPoolCurator.lockAndLoad(pool)).thenReturn(pool);
when(enforcerMock.update(any(Consumer.class), any(Entitlement.class), any(Integer.class))).thenReturn(new ValidationResult());
when(mockPoolCurator.lookupOversubscribedBySubscriptionIds(any(String.class), anyMap())).thenReturn(Arrays.asList(derivedPool, derivedPool2, derivedPool3));
when(mockPoolCurator.retrieveOrderedEntitlementsOf(eq(Arrays.asList(derivedPool)))).thenReturn(Arrays.asList(derivedEnt, derivedEnt2));
when(mockPoolCurator.retrieveOrderedEntitlementsOf(eq(Arrays.asList(derivedPool2)))).thenReturn(Arrays.asList(derivedEnt3));
when(mockPoolCurator.retrieveOrderedEntitlementsOf(eq(Arrays.asList(derivedPool3)))).thenReturn(new ArrayList<>());
Collection<Pool> overPools = new ArrayList<Pool>() {
{
add(derivedPool);
add(derivedPool2);
}
};
when(mockPoolCurator.lockAndLoad(any(Collection.class))).thenReturn(overPools);
when(mockPoolCurator.lockAndLoad(eq(derivedPool))).thenReturn(derivedPool);
when(mockPoolCurator.lockAndLoad(eq(derivedPool2))).thenReturn(derivedPool2);
when(mockPoolCurator.lockAndLoad(eq(derivedPool3))).thenReturn(derivedPool3);
pool.setId("masterpool");
manager.adjustEntitlementQuantity(consumer, masterEnt, 3);
Class<List<Entitlement>> listClass = (Class<List<Entitlement>>) (Class) ArrayList.class;
ArgumentCaptor<List<Entitlement>> arg = ArgumentCaptor.forClass(listClass);
verify(entitlementCurator).batchDelete(arg.capture());
List<Entitlement> entsDeleted = arg.getValue();
assertThat(entsDeleted, hasItems(derivedEnt, derivedEnt2, derivedEnt3));
assertEquals(1, derivedPool.getConsumed().intValue());
assertEquals(1, derivedPool2.getConsumed().intValue());
assertEquals(2, derivedPool3.getConsumed().intValue());
}
Aggregations