Skip to content

Commit

Permalink
Merge pull request #598 from commercetools/customer-sync
Browse files Browse the repository at this point in the history
Support customer sync.
  • Loading branch information
ahmetoz authored Oct 15, 2020
2 parents 4de340c + 57fefec commit 3e7db6e
Show file tree
Hide file tree
Showing 64 changed files with 8,329 additions and 80 deletions.
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
# commercetools sync
[![Build Status](https://travis-ci.org/commercetools/commercetools-sync-java.svg?branch=master)](https://travis-ci.org/commercetools/commercetools-sync-java)
[![codecov](https://codecov.io/gh/commercetools/commercetools-sync-java/branch/master/graph/badge.svg)](https://codecov.io/gh/commercetools/commercetools-sync-java)
[![Benchmarks 2.2.1](https://img.shields.io/badge/Benchmarks-2.2.1-orange.svg)](https://commercetools.github.io/commercetools-sync-java/benchmarks/)
[![Benchmarks 2.3.0](https://img.shields.io/badge/Benchmarks-2.3.0-orange.svg)](https://commercetools.github.io/commercetools-sync-java/benchmarks/)
[![Download](https://api.bintray.com/packages/commercetools/maven/commercetools-sync-java/images/download.svg) ](https://bintray.com/commercetools/maven/commercetools-sync-java/_latestVersion)
[![Javadoc](http://javadoc-badge.appspot.com/com.commercetools/commercetools-sync-java.svg?label=Javadoc)](https://commercetools.github.io/commercetools-sync-java/v/2.2.1/)
[![Javadoc](http://javadoc-badge.appspot.com/com.commercetools/commercetools-sync-java.svg?label=Javadoc)](https://commercetools.github.io/commercetools-sync-java/v/2.3.0/)
[![Known Vulnerabilities](https://snyk.io/test/github/commercetools/commercetools-sync-java/4b2e26113d591bda158217c5dc1cf80a88665646/badge.svg)](https://snyk.io/test/github/commercetools/commercetools-sync-java/4b2e26113d591bda158217c5dc1cf80a88665646)

More at https://commercetools.github.io/commercetools-sync-java
Expand Down Expand Up @@ -37,7 +37,7 @@ The library supports synchronising the following entities in commercetools
- [Ivy](#ivy)
- [Roadmap](#roadmap)
- [Release Notes](/docs/RELEASE_NOTES.md)
- [Javadoc](https://commercetools.github.io/commercetools-sync-java/v/2.2.1/)
- [Javadoc](https://commercetools.github.io/commercetools-sync-java/v/2.3.0/)
- [Benchmarks](https://commercetools.github.io/commercetools-sync-java/benchmarks/)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->
Expand Down Expand Up @@ -79,26 +79,26 @@ Here are the most popular ones:
<dependency>
<groupId>com.commercetools</groupId>
<artifactId>commercetools-sync-java</artifactId>
<version>2.2.1</version>
<version>2.3.0</version>
</dependency>
````

#### Gradle

````groovy
implementation 'com.commercetools:commercetools-sync-java:2.2.1'
implementation 'com.commercetools:commercetools-sync-java:2.3.0'
````

#### SBT

````
libraryDependencies += "com.commercetools" % "commercetools-sync-java" % "2.2.1"
libraryDependencies += "com.commercetools" % "commercetools-sync-java" % "2.3.0"
````

#### Ivy

````xml
<dependency org="com.commercetools" name="commercetools-sync-java" rev="2.2.1"/>
<dependency org="com.commercetools" name="commercetools-sync-java" rev="2.3.0"/>
````


Expand Down
12 changes: 6 additions & 6 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
# commercetools sync
[![Build Status](https://travis-ci.org/commercetools/commercetools-sync-java.svg?branch=master)](https://travis-ci.org/commercetools/commercetools-sync-java)
[![codecov](https://codecov.io/gh/commercetools/commercetools-sync-java/branch/master/graph/badge.svg)](https://codecov.io/gh/commercetools/commercetools-sync-java)
[![Benchmarks 2.2.1](https://img.shields.io/badge/Benchmarks-2.2.1-orange.svg)](https://commercetools.github.io/commercetools-sync-java/benchmarks/)
[![Benchmarks 2.3.0](https://img.shields.io/badge/Benchmarks-2.3.0-orange.svg)](https://commercetools.github.io/commercetools-sync-java/benchmarks/)
[![Download](https://api.bintray.com/packages/commercetools/maven/commercetools-sync-java/images/download.svg) ](https://bintray.com/commercetools/maven/commercetools-sync-java/_latestVersion)
[![Javadoc](http://javadoc-badge.appspot.com/com.commercetools/commercetools-sync-java.svg?label=Javadoc)](https://commercetools.github.io/commercetools-sync-java/v/2.2.1/)
[![Javadoc](http://javadoc-badge.appspot.com/com.commercetools/commercetools-sync-java.svg?label=Javadoc)](https://commercetools.github.io/commercetools-sync-java/v/2.3.0/)
[![Known Vulnerabilities](https://snyk.io/test/github/commercetools/commercetools-sync-java/4b2e26113d591bda158217c5dc1cf80a88665646/badge.svg)](https://snyk.io/test/github/commercetools/commercetools-sync-java/4b2e26113d591bda158217c5dc1cf80a88665646)


Expand Down Expand Up @@ -56,18 +56,18 @@ Here are the most popular ones:
<dependency>
<groupId>com.commercetools</groupId>
<artifactId>commercetools-sync-java</artifactId>
<version>2.2.1</version>
<version>2.3.0</version>
</dependency>
````
#### Gradle
````groovy
implementation 'com.commercetools:commercetools-sync-java:2.2.1'
implementation 'com.commercetools:commercetools-sync-java:2.3.0'
````
#### SBT
````
libraryDependencies += "com.commercetools" % "commercetools-sync-java" % "2.2.1"
libraryDependencies += "com.commercetools" % "commercetools-sync-java" % "2.3.0"
````
#### Ivy
````xml
<dependency org="com.commercetools" name="commercetools-sync-java" rev="2.2.1"/>
<dependency org="com.commercetools" name="commercetools-sync-java" rev="2.3.0"/>
````
14 changes: 12 additions & 2 deletions docs/RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
6. Depending on the contents of the release use the subitems below to
document the new changes in the release accordingly. Please always include
a link to the releated issue number.
a link to the related issue number.
**New Features** (n) 🎉
**Breaking Changes** (n) 🚧
**Enhancements** (n) ✨
Expand All @@ -22,11 +22,21 @@
**Critical Bug Fixes** (n) 🔥
**Bug Fixes** (n)🐞
- **Category Sync** - Sync now supports product variant images syncing. [#114](https://github.com/commercetools/commercetools-sync-java/issues/114)
- **Build Tools** - Convinient handelling of env vars for integration tests.
- **Build Tools** - Convenient handling of env vars for integration tests.
7. Add Migration guide section which specifies explicitly if there are breaking changes and how to tackle them.
-->
### 2.3.0 - Oct 15, 2020
[Commits](https://github.com/commercetools/commercetools-sync-java/compare/2.2.1...2.3.0) |
[Javadoc](https://commercetools.github.io/commercetools-sync-java/v/2.3.0/) |
[Jar](https://bintray.com/commercetools/maven/commercetools-sync-java/2.3.0)

- 🎉 **New Features** (1)
- **Customer Sync** - Added support for syncing customers between ctp projects. [#579](https://github.com/commercetools/commercetools-sync-java/issues/579)
- **Customer Sync** - Introduced `CustomerSyncUtils` which calculates all needed update actions after comparing a `Customer` and a `CustomerDraft`. [#579](https://github.com/commercetools/commercetools-sync-java/issues/579)
- **Customer Sync** - Introduced `CustomerUpdateActionUtils` which contains utils for calculating needed update actions after comparing individual fields of a `Customer` and a `CustomerDraft`. [#579](https://github.com/commercetools/commercetools-sync-java/issues/579)
- **Customer Sync** - Introduced `CustomerReferenceResolutionUtils` which resolves CustomerGroup and Type references from a Customer to a CustomerDraft. [#579](https://github.com/commercetools/commercetools-sync-java/issues/579)

### 2.2.1 - Sep 29, 2020
[Commits](https://github.com/commercetools/commercetools-sync-java/compare/2.2.0...2.2.1) |
Expand Down
2 changes: 1 addition & 1 deletion docs/usage/CART_DISCOUNT_SYNC.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ fields set, otherwise they won't be matched.
Types are matched by their `key`s. Therefore, in order for the sync to resolve the
actual ids of the type reference, the `key` of the `Type` has to be supplied.

- When syncing from a source commercetools project, you can use [`mapToCartDiscountDrafts`](https://commercetools.github.io/commercetools-sync-java/v/2.2.1/com/commercetools/sync/cartdiscounts/utils/CartDiscountReferenceResolutionUtils.html#mapToCartDiscountDrafts-java.util.List-)
- When syncing from a source commercetools project, you can use [`mapToCartDiscountDrafts`](https://commercetools.github.io/commercetools-sync-java/v/2.3.0/com/commercetools/sync/cartdiscounts/utils/CartDiscountReferenceResolutionUtils.html#mapToCartDiscountDrafts-java.util.List-)
method that maps from a `CartDiscount` to `CartDiscountDraft` in order to make them ready for reference resolution by the sync:

````java
Expand Down
2 changes: 1 addition & 1 deletion docs/usage/CATEGORY_SYNC.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ otherwise they won't be matched.
These references are matched by their `key`s. Therefore, in order for the sync to resolve the
actual ids of the references, their `key`s has to be supplied.

- When syncing from a source commercetools project, you can use [`mapToCategoryDrafts`](https://commercetools.github.io/commercetools-sync-java/v/2.2.1/com/commercetools/sync/categories/utils/CategoryReferenceResolutionUtils.html#mapToCategoryDrafts-java.util.List-)
- When syncing from a source commercetools project, you can use [`mapToCategoryDrafts`](https://commercetools.github.io/commercetools-sync-java/v/2.3.0/com/commercetools/sync/categories/utils/CategoryReferenceResolutionUtils.html#mapToCategoryDrafts-java.util.List-)
method that maps from a `Category` to `CategoryDraft` in order to make them ready for reference resolution by the sync:
````java
final List<CategoryDraft> categoryDrafts = CategoryReferenceResolutionUtils.mapToCategoryDrafts(categories);
Expand Down
191 changes: 191 additions & 0 deletions docs/usage/CUSTOMER_SYNC.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
# Customer Sync

Module used for importing/syncing Customers into a commercetools project.
It also provides utilities for generating update actions based on the comparison of a [Customer](https://docs.commercetools.com/api/projects/customers#customer)
against a [CustomerDraft](https://docs.commercetools.com/api/projects/customers#customerdraft).

<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
- [Usage](#usage)
- [Sync list of cart discount drafts](#sync-list-of-customer-drafts)
- [Prerequisites](#prerequisites)
- [Running the sync](#running-the-sync)
- [More examples of how to use the sync](#more-examples-of-how-to-use-the-sync)
- [Build all update actions](#build-all-update-actions)
- [Build particular update action(s)](#build-particular-update-actions)
- [Caveats](#caveats)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->

## Usage

### Sync list of customer drafts

#### Prerequisites
1. The sync expects a list of `CustomerDraft`s that have their `key` fields set to be matched with customers in the
target CTP project. The customers in the target project need to have the `key` fields set, otherwise they won't be
matched.

2. To sync customer address data, every customer [Address](https://docs.commercetools.com/api/types#address) needs a
unique key to match the existing `Address` with the new Address.

3. Every customer may have a reference to their [CustomerGroup](https://docs.commercetools.com/api/projects/customerGroups#customergroup)
and/or the [Type](https://docs.commercetools.com/api/projects/customers#set-custom-type) of their custom fields.
The `CustomerGroup` and `Type` references should be expanded with a key.
Any reference that is not expanded will have its id in place and not replaced by the key will be considered as existing
resources on the target commercetools project and the library will issue an update/create an API request without reference
resolution.

- When syncing from a source commercetools project, you can use [`mapToCustomerDrafts`](https://commercetools.github.io/commercetools-sync-java/v/2.3.0/com/commercetools/sync/customers/utils/CustomerReferenceResolutionUtils.html#mapToCustomerDrafts-java.util.List-)
method that maps from a `Customer` to `CustomerDraft` to make them ready for reference resolution by the sync:

````java
final List<CustomerDraft> customerDrafts = CustomerReferenceResolutionUtils.mapToCustomertDrafts(customerDrafts);
````

4. Create a `sphereClient` [as described here](IMPORTANT_USAGE_TIPS.md#sphereclient-creation).

5. After the `sphereClient` is set up, a `CustomerSyncOptions` should be built as follows:
````java
// instantiating a CustomerSyncOptions
final CustomerSyncOptions customerSyncOptions = CustomerSyncOptionsBuilder.of(sphereClient).build();
````

[More information about Sync Options](SYNC_OPTIONS.md).

#### About SyncOptions
`SyncOptions` is an object which provides a place for users to add certain configurations to customize the sync process.
Available configurations:

##### 1. `errorCallback`
A callback that is called whenever an error event occurs during the sync process. Each resource executes its own
error-callback. When sync process of particular resource runs successfully, it is not triggered. It contains the
following context about the error-event:

* sync exception
* customer draft from the source
* customer of the target project (only provided if an existing customer could be found)
* the update-actions, which failed (only provided if an existing customer could be found)

##### Example
````java
final Logger logger = LoggerFactory.getLogger(CustomerSync.class);
final CustomerSyncOptions customerSyncOptions = CustomerSyncOptionsBuilder
.of(sphereClient)
.errorCallback((syncException, draft, customer, updateActions) ->
logger.error(new SyncException("My customized message"), syncException)).build();
````

##### 2. `warningCallback`
A callback that is called whenever a warning event occurs during the sync process. Each resource executes its own
warning-callback. When sync process of particular resource runs successfully, it is not triggered. It contains the
following context about the warning message:

* sync exception
* customer draft from the source
* customer of the target project (only provided if an existing cart discount could be found)

##### Example
````java
final Logger logger = LoggerFactory.getLogger(CustomerSync.class);
final CustomerSyncOptions customerSyncOptions = CustomerSyncOptionsBuilder
.of(sphereClient)
.warningCallback((syncException, draft, customer, updateActions) ->
logger.warn(new SyncException("My customized message"), syncException)).build();
````

##### 3. `beforeUpdateCallback`
During the sync process if a target customer and a customer draft are matched, this callback can be used to
intercept the **_update_** request just before it is sent to commercetools platform. This allows the user to modify
update actions array with custom actions or discard unwanted actions. The callback provides the following information :

* customer draft from the source
* customer from the target project
* update actions that were calculated after comparing both

##### Example
````java
final TriFunction<List<UpdateAction<Customer>>, CustomerDraft, Customer,
List<UpdateAction<Customer>>> beforeUpdateCallback, =
(updateActions, newCustomerDraft, oldCustomer) -> updateActions
.stream()
.filter(updateAction -> !(updateAction instanceof SetLastName))
.collect(Collectors.toList());

final CustomerSyncOptions customerSyncOptions = CustomerSyncOptionsBuilder
.of(CTP_CLIENT)
.beforeUpdateCallback(beforeUpdateCallback)
.build();
````

##### 4. `beforeCreateCallback`
During the sync process if a cart discount draft should be created, this callback can be used to intercept
the **_create_** request just before it is sent to commercetools platform. It contains following information :

* customer draft that should be created
##### Example
Please refer to the [example in the product sync document](https://github.com/commercetools/commercetools-sync-java/blob/master/docs/usage/PRODUCT_SYNC.md#example-set-publish-stage-if-category-references-of-given-product-draft-exists).

##### 5. `batchSize`
A number that could be used to set the batch size with which customers are fetched and processed,
as customers are obtained from the target project on commercetools platform in batches for better performance. The
algorithm accumulates up to `batchSize` resources from the input list, then fetches the corresponding customers
from the target project on commercetools platform in a single request. Playing with this option can slightly improve or
reduce processing speed. If it is not set, the default batch size is 50 for customer sync.
##### Example
````java
final CustomerSyncOptions customerSyncOptions =
CustomerSyncOptionsBuilder.of(sphereClient).batchSize(30).build();
````

#### Running the sync
When all prerequisites are fulfilled, follow those steps to run the sync:

````java
// instantiating a cart discount sync
final CustomerSync customerSync = new CustomerSync(customerSyncOptions);

// execute the sync on your list of customers
CompletionStage<CustomerSyncStatistics> syncStatisticsStage = customerSync.sync(customerDrafts);
````
The result of the completing the `syncStatisticsStage` in the previous code snippet contains a `CustomerSyncStatistics`
which contains all the stats of the sync process; which includes a report message, the total number of updated, created,
failed, processed cart discounts, and the processing time of the last sync batch in different time units and in a
human-readable format.

````java
final CustomerSyncStatistics stats = syncStatisticsStage.toCompletebleFuture().join();
stats.getReportMessage();
/*"Summary: 100 customers were processed in total (11 created, 87 updated, 2 failed to sync)."*/
````

__Note__ The statistics object contains the processing time of the last batch only. This is due to two reasons:

1. The sync processing time should not take into account the time between supplying batches to the sync.
2. It is not known by the sync which batch is going to be the last one supplied.

#### More examples of how to use the sync

[Sync from an external source](https://github.com/commercetools/commercetools-sync-java/tree/master/src/integration-test/java/com/commercetools/sync/integration/externalsource/customers/CustomerSyncIT.java).

*Make sure to read the [Important Usage Tips](IMPORTANT_USAGE_TIPS.md) for optimal performance.*

### Build all update actions
A utility method provided by the library to compare a `Customer` to a new `CustomerDraft`. The results are collected in a list of customer update actions.
```java
List<UpdateAction<Customer>> updateActions = CustomerSyncUtils.buildActions(customer, customerDraft, customerSyncOptions);
```

### Build particular update action(s)
The library provides utility methods to compare specific fields of a `Customer` and a new `CustomerDraft`, and builds the update action(s) as a result.
One example is the `buildChangeEmailUpdateAction` which compare email addresses:
````java
Optional<UpdateAction<Customer>> updateAction = CustomerUpdateActionUtils.buildChangeEmailAction(oldCustomer, customerDraft);
````

More examples for particular update actions can be found in the test scenarios for [CustomerUpdateActionUtils](https://github.com/commercetools/commercetools-sync-java/tree/master/src/test/java/com/commercetools/sync/customers/utils/CustomerUpdateActionUtilsTest.java)
and [AddressUpdateActionUtils](https://github.com/commercetools/commercetools-sync-java/tree/master/src/test/java/com/commercetools/sync/customers/utils/AddressUpdateActionUtilsTest.java).


## Caveats
The library does not support the synchronization of the `password` field of existing customers.
For customers that do not exist in the project, a password will be created with the given customer draft’s password.
Loading

0 comments on commit 3e7db6e

Please sign in to comment.