SubscriptionReconciler { public Collection<SubscriptionDTO> reconcile(Owner owner, Collection<SubscriptionDTO> subsToImport) { Map<String, Map<String, Pool>> existingPoolsByUpstreamPool = this.mapPoolsByUpstreamPool(owner); Set<SubscriptionDTO> subscriptionsStillToImport = new HashSet<>(); for (SubscriptionDTO 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() ); } } List<SubscriptionDTO> subscriptionsNeedQuantityMatch = new ArrayList<>(); for (SubscriptionDTO subscription : subscriptionsStillToImport) { Pool local = null; Map<String, Pool> map = existingPoolsByUpstreamPool.get(subscription.getUpstreamPoolId()); if (map == null) { map = new HashMap<>(); } for (Pool localSub : map.values()) { 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() ); } } subscriptionsNeedQuantityMatch.sort((lhs, rhs) -> rhs.getQuantity().compareTo(lhs.getQuantity())); for (SubscriptionDTO subscription : subscriptionsNeedQuantityMatch) { 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 local = map.values().stream() .max((lhs, rhs) -> lhs.getQuantity().compareTo(rhs.getQuantity())) .get(); this.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; } @Inject  SubscriptionReconciler(PoolCurator poolCurator); Collection<SubscriptionDTO> reconcile(Owner owner, Collection<SubscriptionDTO> subsToImport);  }
@Test public void oneExistsUnchanged() { SubscriptionDTO testSub1 = createSubscription(ownerDto, "test-prod-1", "up1", "ue1", "uc1", 25); createPoolsFor(testSub1); reconciler.reconcile(owner, Arrays.asList(testSub1)); assertUpstream(testSub1, testSub1.getId()); }
@Test public void oneExistsOneNew() { SubscriptionDTO testSub2 = createSubscription(ownerDto, "test-prod-1", "up1", "ue2", "uc1", 20); SubscriptionDTO testSub3 = createSubscription(ownerDto, "test-prod-1", "up1", "ue3", "uc1", 15); createPoolsFor(testSub2); reconciler.reconcile(owner, Arrays.asList(testSub2, testSub3)); assertUpstream(testSub2, testSub2.getId()); assertUpstream(testSub3, testSub3.getId()); }
@Test public void testTwoExistOneRemoved() { SubscriptionDTO testSub2 = createSubscription(ownerDto, "test-prod-1", "up1", "ue2", "uc1", 20); SubscriptionDTO testSub3 = createSubscription(ownerDto, "test-prod-1", "up1", "ue3", "uc1", 15); createPoolsFor(testSub2, testSub3); reconciler.reconcile(owner, Arrays.asList(testSub3)); assertUpstream(testSub3, testSub3.getId()); }
@Test public void testThreeExistThreeNewOneDifferent() { SubscriptionDTO testSub2 = createSubscription(ownerDto, "test-prod-1", "up1", "ue2", "uc1", 20); SubscriptionDTO testSub3 = createSubscription(ownerDto, "test-prod-1", "up1", "ue3", "uc1", 15); SubscriptionDTO testSub4 = createSubscription(ownerDto, "test-prod-1", "up1", "ue4", "uc1", 10); SubscriptionDTO testSub5 = createSubscription(ownerDto, "test-prod-1", "up1", "ue5", "uc1", 5); createPoolsFor(testSub2, testSub3, testSub4); reconciler.reconcile(owner, Arrays.asList(testSub2, testSub4, testSub5)); assertUpstream(testSub2, testSub2.getId()); assertUpstream(testSub4, testSub4.getId()); assertUpstream(testSub5, testSub3.getId()); }
@Test public void testThreeExistThreeNewSameQuantitiesNewConsumer() { SubscriptionDTO testSub3 = createSubscription(ownerDto, "test-prod-1", "up1", "ue3", "uc1", 15); SubscriptionDTO testSub4 = createSubscription(ownerDto, "test-prod-1", "up1", "ue4", "uc1", 10); SubscriptionDTO testSub5 = createSubscription(ownerDto, "test-prod-1", "up1", "ue5", "uc1", 5); SubscriptionDTO testSub6 = createSubscription(ownerDto, "test-prod-1", "up1", "ue6", "uc2", 15); SubscriptionDTO testSub7 = createSubscription(ownerDto, "test-prod-1", "up1", "ue7", "uc2", 10); SubscriptionDTO testSub8 = createSubscription(ownerDto, "test-prod-1", "up1", "ue8", "uc2", 5); createPoolsFor(testSub3, testSub4, testSub5); reconciler.reconcile(owner, Arrays.asList(testSub6, testSub7, testSub8)); assertUpstream(testSub6, testSub3.getId()); assertUpstream(testSub7, testSub4.getId()); assertUpstream(testSub8, testSub5.getId()); }
@Test public void testThreeExistTwoNewQuantityMatchNewConsumer() { SubscriptionDTO testSub3 = createSubscription(ownerDto, "test-prod-1", "up1", "ue3", "uc1", 15); SubscriptionDTO testSub4 = createSubscription(ownerDto, "test-prod-1", "up1", "ue4", "uc1", 10); SubscriptionDTO testSub5 = createSubscription(ownerDto, "test-prod-1", "up1", "ue5", "uc1", 5); SubscriptionDTO testSub6 = createSubscription(ownerDto, "test-prod-1", "up1", "ue6", "uc2", 15); SubscriptionDTO testSub8 = createSubscription(ownerDto, "test-prod-1", "up1", "ue8", "uc2", 5); createPoolsFor(testSub3, testSub4, testSub5); reconciler.reconcile(owner, Arrays.asList(testSub6, testSub8)); assertUpstream(testSub6, testSub3.getId()); assertUpstream(testSub8, testSub5.getId()); }
@Test public void testTwoExistThreeNewConsumer() { SubscriptionDTO testSub3 = createSubscription(ownerDto, "test-prod-1", "up1", "ue3", "uc1", 15); SubscriptionDTO testSub4 = createSubscription(ownerDto, "test-prod-1", "up1", "ue4", "uc1", 10); SubscriptionDTO testSub6 = createSubscription(ownerDto, "test-prod-1", "up1", "ue6", "uc2", 15); SubscriptionDTO testSub7 = createSubscription(ownerDto, "test-prod-1", "up1", "ue7", "uc2", 10); SubscriptionDTO testSub8 = createSubscription(ownerDto, "test-prod-1", "up1", "ue8", "uc2", 5); createPoolsFor(testSub3, testSub4); reconciler.reconcile(owner, Arrays.asList(testSub6, testSub7, testSub8)); assertUpstream(testSub6, testSub3.getId()); assertUpstream(testSub7, testSub4.getId()); assertUpstream(testSub8, testSub8.getId()); }
@Test public void testThreeExistOldThreeNew() { SubscriptionDTO testSub3 = createSubscription(ownerDto, "test-prod-1", "up1", "ue3", "uc1", 15); SubscriptionDTO testSub4 = createSubscription(ownerDto, "test-prod-1", "up1", "ue4", "uc1", 10); SubscriptionDTO testSub5 = createSubscription(ownerDto, "test-prod-1", "up1", "ue5", "uc1", 5); SubscriptionDTO testSub9 = createSubscription(ownerDto, "test-prod-1", "up1", "", "", 15); SubscriptionDTO testSub10 = createSubscription(ownerDto, "test-prod-1", "up1", "", "", 10); SubscriptionDTO testSub11 = createSubscription(ownerDto, "test-prod-1", "up1", "", "", 5); createPoolsFor(testSub9, testSub10, testSub11); reconciler.reconcile(owner, Arrays.asList(testSub3, testSub4, testSub5)); assertUpstream(testSub3, testSub9.getId()); assertUpstream(testSub4, testSub10.getId()); assertUpstream(testSub5, testSub11.getId()); }
@Test public void testQuantMatchAllLower() { SubscriptionDTO testSub1 = createSubscription(ownerDto, "test-prod-1", "up1", "ue1", "uc1", 25); SubscriptionDTO testSub2 = createSubscription(ownerDto, "test-prod-1", "up1", "ue2", "uc1", 20); SubscriptionDTO testSub3 = createSubscription(ownerDto, "test-prod-1", "up1", "ue3", "uc1", 15); SubscriptionDTO testSub12 = createSubscription(ownerDto, "test-prod-1", "up1", "ue12", "uc3", 23); SubscriptionDTO testSub13 = createSubscription(ownerDto, "test-prod-1", "up1", "ue13", "uc3", 17); SubscriptionDTO testSub14 = createSubscription(ownerDto, "test-prod-1", "up1", "ue14", "uc3", 10); createPoolsFor(testSub1, testSub2, testSub3); reconciler.reconcile(owner, Arrays.asList(testSub12, testSub13, testSub14)); assertUpstream(testSub12, testSub1.getId()); assertUpstream(testSub13, testSub2.getId()); assertUpstream(testSub14, testSub3.getId()); }
@Test public void testQuantMatchMix() { SubscriptionDTO testSub2 = createSubscription(ownerDto, "test-prod-1", "up1", "ue2", "uc1", 20); SubscriptionDTO testSub3 = createSubscription(ownerDto, "test-prod-1", "up1", "ue3", "uc1", 15); SubscriptionDTO testSub4 = createSubscription(ownerDto, "test-prod-1", "up1", "ue4", "uc1", 10); SubscriptionDTO testSub5 = createSubscription(ownerDto, "test-prod-1", "up1", "ue5", "uc1", 5); SubscriptionDTO testSub12 = createSubscription(ownerDto, "test-prod-1", "up1", "ue12", "uc3", 23); SubscriptionDTO testSub14 = createSubscription(ownerDto, "test-prod-1", "up1", "ue14", "uc3", 10); createPoolsFor(testSub2, testSub3, testSub4, testSub5); reconciler.reconcile(owner, Arrays.asList(testSub12, testSub14)); assertUpstream(testSub12, testSub2.getId()); assertUpstream(testSub14, testSub4.getId()); }
@Test public void testQuantMatchAllSame() { SubscriptionDTO testSub3 = createSubscription(ownerDto, "test-prod-1", "up1", "ue3", "uc1", 15); SubscriptionDTO testSub15 = createSubscription(ownerDto, "test-prod-1", "up1", "ue15", "uc1", 15); SubscriptionDTO testSub16 = createSubscription(ownerDto, "test-prod-1", "up1", "ue16", "uc1", 15); createPoolsFor(testSub3, testSub15); reconciler.reconcile(owner, Arrays.asList(testSub3, testSub16)); assertUpstream(testSub3, testSub3.getId()); assertUpstream(testSub16, testSub15.getId()); }
@Test public void testMultiPools() { SubscriptionDTO testSub1 = createSubscription(ownerDto, "test-prod-1", "up1", "ue1", "uc1", 25); SubscriptionDTO testSub2 = createSubscription(ownerDto, "test-prod-1", "up1", "ue2", "uc1", 20); SubscriptionDTO testSub3 = createSubscription(ownerDto, "test-prod-1", "up1", "ue3", "uc1", 15); SubscriptionDTO testSub4 = createSubscription(ownerDto, "test-prod-1", "up1", "ue4", "uc1", 10); SubscriptionDTO testSub5 = createSubscription(ownerDto, "test-prod-1", "up1", "ue5", "uc1", 5); SubscriptionDTO testSub20 = createSubscription(ownerDto, "test-prod-1", "up2", "ue20", "uc1", 25); SubscriptionDTO testSub21 = createSubscription(ownerDto, "test-prod-1", "up2", "ue21", "uc1", 20); SubscriptionDTO testSub22 = createSubscription(ownerDto, "test-prod-1", "up2", "ue22", "uc1", 15); SubscriptionDTO testSub24 = createSubscription(ownerDto, "test-prod-1", "up2", "ue24", "uc1", 5); SubscriptionDTO testSub30 = createSubscription(ownerDto, "test-prod-1", "up3", "ue30", "uc1", 25); SubscriptionDTO testSub31 = createSubscription(ownerDto, "test-prod-1", "up3", "ue31", "uc1", 20); SubscriptionDTO testSub32 = createSubscription(ownerDto, "test-prod-1", "up3", "ue32", "uc1", 15); SubscriptionDTO testSub33 = createSubscription(ownerDto, "test-prod-1", "up3", "ue33", "uc1", 10); SubscriptionDTO testSub34 = createSubscription(ownerDto, "test-prod-1", "up3", "ue34", "uc1", 5); createPoolsFor(testSub1, testSub2, testSub3, testSub4, testSub5, testSub20, testSub21, testSub22, testSub24); reconciler.reconcile(owner, Arrays.asList(testSub1, testSub2, testSub3, testSub4, testSub5, testSub30, testSub31, testSub32, testSub33, testSub34)); assertUpstream(testSub1, testSub1.getId()); assertUpstream(testSub2, testSub2.getId()); assertUpstream(testSub3, testSub3.getId()); assertUpstream(testSub4, testSub4.getId()); assertUpstream(testSub5, testSub5.getId()); assertUpstream(testSub30, testSub30.getId()); assertUpstream(testSub31, testSub31.getId()); assertUpstream(testSub32, testSub32.getId()); assertUpstream(testSub33, testSub33.getId()); assertUpstream(testSub34, testSub34.getId()); }