Search in sources :

Example 41 with Subscription

use of org.candlepin.model.dto.Subscription in project candlepin by candlepin.

the class SubscriptionReconciler method reconcile.

/**
 *  Reconciles incoming entitlements to existing pools to attempt to limit
 *  the number of pools we must destroy and revoke.
 *
 *  Each set is mapped against the upstream pool ID. Subscriptions originating from
 *  different pools will never match each other for replacement.
 *
 *  First match attempts a direct match of entitlement ID from incoming
 *  entitlements for comparison to existing pools. If so we re-use the existing pool.
 *  (note that despite the same entitlement ID, quantity and other data may have
 *  changed)
 *
 *  Next we attempt to match on exact quantity. This would allow the user to re-create
 *  a distributor upstream and re-assign it the same entitlement quantities from the
 *  same pools, without triggering a mass regen on import.
 *
 *  The last attempt will order the remaining incoming entitlements by quantity, and
 *  match these against a quantity ordered list of the remaining pools for that
 *  upstream pool.
 *
 *  Remaining incoming subscriptions that did not match any pools per the above are
 *  treated as new subscriptions.
 *
 * @param owner
 *  The owner for which the subscriptions are being imported
 *
 * @param subsToImport
 *  A collection of subscriptions which are being imported
 *
 * @return
 *  The collection of reconciled subscriptions
 */
public Collection<Subscription> reconcile(Owner owner, Collection<Subscription> subsToImport) {
    Map<String, Map<String, Pool>> existingPoolsByUpstreamPool = this.mapPoolsByUpstreamPool(owner);
    // if we can match to the entitlement id do it.
    // we need a new list to hold the ones that are left
    Set<Subscription> subscriptionsStillToImport = new HashSet<>();
    for (Subscription subscription : subsToImport) {
        Pool local = null;
        Map<String, Pool> map = existingPoolsByUpstreamPool.get(subscription.getUpstreamPoolId());
        if (map == null || map.isEmpty()) {
            log.info("New subscription for incoming entitlement ID: {}", subscription.getUpstreamEntitlementId());
            continue;
        }
        local = map.get(subscription.getUpstreamEntitlementId());
        if (local != null) {
            mergeSubscription(subscription, local, map);
            log.info("Merging subscription for incoming entitlement id [{}] into subscription with " + "existing entitlement id [{}]. Entitlement id match.", subscription.getUpstreamEntitlementId(), local.getUpstreamEntitlementId());
        } else {
            subscriptionsStillToImport.add(subscription);
            log.warn("Subscription for incoming entitlement id [{}] does not have an entitlement id " + "match in the current subscriptions for the upstream pool id [{}]", subscription.getUpstreamEntitlementId(), subscription.getUpstreamPoolId());
        }
    }
    // matches will be made against the upstream pool id and quantity.
    // we need a new list to hold the ones that are left
    List<Subscription> subscriptionsNeedQuantityMatch = new ArrayList<>();
    for (Subscription subscription : subscriptionsStillToImport) {
        Pool local = null;
        Map<String, Pool> map = existingPoolsByUpstreamPool.get(subscription.getUpstreamPoolId());
        if (map == null) {
            map = new HashMap<>();
        }
        for (Pool localSub : map.values()) {
            // TODO quantity
            long quantity = localSub.getQuantity() != null ? localSub.getQuantity() : 1;
            long multiplier = localSub.getProduct().getMultiplier() != null ? localSub.getProduct().getMultiplier() : 1;
            Long effectiveQuantity = Long.valueOf(quantity / multiplier);
            if (effectiveQuantity.equals(subscription.getQuantity())) {
                local = localSub;
                break;
            }
        }
        if (local != null) {
            mergeSubscription(subscription, local, map);
            log.info("Merging subscription for incoming entitlement id [{}] into subscription with " + "existing entitlement id [{}]. Exact quantity match.", subscription.getUpstreamEntitlementId(), local.getUpstreamEntitlementId());
        } else {
            subscriptionsNeedQuantityMatch.add(subscription);
            log.warn("Subscription for incoming entitlement id [{}] does not have an exact quantity " + "match in the current subscriptions for the upstream pool id [{}]", subscription.getUpstreamEntitlementId(), subscription.getUpstreamPoolId());
        }
    }
    // matches will be made against the upstream pool id and quantity.
    // quantities will just match by position from highest to lowest
    // we need a new list to hold the ones that are left
    Subscription[] inNeed = subscriptionsNeedQuantityMatch.toArray(new Subscription[0]);
    Arrays.sort(inNeed, new SubQuantityComparator());
    for (Subscription subscription : inNeed) {
        Pool local = null;
        Map<String, Pool> map = existingPoolsByUpstreamPool.get(subscription.getUpstreamPoolId());
        if (map == null || map.isEmpty()) {
            log.info("Creating new subscription for incoming entitlement with id [{}]", subscription.getUpstreamEntitlementId());
            continue;
        }
        Pool[] locals = map.values().toArray(new Pool[0]);
        Arrays.sort(locals, new QuantityComparator());
        local = locals[0];
        mergeSubscription(subscription, local, map);
        log.info("Merging subscription for incoming entitlement id [{}] into subscription with " + "existing entitlement id [{}] Ordered quantity match.", subscription.getUpstreamEntitlementId(), local.getUpstreamEntitlementId());
    }
    return subsToImport;
}
Also used : ArrayList(java.util.ArrayList) Pool(org.candlepin.model.Pool) Subscription(org.candlepin.model.dto.Subscription) HashMap(java.util.HashMap) Map(java.util.Map) HashSet(java.util.HashSet)

Example 42 with Subscription

use of org.candlepin.model.dto.Subscription in project candlepin by candlepin.

the class HostedTestSubscriptionServiceAdapter method deleteSubscription.

public boolean deleteSubscription(String id) {
    if (idMap.containsKey(id)) {
        Subscription s = idMap.remove(id);
        ownerMap.get(s.getOwner().getKey()).remove(s);
        productMap.get(s.getProduct().getId()).remove(s);
        return true;
    }
    return false;
}
Also used : Subscription(org.candlepin.model.dto.Subscription)

Example 43 with Subscription

use of org.candlepin.model.dto.Subscription in project candlepin by candlepin.

the class HostedTestSubscriptionServiceAdapter method updateSubscription.

public Subscription updateSubscription(Subscription ss) {
    deleteSubscription(ss.getId());
    Subscription s = createSubscription(ss);
    return s;
}
Also used : Subscription(org.candlepin.model.dto.Subscription)

Example 44 with Subscription

use of org.candlepin.model.dto.Subscription in project candlepin by candlepin.

the class PoolCuratorTest method confirmBonusPoolDeleted.

@Test
public void confirmBonusPoolDeleted() {
    Subscription sub = TestUtil.createSubscription(owner, product, new HashSet<>());
    sub.setId(Util.generateDbUUID());
    sub.setQuantity(16L);
    sub.setStartDate(TestUtil.createDate(2006, 10, 21));
    sub.setEndDate(TestUtil.createDate(2020, 1, 1));
    sub.setModified(new Date());
    Pool sourcePool = poolManager.createAndEnrichPools(sub).get(0);
    poolCurator.create(sourcePool);
    Entitlement e = new Entitlement(sourcePool, consumer, owner, 1);
    e.setId(Util.generateDbUUID());
    entitlementCurator.create(e);
    Pool pool2 = TestUtil.createPool(owner, product);
    pool2.setSourceEntitlement(e);
    pool2.setSourceSubscription(new SourceSubscription(sourcePool.getSubscriptionId(), "derived"));
    poolCurator.create(pool2);
    assertTrue(poolCurator.lookupBySubscriptionId(owner, sub.getId()).size() == 2);
    poolManager.deletePool(sourcePool);
    // because we check for null now, we want to verify the
    // subpool gets deleted when the original pool is deleted.
    Pool gone = poolCurator.find(pool2.getId());
    assertEquals(gone, null);
}
Also used : Subscription(org.candlepin.model.dto.Subscription) Date(java.util.Date) Test(org.junit.Test)

Example 45 with Subscription

use of org.candlepin.model.dto.Subscription in project candlepin by candlepin.

the class PoolCuratorTest method testMultiplierCreation.

// Note:  This simply tests that the multiplier is read and used in pool creation.
// All of the null/negative multiplier test cases are in ProductTest
@Test
public void testMultiplierCreation() {
    Product product = new Product("someProduct", "An Extremely Great Product", 10L);
    product = this.createProduct(product, owner);
    Subscription sub = TestUtil.createSubscription(owner, product, new HashSet<>());
    sub.setId(Util.generateDbUUID());
    sub.setQuantity(16L);
    sub.setStartDate(TestUtil.createDate(2006, 10, 21));
    sub.setEndDate(TestUtil.createDate(2020, 1, 1));
    sub.setModified(new Date());
    Pool newPool = poolManager.createAndEnrichPools(sub).get(0);
    List<Pool> pools = poolCurator.lookupBySubscriptionId(owner, sub.getId());
    assertEquals(160L, pools.get(0).getQuantity().longValue());
    assertEquals(newPool.getQuantity(), pools.get(0).getQuantity());
}
Also used : Subscription(org.candlepin.model.dto.Subscription) Date(java.util.Date) Test(org.junit.Test)

Aggregations

Subscription (org.candlepin.model.dto.Subscription)101 Test (org.junit.Test)77 Pool (org.candlepin.model.Pool)60 Product (org.candlepin.model.Product)48 SourceSubscription (org.candlepin.model.SourceSubscription)36 LinkedList (java.util.LinkedList)35 ArrayList (java.util.ArrayList)34 Owner (org.candlepin.model.Owner)33 ConsumerInstalledProduct (org.candlepin.model.ConsumerInstalledProduct)27 HashMap (java.util.HashMap)20 HashSet (java.util.HashSet)18 Matchers.anyString (org.mockito.Matchers.anyString)18 Entitlement (org.candlepin.model.Entitlement)16 Date (java.util.Date)15 PoolType (org.candlepin.model.Pool.PoolType)13 ImportSubscriptionServiceAdapter (org.candlepin.service.impl.ImportSubscriptionServiceAdapter)13 List (java.util.List)11 OwnerServiceAdapter (org.candlepin.service.OwnerServiceAdapter)11 ConsumerType (org.candlepin.model.ConsumerType)10 ProductData (org.candlepin.model.dto.ProductData)9