From 4d1a82d50b2e21be39966cd7c66fde2d8ebc8c19 Mon Sep 17 00:00:00 2001 From: Viacheslav Klimov Date: Tue, 28 Jun 2022 13:39:09 +0300 Subject: [PATCH 1/2] Fix export/import of deprecated dashboards --- .../server/common/data/Dashboard.java | 21 +++++++------------ 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/Dashboard.java b/common/data/src/main/java/org/thingsboard/server/common/data/Dashboard.java index 049c830745..f0d0d88f68 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/Dashboard.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/Dashboard.java @@ -17,19 +17,18 @@ package org.thingsboard.server.common.data; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; +import com.google.common.collect.Streams; import io.swagger.annotations.ApiModelProperty; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; import org.thingsboard.server.common.data.id.DashboardId; -import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Optional; -import java.util.stream.StreamSupport; +import java.util.stream.Collectors; @EqualsAndHashCode(callSuper = true) public class Dashboard extends DashboardInfo implements ExportableEntity { @@ -86,17 +85,11 @@ public class Dashboard extends DashboardInfo implements ExportableEntity getChildObjects(String propertyName) { return Optional.ofNullable(configuration) .map(config -> config.get(propertyName)) - .filter(node -> !node.isEmpty()) - .map(node -> (ObjectNode) node) - .map(object -> { - List widgets = new ArrayList<>(object.size()); - object.forEach(child -> { - if (child.isObject()) { - widgets.add((ObjectNode) child); - } - }); - return widgets; - }) + .filter(node -> !node.isEmpty() && (node.isObject() || node.isArray())) + .map(node -> Streams.stream(node.elements()) + .filter(JsonNode::isObject) + .map(jsonNode -> (ObjectNode) jsonNode) + .collect(Collectors.toList())) .orElse(Collections.emptyList()); } From 4f74df66cd0012086f0d86ddcc47b4061be12209 Mon Sep 17 00:00:00 2001 From: Viacheslav Klimov Date: Tue, 28 Jun 2022 15:25:36 +0300 Subject: [PATCH 2/2] Fix invalid error message on relations import failure --- .../ie/DefaultEntitiesExportImportService.java | 14 +++++++++++--- .../DefaultEntitiesVersionControlService.java | 18 +++++++++--------- .../service/sync/vc/LoadEntityException.java | 8 ++++---- .../sync/vc/data/EntitiesImportCtx.java | 6 +++--- 4 files changed, 27 insertions(+), 19 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/sync/ie/DefaultEntitiesExportImportService.java b/application/src/main/java/org/thingsboard/server/service/sync/ie/DefaultEntitiesExportImportService.java index 2d6d14c4ac..0f43159e30 100644 --- a/application/src/main/java/org/thingsboard/server/service/sync/ie/DefaultEntitiesExportImportService.java +++ b/application/src/main/java/org/thingsboard/server/service/sync/ie/DefaultEntitiesExportImportService.java @@ -38,6 +38,8 @@ import org.thingsboard.server.service.sync.ie.exporting.EntityExportService; import org.thingsboard.server.service.sync.ie.exporting.impl.BaseEntityExportService; import org.thingsboard.server.service.sync.ie.exporting.impl.DefaultEntityExportService; import org.thingsboard.server.service.sync.ie.importing.EntityImportService; +import org.thingsboard.server.service.sync.ie.importing.impl.MissingEntityException; +import org.thingsboard.server.service.sync.vc.LoadEntityException; import org.thingsboard.server.service.sync.vc.data.EntitiesExportCtx; import org.thingsboard.server.service.sync.vc.data.EntitiesImportCtx; @@ -95,15 +97,21 @@ public class DefaultEntitiesExportImportService implements EntitiesExportImportS EntityImportResult importResult = importService.importEntity(ctx, exportData); ctx.putInternalId(exportData.getExternalId(), importResult.getSavedEntity().getId()); - ctx.addReferenceCallback(importResult.getSaveReferencesCallback()); + ctx.addReferenceCallback(exportData.getExternalId(), importResult.getSaveReferencesCallback()); ctx.addEventCallback(importResult.getSendEventsCallback()); return importResult; } @Override public void saveReferencesAndRelations(EntitiesImportCtx ctx) throws ThingsboardException { - for (ThrowingRunnable saveReferencesCallback : ctx.getReferenceCallbacks()) { - saveReferencesCallback.run(); + for (Map.Entry callbackEntry : ctx.getReferenceCallbacks().entrySet()) { + EntityId externalId = callbackEntry.getKey(); + ThrowingRunnable saveReferencesCallback = callbackEntry.getValue(); + try { + saveReferencesCallback.run(); + } catch (MissingEntityException e) { + throw new LoadEntityException(externalId, e); + } } relationService.saveRelations(ctx.getTenantId(), new ArrayList<>(ctx.getRelations())); diff --git a/application/src/main/java/org/thingsboard/server/service/sync/vc/DefaultEntitiesVersionControlService.java b/application/src/main/java/org/thingsboard/server/service/sync/vc/DefaultEntitiesVersionControlService.java index 0f6eb1b2f3..88a15f7cdc 100644 --- a/application/src/main/java/org/thingsboard/server/service/sync/vc/DefaultEntitiesVersionControlService.java +++ b/application/src/main/java/org/thingsboard/server/service/sync/vc/DefaultEntitiesVersionControlService.java @@ -286,7 +286,7 @@ public class DefaultEntitiesVersionControlService implements EntitiesVersionCont result.setDone(true); return cachePut(ctx.getRequestId(), result); } catch (LoadEntityException e) { - return cachePut(ctx.getRequestId(), onError(e.getData(), e.getCause())); + return cachePut(ctx.getRequestId(), onError(e.getExternalId(), e.getCause())); } catch (Exception e) { log.info("[{}] Failed to process request [{}] due to: ", ctx.getTenantId(), request, e); return cachePut(ctx.getRequestId(), VersionLoadResult.error(EntityLoadError.runtimeError(e.getMessage()))); @@ -313,7 +313,7 @@ public class DefaultEntitiesVersionControlService implements EntitiesVersionCont .deleted(0) .build()); } catch (Exception e) { - throw new LoadEntityException(entityData, e); + throw new LoadEntityException(entityData.getExternalId(), e); } } @@ -382,7 +382,7 @@ public class DefaultEntitiesVersionControlService implements EntitiesVersionCont try { importResult = exportImportService.importEntity(ctx, entityData); } catch (Exception e) { - throw new LoadEntityException(entityData, e); + throw new LoadEntityException(entityData.getExternalId(), e); } registerResult(ctx, entityType, importResult); @@ -432,20 +432,20 @@ public class DefaultEntitiesVersionControlService implements EntitiesVersionCont }); } - private VersionLoadResult onError(EntityExportData entityData, Throwable e) { - return analyze(e, entityData).orElse(VersionLoadResult.error(EntityLoadError.runtimeError(e.getMessage()))); + private VersionLoadResult onError(EntityId externalId, Throwable e) { + return analyze(e, externalId).orElse(VersionLoadResult.error(EntityLoadError.runtimeError(e.getMessage()))); } - private Optional analyze(Throwable e, EntityExportData entityData) { + private Optional analyze(Throwable e, EntityId externalId) { if (e == null) { return Optional.empty(); } else { if (e instanceof DeviceCredentialsValidationException) { - return Optional.of(VersionLoadResult.error(EntityLoadError.credentialsError(entityData.getExternalId()))); + return Optional.of(VersionLoadResult.error(EntityLoadError.credentialsError(externalId))); } else if (e instanceof MissingEntityException) { - return Optional.of(VersionLoadResult.error(EntityLoadError.referenceEntityError(entityData.getExternalId(), ((MissingEntityException) e).getEntityId()))); + return Optional.of(VersionLoadResult.error(EntityLoadError.referenceEntityError(externalId, ((MissingEntityException) e).getEntityId()))); } else { - return analyze(e.getCause(), entityData); + return analyze(e.getCause(), externalId); } } } diff --git a/application/src/main/java/org/thingsboard/server/service/sync/vc/LoadEntityException.java b/application/src/main/java/org/thingsboard/server/service/sync/vc/LoadEntityException.java index a1b036d37b..13d8280046 100644 --- a/application/src/main/java/org/thingsboard/server/service/sync/vc/LoadEntityException.java +++ b/application/src/main/java/org/thingsboard/server/service/sync/vc/LoadEntityException.java @@ -16,17 +16,17 @@ package org.thingsboard.server.service.sync.vc; import lombok.Getter; -import org.thingsboard.server.common.data.sync.ie.EntityExportData; +import org.thingsboard.server.common.data.id.EntityId; @SuppressWarnings("rawtypes") public class LoadEntityException extends RuntimeException { private static final long serialVersionUID = -1749719992370409504L; @Getter - private final EntityExportData data; + private final EntityId externalId; - public LoadEntityException(EntityExportData data, Throwable cause) { + public LoadEntityException(EntityId externalId, Throwable cause) { super(cause); - this.data = data; + this.externalId = externalId; } } diff --git a/application/src/main/java/org/thingsboard/server/service/sync/vc/data/EntitiesImportCtx.java b/application/src/main/java/org/thingsboard/server/service/sync/vc/data/EntitiesImportCtx.java index d7b85a1560..fddc91883e 100644 --- a/application/src/main/java/org/thingsboard/server/service/sync/vc/data/EntitiesImportCtx.java +++ b/application/src/main/java/org/thingsboard/server/service/sync/vc/data/EntitiesImportCtx.java @@ -48,7 +48,7 @@ public class EntitiesImportCtx { private final Map results = new HashMap<>(); private final Map> importedEntities = new HashMap<>(); private final Map toReimport = new HashMap<>(); - private final List referenceCallbacks = new ArrayList<>(); + private final Map referenceCallbacks = new HashMap<>(); private final List eventCallbacks = new ArrayList<>(); private final Map externalToInternalIdMap = new HashMap<>(); private final Set notFoundIds = new HashSet<>(); @@ -119,9 +119,9 @@ public class EntitiesImportCtx { relations.addAll(values); } - public void addReferenceCallback(ThrowingRunnable tr) { + public void addReferenceCallback(EntityId externalId, ThrowingRunnable tr) { if (tr != null) { - referenceCallbacks.add(tr); + referenceCallbacks.put(externalId, tr); } }