use of com.commercetools.sync.commons.exceptions.SyncException in project commercetools-sync-java by commercetools.
the class ShoppingListSync method updateShoppinglist.
@Nonnull
private CompletionStage<Void> updateShoppinglist(@Nonnull final ShoppingList oldShoppingList, @Nonnull final ShoppingListDraft newShoppingListDraft, @Nonnull final List<UpdateAction<ShoppingList>> updateActionsAfterCallback) {
return shoppingListService.updateShoppingList(oldShoppingList, updateActionsAfterCallback).handle(ImmutablePair::of).thenCompose(updateResponse -> {
final Throwable exception = updateResponse.getValue();
if (exception != null) {
return executeSupplierIfConcurrentModificationException(exception, () -> fetchAndUpdate(oldShoppingList, newShoppingListDraft), () -> {
final String errorMessage = format(CTP_SHOPPING_LIST_UPDATE_FAILED, newShoppingListDraft.getKey(), exception.getMessage());
handleError(new SyncException(errorMessage, exception), 1);
return CompletableFuture.completedFuture(null);
});
} else {
statistics.incrementUpdated();
return CompletableFuture.completedFuture(null);
}
});
}
use of com.commercetools.sync.commons.exceptions.SyncException in project commercetools-sync-java by commercetools.
the class ShoppingListSync method syncBatch.
@Nonnull
private CompletionStage<Void> syncBatch(@Nonnull final Set<ShoppingList> oldShoppingLists, @Nonnull final Set<ShoppingListDraft> newShoppingListDrafts) {
Map<String, ShoppingList> keyShoppingListsMap = oldShoppingLists.stream().collect(toMap(ShoppingList::getKey, identity()));
return CompletableFuture.allOf(newShoppingListDrafts.stream().map(shoppingListDraft -> shoppingListReferenceResolver.resolveReferences(shoppingListDraft).thenCompose(resolvedShoppingListDraft -> syncDraft(keyShoppingListsMap, resolvedShoppingListDraft)).exceptionally(completionException -> {
final String errorMessage = format(FAILED_TO_PROCESS, shoppingListDraft.getKey(), completionException.getMessage());
handleError(new SyncException(errorMessage, completionException), 1);
return null;
})).map(CompletionStage::toCompletableFuture).toArray(CompletableFuture[]::new));
}
use of com.commercetools.sync.commons.exceptions.SyncException in project commercetools-sync-java by commercetools.
the class ShoppingListSync method fetchAndUpdate.
@Nonnull
private CompletionStage<Void> fetchAndUpdate(@Nonnull final ShoppingList oldShoppingList, @Nonnull final ShoppingListDraft newShoppingListDraft) {
final String shoppingListKey = oldShoppingList.getKey();
return shoppingListService.fetchShoppingList(shoppingListKey).handle(ImmutablePair::of).thenCompose(fetchResponse -> {
final Optional<ShoppingList> fetchedShoppingListOptional = fetchResponse.getKey();
final Throwable exception = fetchResponse.getValue();
if (exception != null) {
final String errorMessage = format(CTP_SHOPPING_LIST_UPDATE_FAILED, shoppingListKey, "Failed to fetch from CTP while retrying after concurrency modification.");
handleError(new SyncException(errorMessage, exception), 1);
return CompletableFuture.completedFuture(null);
}
return fetchedShoppingListOptional.map(fetchedShoppingList -> buildActionsAndUpdate(fetchedShoppingList, newShoppingListDraft)).orElseGet(() -> {
final String errorMessage = format(CTP_SHOPPING_LIST_UPDATE_FAILED, shoppingListKey, "Not found when attempting to fetch while retrying after concurrency modification.");
handleError(new SyncException(errorMessage, null), 1);
return CompletableFuture.completedFuture(null);
});
});
}
use of com.commercetools.sync.commons.exceptions.SyncException in project commercetools-sync-java by commercetools.
the class LineItemUpdateActionUtils method buildUpdateActions.
/**
* The decisions in the calculating update actions are documented on the
* `docs/adr/0002-shopping-lists-lineitem-and-textlineitem-update-actions.md`
*/
@Nonnull
private static List<UpdateAction<ShoppingList>> buildUpdateActions(@Nonnull final ShoppingList oldShoppingList, @Nonnull final ShoppingListDraft newShoppingList, @Nonnull final List<LineItem> oldLineItems, @Nonnull final List<LineItemDraft> newlineItems, @Nonnull final ShoppingListSyncOptions syncOptions) {
final List<UpdateAction<ShoppingList>> updateActions = new ArrayList<>();
final int minSize = Math.min(oldLineItems.size(), newlineItems.size());
int indexOfFirstDifference = minSize;
for (int i = 0; i < minSize; i++) {
final LineItem oldLineItem = oldLineItems.get(i);
final LineItemDraft newLineItem = newlineItems.get(i);
if (oldLineItem.getVariant() == null || StringUtils.isBlank(oldLineItem.getVariant().getSku())) {
syncOptions.applyErrorCallback(new SyncException(format("LineItem at position '%d' of the ShoppingList with key '%s' has no SKU set. " + "Please make sure all line items have SKUs.", i, oldShoppingList.getKey())), oldShoppingList, newShoppingList, updateActions);
return emptyList();
} else if (StringUtils.isBlank(newLineItem.getSku())) {
syncOptions.applyErrorCallback(new SyncException(format("LineItemDraft at position '%d' of the ShoppingListDraft with key '%s' has no SKU set. " + "Please make sure all line item drafts have SKUs.", i, newShoppingList.getKey())), oldShoppingList, newShoppingList, updateActions);
return emptyList();
}
if (oldLineItem.getVariant().getSku().equals(newLineItem.getSku())) {
updateActions.addAll(buildLineItemUpdateActions(oldShoppingList, newShoppingList, oldLineItem, newLineItem, syncOptions));
} else {
// different sku means the order is different.
// To be able to ensure the order, we need to remove and add this line item back
// with the up to date values.
indexOfFirstDifference = i;
break;
}
}
// expected: remove from old li-2, add from draft li-3, li-2 starting from the index.
for (int i = indexOfFirstDifference; i < oldLineItems.size(); i++) {
updateActions.add(RemoveLineItem.of(oldLineItems.get(i).getId()));
}
for (int i = indexOfFirstDifference; i < newlineItems.size(); i++) {
if (hasQuantity(newlineItems.get(i))) {
updateActions.add(AddLineItem.of(newlineItems.get(i)));
}
}
return updateActions;
}
use of com.commercetools.sync.commons.exceptions.SyncException in project commercetools-sync-java by commercetools.
the class CustomUpdateActionUtilsTest method buildCustomUpdateActions_WithNullIds_ShouldCallSyncOptionsCallBack.
@Test
void buildCustomUpdateActions_WithNullIds_ShouldCallSyncOptionsCallBack() {
final Reference<Type> assetCustomTypeReference = Type.referenceOfId(null);
// Mock old CustomFields
final CustomFields oldCustomFieldsMock = mock(CustomFields.class);
when(oldCustomFieldsMock.getType()).thenReturn(assetCustomTypeReference);
// Mock new CustomFieldsDraft
final CustomFieldsDraft newCustomFieldsMock = mock(CustomFieldsDraft.class);
when(newCustomFieldsMock.getType()).thenReturn(assetCustomTypeReference);
// Mock old Asset
final Asset oldAsset = mock(Asset.class);
final String oldAssetId = "oldAssetId";
when(oldAsset.getId()).thenReturn(oldAssetId);
when(oldAsset.getCustom()).thenReturn(oldCustomFieldsMock);
final AssetDraft newAssetDraft = AssetDraftBuilder.of(emptyList(), ofEnglish("assetName")).custom(newCustomFieldsMock).build();
// Mock custom options error callback
final ArrayList<Object> callBackResponses = new ArrayList<>();
final QuadConsumer<SyncException, Optional<ProductDraft>, Optional<ProductProjection>, List<UpdateAction<Product>>> errorCallback = (exception, newResource, oldResource, updateActions) -> {
callBackResponses.add(exception.getMessage());
callBackResponses.add(exception.getCause());
};
// Mock sync options
final ProductSyncOptions productSyncOptions = ProductSyncOptionsBuilder.of(CTP_CLIENT).errorCallback(errorCallback).build();
final List<UpdateAction<Product>> updateActions = buildCustomUpdateActions(maiNewResource, oldAsset, newAssetDraft, new AssetCustomActionBuilder(), 10, Asset::getId, asset -> Asset.resourceTypeId(), Asset::getKey, productSyncOptions);
assertThat(callBackResponses).hasSize(2);
assertThat(callBackResponses.get(0)).isEqualTo("Failed to build custom fields update actions on the asset" + " with id 'oldAssetId'. Reason: Custom type ids are not set for both the old and new asset.");
assertThat((Exception) callBackResponses.get(1)).isInstanceOf(BuildUpdateActionException.class);
assertThat(updateActions).isEmpty();
}
Aggregations