|
|
|
@ -18,6 +18,8 @@ package org.thingsboard.server.service.sync.ie.importing.impl; |
|
|
|
import com.fasterxml.jackson.databind.JsonNode; |
|
|
|
import com.google.api.client.util.Objects; |
|
|
|
import com.google.common.util.concurrent.FutureCallback; |
|
|
|
import lombok.AllArgsConstructor; |
|
|
|
import lombok.Data; |
|
|
|
import lombok.RequiredArgsConstructor; |
|
|
|
import lombok.extern.slf4j.Slf4j; |
|
|
|
import org.checkerframework.checker.nullness.qual.Nullable; |
|
|
|
@ -117,10 +119,10 @@ public abstract class BaseEntityImportService<I extends EntityId, E extends Expo |
|
|
|
|
|
|
|
E prepared = prepare(ctx, entity, existingEntity, exportData, idProvider); |
|
|
|
|
|
|
|
boolean saveOrUpdate = existingEntity == null || compare(ctx, exportData, prepared, existingEntity); |
|
|
|
CompareResult compareResult = compare(ctx, exportData, prepared, existingEntity); |
|
|
|
|
|
|
|
if (saveOrUpdate) { |
|
|
|
E savedEntity = saveOrUpdate(ctx, prepared, exportData, idProvider); |
|
|
|
if (compareResult.isNeedUpdate()) { |
|
|
|
E savedEntity = saveOrUpdate(ctx, prepared, exportData, idProvider, compareResult); |
|
|
|
boolean created = existingEntity == null; |
|
|
|
importResult.setCreated(created); |
|
|
|
importResult.setUpdated(!created); |
|
|
|
@ -137,6 +139,13 @@ public abstract class BaseEntityImportService<I extends EntityId, E extends Expo |
|
|
|
return importResult; |
|
|
|
} |
|
|
|
|
|
|
|
@Data |
|
|
|
@AllArgsConstructor |
|
|
|
protected static class CompareResult { |
|
|
|
private boolean needUpdate; |
|
|
|
private boolean externalIdChangedOnly; |
|
|
|
} |
|
|
|
|
|
|
|
protected boolean updateRelatedEntitiesIfUnmodified(EntitiesImportCtx ctx, E prepared, D exportData, IdProvider idProvider) { |
|
|
|
return importCalculatedFields(ctx, prepared, exportData, idProvider); |
|
|
|
} |
|
|
|
@ -148,18 +157,26 @@ public abstract class BaseEntityImportService<I extends EntityId, E extends Expo |
|
|
|
|
|
|
|
protected abstract E prepare(EntitiesImportCtx ctx, E entity, E oldEntity, D exportData, IdProvider idProvider); |
|
|
|
|
|
|
|
protected boolean compare(EntitiesImportCtx ctx, D exportData, E prepared, E existing) { |
|
|
|
protected CompareResult compare(EntitiesImportCtx ctx, D exportData, E prepared, E existing) { |
|
|
|
var newCopy = deepCopy(prepared); |
|
|
|
var existingCopy = deepCopy(existing); |
|
|
|
cleanupForComparison(newCopy); |
|
|
|
cleanupForComparison(existingCopy); |
|
|
|
var result = !newCopy.equals(existingCopy); |
|
|
|
if (result) { |
|
|
|
var needUpdate = !newCopy.equals(existingCopy); |
|
|
|
boolean externalIdChangedOnly = false; |
|
|
|
if (needUpdate) { |
|
|
|
log.debug("[{}] Found update.", prepared.getId()); |
|
|
|
log.debug("[{}] From: {}", prepared.getId(), newCopy); |
|
|
|
log.debug("[{}] To: {}", prepared.getId(), existingCopy); |
|
|
|
externalIdChangedOnly = isExternalIdChangedOnly(newCopy, existingCopy); |
|
|
|
} |
|
|
|
return result; |
|
|
|
return new CompareResult(existing == null || needUpdate, externalIdChangedOnly); |
|
|
|
} |
|
|
|
|
|
|
|
private boolean isExternalIdChangedOnly(E newCopy, E existingCopy) { |
|
|
|
newCopy.setExternalId(null); |
|
|
|
existingCopy.setExternalId(null); |
|
|
|
return newCopy.equals(existingCopy); |
|
|
|
} |
|
|
|
|
|
|
|
protected abstract E deepCopy(E e); |
|
|
|
@ -172,7 +189,7 @@ public abstract class BaseEntityImportService<I extends EntityId, E extends Expo |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
protected abstract E saveOrUpdate(EntitiesImportCtx ctx, E entity, D exportData, IdProvider idProvider); |
|
|
|
protected abstract E saveOrUpdate(EntitiesImportCtx ctx, E entity, D exportData, IdProvider idProvider, CompareResult compareResult); |
|
|
|
|
|
|
|
|
|
|
|
protected void processAfterSaved(EntitiesImportCtx ctx, EntityImportResult<E> importResult, D exportData, IdProvider idProvider) throws ThingsboardException { |
|
|
|
|