use of com.commercetools.sync.commons.exceptions.SyncException in project commercetools-sync-java by commercetools.
the class ProductTypeSync method handleError.
/**
* Given a {@link String} {@code errorMessage} and a {@link Throwable} {@code exception}, this
* method calls the optional error callback specified in the {@code syncOptions} and updates the
* {@code statistics} instance by incrementing the total number of failed product types to sync.
*
* @param errorMessage The error message describing the reason(s) of failure.
* @param exception The exception that called caused the failure, if any.
* @param failedTimes The number of times that the failed product types counter is incremented.
* @param oldProductType existing product type that could be updated.
* @param newProductType draft containing data that could differ from data in {@code
* oldProductType}.
* @param updateActions the update actions to update the {@link ProductType} with.
*/
private void handleError(@Nonnull final String errorMessage, @Nullable final Throwable exception, final int failedTimes, @Nullable final ProductType oldProductType, @Nullable final ProductTypeDraft newProductType, @Nullable final List<UpdateAction<ProductType>> updateActions) {
SyncException syncException = exception != null ? new SyncException(errorMessage, exception) : new SyncException(errorMessage);
syncOptions.applyErrorCallback(syncException, oldProductType, newProductType, updateActions);
statistics.incrementFailed(failedTimes);
}
use of com.commercetools.sync.commons.exceptions.SyncException in project commercetools-sync-java by commercetools.
the class ProductTypeSync method resolveMissingNestedReferences.
/**
* Given a map of product type keys pointing to a set of attribute definition drafts which are now
* ready to be added for this product type. This method first converts the drafts to {@link
* AddAttributeDefinition} actions in which the reference id value (which is a key) is resolved to
* an actual UUID of the product type key pointed by this key. Then, for each product type, the
* method issues an update request containing all the actions.
*
* @return a {@link CompletionStage} which contains an empty result after execution of all the
* update requests.
*/
@Nonnull
private CompletionStage<Void> resolveMissingNestedReferences(@Nonnull final Map<String, Set<AttributeDefinitionDraft>> productTypesToUpdate) {
final Set<String> keys = productTypesToUpdate.keySet();
return productTypeService.fetchMatchingProductTypesByKeys(keys).handle(ImmutablePair::new).thenCompose(fetchResponse -> {
final Set<ProductType> matchingProductTypes = fetchResponse.getKey();
final Throwable exception = fetchResponse.getValue();
if (exception != null) {
final String errorMessage = format(CTP_PRODUCT_TYPE_FETCH_FAILED, keys);
syncOptions.applyErrorCallback(new SyncException(errorMessage, exception));
return CompletableFuture.completedFuture(null);
} else {
final Map<String, ProductType> keyToProductType = matchingProductTypes.stream().collect(Collectors.toMap(ProductType::getKey, productType -> productType));
return CompletableFuture.allOf(productTypesToUpdate.entrySet().stream().map(entry -> {
final String productTypeToUpdateKey = entry.getKey();
final Set<AttributeDefinitionDraft> attributeDefinitionDrafts = entry.getValue();
final List<UpdateAction<ProductType>> actionsWithResolvedReferences = draftsToActions(attributeDefinitionDrafts);
final ProductType productTypeToUpdate = keyToProductType.get(productTypeToUpdateKey);
return resolveMissingNestedReferences(productTypeToUpdate, actionsWithResolvedReferences);
}).map(CompletionStage::toCompletableFuture).toArray(CompletableFuture[]::new));
}
});
}
use of com.commercetools.sync.commons.exceptions.SyncException in project commercetools-sync-java by commercetools.
the class ProductTypeBatchValidator method getReferencedProductTypeKeys.
@Nonnull
private static Set<String> getReferencedProductTypeKeys(@Nonnull final ProductTypeDraft productTypeDraft) throws SyncException {
final List<AttributeDefinitionDraft> attributeDefinitionDrafts = productTypeDraft.getAttributes();
if (attributeDefinitionDrafts == null || attributeDefinitionDrafts.isEmpty()) {
return emptySet();
}
final Set<String> referencedProductTypeKeys = new HashSet<>();
final List<String> invalidAttributeDefinitionNames = new ArrayList<>();
for (AttributeDefinitionDraft attributeDefinitionDraft : attributeDefinitionDrafts) {
if (attributeDefinitionDraft != null) {
final AttributeType attributeType = attributeDefinitionDraft.getAttributeType();
try {
getProductTypeKey(attributeType).ifPresent(referencedProductTypeKeys::add);
} catch (InvalidReferenceException invalidReferenceException) {
invalidAttributeDefinitionNames.add(attributeDefinitionDraft.getName());
}
}
}
if (!invalidAttributeDefinitionNames.isEmpty()) {
final String errorMessage = format(PRODUCT_TYPE_HAS_INVALID_REFERENCES, productTypeDraft.getKey(), invalidAttributeDefinitionNames);
throw new SyncException(errorMessage, new InvalidReferenceException(BLANK_ID_VALUE_ON_REFERENCE));
}
return referencedProductTypeKeys;
}
use of com.commercetools.sync.commons.exceptions.SyncException in project commercetools-sync-java by commercetools.
the class TextLineItemUpdateActionUtils 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<TextLineItem> oldTextLineItems, @Nonnull final List<TextLineItemDraft> newTextLineItems, @Nonnull final ShoppingListSyncOptions syncOptions) {
final List<UpdateAction<ShoppingList>> updateActions = new ArrayList<>();
final int minSize = Math.min(oldTextLineItems.size(), newTextLineItems.size());
for (int i = 0; i < minSize; i++) {
final TextLineItem oldTextLineItem = oldTextLineItems.get(i);
final TextLineItemDraft newTextLineItem = newTextLineItems.get(i);
if (newTextLineItem.getName() == null || newTextLineItem.getName().getLocales().isEmpty()) {
/*
checking the name of the oldTextLineItem is not needed, because it's required.
with this check below, it's avoided bad request case like:
"detailedErrorMessage": "actions -> name: Missing required value"
*/
syncOptions.applyErrorCallback(new SyncException(format("TextLineItemDraft at position '%d' of the ShoppingListDraft with key '%s' has no name " + "set. Please make sure all text line items have names.", i, newShoppingList.getKey())), oldShoppingList, newShoppingList, updateActions);
return emptyList();
}
updateActions.addAll(buildTextLineItemUpdateActions(oldShoppingList, newShoppingList, oldTextLineItem, newTextLineItem, syncOptions));
}
for (int i = minSize; i < oldTextLineItems.size(); i++) {
updateActions.add(RemoveTextLineItem.of(oldTextLineItems.get(i).getId()));
}
for (int i = minSize; i < newTextLineItems.size(); i++) {
if (hasQuantity(newTextLineItems.get(i))) {
updateActions.add(mapToAddTextLineItemAction(newTextLineItems.get(i)));
}
}
return updateActions;
}
use of com.commercetools.sync.commons.exceptions.SyncException in project commercetools-sync-java by commercetools.
the class StateSync method updateState.
/**
* Given an existing {@link State} and a new {@link StateDraft}, the method calculates all the
* update actions required to synchronize the existing state to be the same as the new one. If
* there are update actions found, a request is made to CTP to update the existing state,
* otherwise it doesn't issue a request.
*
* <p>The {@code statistics} instance is updated accordingly to whether the CTP request was
* carried out successfully or not. If an exception was thrown on executing the request to CTP,
* the error handling method is called.
*
* @param oldState existing state that could be updated.
* @param newState draft containing data that could differ from data in {@code oldState}.
* @return a {@link CompletionStage} which contains an empty result after execution of the update.
*/
@Nonnull
private CompletionStage<Void> updateState(@Nonnull final State oldState, @Nonnull final StateDraft newState, @Nonnull final List<UpdateAction<State>> updateActions) {
return stateService.updateState(oldState, updateActions).handle(ImmutablePair::new).thenCompose(updateResponse -> {
final Throwable sphereException = updateResponse.getValue();
if (sphereException != null) {
return executeSupplierIfConcurrentModificationException(sphereException, () -> fetchAndUpdate(oldState, newState), () -> {
final String errorMessage = format(CTP_STATE_UPDATE_FAILED, newState.getKey(), sphereException.getMessage());
handleError(new SyncException(errorMessage, sphereException), oldState, newState, updateActions, 1);
return completedFuture(null);
});
} else {
statistics.incrementUpdated();
return completedFuture(null);
}
});
}
Aggregations