Set external ids in the config of rule chains and dashboards on export; add JsonIgnoreProperties in export data

This commit is contained in:
Viacheslav Klimov 2022-06-16 11:10:49 +03:00
parent fe4ec688b0
commit 88fcff5556
11 changed files with 90 additions and 22 deletions

View File

@ -15,18 +15,23 @@
*/ */
package org.thingsboard.server.service.sync.ie.exporting.impl; package org.thingsboard.server.service.sync.ie.exporting.impl;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.collect.Lists;
import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.server.common.data.Dashboard; import org.thingsboard.server.common.data.Dashboard;
import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.id.DashboardId; import org.thingsboard.server.common.data.id.DashboardId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.sync.ie.EntityExportData; import org.thingsboard.server.common.data.sync.ie.EntityExportData;
import org.thingsboard.server.common.data.sync.ie.EntityExportSettings;
import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.sync.vc.data.EntitiesExportCtx; import org.thingsboard.server.service.sync.vc.data.EntitiesExportCtx;
import org.thingsboard.server.utils.RegexUtils;
import java.util.ArrayList;
import java.util.Set; import java.util.Set;
import java.util.UUID;
@Service @Service
@TbCoreComponent @TbCoreComponent
@ -39,6 +44,19 @@ public class DashboardExportService extends BaseEntityExportService<DashboardId,
customerInfo.setCustomerId(getExternalIdOrElseInternal(ctx, customerInfo.getCustomerId())); customerInfo.setCustomerId(getExternalIdOrElseInternal(ctx, customerInfo.getCustomerId()));
}); });
} }
if (dashboard.getEntityAliasesConfig() != null) {
for (JsonNode entityAlias : dashboard.getEntityAliasesConfig()) {
ArrayList<String> fields = Lists.newArrayList(entityAlias.fieldNames());
for (String field : fields) {
if (field.equals("id")) continue;
JsonNode oldFieldValue = entityAlias.get(field);
JsonNode newFieldValue = JacksonUtil.toJsonNode(RegexUtils.replace(oldFieldValue.toString(), RegexUtils.UUID_PATTERN, uuid -> {
return getExternalIdOrElseInternalByUuid(ctx, UUID.fromString(uuid)).toString();
}));
((ObjectNode) entityAlias).set(field, newFieldValue);
}
}
}
} }
@Override @Override

View File

@ -24,27 +24,25 @@ import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.ExportableEntity; import org.thingsboard.server.common.data.ExportableEntity;
import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.EntityIdFactory;
import org.thingsboard.server.common.data.relation.EntityRelation; import org.thingsboard.server.common.data.relation.EntityRelation;
import org.thingsboard.server.common.data.relation.RelationTypeGroup; import org.thingsboard.server.common.data.relation.RelationTypeGroup;
import org.thingsboard.server.common.data.sync.ie.AttributeExportData; import org.thingsboard.server.common.data.sync.ie.AttributeExportData;
import org.thingsboard.server.common.data.sync.ie.EntityExportData; import org.thingsboard.server.common.data.sync.ie.EntityExportData;
import org.thingsboard.server.common.data.sync.ie.EntityExportSettings;
import org.thingsboard.server.dao.attributes.AttributesService; import org.thingsboard.server.dao.attributes.AttributesService;
import org.thingsboard.server.dao.relation.RelationService; import org.thingsboard.server.dao.relation.RelationService;
import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.security.model.SecurityUser;
import org.thingsboard.server.service.security.permission.Operation;
import org.thingsboard.server.service.sync.ie.exporting.EntityExportService; import org.thingsboard.server.service.sync.ie.exporting.EntityExportService;
import org.thingsboard.server.service.sync.ie.exporting.ExportableEntitiesService; import org.thingsboard.server.service.sync.ie.exporting.ExportableEntitiesService;
import org.thingsboard.server.service.sync.vc.data.EntitiesExportCtx; import org.thingsboard.server.service.sync.vc.data.EntitiesExportCtx;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -150,6 +148,35 @@ public class DefaultEntityExportService<I extends EntityId, E extends Exportable
return result; return result;
} }
protected UUID getExternalIdOrElseInternalByUuid(EntitiesExportCtx<?> ctx, UUID internalUuid) {
for (EntityType entityType : EntityType.values()) {
EntityId internalId;
try {
internalId = EntityIdFactory.getByTypeAndUuid(entityType, internalUuid);
} catch (Exception e) {
continue;
}
EntityId externalId = ctx.getExternalId(internalId);
if (externalId != null) {
return externalId.getId();
}
}
for (EntityType entityType : EntityType.values()) {
EntityId internalId;
try {
internalId = EntityIdFactory.getByTypeAndUuid(entityType, internalUuid);
} catch (Exception e) {
continue;
}
EntityId externalId = exportableEntitiesService.getExternalIdByInternal(internalId);
if (externalId != null) {
ctx.putExternalId(internalId, externalId);
return externalId.getId();
}
}
return internalUuid;
}
protected D newExportData() { protected D newExportData() {
return (D) new EntityExportData<E>(); return (D) new EntityExportData<E>();
} }

View File

@ -15,19 +15,26 @@
*/ */
package org.thingsboard.server.service.sync.ie.exporting.impl; package org.thingsboard.server.service.sync.ie.exporting.impl;
import com.fasterxml.jackson.databind.JsonNode;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.RuleChainId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.rule.RuleChain; import org.thingsboard.server.common.data.rule.RuleChain;
import org.thingsboard.server.common.data.rule.RuleChainMetaData;
import org.thingsboard.server.common.data.sync.ie.EntityExportSettings; import org.thingsboard.server.common.data.sync.ie.EntityExportSettings;
import org.thingsboard.server.dao.rule.RuleChainService; import org.thingsboard.server.dao.rule.RuleChainService;
import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.common.data.sync.ie.RuleChainExportData; import org.thingsboard.server.common.data.sync.ie.RuleChainExportData;
import org.thingsboard.server.service.sync.vc.data.EntitiesExportCtx; import org.thingsboard.server.service.sync.vc.data.EntitiesExportCtx;
import org.thingsboard.server.utils.RegexUtils;
import java.util.Collections;
import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.UUID;
@Service @Service
@TbCoreComponent @TbCoreComponent
@ -38,7 +45,22 @@ public class RuleChainExportService extends BaseEntityExportService<RuleChainId,
@Override @Override
protected void setRelatedEntities(EntitiesExportCtx<?> ctx, RuleChain ruleChain, RuleChainExportData exportData) { protected void setRelatedEntities(EntitiesExportCtx<?> ctx, RuleChain ruleChain, RuleChainExportData exportData) {
exportData.setMetaData(ruleChainService.loadRuleChainMetaData(ctx.getTenantId(), ruleChain.getId())); RuleChainMetaData metaData = ruleChainService.loadRuleChainMetaData(ctx.getTenantId(), ruleChain.getId());
Optional.ofNullable(metaData.getNodes()).orElse(Collections.emptyList())
.forEach(ruleNode -> {
ruleNode.setRuleChainId(null);
JsonNode ruleNodeConfig = ruleNode.getConfiguration();
String newRuleNodeConfigJson = RegexUtils.replace(ruleNodeConfig.toString(), RegexUtils.UUID_PATTERN, uuid -> {
return getExternalIdOrElseInternalByUuid(ctx, UUID.fromString(uuid)).toString();
});
ruleNodeConfig = JacksonUtil.toJsonNode(newRuleNodeConfigJson);
ruleNode.setConfiguration(ruleNodeConfig);
});
Optional.ofNullable(metaData.getRuleChainConnections()).orElse(Collections.emptyList())
.forEach(ruleChainConnectionInfo -> {
ruleChainConnectionInfo.setTargetRuleChainId(getExternalIdOrElseInternal(ctx, ruleChainConnectionInfo.getTargetRuleChainId()));
});
exportData.setMetaData(metaData);
} }
@Override @Override

View File

@ -307,13 +307,6 @@ public abstract class BaseEntityImportService<I extends EntityId, E extends Expo
EntityId internalId = getInternalId(externalId, false); EntityId internalId = getInternalId(externalId, false);
if (internalId != null) { if (internalId != null) {
return Optional.of(internalId); return Optional.of(internalId);
} else if (ctx.isResetExternalIdsOfAnotherTenant()) {
try {
if (exportableEntitiesService.findEntityById(externalId) != null) {
return Optional.of(EntityIdFactory.getByTypeAndUuid(entityType, EntityId.NULL_UUID));
}
} catch (Exception ignored) {
}
} }
} }

View File

@ -354,7 +354,6 @@ public class DefaultEntitiesVersionControlService implements EntitiesVersionCont
ctx.getToReimport().forEach((externalId, importSettings) -> { ctx.getToReimport().forEach((externalId, importSettings) -> {
try { try {
EntityExportData entityData = gitServiceQueue.getEntity(ctx.getTenantId(), ctx.getVersionId(), externalId).get(); EntityExportData entityData = gitServiceQueue.getEntity(ctx.getTenantId(), ctx.getVersionId(), externalId).get();
importSettings.setResetExternalIdsOfAnotherTenant(true);
ctx.setSettings(importSettings); ctx.setSettings(importSettings);
EntityImportResult<?> importResult = exportImportService.importEntity(ctx, entityData); EntityImportResult<?> importResult = exportImportService.importEntity(ctx, entityData);

View File

@ -83,10 +83,6 @@ public class EntitiesImportCtx {
return getSettings().isSaveCredentials(); return getSettings().isSaveCredentials();
} }
public boolean isResetExternalIdsOfAnotherTenant() {
return getSettings().isResetExternalIdsOfAnotherTenant();
}
public EntityId getInternalId(EntityId externalId) { public EntityId getInternalId(EntityId externalId) {
var result = externalToInternalIdMap.get(externalId); var result = externalToInternalIdMap.get(externalId);
log.debug("[{}][{}] Local cache {} for id", externalId.getEntityType(), externalId.getId(), result != null ? "hit" : "miss"); log.debug("[{}][{}] Local cache {} for id", externalId.getEntityType(), externalId.getId(), result != null ? "hit" : "miss");

View File

@ -15,13 +15,17 @@
*/ */
package org.thingsboard.server.common.data; package org.thingsboard.server.common.data;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import org.thingsboard.server.common.data.id.DashboardId; import org.thingsboard.server.common.data.id.DashboardId;
import java.util.Optional;
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
public class Dashboard extends DashboardInfo implements ExportableEntity<DashboardId> { public class Dashboard extends DashboardInfo implements ExportableEntity<DashboardId> {
@ -62,6 +66,13 @@ public class Dashboard extends DashboardInfo implements ExportableEntity<Dashboa
this.configuration = configuration; this.configuration = configuration;
} }
@JsonIgnore
public ObjectNode getEntityAliasesConfig() {
return (ObjectNode) Optional.ofNullable(getConfiguration())
.map(config -> config.get("entityAliases"))
.filter(JsonNode::isObject).orElse(null);
}
@Override @Override
public String toString() { public String toString() {
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();

View File

@ -16,6 +16,7 @@
package org.thingsboard.server.common.data.sync.ie; package org.thingsboard.server.common.data.sync.ie;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
@ -29,6 +30,7 @@ import org.thingsboard.server.common.data.security.DeviceCredentials;
public class DeviceExportData extends EntityExportData<Device> { public class DeviceExportData extends EntityExportData<Device> {
@JsonProperty(index = 3) @JsonProperty(index = 3)
@JsonIgnoreProperties({"id", "deviceId", "createdTime"})
private DeviceCredentials credentials; private DeviceCredentials credentials;
@JsonIgnore @JsonIgnore

View File

@ -55,6 +55,7 @@ public class EntityExportData<E extends ExportableEntity<? extends EntityId>> {
.comparing(AttributeExportData::getKey).thenComparing(AttributeExportData::getLastUpdateTs); .comparing(AttributeExportData::getKey).thenComparing(AttributeExportData::getLastUpdateTs);
@JsonProperty(index = 2) @JsonProperty(index = 2)
@JsonIgnoreProperties({"tenantId", "createdTime"})
@JsonTbEntity @JsonTbEntity
private E entity; private E entity;
@JsonProperty(index = 1) @JsonProperty(index = 1)

View File

@ -29,7 +29,4 @@ public class EntityImportSettings {
private boolean updateRelations; private boolean updateRelations;
private boolean saveAttributes; private boolean saveAttributes;
private boolean saveCredentials; private boolean saveCredentials;
// internal
private boolean resetExternalIdsOfAnotherTenant;
} }

View File

@ -15,6 +15,7 @@
*/ */
package org.thingsboard.server.common.data.sync.ie; package org.thingsboard.server.common.data.sync.ie;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
@ -28,6 +29,7 @@ import org.thingsboard.server.common.data.rule.RuleChainMetaData;
public class RuleChainExportData extends EntityExportData<RuleChain> { public class RuleChainExportData extends EntityExportData<RuleChain> {
@JsonProperty(index = 3) @JsonProperty(index = 3)
@JsonIgnoreProperties("ruleChainId")
private RuleChainMetaData metaData; private RuleChainMetaData metaData;
} }