Skip to content

Commit

Permalink
DEVX-272 correctly deserialize sync statistics classes (#525)
Browse files Browse the repository at this point in the history
  • Loading branch information
lojzatran authored Nov 15, 2023
1 parent 4a1147f commit 7092496
Show file tree
Hide file tree
Showing 10 changed files with 76 additions and 166 deletions.
34 changes: 17 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ Example:
##### Download

```bash
docker pull commercetools/commercetools-project-sync:5.4.0
docker pull commercetools/commercetools-project-sync:5.4.1
```
##### Run

Expand All @@ -222,14 +222,14 @@ docker run \
-e TARGET_PROJECT_KEY=xxxx \
-e TARGET_CLIENT_ID=xxxx \
-e TARGET_CLIENT_SECRET=xxxx \
commercetools/commercetools-project-sync:5.4.0 -s all
commercetools/commercetools-project-sync:5.4.1 -s all
```


### Examples
- To run the all sync modules from a source project to a target project
```bash
docker run commercetools/commercetools-project-sync:5.4.0 -s all
docker run commercetools/commercetools-project-sync:5.4.1 -s all
```
This will run the following sync modules in the given order:
1. `Type` Sync and `ProductType` Sync and `States` Sync and `TaxCategory` Sync and `CustomObject` Sync in parallel.
Expand All @@ -239,70 +239,70 @@ commercetools/commercetools-project-sync:5.4.0 -s all

- To run the type sync
```bash
docker run commercetools/commercetools-project-sync:5.4.0 -s types
docker run commercetools/commercetools-project-sync:5.4.1 -s types
```

- To run the productType sync
```bash
docker run commercetools/commercetools-project-sync:5.4.0 -s productTypes
docker run commercetools/commercetools-project-sync:5.4.1 -s productTypes
```

- To run the states sync
```bash
docker run commercetools/commercetools-project-sync:5.4.0 -s states
docker run commercetools/commercetools-project-sync:5.4.1 -s states
```
- To run the taxCategory sync
```bash
docker run commercetools/commercetools-project-sync:5.4.0 -s taxCategories
docker run commercetools/commercetools-project-sync:5.4.1 -s taxCategories
```

- To run the category sync
```bash
docker run commercetools/commercetools-project-sync:5.4.0 -s categories
docker run commercetools/commercetools-project-sync:5.4.1 -s categories
```

- To run the product sync
```bash
docker run commercetools/commercetools-project-sync:5.4.0 -s products
docker run commercetools/commercetools-project-sync:5.4.1 -s products
```

- To run the cartDiscount sync
```bash
docker run commercetools/commercetools-project-sync:5.4.0 -s cartDiscounts
docker run commercetools/commercetools-project-sync:5.4.1 -s cartDiscounts
```

- To run the inventoryEntry sync
```bash
docker run commercetools/commercetools-project-sync:5.4.0 -s inventoryEntries
docker run commercetools/commercetools-project-sync:5.4.1 -s inventoryEntries
```

- To run the customObject sync
```bash
docker run commercetools/commercetools-project-sync:5.4.0 -s customObjects
docker run commercetools/commercetools-project-sync:5.4.1 -s customObjects
```

- To run the customer sync
```bash
docker run commercetools/commercetools-project-sync:5.4.0 -s customers
docker run commercetools/commercetools-project-sync:5.4.1 -s customers
```

- To run the shoppingList sync
```bash
docker run commercetools/commercetools-project-sync:5.4.0 -s shoppingLists
docker run commercetools/commercetools-project-sync:5.4.1 -s shoppingLists
```
- To run both products and shoppingList sync
```bash
docker run commercetools/commercetools-project-sync:5.4.0 -s products shoppingLists
docker run commercetools/commercetools-project-sync:5.4.1 -s products shoppingLists
```

- To run type, productType and shoppingList sync
```bash
docker run commercetools/commercetools-project-sync:5.4.0 -s types productTypes shoppingLists
docker run commercetools/commercetools-project-sync:5.4.1 -s types productTypes shoppingLists
```

- To run all sync modules using a runner name
```bash
docker run commercetools/commercetools-project-sync:5.4.0 -s all -r myRunnerName
docker run commercetools/commercetools-project-sync:5.4.1 -s all -r myRunnerName
```

## Scopes
Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ ext {
assertjVersion = '3.24.2'
pmdVersion = '6.55.0'
jacocoVersion = '0.8.11'
commercetoolsSyncJava = '10.0.0-beta.4'
commercetoolsSyncJava = '10.0.1'
httpClientVersion = '17.2.0'
apacheCliVersion = '1.6.0'
jupiterApiVersion = '5.10.1'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import static com.commercetools.project.sync.util.CtpClientUtils.CTP_SOURCE_CLIENT;
import static com.commercetools.project.sync.util.CtpClientUtils.CTP_TARGET_CLIENT;
import static com.commercetools.project.sync.util.IntegrationTestUtils.*;
import static java.util.Arrays.asList;
import static org.assertj.core.api.Assertions.assertThat;

import com.commercetools.api.client.ProjectApiRoot;
Expand Down Expand Up @@ -85,7 +84,7 @@ private void setupSourceProjectData(ProjectApiRoot sourceProjectClient) {
.name(ofEnglish("t-shirts"))
.slug(ofEnglish("t-shirts"))
.key(RESOURCE_KEY)
.assets(asList(assetDraft))
.assets(assetDraft)
.custom(customFieldsDraft)
.build();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import static com.commercetools.project.sync.util.IntegrationTestUtils.cleanUpProjects;
import static com.commercetools.project.sync.util.IntegrationTestUtils.createITSyncerFactory;
import static com.commercetools.project.sync.util.SyncUtils.APPLICATION_DEFAULT_NAME;
import static com.commercetools.project.sync.util.SyncUtils.DEFAULT_RUNNER_NAME;
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.assertCustomObjectSyncerLoggingEvents;
Expand Down Expand Up @@ -85,6 +86,7 @@
import com.commercetools.project.sync.taxcategory.TaxCategorySyncer;
import com.commercetools.project.sync.type.TypeSyncer;
import com.commercetools.sync.commons.helpers.BaseSyncStatistics;
import com.commercetools.sync.producttypes.helpers.ProductTypeSyncStatistics;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
Expand Down Expand Up @@ -704,20 +706,19 @@ private void prepareDataForShoppingListSync(ProjectApiRoot sourceClient) {

assertProductTypesAreSyncedCorrectly(CTP_TARGET_CLIENT);

// todo: https://commercetools.atlassian.net/browse/DEVX-272
// final ZonedDateTime lastSyncTimestamp =
// assertCurrentCtpTimestampGeneratorAndGetLastModifiedAt(
// CTP_TARGET_CLIENT, DEFAULT_RUNNER_NAME, "ProductTypeSync");
final ZonedDateTime lastSyncTimestamp =
assertCurrentCtpTimestampGeneratorAndGetLastModifiedAt(
CTP_TARGET_CLIENT, DEFAULT_RUNNER_NAME, "ProductTypeSync");

// final String sourceProjectKey = CTP_SOURCE_CLIENT.getProjectKey();
final String sourceProjectKey = CTP_SOURCE_CLIENT.getProjectKey();

// assertLastSyncCustomObjectIsCorrect(
// CTP_TARGET_CLIENT,
// sourceProjectKey,
// "productTypeSync",
// DEFAULT_RUNNER_NAME,
// ProductSyncStatistics.class,
// lastSyncTimestamp);
assertLastSyncCustomObjectIsCorrect(
CTP_TARGET_CLIENT,
sourceProjectKey,
"productTypeSync",
DEFAULT_RUNNER_NAME,
ProductTypeSyncStatistics.class,
lastSyncTimestamp);
}

private static void assertTypesAreSyncedCorrectly(@Nonnull final ProjectApiRoot ctpClient) {
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import java.io.IOException;

// This class compiles but not tested yet
// TODO: Test class and adjust logic if needed
public class BaseSyncStatisticsDeserializer extends StdDeserializer<BaseSyncStatistics> {

public BaseSyncStatisticsDeserializer() {
Expand All @@ -26,15 +24,16 @@ public BaseSyncStatistics deserialize(JsonParser jsonParser, DeserializationCont
throws IOException {
final ObjectMapper mapper = (ObjectMapper) jsonParser.getCodec();
final JsonNode syncStatisticsNode = mapper.readTree(jsonParser);
// since BaseSyncStatistics is abstract and there's no difference in the Subclasses except
// implementation of
// method getReportMessage(), additionally there's no field which could be used to identify the
// type of the
// subclass, the jsonNode is mapped to any concrete class
// this is a workaround, to fix that BaseSyncStatistics in java-sync library needs to be
// adjusted declaring
// the subtypes with Json annotations: JsonTypeInfo and JsonSubTypes
// more details: https://www.baeldung.com/jackson-inheritance#2-per-class-annotations
return mapper.treeToValue(syncStatisticsNode, CustomerSyncStatistics.class);
try {
final String syncStatisticsClassName =
syncStatisticsNode.get("syncStatisticsClassName").asText();
final Class<? extends BaseSyncStatistics> c =
Class.forName(syncStatisticsClassName).asSubclass(BaseSyncStatistics.class);
return mapper.treeToValue(syncStatisticsNode, c);
} catch (ClassNotFoundException | ClassCastException e) {
final Class<CustomerSyncStatistics> customerSyncStatisticsClass =
CustomerSyncStatistics.class;
return mapper.treeToValue(syncStatisticsNode, customerSyncStatisticsClass);
}
}
}
2 changes: 1 addition & 1 deletion src/main/java/com/commercetools/project/sync/Syncer.java
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public abstract class Syncer<
ResourceUpdateActionT extends ResourceUpdateAction<ResourceUpdateActionT>,
ResourceDraftT,
QueryBuilderDslT,
SyncStatisticsT extends BaseSyncStatistics,
SyncStatisticsT extends BaseSyncStatistics<SyncStatisticsT>,
SyncOptionsT extends BaseSyncOptions<ResourceT, ResourceDraftT, ResourceUpdateActionT>,
PagedQueryT extends
PagedQueryResourceRequest<PagedQueryT, PagedQueryResponseT, QueryBuilderDslT>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ private LastSyncCustomObject(
public LastSyncCustomObject() {}

@Nonnull
public static <T extends BaseSyncStatistics> LastSyncCustomObject<T> of(
public static <T extends BaseSyncStatistics<T>> LastSyncCustomObject<T> of(
@Nonnull final ZonedDateTime lastSyncTimestamp,
@Nonnull final T lastSyncStatistics,
final long lastSyncDurationInSeconds) {
Expand All @@ -64,7 +64,7 @@ public static <T extends BaseSyncStatistics> LastSyncCustomObject<T> of(
}

@Nonnull
public static <T extends BaseSyncStatistics> LastSyncCustomObject<T> of(
public static <T extends BaseSyncStatistics<T>> LastSyncCustomObject<T> of(
@Nonnull final ZonedDateTime lastSyncTimestamp,
@Nonnull final T lastSyncStatistics,
@Nonnull final String applicationVersion,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import com.commercetools.project.sync.model.response.LastSyncCustomObject;
import com.commercetools.project.sync.service.CustomObjectService;
import com.commercetools.project.sync.util.TestUtils;
import com.commercetools.sync.customers.helpers.CustomerSyncStatistics;
import com.commercetools.sync.products.helpers.ProductSyncStatistics;
import io.vrap.rmf.base.client.ApiHttpResponse;
import io.vrap.rmf.base.client.error.BadGatewayException;
Expand All @@ -34,7 +35,6 @@
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;

Expand Down Expand Up @@ -123,7 +123,6 @@ void getCurrentCtpTimestamp_OnFailedUpsert_ShouldCompleteExceptionally() {
}

@Test
@Disabled("https://commercetools.atlassian.net/browse/DEVX-272")
void
getLastSyncCustomObject_OnSuccessfulQueryWithResults_ShouldCompleteWithLastSyncCustomObject() {
// preparation
Expand Down Expand Up @@ -201,6 +200,35 @@ void getLastSyncCustomObject_OnFailedQuery_ShouldCompleteExceptionally() {
.hasMessageContaining("test"));
}

@Test
void
getLastSyncCustomObject_OnCustomObjectWithoutSyncStatisticsClassNameAttr_ShouldCompleteWithCustomerSyncStatisticsClass() {
// preparation
final CustomObject mockCustomObject = mock(CustomObject.class);

final ProductSyncStatistics productSyncStatistics = mock(ProductSyncStatistics.class);
when(productSyncStatistics.getSyncStatisticsClassName()).thenReturn("");

final LastSyncCustomObject<ProductSyncStatistics> lastSyncCustomObjectValue =
LastSyncCustomObject.of(now, productSyncStatistics, 0);
when(mockCustomObject.getValue()).thenReturn(lastSyncCustomObjectValue);

when(apiHttpResponse.getBody()).thenReturn(mockCustomObject);

when(byProjectKeyCustomObjectsByContainerByKeyGet.execute())
.thenReturn(CompletableFuture.completedFuture(apiHttpResponse));

final CustomObjectService customObjectService = new CustomObjectServiceImpl(ctpClient);

// test
final LastSyncCustomObject lastSyncCustomObject =
customObjectService.getLastSyncCustomObject("foo", "bar", DEFAULT_RUNNER_NAME).join().get();

// assert
assertThat(lastSyncCustomObject.getLastSyncStatistics())
.isInstanceOf(CustomerSyncStatistics.class);
}

@Test
void createLastSyncCustomObject_OnSuccessfulCreation_ShouldCompleteWithLastSyncCustomObject() {
// preparation
Expand Down
Loading

0 comments on commit 7092496

Please sign in to comment.