Set external ids in the config of rule chains and dashboards on export; add JsonIgnoreProperties in export data
This commit is contained in:
		
							parent
							
								
									fe4ec688b0
								
							
						
					
					
						commit
						88fcff5556
					
				@ -15,18 +15,23 @@
 | 
			
		||||
 */
 | 
			
		||||
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.springframework.stereotype.Service;
 | 
			
		||||
import org.thingsboard.common.util.JacksonUtil;
 | 
			
		||||
import org.thingsboard.server.common.data.Dashboard;
 | 
			
		||||
import org.thingsboard.server.common.data.EntityType;
 | 
			
		||||
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.EntityExportSettings;
 | 
			
		||||
import org.thingsboard.server.queue.util.TbCoreComponent;
 | 
			
		||||
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.UUID;
 | 
			
		||||
 | 
			
		||||
@Service
 | 
			
		||||
@TbCoreComponent
 | 
			
		||||
@ -39,6 +44,19 @@ public class DashboardExportService extends BaseEntityExportService<DashboardId,
 | 
			
		||||
                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
 | 
			
		||||
 | 
			
		||||
@ -24,27 +24,25 @@ import org.thingsboard.server.common.data.EntityType;
 | 
			
		||||
import org.thingsboard.server.common.data.ExportableEntity;
 | 
			
		||||
import org.thingsboard.server.common.data.exception.ThingsboardException;
 | 
			
		||||
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.RelationTypeGroup;
 | 
			
		||||
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.EntityExportSettings;
 | 
			
		||||
import org.thingsboard.server.dao.attributes.AttributesService;
 | 
			
		||||
import org.thingsboard.server.dao.relation.RelationService;
 | 
			
		||||
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.ExportableEntitiesService;
 | 
			
		||||
import org.thingsboard.server.service.sync.vc.data.EntitiesExportCtx;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.LinkedHashMap;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.Optional;
 | 
			
		||||
import java.util.UUID;
 | 
			
		||||
import java.util.concurrent.ExecutionException;
 | 
			
		||||
import java.util.stream.Collectors;
 | 
			
		||||
 | 
			
		||||
@ -150,6 +148,35 @@ public class DefaultEntityExportService<I extends EntityId, E extends Exportable
 | 
			
		||||
        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() {
 | 
			
		||||
        return (D) new EntityExportData<E>();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -15,19 +15,26 @@
 | 
			
		||||
 */
 | 
			
		||||
package org.thingsboard.server.service.sync.ie.exporting.impl;
 | 
			
		||||
 | 
			
		||||
import com.fasterxml.jackson.databind.JsonNode;
 | 
			
		||||
import lombok.RequiredArgsConstructor;
 | 
			
		||||
import org.springframework.stereotype.Service;
 | 
			
		||||
import org.thingsboard.common.util.JacksonUtil;
 | 
			
		||||
import org.thingsboard.server.common.data.EntityType;
 | 
			
		||||
import org.thingsboard.server.common.data.id.RuleChainId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.TenantId;
 | 
			
		||||
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.dao.rule.RuleChainService;
 | 
			
		||||
import org.thingsboard.server.queue.util.TbCoreComponent;
 | 
			
		||||
import org.thingsboard.server.common.data.sync.ie.RuleChainExportData;
 | 
			
		||||
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.UUID;
 | 
			
		||||
 | 
			
		||||
@Service
 | 
			
		||||
@TbCoreComponent
 | 
			
		||||
@ -38,7 +45,22 @@ public class RuleChainExportService extends BaseEntityExportService<RuleChainId,
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    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
 | 
			
		||||
 | 
			
		||||
@ -307,13 +307,6 @@ public abstract class BaseEntityImportService<I extends EntityId, E extends Expo
 | 
			
		||||
                EntityId internalId = getInternalId(externalId, false);
 | 
			
		||||
                if (internalId != null) {
 | 
			
		||||
                    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) {
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -354,7 +354,6 @@ public class DefaultEntitiesVersionControlService implements EntitiesVersionCont
 | 
			
		||||
        ctx.getToReimport().forEach((externalId, importSettings) -> {
 | 
			
		||||
            try {
 | 
			
		||||
                EntityExportData entityData = gitServiceQueue.getEntity(ctx.getTenantId(), ctx.getVersionId(), externalId).get();
 | 
			
		||||
                importSettings.setResetExternalIdsOfAnotherTenant(true);
 | 
			
		||||
                ctx.setSettings(importSettings);
 | 
			
		||||
                EntityImportResult<?> importResult = exportImportService.importEntity(ctx, entityData);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -83,10 +83,6 @@ public class EntitiesImportCtx {
 | 
			
		||||
        return getSettings().isSaveCredentials();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean isResetExternalIdsOfAnotherTenant() {
 | 
			
		||||
        return getSettings().isResetExternalIdsOfAnotherTenant();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public EntityId getInternalId(EntityId externalId) {
 | 
			
		||||
        var result = externalToInternalIdMap.get(externalId);
 | 
			
		||||
        log.debug("[{}][{}] Local cache {} for id", externalId.getEntityType(), externalId.getId(), result != null ? "hit" : "miss");
 | 
			
		||||
 | 
			
		||||
@ -15,13 +15,17 @@
 | 
			
		||||
 */
 | 
			
		||||
package org.thingsboard.server.common.data;
 | 
			
		||||
 | 
			
		||||
import com.fasterxml.jackson.annotation.JsonIgnore;
 | 
			
		||||
import com.fasterxml.jackson.databind.JsonNode;
 | 
			
		||||
import com.fasterxml.jackson.databind.node.ObjectNode;
 | 
			
		||||
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.Optional;
 | 
			
		||||
 | 
			
		||||
@EqualsAndHashCode(callSuper = true)
 | 
			
		||||
public class Dashboard extends DashboardInfo implements ExportableEntity<DashboardId> {
 | 
			
		||||
 | 
			
		||||
@ -62,6 +66,13 @@ public class Dashboard extends DashboardInfo implements ExportableEntity<Dashboa
 | 
			
		||||
        this.configuration = configuration;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @JsonIgnore
 | 
			
		||||
    public ObjectNode getEntityAliasesConfig() {
 | 
			
		||||
        return (ObjectNode) Optional.ofNullable(getConfiguration())
 | 
			
		||||
                .map(config -> config.get("entityAliases"))
 | 
			
		||||
                .filter(JsonNode::isObject).orElse(null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toString() {
 | 
			
		||||
        StringBuilder builder = new StringBuilder();
 | 
			
		||||
 | 
			
		||||
@ -16,6 +16,7 @@
 | 
			
		||||
package org.thingsboard.server.common.data.sync.ie;
 | 
			
		||||
 | 
			
		||||
import com.fasterxml.jackson.annotation.JsonIgnore;
 | 
			
		||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
 | 
			
		||||
import com.fasterxml.jackson.annotation.JsonProperty;
 | 
			
		||||
import lombok.Data;
 | 
			
		||||
import lombok.EqualsAndHashCode;
 | 
			
		||||
@ -29,6 +30,7 @@ import org.thingsboard.server.common.data.security.DeviceCredentials;
 | 
			
		||||
public class DeviceExportData extends EntityExportData<Device> {
 | 
			
		||||
 | 
			
		||||
    @JsonProperty(index = 3)
 | 
			
		||||
    @JsonIgnoreProperties({"id", "deviceId", "createdTime"})
 | 
			
		||||
    private DeviceCredentials credentials;
 | 
			
		||||
 | 
			
		||||
    @JsonIgnore
 | 
			
		||||
 | 
			
		||||
@ -55,6 +55,7 @@ public class EntityExportData<E extends ExportableEntity<? extends EntityId>> {
 | 
			
		||||
            .comparing(AttributeExportData::getKey).thenComparing(AttributeExportData::getLastUpdateTs);
 | 
			
		||||
 | 
			
		||||
    @JsonProperty(index = 2)
 | 
			
		||||
    @JsonIgnoreProperties({"tenantId", "createdTime"})
 | 
			
		||||
    @JsonTbEntity
 | 
			
		||||
    private E entity;
 | 
			
		||||
    @JsonProperty(index = 1)
 | 
			
		||||
 | 
			
		||||
@ -29,7 +29,4 @@ public class EntityImportSettings {
 | 
			
		||||
    private boolean updateRelations;
 | 
			
		||||
    private boolean saveAttributes;
 | 
			
		||||
    private boolean saveCredentials;
 | 
			
		||||
 | 
			
		||||
    // internal
 | 
			
		||||
    private boolean resetExternalIdsOfAnotherTenant;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -15,6 +15,7 @@
 | 
			
		||||
 */
 | 
			
		||||
package org.thingsboard.server.common.data.sync.ie;
 | 
			
		||||
 | 
			
		||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
 | 
			
		||||
import com.fasterxml.jackson.annotation.JsonProperty;
 | 
			
		||||
import lombok.Data;
 | 
			
		||||
import lombok.EqualsAndHashCode;
 | 
			
		||||
@ -28,6 +29,7 @@ import org.thingsboard.server.common.data.rule.RuleChainMetaData;
 | 
			
		||||
public class RuleChainExportData extends EntityExportData<RuleChain> {
 | 
			
		||||
 | 
			
		||||
    @JsonProperty(index = 3)
 | 
			
		||||
    @JsonIgnoreProperties("ruleChainId")
 | 
			
		||||
    private RuleChainMetaData metaData;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user