Fix UUIDs in rule node config replaced with tenant id

This commit is contained in:
ViacheslavKlimov 2023-08-16 15:13:16 +03:00
parent 7e57286667
commit cc1c2094c9
7 changed files with 32 additions and 17 deletions

View File

@ -25,6 +25,7 @@ import org.thingsboard.server.common.data.sync.ie.EntityExportData;
import org.thingsboard.server.service.sync.vc.data.EntitiesExportCtx; import org.thingsboard.server.service.sync.vc.data.EntitiesExportCtx;
import java.util.Set; import java.util.Set;
import java.util.regex.Pattern;
public abstract class BaseEntityExportService<I extends EntityId, E extends ExportableEntity<I>, D extends EntityExportData<E>> extends DefaultEntityExportService<I, E, D> { public abstract class BaseEntityExportService<I extends EntityId, E extends ExportableEntity<I>, D extends EntityExportData<E>> extends DefaultEntityExportService<I, E, D> {
@ -43,8 +44,8 @@ public abstract class BaseEntityExportService<I extends EntityId, E extends Expo
public abstract Set<EntityType> getSupportedEntityTypes(); public abstract Set<EntityType> getSupportedEntityTypes();
protected void replaceUuidsRecursively(EntitiesExportCtx<?> ctx, JsonNode node, Set<String> skipFieldsSet) { protected void replaceUuidsRecursively(EntitiesExportCtx<?> ctx, JsonNode node, Set<String> skipFieldsSet, Pattern includedFieldsPattern) {
JacksonUtil.replaceUuidsRecursively(node, skipFieldsSet, uuid -> getExternalIdOrElseInternalByUuid(ctx, uuid)); JacksonUtil.replaceUuidsRecursively(node, skipFieldsSet, includedFieldsPattern, uuid -> getExternalIdOrElseInternalByUuid(ctx, uuid));
} }
} }

View File

@ -26,7 +26,6 @@ import org.thingsboard.server.common.data.sync.ie.EntityExportData;
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 java.util.Collections;
import java.util.Set; import java.util.Set;
@Service @Service
@ -41,10 +40,10 @@ public class DashboardExportService extends BaseEntityExportService<DashboardId,
}); });
} }
for (JsonNode entityAlias : dashboard.getEntityAliasesConfig()) { for (JsonNode entityAlias : dashboard.getEntityAliasesConfig()) {
replaceUuidsRecursively(ctx, entityAlias, Collections.emptySet()); replaceUuidsRecursively(ctx, entityAlias, Set.of("id"), null);
} }
for (JsonNode widgetConfig : dashboard.getWidgetsConfig()) { for (JsonNode widgetConfig : dashboard.getWidgetsConfig()) {
replaceUuidsRecursively(ctx, JacksonUtil.getSafely(widgetConfig, "config", "actions"), Collections.singleton("id")); replaceUuidsRecursively(ctx, JacksonUtil.getSafely(widgetConfig, "config", "actions"), Set.of("id"), null);
} }
} }

View File

@ -30,6 +30,8 @@ import java.util.Collections;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
import static org.thingsboard.server.service.sync.ie.importing.impl.RuleChainImportService.PROCESSED_CONFIG_FIELDS_PATTERN;
@Service @Service
@TbCoreComponent @TbCoreComponent
@RequiredArgsConstructor @RequiredArgsConstructor
@ -47,7 +49,7 @@ public class RuleChainExportService extends BaseEntityExportService<RuleChainId,
ruleNode.setId(ctx.getExternalId(ruleNode.getId())); ruleNode.setId(ctx.getExternalId(ruleNode.getId()));
ruleNode.setCreatedTime(0); ruleNode.setCreatedTime(0);
ruleNode.setExternalId(null); ruleNode.setExternalId(null);
replaceUuidsRecursively(ctx, ruleNode.getConfiguration(), Collections.emptySet()); replaceUuidsRecursively(ctx, ruleNode.getConfiguration(), Collections.emptySet(), PROCESSED_CONFIG_FIELDS_PATTERN);
}); });
Optional.ofNullable(metaData.getRuleChainConnections()).orElse(Collections.emptyList()) Optional.ofNullable(metaData.getRuleChainConnections()).orElse(Collections.emptyList())
.forEach(ruleChainConnectionInfo -> { .forEach(ruleChainConnectionInfo -> {

View File

@ -65,6 +65,7 @@ import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.function.Function; import java.util.function.Function;
import java.util.regex.Pattern;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@Slf4j @Slf4j
@ -386,9 +387,12 @@ public abstract class BaseEntityImportService<I extends EntityId, E extends Expo
return oldEntity == null ? null : getter.apply(oldEntity); return oldEntity == null ? null : getter.apply(oldEntity);
} }
protected void replaceIdsRecursively(EntitiesImportCtx ctx, IdProvider idProvider, JsonNode entityAlias, Set<String> skipFieldsSet, LinkedHashSet<EntityType> hints) { protected void replaceIdsRecursively(EntitiesImportCtx ctx, IdProvider idProvider, JsonNode json,
JacksonUtil.replaceUuidsRecursively(entityAlias, skipFieldsSet, Set<String> skipFieldsSet, Pattern includedFieldsPattern,
uuid -> idProvider.getInternalIdByUuid(uuid, ctx.isFinalImportAttempt(), hints).map(EntityId::getId).orElse(uuid)); LinkedHashSet<EntityType> hints) {
JacksonUtil.replaceUuidsRecursively(json, skipFieldsSet, includedFieldsPattern,
uuid -> idProvider.getInternalIdByUuid(uuid, ctx.isFinalImportAttempt(), hints)
.map(EntityId::getId).orElse(uuid));
} }
} }

View File

@ -65,10 +65,10 @@ public class DashboardImportService extends BaseEntityImportService<DashboardId,
@Override @Override
protected Dashboard prepare(EntitiesImportCtx ctx, Dashboard dashboard, Dashboard old, EntityExportData<Dashboard> exportData, IdProvider idProvider) { protected Dashboard prepare(EntitiesImportCtx ctx, Dashboard dashboard, Dashboard old, EntityExportData<Dashboard> exportData, IdProvider idProvider) {
for (JsonNode entityAlias : dashboard.getEntityAliasesConfig()) { for (JsonNode entityAlias : dashboard.getEntityAliasesConfig()) {
replaceIdsRecursively(ctx, idProvider, entityAlias, Set.of("id"), HINTS); replaceIdsRecursively(ctx, idProvider, entityAlias, Set.of("id"), null, HINTS);
} }
for (JsonNode widgetConfig : dashboard.getWidgetsConfig()) { for (JsonNode widgetConfig : dashboard.getWidgetsConfig()) {
replaceIdsRecursively(ctx, idProvider, JacksonUtil.getSafely(widgetConfig, "config", "actions"), Set.of("id"), HINTS); replaceIdsRecursively(ctx, idProvider, JacksonUtil.getSafely(widgetConfig, "config", "actions"), Set.of("id"), null, HINTS);
} }
return dashboard; return dashboard;
} }

View File

@ -42,6 +42,7 @@ import java.util.Collections;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.regex.Pattern;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@Slf4j @Slf4j
@ -50,11 +51,12 @@ import java.util.stream.Collectors;
@RequiredArgsConstructor @RequiredArgsConstructor
public class RuleChainImportService extends BaseEntityImportService<RuleChainId, RuleChain, RuleChainExportData> { public class RuleChainImportService extends BaseEntityImportService<RuleChainId, RuleChain, RuleChainExportData> {
private static final LinkedHashSet<EntityType> HINTS = new LinkedHashSet<>(Arrays.asList(EntityType.RULE_CHAIN, EntityType.DEVICE, EntityType.ASSET));
private final RuleChainService ruleChainService; private final RuleChainService ruleChainService;
private final RuleNodeDao ruleNodeDao; private final RuleNodeDao ruleNodeDao;
private static final LinkedHashSet<EntityType> HINTS = new LinkedHashSet<>(Arrays.asList(EntityType.RULE_CHAIN, EntityType.DEVICE, EntityType.ASSET));
public static final Pattern PROCESSED_CONFIG_FIELDS_PATTERN = Pattern.compile(".*[iI]d.*");
@Override @Override
protected void setOwner(TenantId tenantId, RuleChain ruleChain, IdProvider idProvider) { protected void setOwner(TenantId tenantId, RuleChain ruleChain, IdProvider idProvider) {
ruleChain.setTenantId(tenantId); ruleChain.setTenantId(tenantId);
@ -90,7 +92,8 @@ public class RuleChainImportService extends BaseEntityImportService<RuleChainId,
}); });
} }
ruleNodes.forEach(ruleNode -> replaceIdsRecursively(ctx, idProvider, ruleNode.getConfiguration(), Collections.emptySet(), HINTS)); ruleNodes.forEach(ruleNode -> replaceIdsRecursively(ctx, idProvider, ruleNode.getConfiguration(),
Collections.emptySet(), PROCESSED_CONFIG_FIELDS_PATTERN, HINTS));
Optional.ofNullable(metaData.getRuleChainConnections()).orElse(Collections.emptyList()) Optional.ofNullable(metaData.getRuleChainConnections()).orElse(Collections.emptyList())
.forEach(ruleChainConnectionInfo -> { .forEach(ruleChainConnectionInfo -> {
ruleChainConnectionInfo.setTargetRuleChainId(idProvider.getInternalId(ruleChainConnectionInfo.getTargetRuleChainId(), false)); ruleChainConnectionInfo.setTargetRuleChainId(idProvider.getInternalId(ruleChainConnectionInfo.getTargetRuleChainId(), false));

View File

@ -39,6 +39,7 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.function.UnaryOperator; import java.util.function.UnaryOperator;
import java.util.regex.Pattern;
/** /**
* Created by Valerii Sosliuk on 5/12/2017. * Created by Valerii Sosliuk on 5/12/2017.
@ -200,7 +201,7 @@ public class JacksonUtil {
return node; return node;
} }
public static void replaceUuidsRecursively(JsonNode node, Set<String> skipFieldsSet, UnaryOperator<UUID> replacer) { public static void replaceUuidsRecursively(JsonNode node, Set<String> skipFieldsSet, Pattern includedFieldsPattern, UnaryOperator<UUID> replacer) {
if (node == null) { if (node == null) {
return; return;
} }
@ -212,9 +213,14 @@ public class JacksonUtil {
if (skipFieldsSet.contains(fieldName)) { if (skipFieldsSet.contains(fieldName)) {
continue; continue;
} }
if (includedFieldsPattern != null) {
if (!RegexUtils.matches(fieldName, includedFieldsPattern)) {
continue;
}
}
var child = objectNode.get(fieldName); var child = objectNode.get(fieldName);
if (child.isObject() || child.isArray()) { if (child.isObject() || child.isArray()) {
replaceUuidsRecursively(child, skipFieldsSet, replacer); replaceUuidsRecursively(child, skipFieldsSet, includedFieldsPattern, replacer);
} else if (child.isTextual()) { } else if (child.isTextual()) {
String text = child.asText(); String text = child.asText();
String newText = RegexUtils.replace(text, RegexUtils.UUID_PATTERN, uuid -> replacer.apply(UUID.fromString(uuid)).toString()); String newText = RegexUtils.replace(text, RegexUtils.UUID_PATTERN, uuid -> replacer.apply(UUID.fromString(uuid)).toString());
@ -228,7 +234,7 @@ public class JacksonUtil {
for (int i = 0; i < array.size(); i++) { for (int i = 0; i < array.size(); i++) {
JsonNode arrayElement = array.get(i); JsonNode arrayElement = array.get(i);
if (arrayElement.isObject() || arrayElement.isArray()) { if (arrayElement.isObject() || arrayElement.isArray()) {
replaceUuidsRecursively(arrayElement, skipFieldsSet, replacer); replaceUuidsRecursively(arrayElement, skipFieldsSet, includedFieldsPattern, replacer);
} else if (arrayElement.isTextual()) { } else if (arrayElement.isTextual()) {
String text = arrayElement.asText(); String text = arrayElement.asText();
String newText = RegexUtils.replace(text, RegexUtils.UUID_PATTERN, uuid -> replacer.apply(UUID.fromString(uuid)).toString()); String newText = RegexUtils.replace(text, RegexUtils.UUID_PATTERN, uuid -> replacer.apply(UUID.fromString(uuid)).toString());