Fix re-import of rule chains, and different not related test
This commit is contained in:
parent
3d85fb7c0a
commit
7a4fec93cd
@ -43,7 +43,7 @@ public class DefaultTbCustomerService extends AbstractTbEntityService implements
|
||||
try {
|
||||
Customer savedCustomer = checkNotNull(customerService.saveCustomer(customer));
|
||||
vcService.autoCommit(user, savedCustomer.getId());
|
||||
notificationEntityService.notifyCreateOrUpdateEntity(tenantId, savedCustomer.getId(), savedCustomer, savedCustomer.getId(), actionType, user);
|
||||
notificationEntityService.notifyCreateOrUpdateEntity(tenantId, savedCustomer.getId(), savedCustomer, null, actionType, user);
|
||||
return savedCustomer;
|
||||
} catch (Exception e) {
|
||||
notificationEntityService.notifyEntity(tenantId, emptyId(EntityType.CUSTOMER), customer, null, actionType, user, e);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright © 2016-2021 The Thingsboard Authors
|
||||
* Copyright © 2016-2022 The Thingsboard Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
||||
@ -87,6 +87,7 @@ public abstract class BaseEntityImportService<I extends EntityId, E extends Expo
|
||||
@Override
|
||||
public EntityImportResult<E> importEntity(EntitiesImportCtx ctx, D exportData) throws ThingsboardException {
|
||||
EntityImportResult<E> importResult = new EntityImportResult<>();
|
||||
ctx.setCurrentImportResult(importResult);
|
||||
importResult.setEntityType(getEntityType());
|
||||
IdProvider idProvider = new IdProvider(ctx, importResult);
|
||||
|
||||
|
||||
@ -81,7 +81,7 @@ public class DashboardImportService extends BaseEntityImportService<DashboardId,
|
||||
if (field.equals("id")) continue;
|
||||
JsonNode oldFieldValue = entityAlias.get(field);
|
||||
JsonNode newFieldValue = JacksonUtil.toJsonNode(RegexUtils.replace(oldFieldValue.toString(), RegexUtils.UUID_PATTERN, uuid -> {
|
||||
return idProvider.getInternalIdByUuid(UUID.fromString(uuid), ctx.isFetchAllUUIDs(), HINTS)
|
||||
return idProvider.getInternalIdByUuid(UUID.fromString(uuid), ctx.isFinalImportAttempt(), HINTS)
|
||||
.map(entityId -> entityId.getId().toString()).orElse(uuid);
|
||||
}));
|
||||
((ObjectNode) entityAlias).set(field, newFieldValue);
|
||||
|
||||
@ -77,15 +77,12 @@ public class RuleChainImportService extends BaseEntityImportService<RuleChainId,
|
||||
RuleChainMetaData metaData = exportData.getMetaData();
|
||||
List<RuleNode> ruleNodes = Optional.ofNullable(metaData.getNodes()).orElse(Collections.emptyList());
|
||||
if (old != null) {
|
||||
// boolean original = old.getId().equals(old.getExternalId());
|
||||
List<RuleNodeId> nodeIds = ruleNodes.stream().map(RuleNode::getId).collect(Collectors.toList());
|
||||
List<RuleNode> existing = ruleNodeDao.findByExternalIds(old.getId(), nodeIds);
|
||||
existing.forEach(node -> ctx.putInternalId(node.getExternalId(), node.getId()));
|
||||
ruleNodes.forEach(node -> {
|
||||
node.setRuleChainId(old.getId());
|
||||
// if (!original) {
|
||||
node.setExternalId(node.getId());
|
||||
// }
|
||||
node.setId((RuleNodeId) ctx.getInternalId(node.getId()));
|
||||
});
|
||||
} else {
|
||||
@ -99,7 +96,7 @@ public class RuleChainImportService extends BaseEntityImportService<RuleChainId,
|
||||
ruleNodes.forEach(ruleNode -> {
|
||||
JsonNode ruleNodeConfig = ruleNode.getConfiguration();
|
||||
String newRuleNodeConfigJson = RegexUtils.replace(ruleNodeConfig.toString(), RegexUtils.UUID_PATTERN, uuid -> {
|
||||
return idProvider.getInternalIdByUuid(UUID.fromString(uuid), ctx.isFetchAllUUIDs(), HINTS)
|
||||
return idProvider.getInternalIdByUuid(UUID.fromString(uuid), ctx.isFinalImportAttempt(), HINTS)
|
||||
.map(entityId -> entityId.getId().toString())
|
||||
.orElse(uuid);
|
||||
});
|
||||
@ -119,9 +116,13 @@ public class RuleChainImportService extends BaseEntityImportService<RuleChainId,
|
||||
@Override
|
||||
protected RuleChain saveOrUpdate(EntitiesImportCtx ctx, RuleChain ruleChain, RuleChainExportData exportData, IdProvider idProvider) {
|
||||
ruleChain = ruleChainService.saveRuleChain(ruleChain);
|
||||
if (ctx.isFinalImportAttempt() || ctx.getCurrentImportResult().isUpdatedAllExternalIds()) {
|
||||
exportData.getMetaData().setRuleChainId(ruleChain.getId());
|
||||
ruleChainService.saveRuleChainMetaData(ctx.getTenantId(), exportData.getMetaData());
|
||||
return ruleChainService.findRuleChainById(ctx.getTenantId(), ruleChain.getId());
|
||||
} else {
|
||||
return ruleChain;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -259,6 +259,7 @@ public class DefaultEntitiesVersionControlService implements EntitiesVersionCont
|
||||
.saveCredentials(config.isLoadCredentials())
|
||||
.findExistingByName(false)
|
||||
.build());
|
||||
ctx.setFinalImportAttempt(true);
|
||||
EntityImportResult<?> importResult = exportImportService.importEntity(ctx, entityData);
|
||||
|
||||
exportImportService.saveReferencesAndRelations(ctx);
|
||||
@ -329,6 +330,7 @@ public class DefaultEntitiesVersionControlService implements EntitiesVersionCont
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
for (EntityExportData entityData : entityDataList) {
|
||||
EntityExportData reimportBackup = JacksonUtil.clone(entityData);
|
||||
log.debug("[{}] Loading {} entities", ctx.getTenantId(), entityType);
|
||||
EntityImportResult<?> importResult;
|
||||
try {
|
||||
@ -336,8 +338,8 @@ public class DefaultEntitiesVersionControlService implements EntitiesVersionCont
|
||||
} catch (Exception e) {
|
||||
throw new LoadEntityException(entityData, e);
|
||||
}
|
||||
if (importResult.getUpdatedAllExternalIds() != null && !importResult.getUpdatedAllExternalIds()) {
|
||||
ctx.getToReimport().put(entityData.getEntity().getExternalId(), new ReimportTask(entityData, ctx.getSettings()));
|
||||
if (!importResult.isUpdatedAllExternalIds()) {
|
||||
ctx.getToReimport().put(entityData.getEntity().getExternalId(), new ReimportTask(reimportBackup, ctx.getSettings()));
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -351,7 +353,7 @@ public class DefaultEntitiesVersionControlService implements EntitiesVersionCont
|
||||
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
private void reimport(EntitiesImportCtx ctx) {
|
||||
ctx.setFetchAllUUIDs(true);
|
||||
ctx.setFinalImportAttempt(true);
|
||||
ctx.getToReimport().forEach((externalId, task) -> {
|
||||
try {
|
||||
EntityExportData entityData = task.getData();
|
||||
|
||||
@ -22,6 +22,7 @@ import org.thingsboard.server.common.data.id.EntityId;
|
||||
import org.thingsboard.server.common.data.id.TenantId;
|
||||
import org.thingsboard.server.common.data.relation.EntityRelation;
|
||||
import org.thingsboard.server.common.data.sync.ThrowingRunnable;
|
||||
import org.thingsboard.server.common.data.sync.ie.EntityImportResult;
|
||||
import org.thingsboard.server.common.data.sync.ie.EntityImportSettings;
|
||||
import org.thingsboard.server.common.data.sync.vc.EntityTypeLoadResult;
|
||||
import org.thingsboard.server.service.security.model.SecurityUser;
|
||||
@ -52,8 +53,9 @@ public class EntitiesImportCtx {
|
||||
|
||||
private final Set<EntityRelation> relations = new LinkedHashSet<>();
|
||||
|
||||
private boolean fetchAllUUIDs = false;
|
||||
private boolean finalImportAttempt = false;
|
||||
private EntityImportSettings settings;
|
||||
private EntityImportResult<?> currentImportResult;
|
||||
|
||||
public EntitiesImportCtx(SecurityUser user, String versionId) {
|
||||
this(user, versionId, null);
|
||||
@ -134,4 +136,6 @@ public class EntitiesImportCtx {
|
||||
return notFoundIds.contains(externalId);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -31,6 +31,7 @@ import org.thingsboard.server.common.data.Customer;
|
||||
import org.thingsboard.server.common.data.Tenant;
|
||||
import org.thingsboard.server.common.data.User;
|
||||
import org.thingsboard.server.common.data.audit.ActionType;
|
||||
import org.thingsboard.server.common.data.id.CustomerId;
|
||||
import org.thingsboard.server.common.data.id.TenantId;
|
||||
import org.thingsboard.server.common.data.page.PageData;
|
||||
import org.thingsboard.server.common.data.page.PageLink;
|
||||
@ -108,7 +109,7 @@ public abstract class BaseCustomerControllerTest extends AbstractControllerTest
|
||||
doPost("/api/customer", savedCustomer, Customer.class);
|
||||
|
||||
testNotifyEntityAllOneTime(savedCustomer, savedCustomer.getId(), savedCustomer.getId(), savedCustomer.getTenantId(),
|
||||
savedCustomer.getId(), tenantAdmin.getId(), tenantAdmin.getEmail(),
|
||||
new CustomerId(CustomerId.NULL_UUID), tenantAdmin.getId(), tenantAdmin.getEmail(),
|
||||
ActionType.UPDATED);
|
||||
|
||||
Customer foundCustomer = doGet("/api/customer/" + savedCustomer.getId().getId().toString(), Customer.class);
|
||||
|
||||
@ -434,7 +434,7 @@ public abstract class BaseExportImportServiceTest extends AbstractControllerTest
|
||||
|
||||
protected <E extends ExportableEntity<I>, I extends EntityId> EntityImportResult<E> importEntity(User user, EntityExportData<E> exportData, EntityImportSettings importSettings) throws Exception {
|
||||
EntitiesImportCtx ctx = new EntitiesImportCtx(getSecurityUser(user), null, importSettings);
|
||||
ctx.setFetchAllUUIDs(true);
|
||||
ctx.setFinalImportAttempt(true);
|
||||
exportData = JacksonUtil.treeToValue(JacksonUtil.valueToTree(exportData), EntityExportData.class);
|
||||
EntityImportResult<E> importResult = exportImportService.importEntity(ctx, exportData);
|
||||
exportImportService.saveReferencesAndRelations(ctx);
|
||||
|
||||
@ -20,6 +20,7 @@ import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import com.fasterxml.jackson.databind.node.TextNode;
|
||||
import com.google.common.collect.Streams;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.mock.mockito.SpyBean;
|
||||
import org.thingsboard.common.util.JacksonUtil;
|
||||
@ -433,6 +434,12 @@ public class ExportImportServiceSqlTest extends BaseExportImportServiceTest {
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("rawTypes")
|
||||
private static EntityExportData getAndClone(Map<EntityType, EntityExportData> map, EntityType entityType) {
|
||||
return JacksonUtil.clone(map.get(entityType));
|
||||
}
|
||||
|
||||
@SuppressWarnings({"rawTypes", "unchecked"})
|
||||
@Test
|
||||
public void testEntityEventsOnImport() throws Exception {
|
||||
Customer customer = createCustomer(tenantId1, "Customer 1");
|
||||
@ -455,32 +462,50 @@ public class ExportImportServiceSqlTest extends BaseExportImportServiceTest {
|
||||
})
|
||||
.collect(Collectors.toMap(EntityExportData::getEntityType, d -> d));
|
||||
|
||||
Customer importedCustomer = (Customer) importEntity(tenantAdmin2, entitiesExportData.get(EntityType.CUSTOMER)).getSavedEntity();
|
||||
Mockito.reset(entityActionService);
|
||||
Customer importedCustomer = (Customer) importEntity(tenantAdmin2, getAndClone(entitiesExportData, EntityType.CUSTOMER)).getSavedEntity();
|
||||
verify(entityActionService).logEntityAction(any(), eq(importedCustomer.getId()), eq(importedCustomer),
|
||||
any(), eq(ActionType.ADDED), isNull());
|
||||
importEntity(tenantAdmin2, entitiesExportData.get(EntityType.CUSTOMER));
|
||||
verify(entityActionService).logEntityAction(any(), eq(importedCustomer.getId()), eq(importedCustomer),
|
||||
Mockito.reset(entityActionService);
|
||||
importEntity(tenantAdmin2, getAndClone(entitiesExportData, EntityType.CUSTOMER));
|
||||
verify(entityActionService, Mockito.never()).logEntityAction(any(), eq(importedCustomer.getId()), eq(importedCustomer),
|
||||
any(), eq(ActionType.UPDATED), isNull());
|
||||
|
||||
EntityExportData<Customer> updatedCustomerEntity = getAndClone(entitiesExportData, EntityType.CUSTOMER);
|
||||
updatedCustomerEntity.getEntity().setEmail("t" + updatedCustomerEntity.getEntity().getEmail());
|
||||
Customer updatedCustomer = importEntity(tenantAdmin2, updatedCustomerEntity).getSavedEntity();
|
||||
verify(entityActionService).logEntityAction(any(), eq(importedCustomer.getId()), eq(updatedCustomer),
|
||||
any(), eq(ActionType.UPDATED), isNull());
|
||||
verify(tbClusterService).sendNotificationMsgToEdgeService(any(), any(), eq(importedCustomer.getId()), any(), any(), eq(EdgeEventActionType.UPDATED));
|
||||
|
||||
Asset importedAsset = (Asset) importEntity(tenantAdmin2, entitiesExportData.get(EntityType.ASSET)).getSavedEntity();
|
||||
Mockito.reset(entityActionService);
|
||||
|
||||
Asset importedAsset = (Asset) importEntity(tenantAdmin2, getAndClone(entitiesExportData, EntityType.ASSET)).getSavedEntity();
|
||||
verify(entityActionService).logEntityAction(any(), eq(importedAsset.getId()), eq(importedAsset),
|
||||
any(), eq(ActionType.ADDED), isNull());
|
||||
importEntity(tenantAdmin2, entitiesExportData.get(EntityType.ASSET));
|
||||
verify(entityActionService).logEntityAction(any(), eq(importedAsset.getId()), eq(importedAsset),
|
||||
verify(entityActionService, Mockito.never()).logEntityAction(any(), eq(importedAsset.getId()), eq(importedAsset),
|
||||
any(), eq(ActionType.UPDATED), isNull());
|
||||
|
||||
|
||||
EntityExportData<Asset> updatedAssetEntity = getAndClone(entitiesExportData, EntityType.ASSET);
|
||||
updatedAssetEntity.getEntity().setLabel("t" + updatedAssetEntity.getEntity().getLabel());
|
||||
Asset updatedAsset = importEntity(tenantAdmin2, updatedAssetEntity).getSavedEntity();
|
||||
|
||||
verify(entityActionService).logEntityAction(any(), eq(importedAsset.getId()), eq(updatedAsset),
|
||||
any(), eq(ActionType.UPDATED), isNull());
|
||||
verify(tbClusterService).sendNotificationMsgToEdgeService(any(), any(), eq(importedAsset.getId()), any(), any(), eq(EdgeEventActionType.UPDATED));
|
||||
|
||||
RuleChain importedRuleChain = (RuleChain) importEntity(tenantAdmin2, entitiesExportData.get(EntityType.RULE_CHAIN)).getSavedEntity();
|
||||
RuleChain importedRuleChain = (RuleChain) importEntity(tenantAdmin2, getAndClone(entitiesExportData, EntityType.RULE_CHAIN)).getSavedEntity();
|
||||
verify(entityActionService).logEntityAction(any(), eq(importedRuleChain.getId()), eq(importedRuleChain),
|
||||
any(), eq(ActionType.ADDED), isNull());
|
||||
verify(tbClusterService).broadcastEntityStateChangeEvent(any(), eq(importedRuleChain.getId()), eq(ComponentLifecycleEvent.CREATED));
|
||||
|
||||
Dashboard importedDashboard = (Dashboard) importEntity(tenantAdmin2, entitiesExportData.get(EntityType.DASHBOARD)).getSavedEntity();
|
||||
Dashboard importedDashboard = (Dashboard) importEntity(tenantAdmin2, getAndClone(entitiesExportData, EntityType.DASHBOARD)).getSavedEntity();
|
||||
verify(entityActionService).logEntityAction(any(), eq(importedDashboard.getId()), eq(importedDashboard),
|
||||
any(), eq(ActionType.ADDED), isNull());
|
||||
|
||||
DeviceProfile importedDeviceProfile = (DeviceProfile) importEntity(tenantAdmin2, entitiesExportData.get(EntityType.DEVICE_PROFILE)).getSavedEntity();
|
||||
DeviceProfile importedDeviceProfile = (DeviceProfile) importEntity(tenantAdmin2, getAndClone(entitiesExportData, EntityType.DEVICE_PROFILE)).getSavedEntity();
|
||||
verify(entityActionService).logEntityAction(any(), eq(importedDeviceProfile.getId()), eq(importedDeviceProfile),
|
||||
any(), eq(ActionType.ADDED), isNull());
|
||||
verify(tbClusterService).onDeviceProfileChange(eq(importedDeviceProfile), any());
|
||||
@ -488,12 +513,17 @@ public class ExportImportServiceSqlTest extends BaseExportImportServiceTest {
|
||||
verify(tbClusterService).sendNotificationMsgToEdgeService(any(), any(), eq(importedDeviceProfile.getId()), any(), any(), eq(EdgeEventActionType.ADDED));
|
||||
verify(otaPackageStateService).update(eq(importedDeviceProfile), eq(false), eq(false));
|
||||
|
||||
Device importedDevice = (Device) importEntity(tenantAdmin2, entitiesExportData.get(EntityType.DEVICE)).getSavedEntity();
|
||||
Device importedDevice = (Device) importEntity(tenantAdmin2, getAndClone(entitiesExportData, EntityType.DEVICE)).getSavedEntity();
|
||||
verify(entityActionService).logEntityAction(any(), eq(importedDevice.getId()), eq(importedDevice),
|
||||
any(), eq(ActionType.ADDED), isNull());
|
||||
verify(tbClusterService).onDeviceUpdated(eq(importedDevice), isNull());
|
||||
importEntity(tenantAdmin2, entitiesExportData.get(EntityType.DEVICE));
|
||||
verify(tbClusterService).onDeviceUpdated(eq(importedDevice), eq(importedDevice));
|
||||
importEntity(tenantAdmin2, getAndClone(entitiesExportData, EntityType.DEVICE));
|
||||
verify(tbClusterService, Mockito.never()).onDeviceUpdated(eq(importedDevice), eq(importedDevice));
|
||||
|
||||
EntityExportData<Device> updatedDeviceEntity = getAndClone(entitiesExportData, EntityType.DEVICE);
|
||||
updatedDeviceEntity.getEntity().setLabel("t" + updatedDeviceEntity.getEntity().getLabel());
|
||||
Device updatedDevice = importEntity(tenantAdmin2, updatedDeviceEntity).getSavedEntity();
|
||||
verify(tbClusterService).onDeviceUpdated(eq(updatedDevice), eq(importedDevice));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@ -31,7 +31,7 @@ public class EntityImportResult<E extends ExportableEntity<? extends EntityId>>
|
||||
private ThrowingRunnable saveReferencesCallback = () -> {};
|
||||
private ThrowingRunnable sendEventsCallback = () -> {};
|
||||
|
||||
private Boolean updatedAllExternalIds;
|
||||
private boolean updatedAllExternalIds = true;
|
||||
|
||||
private boolean created;
|
||||
private boolean updated;
|
||||
|
||||
@ -301,8 +301,10 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ruleChainMetaData.getConnections() != null) {
|
||||
Collections.sort(ruleChainMetaData.getConnections(), Comparator.comparingInt(NodeConnectionInfo::getFromIndex)
|
||||
.thenComparing(NodeConnectionInfo::getToIndex).thenComparing(NodeConnectionInfo::getType));
|
||||
}
|
||||
return ruleChainMetaData;
|
||||
}
|
||||
|
||||
|
||||
@ -1109,7 +1109,7 @@ public class TbDeviceProfileNodeTest {
|
||||
AttributeKvEntity attributeKvEntityActiveSchedule = new AttributeKvEntity();
|
||||
attributeKvEntityActiveSchedule.setId(compositeKeyActiveSchedule);
|
||||
attributeKvEntityActiveSchedule.setJsonValue(
|
||||
"{\"timezone\":\"Europe/Kiev\",\"items\":[{\"enabled\":true,\"dayOfWeek\":1,\"startsOn\":0,\"endsOn\":8.64e+7},{\"enabled\":true,\"dayOfWeek\":2,\"startsOn\":0,\"endsOn\":8.64e+7},{\"enabled\":true,\"dayOfWeek\":3,\"startsOn\":0,\"endsOn\":8.64e+7},{\"enabled\":true,\"dayOfWeek\":4,\"startsOn\":0,\"endsOn\":8.64e+7},{\"enabled\":true,\"dayOfWeek\":5,\"startsOn\":0,\"endsOn\":8.64e+7},{\"enabled\":true,\"dayOfWeek\":6,\"startsOn\":8.64e+7,\"endsOn\":8.64e+7},{\"enabled\":true,\"dayOfWeek\":7,\"startsOn\":0,\"endsOn\":8.64e+7}],\"dynamicValue\":null}"
|
||||
"{\"timezone\":\"Europe/Kiev\",\"items\":[{\"enabled\":true,\"dayOfWeek\":1,\"startsOn\":0,\"endsOn\":8.64e+7},{\"enabled\":true,\"dayOfWeek\":2,\"startsOn\":0,\"endsOn\":8.64e+7},{\"enabled\":true,\"dayOfWeek\":3,\"startsOn\":0,\"endsOn\":8.64e+7},{\"enabled\":true,\"dayOfWeek\":4,\"startsOn\":0,\"endsOn\":8.64e+7},{\"enabled\":true,\"dayOfWeek\":5,\"startsOn\":0,\"endsOn\":8.64e+7},{\"enabled\":true,\"dayOfWeek\":6,\"startsOn\":0,\"endsOn\":8.64e+7},{\"enabled\":true,\"dayOfWeek\":7,\"startsOn\":0,\"endsOn\":8.64e+7}],\"dynamicValue\":null}"
|
||||
);
|
||||
attributeKvEntityActiveSchedule.setLastUpdateTs(0L);
|
||||
|
||||
@ -1166,6 +1166,8 @@ public class TbDeviceProfileNodeTest {
|
||||
TbMsg msg = TbMsg.newMsg(SessionMsgType.POST_TELEMETRY_REQUEST.name(), deviceId, new TbMsgMetaData(),
|
||||
TbMsgDataType.JSON, mapper.writeValueAsString(data), null, null);
|
||||
|
||||
// Mockito.reset(ctx);
|
||||
|
||||
node.onMsg(ctx, msg);
|
||||
verify(ctx).tellSuccess(msg);
|
||||
verify(ctx).enqueueForTellNext(theMsg, "Alarm Created");
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user