use of org.candlepin.model.ProductShare in project candlepin by candlepin.
the class EntitlementRules method resolveProductShares.
private Map<String, Product> resolveProductShares(Owner sharingOwner, Owner recipient, Set<Product> products) {
Map<String, Product> sharedProductsIdMap = new HashMap<>();
Map<String, Product> sharedProductsUuidMap = new HashMap<>();
Map<String, Product> resolvedProducts = new HashMap<>();
List<Event> events = new LinkedList<>();
List<ProductShare> sharesToDelete = new LinkedList<>();
List<ProductShare> sharesToCreate = new LinkedList<>();
Map<String, ProductShare> existingSharesMap = new HashMap<>();
Map<String, String> productRefsToUpdate = new HashMap<>();
for (Product product : products) {
sharedProductsIdMap.put(product.getId(), product);
sharedProductsUuidMap.put(product.getUuid(), product);
}
List<Product> recipientProducts = ownerProductCurator.getProductsByIds(recipient, sharedProductsIdMap.keySet()).list();
for (Product product : recipientProducts) {
Map<String, Product> conflictedRecipientProducts = new HashMap<>();
if (sharedProductsUuidMap.containsKey(product.getUuid())) {
// Recipient has a product with the same ID already. If they are the same instance
// use then nothing needs doing. Everything is already in place.
resolvedProducts.put(product.getId(), product);
log.debug("Owner {} has the same product {} as the sharer {}", recipient.getKey(), product.getId(), sharingOwner.getKey());
} else {
// The recipient and owner have two products with the same ID but they are different
// instances since their uuids do not match.
conflictedRecipientProducts.put(product.getId(), product);
}
if (conflictedRecipientProducts.size() > 0) {
List<ProductShare> existingShares = shareCurator.findProductSharesByRecipient(recipient, conflictedRecipientProducts.keySet());
for (ProductShare pShare : existingShares) {
existingSharesMap.put(pShare.getProduct().getId(), pShare);
}
}
for (String id : conflictedRecipientProducts.keySet()) {
if (!existingSharesMap.containsKey(id)) {
// If the recipient's product isn't from a share, let the recipient just continue to
// use its existing product definition.
log.debug("Owner {} already has product {} defined that is not a share", recipient.getKey(), id);
resolvedProducts.put(id, conflictedRecipientProducts.get(id));
} else {
// If the recipient's product is a share then two owners are sharing into the same
// recipient and we must resolve the conflict.
Product sharingOwnerProduct = sharedProductsIdMap.get(id);
Product existingProduct = conflictedRecipientProducts.get(id);
ProductShare existingShare = existingSharesMap.get(id);
log.debug("Owner {} already has a share for Product {} from owner {}. Solving conflict.", recipient.getKey(), id, existingShare.getOwner());
EventBuilder builder = eventFactory.getEventBuilder(Event.Target.PRODUCT, Event.Type.MODIFIED);
builder.setEventData(existingProduct);
sharesToDelete.add(existingShare);
sharesToCreate.add(new ProductShare(sharingOwner, sharingOwnerProduct, recipient));
// Now we need to reconcile all of recipient's pools that were using the old product.
Product resolvedProduct = productManager.updateProduct(sharingOwnerProduct.toDTO(), recipient, true);
builder.setEventData(resolvedProduct);
resolvedProducts.put(resolvedProduct.getId(), resolvedProduct);
events.add(builder.buildEvent());
}
}
}
Set<String> idsNonExisting = new HashSet<>(sharedProductsIdMap.keySet());
idsNonExisting.removeAll(resolvedProducts.keySet());
for (String id : idsNonExisting) {
// The recipient doesn't have a definition for the product at all. Link the recipient
// and product and create a record of a share.
log.debug("Linking product {} from owner {} to owner {} as product share", id, sharingOwner.getKey(), recipient.getKey());
Product sharedProduct = sharedProductsIdMap.get(id);
ownerProductCurator.mapProductToOwner(sharedProduct, recipient);
sharesToCreate.add(new ProductShare(sharingOwner, sharedProduct, recipient));
resolvedProducts.put(id, sharedProduct);
}
shareCurator.bulkDelete(sharesToDelete);
shareCurator.saveOrUpdateAll(sharesToCreate, false, false);
for (Event event : events) {
eventSink.queueEvent(event);
}
return resolvedProducts;
}
Aggregations