Skip to content

Commit

Permalink
#54: Bump commercetoools-sync-java
Browse files Browse the repository at this point in the history
  • Loading branch information
heshamMassoud authored Oct 10, 2019
1 parent 93fae59 commit 60ebcbd
Show file tree
Hide file tree
Showing 10 changed files with 442 additions and 53 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ buildscript {

plugins {
id "com.github.ben-manes.versions" version '0.26.0'
id 'com.adarshr.test-logger' version '1.7.1'
id 'com.adarshr.test-logger' version '2.0.0'
id "com.diffplug.gradle.spotless" version '3.25.0'
id 'com.bmuschko.docker-java-application' version '5.2.0'
}
Expand Down
5 changes: 3 additions & 2 deletions gradle-scripts/dependencies.gradle
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
ext {
commercetoolsJvmSdkVersion = '1.46.0'
mockitoVersion = '3.0.0'
mockitoVersion = '3.1.0'
slf4jVersion = '1.7.25'
slf4jTestVersion = '1.2.0'
assertjVersion = '3.13.2'
pmdVersion = '5.6.1'
jacocoVersion = '0.7.9'
findbugsVersion = '3.0.1'
commercetoolsSyncJava='1.5.0'
commercetoolsSyncJava='1.6.0'
apacheCliVersion = '1.4'
jupiterApiVersion = '5.5.2'
}
Expand All @@ -16,6 +16,7 @@ dependencies {
implementation "com.commercetools.sdk.jvm.core:commercetools-models:${commercetoolsJvmSdkVersion}"
implementation "com.commercetools.sdk.jvm.core:commercetools-java-client:${commercetoolsJvmSdkVersion}"
implementation "com.commercetools:commercetools-sync-java:${commercetoolsSyncJava}"
implementation "com.commercetools.sdk.jvm.core:commercetools-convenience:${commercetoolsJvmSdkVersion}"
implementation "commons-cli:commons-cli:${apacheCliVersion}"
implementation "org.slf4j:slf4j-api:${slf4jVersion}"
implementation "org.slf4j:slf4j-simple:${slf4jVersion}"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import static com.commercetools.project.sync.util.IntegrationTestUtils.assertCategoryExists;
import static com.commercetools.project.sync.util.IntegrationTestUtils.assertProductTypeExists;
import static com.commercetools.project.sync.util.IntegrationTestUtils.cleanUpProjects;
import static com.commercetools.project.sync.util.IntegrationTestUtils.createAttributeObject;
import static com.commercetools.project.sync.util.IntegrationTestUtils.createReferenceObject;
import static com.commercetools.project.sync.util.SphereClientUtils.CTP_SOURCE_CLIENT_CONFIG;
import static com.commercetools.project.sync.util.SphereClientUtils.CTP_TARGET_CLIENT_CONFIG;
import static com.commercetools.project.sync.util.TestUtils.assertCartDiscountSyncerLoggingEvents;
Expand All @@ -21,7 +23,6 @@
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
import io.sphere.sdk.categories.Category;
import io.sphere.sdk.categories.CategoryDraft;
import io.sphere.sdk.categories.CategoryDraftBuilder;
Expand Down Expand Up @@ -195,24 +196,6 @@ static void setupSourceProjectData(@Nonnull final SphereClient sourceProjectClie
.join();
}

@Nonnull
private static ObjectNode createReferenceObject(
@Nonnull final String typeId, @Nonnull final String id) {
final ObjectNode referenceObject = JsonNodeFactory.instance.objectNode();
referenceObject.set("typeId", JsonNodeFactory.instance.textNode(typeId));
referenceObject.set("id", JsonNodeFactory.instance.textNode(id));
return referenceObject;
}

@Nonnull
private static ObjectNode createAttributeObject(
@Nonnull final String name, @Nonnull final ArrayNode value) {
final ObjectNode attributeObject = JsonNodeFactory.instance.objectNode();
attributeObject.set("name", JsonNodeFactory.instance.textNode(name));
attributeObject.set("value", value);
return attributeObject;
}

@AfterAll
static void tearDownSuite() {
cleanUpProjects(createClient(CTP_SOURCE_CLIENT_CONFIG), createClient(CTP_TARGET_CLIENT_CONFIG));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,227 @@
package com.commercetools.project.sync;

import static com.commercetools.project.sync.util.ClientConfigurationUtils.createClient;
import static com.commercetools.project.sync.util.IntegrationTestUtils.assertProductTypeExists;
import static com.commercetools.project.sync.util.IntegrationTestUtils.cleanUpProjects;
import static com.commercetools.project.sync.util.IntegrationTestUtils.createReferenceObject;
import static com.commercetools.project.sync.util.SphereClientUtils.CTP_SOURCE_CLIENT;
import static com.commercetools.project.sync.util.SphereClientUtils.CTP_SOURCE_CLIENT_CONFIG;
import static com.commercetools.project.sync.util.SphereClientUtils.CTP_TARGET_CLIENT_CONFIG;
import static com.commercetools.project.sync.util.TestUtils.assertCartDiscountSyncerLoggingEvents;
import static com.commercetools.project.sync.util.TestUtils.assertCategorySyncerLoggingEvents;
import static com.commercetools.project.sync.util.TestUtils.assertInventoryEntrySyncerLoggingEvents;
import static com.commercetools.project.sync.util.TestUtils.assertProductSyncerLoggingEvents;
import static com.commercetools.project.sync.util.TestUtils.assertProductTypeSyncerLoggingEvents;
import static com.commercetools.project.sync.util.TestUtils.assertTypeSyncerLoggingEvents;
import static io.sphere.sdk.models.LocalizedString.ofEnglish;
import static java.lang.String.format;
import static java.util.Collections.emptyList;
import static java.util.Collections.singletonList;
import static org.assertj.core.api.Assertions.assertThat;

import com.commercetools.sync.commons.models.WaitingToBeResolved;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
import io.sphere.sdk.client.SphereClient;
import io.sphere.sdk.customobjects.CustomObject;
import io.sphere.sdk.customobjects.queries.CustomObjectQuery;
import io.sphere.sdk.products.Product;
import io.sphere.sdk.products.ProductDraft;
import io.sphere.sdk.products.ProductDraftBuilder;
import io.sphere.sdk.products.ProductVariantDraft;
import io.sphere.sdk.products.ProductVariantDraftBuilder;
import io.sphere.sdk.products.attributes.AttributeConstraint;
import io.sphere.sdk.products.attributes.AttributeDefinitionDraft;
import io.sphere.sdk.products.attributes.AttributeDefinitionDraftBuilder;
import io.sphere.sdk.products.attributes.AttributeDraft;
import io.sphere.sdk.products.attributes.ReferenceAttributeType;
import io.sphere.sdk.products.attributes.SetAttributeType;
import io.sphere.sdk.products.commands.ProductCreateCommand;
import io.sphere.sdk.products.queries.ProductQuery;
import io.sphere.sdk.producttypes.ProductType;
import io.sphere.sdk.producttypes.ProductTypeDraft;
import io.sphere.sdk.producttypes.ProductTypeDraftBuilder;
import io.sphere.sdk.producttypes.commands.ProductTypeCreateCommand;
import io.sphere.sdk.queries.PagedQueryResult;
import io.sphere.sdk.queries.QueryExecutionUtils;
import java.time.Clock;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import javax.annotation.Nonnull;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import uk.org.lidalia.slf4jext.Level;
import uk.org.lidalia.slf4jtest.TestLogger;
import uk.org.lidalia.slf4jtest.TestLoggerFactory;

class ProductSyncWithReferencesIT {

private static final TestLogger syncerTestLogger = TestLoggerFactory.getTestLogger(Syncer.class);
private static final TestLogger cliRunnerTestLogger =
TestLoggerFactory.getTestLogger(CliRunner.class);

private static final String MAIN_PRODUCT_TYPE_KEY = "main-product-type";
private static final String MAIN_PRODUCT_MASTER_VARIANT_KEY = "main-product-master-variant-key";
private static final String MAIN_PRODUCT_KEY = "product-with-references";

@BeforeEach
void setup() {
syncerTestLogger.clearAll();
cliRunnerTestLogger.clearAll();
cleanUpProjects(createClient(CTP_SOURCE_CLIENT_CONFIG), createClient(CTP_TARGET_CLIENT_CONFIG));
setupSourceProjectData(createClient(CTP_SOURCE_CLIENT_CONFIG));
}

static void setupSourceProjectData(@Nonnull final SphereClient sourceProjectClient) {
final AttributeDefinitionDraft setOfProductsAttributeDef =
AttributeDefinitionDraftBuilder.of(
SetAttributeType.of(ReferenceAttributeType.ofProduct()),
"products",
ofEnglish("products"),
false)
.searchable(false)
.attributeConstraint(AttributeConstraint.NONE)
.build();

final ProductTypeDraft productTypeDraft =
ProductTypeDraftBuilder.of(
MAIN_PRODUCT_TYPE_KEY,
MAIN_PRODUCT_TYPE_KEY,
"a productType for t-shirts",
emptyList())
.attributes(singletonList(setOfProductsAttributeDef))
.build();

final ProductType productType =
sourceProjectClient
.execute(ProductTypeCreateCommand.of(productTypeDraft))
.toCompletableFuture()
.join();

final ConcurrentHashMap.KeySetView<String, Boolean> productIds = ConcurrentHashMap.newKeySet();

// create 500 products
final CompletableFuture[] creationFutures =
IntStream.range(0, 500)
.mapToObj(
index -> {
final ProductVariantDraft masterVariant =
ProductVariantDraftBuilder.of()
.key(format("%d-mv-key", index))
.sku(format("%d-mv-sku", index))
.build();

final ProductDraft draft =
ProductDraftBuilder.of(
productType,
ofEnglish(Integer.toString(index)),
ofEnglish(format("%d-slug", index)),
masterVariant)
.key(format("%d-key", index))
.build();
return CTP_SOURCE_CLIENT
.execute(ProductCreateCommand.of(draft))
.thenAccept(createdProduct -> productIds.add(createdProduct.getId()))
.toCompletableFuture();
})
.toArray(CompletableFuture[]::new);

CompletableFuture.allOf(creationFutures).join();

final ArrayNode setAttributeValue = JsonNodeFactory.instance.arrayNode();
final Set<ObjectNode> productReferences =
productIds
.stream()
.map(productId -> createReferenceObject(Product.referenceTypeId(), productId))
.collect(Collectors.toSet());
setAttributeValue.addAll(productReferences);

final ProductVariantDraft masterVariant =
ProductVariantDraftBuilder.of()
.key(MAIN_PRODUCT_MASTER_VARIANT_KEY)
.sku(MAIN_PRODUCT_MASTER_VARIANT_KEY)
.attributes(AttributeDraft.of(setOfProductsAttributeDef.getName(), setAttributeValue))
.build();

final ProductDraft draft =
ProductDraftBuilder.of(
productType,
ofEnglish(MAIN_PRODUCT_KEY),
ofEnglish(MAIN_PRODUCT_KEY),
masterVariant)
.key(MAIN_PRODUCT_KEY)
.build();

sourceProjectClient.execute(ProductCreateCommand.of(draft)).toCompletableFuture().join();
}

@AfterAll
static void tearDownSuite() {
cleanUpProjects(createClient(CTP_SOURCE_CLIENT_CONFIG), createClient(CTP_TARGET_CLIENT_CONFIG));
}

@Test
void run_WithAProductWith500DistinctReferences_ShouldSyncCorrectly() {
// preparation
try (final SphereClient targetClient = createClient(CTP_TARGET_CLIENT_CONFIG)) {
try (final SphereClient sourceClient = createClient(CTP_SOURCE_CLIENT_CONFIG)) {

final SyncerFactory syncerFactory =
SyncerFactory.of(() -> sourceClient, () -> targetClient, Clock.systemDefaultZone());

// test
CliRunner.of().run(new String[] {"-s", "all", "-r", "runnerName", "-f"}, syncerFactory);
}
}

// create clients again (for assertions and cleanup), since the run method closes the clients
// after execution
// is done.
try (final SphereClient postTargetClient = createClient(CTP_TARGET_CLIENT_CONFIG)) {

// assertions
assertThat(cliRunnerTestLogger.getAllLoggingEvents())
.allMatch(loggingEvent -> !Level.ERROR.equals(loggingEvent.getLevel()));

assertThat(syncerTestLogger.getAllLoggingEvents())
.allMatch(loggingEvent -> !Level.ERROR.equals(loggingEvent.getLevel()));

assertTypeSyncerLoggingEvents(syncerTestLogger, 0);
assertProductTypeSyncerLoggingEvents(syncerTestLogger, 1);
assertCategorySyncerLoggingEvents(syncerTestLogger, 0);
assertProductSyncerLoggingEvents(syncerTestLogger, 501);
assertInventoryEntrySyncerLoggingEvents(syncerTestLogger, 0);
assertCartDiscountSyncerLoggingEvents(syncerTestLogger, 0);

// Every sync module (6 modules) is expected to have 2 logs (start and stats summary) = 12
assertThat(syncerTestLogger.getAllLoggingEvents()).hasSize(12);

assertAllResourcesAreSyncedToTarget(postTargetClient);
}
}

private static void assertAllResourcesAreSyncedToTarget(
@Nonnull final SphereClient targetClient) {

assertProductTypeExists(targetClient, MAIN_PRODUCT_TYPE_KEY);

final List<Product> products =
QueryExecutionUtils.queryAll(targetClient, ProductQuery.of()).toCompletableFuture().join();
assertThat(products).hasSize(501);

final CustomObjectQuery<WaitingToBeResolved> customObjectQuery =
CustomObjectQuery.of(WaitingToBeResolved.class)
.byContainer("commercetools-sync-java.UnresolvedReferencesService.productDrafts");

final PagedQueryResult<CustomObject<WaitingToBeResolved>> queryResult =
targetClient.execute(customObjectQuery).toCompletableFuture().join();

assertThat(queryResult.getResults()).isEmpty();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@

import com.commercetools.project.sync.model.response.LastSyncCustomObject;
import com.commercetools.sync.commons.utils.CtpQueryUtils;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
import io.sphere.sdk.cartdiscounts.commands.CartDiscountDeleteCommand;
import io.sphere.sdk.cartdiscounts.queries.CartDiscountQuery;
import io.sphere.sdk.categories.Category;
Expand Down Expand Up @@ -226,5 +229,23 @@ public static Product assertProductExists(
return productQueryResult.getResults().get(0);
}

@Nonnull
public static ObjectNode createReferenceObject(
@Nonnull final String typeId, @Nonnull final String id) {
final ObjectNode referenceObject = JsonNodeFactory.instance.objectNode();
referenceObject.set("typeId", JsonNodeFactory.instance.textNode(typeId));
referenceObject.set("id", JsonNodeFactory.instance.textNode(id));
return referenceObject;
}

@Nonnull
public static ObjectNode createAttributeObject(
@Nonnull final String name, @Nonnull final ArrayNode value) {
final ObjectNode attributeObject = JsonNodeFactory.instance.objectNode();
attributeObject.set("name", JsonNodeFactory.instance.textNode(name));
attributeObject.set("value", value);
return attributeObject;
}

private IntegrationTestUtils() {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public class CombinedResourceKeysRequest implements SphereRequest<CombinedResult
private final Set<String> productIds;
private final Set<String> categoryIds;
private final Set<String> productTypeIds;
private static final int QUERY_LIMIT = 500;

public CombinedResourceKeysRequest(
@Nonnull final Set<String> productIds,
Expand Down Expand Up @@ -67,18 +68,23 @@ public HttpRequestIntent httpRequestIntent() {

@Nonnull
private static String createProductsGraphQlQuery(@Nonnull final Set<String> productIds) {
return format("products(where: %s) { results { id key } }", createWhereQuery(productIds));
return format(
"products(limit: %d, where: %s) { results { id key } }",
QUERY_LIMIT, createWhereQuery(productIds));
}

@Nonnull
private static String createCategoriesGraphQlQuery(@Nonnull final Set<String> categoryIds) {
return format("categories(where: %s) { results { id key } }", createWhereQuery(categoryIds));
return format(
"categories(limit: %d, where: %s) { results { id key } }",
QUERY_LIMIT, createWhereQuery(categoryIds));
}

@Nonnull
private static String createProductTypesGraphQlQuery(@Nonnull final Set<String> productTypeIds) {
return format(
"productTypes(where: %s) { results { id key } }", createWhereQuery(productTypeIds));
"productTypes(limit: %d, where: %s) { results { id key } }",
QUERY_LIMIT, createWhereQuery(productTypeIds));
}

@Nonnull
Expand Down
Loading

0 comments on commit 60ebcbd

Please sign in to comment.