|
| 1 | +# Customer Sync |
| 2 | + |
| 3 | +Module used for importing/syncing Customers into a commercetools project. |
| 4 | +It also provides utilities for generating update actions based on the comparison of a [Customer](https://docs.commercetools.com/api/projects/customers#customer) |
| 5 | +against a [CustomerDraft](https://docs.commercetools.com/api/projects/customers#customerdraft). |
| 6 | + |
| 7 | +<!-- START doctoc generated TOC please keep comment here to allow auto update --> |
| 8 | +<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --> |
| 9 | +- [Usage](#usage) |
| 10 | + - [Sync list of cart discount drafts](#sync-list-of-customer-drafts) |
| 11 | + - [Prerequisites](#prerequisites) |
| 12 | + - [Running the sync](#running-the-sync) |
| 13 | + - [More examples of how to use the sync](#more-examples-of-how-to-use-the-sync) |
| 14 | + - [Build all update actions](#build-all-update-actions) |
| 15 | + - [Build particular update action(s)](#build-particular-update-actions) |
| 16 | +- [Caveats](#caveats) |
| 17 | +<!-- END doctoc generated TOC please keep comment here to allow auto update --> |
| 18 | + |
| 19 | +## Usage |
| 20 | + |
| 21 | +### Sync list of customer drafts |
| 22 | + |
| 23 | +#### Prerequisites |
| 24 | +1. The sync expects a list of `CustomerDraft`s that have their `key` fields set to be matched with customers in the |
| 25 | +target CTP project. The customers in the target project need to have the `key` fields set, otherwise they won't be |
| 26 | +matched. |
| 27 | + |
| 28 | +2. To sync customer address data, every customer [Address](https://docs.commercetools.com/api/types#address) needs a |
| 29 | +unique key to match the existing `Address` with the new Address. |
| 30 | + |
| 31 | +3. Every customer may have a reference to their [CustomerGroup](https://docs.commercetools.com/api/projects/customerGroups#customergroup) |
| 32 | +and/or the [Type](https://docs.commercetools.com/api/projects/customers#set-custom-type) of their custom fields. |
| 33 | +The `CustomerGroup` and `Type` references should be expanded with a key. |
| 34 | +Any reference that is not expanded will have its id in place and not replaced by the key will be considered as existing |
| 35 | +resources on the target commercetools project and the library will issue an update/create an API request without reference |
| 36 | +resolution. |
| 37 | + |
| 38 | + - 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-) |
| 39 | + method that maps from a `Customer` to `CustomerDraft` to make them ready for reference resolution by the sync: |
| 40 | + |
| 41 | + ````java |
| 42 | + final List<CustomerDraft> customerDrafts = CustomerReferenceResolutionUtils.mapToCustomertDrafts(customerDrafts); |
| 43 | + ```` |
| 44 | + |
| 45 | +4. Create a `sphereClient` [as described here](IMPORTANT_USAGE_TIPS.md#sphereclient-creation). |
| 46 | + |
| 47 | +5. After the `sphereClient` is set up, a `CustomerSyncOptions` should be built as follows: |
| 48 | +````java |
| 49 | +// instantiating a CustomerSyncOptions |
| 50 | +final CustomerSyncOptions customerSyncOptions = CustomerSyncOptionsBuilder.of(sphereClient).build(); |
| 51 | +```` |
| 52 | + |
| 53 | +[More information about Sync Options](SYNC_OPTIONS.md). |
| 54 | + |
| 55 | +#### About SyncOptions |
| 56 | +`SyncOptions` is an object which provides a place for users to add certain configurations to customize the sync process. |
| 57 | +Available configurations: |
| 58 | + |
| 59 | +##### 1. `errorCallback` |
| 60 | +A callback that is called whenever an error event occurs during the sync process. Each resource executes its own |
| 61 | +error-callback. When sync process of particular resource runs successfully, it is not triggered. It contains the |
| 62 | +following context about the error-event: |
| 63 | + |
| 64 | +* sync exception |
| 65 | +* customer draft from the source |
| 66 | +* customer of the target project (only provided if an existing customer could be found) |
| 67 | +* the update-actions, which failed (only provided if an existing customer could be found) |
| 68 | + |
| 69 | +##### Example |
| 70 | +````java |
| 71 | + final Logger logger = LoggerFactory.getLogger(CustomerSync.class); |
| 72 | + final CustomerSyncOptions customerSyncOptions = CustomerSyncOptionsBuilder |
| 73 | + .of(sphereClient) |
| 74 | + .errorCallback((syncException, draft, customer, updateActions) -> |
| 75 | + logger.error(new SyncException("My customized message"), syncException)).build(); |
| 76 | +```` |
| 77 | + |
| 78 | +##### 2. `warningCallback` |
| 79 | +A callback that is called whenever a warning event occurs during the sync process. Each resource executes its own |
| 80 | +warning-callback. When sync process of particular resource runs successfully, it is not triggered. It contains the |
| 81 | +following context about the warning message: |
| 82 | + |
| 83 | +* sync exception |
| 84 | +* customer draft from the source |
| 85 | +* customer of the target project (only provided if an existing cart discount could be found) |
| 86 | + |
| 87 | +##### Example |
| 88 | +````java |
| 89 | + final Logger logger = LoggerFactory.getLogger(CustomerSync.class); |
| 90 | + final CustomerSyncOptions customerSyncOptions = CustomerSyncOptionsBuilder |
| 91 | + .of(sphereClient) |
| 92 | + .warningCallback((syncException, draft, customer, updateActions) -> |
| 93 | + logger.warn(new SyncException("My customized message"), syncException)).build(); |
| 94 | +```` |
| 95 | + |
| 96 | +##### 3. `beforeUpdateCallback` |
| 97 | +During the sync process if a target customer and a customer draft are matched, this callback can be used to |
| 98 | +intercept the **_update_** request just before it is sent to commercetools platform. This allows the user to modify |
| 99 | +update actions array with custom actions or discard unwanted actions. The callback provides the following information : |
| 100 | + |
| 101 | + * customer draft from the source |
| 102 | + * customer from the target project |
| 103 | + * update actions that were calculated after comparing both |
| 104 | + |
| 105 | +##### Example |
| 106 | +````java |
| 107 | +final TriFunction<List<UpdateAction<Customer>>, CustomerDraft, Customer, |
| 108 | + List<UpdateAction<Customer>>> beforeUpdateCallback, = |
| 109 | + (updateActions, newCustomerDraft, oldCustomer) -> updateActions |
| 110 | + .stream() |
| 111 | + .filter(updateAction -> !(updateAction instanceof SetLastName)) |
| 112 | + .collect(Collectors.toList()); |
| 113 | + |
| 114 | +final CustomerSyncOptions customerSyncOptions = CustomerSyncOptionsBuilder |
| 115 | + .of(CTP_CLIENT) |
| 116 | + .beforeUpdateCallback(beforeUpdateCallback) |
| 117 | + .build(); |
| 118 | +```` |
| 119 | + |
| 120 | +##### 4. `beforeCreateCallback` |
| 121 | +During the sync process if a cart discount draft should be created, this callback can be used to intercept |
| 122 | +the **_create_** request just before it is sent to commercetools platform. It contains following information : |
| 123 | + |
| 124 | + * customer draft that should be created |
| 125 | + ##### Example |
| 126 | + 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). |
| 127 | + |
| 128 | +##### 5. `batchSize` |
| 129 | +A number that could be used to set the batch size with which customers are fetched and processed, |
| 130 | +as customers are obtained from the target project on commercetools platform in batches for better performance. The |
| 131 | +algorithm accumulates up to `batchSize` resources from the input list, then fetches the corresponding customers |
| 132 | +from the target project on commercetools platform in a single request. Playing with this option can slightly improve or |
| 133 | +reduce processing speed. If it is not set, the default batch size is 50 for customer sync. |
| 134 | +##### Example |
| 135 | +````java |
| 136 | +final CustomerSyncOptions customerSyncOptions = |
| 137 | + CustomerSyncOptionsBuilder.of(sphereClient).batchSize(30).build(); |
| 138 | +```` |
| 139 | + |
| 140 | +#### Running the sync |
| 141 | +When all prerequisites are fulfilled, follow those steps to run the sync: |
| 142 | + |
| 143 | +````java |
| 144 | +// instantiating a cart discount sync |
| 145 | +final CustomerSync customerSync = new CustomerSync(customerSyncOptions); |
| 146 | + |
| 147 | +// execute the sync on your list of customers |
| 148 | +CompletionStage<CustomerSyncStatistics> syncStatisticsStage = customerSync.sync(customerDrafts); |
| 149 | +```` |
| 150 | +The result of the completing the `syncStatisticsStage` in the previous code snippet contains a `CustomerSyncStatistics` |
| 151 | +which contains all the stats of the sync process; which includes a report message, the total number of updated, created, |
| 152 | +failed, processed cart discounts, and the processing time of the last sync batch in different time units and in a |
| 153 | +human-readable format. |
| 154 | + |
| 155 | +````java |
| 156 | +final CustomerSyncStatistics stats = syncStatisticsStage.toCompletebleFuture().join(); |
| 157 | +stats.getReportMessage(); |
| 158 | +/*"Summary: 100 customers were processed in total (11 created, 87 updated, 2 failed to sync)."*/ |
| 159 | +```` |
| 160 | + |
| 161 | +__Note__ The statistics object contains the processing time of the last batch only. This is due to two reasons: |
| 162 | + |
| 163 | + 1. The sync processing time should not take into account the time between supplying batches to the sync. |
| 164 | + 2. It is not known by the sync which batch is going to be the last one supplied. |
| 165 | + |
| 166 | +#### More examples of how to use the sync |
| 167 | + |
| 168 | + [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). |
| 169 | + |
| 170 | +*Make sure to read the [Important Usage Tips](IMPORTANT_USAGE_TIPS.md) for optimal performance.* |
| 171 | + |
| 172 | +### Build all update actions |
| 173 | +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. |
| 174 | +```java |
| 175 | +List<UpdateAction<Customer>> updateActions = CustomerSyncUtils.buildActions(customer, customerDraft, customerSyncOptions); |
| 176 | +``` |
| 177 | + |
| 178 | +### Build particular update action(s) |
| 179 | +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. |
| 180 | +One example is the `buildChangeEmailUpdateAction` which compare email addresses: |
| 181 | +````java |
| 182 | +Optional<UpdateAction<Customer>> updateAction = CustomerUpdateActionUtils.buildChangeEmailAction(oldCustomer, customerDraft); |
| 183 | +```` |
| 184 | + |
| 185 | +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) |
| 186 | +and [AddressUpdateActionUtils](https://github.com/commercetools/commercetools-sync-java/tree/master/src/test/java/com/commercetools/sync/customers/utils/AddressUpdateActionUtilsTest.java). |
| 187 | + |
| 188 | + |
| 189 | +## Caveats |
| 190 | +The library does not support the synchronization of the `password` field of existing customers. |
| 191 | +For customers that do not exist in the project, a password will be created with the given customer draft’s password. |
0 commit comments