Skip to content

Commit 7ed46c0

Browse files
committed
Merge remote-tracking branch 'nm-ce/avoid-duplicate-edge-updates' into avoid-duplicate-edge-update
2 parents 06cda9e + ffae956 commit 7ed46c0

6 files changed

Lines changed: 109 additions & 72 deletions

File tree

application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/BaseEdgeProcessor.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@
2828
import org.thingsboard.server.common.data.EdgeUtils;
2929
import org.thingsboard.server.common.data.EntityType;
3030
import org.thingsboard.server.common.data.HasCustomerId;
31+
import org.thingsboard.server.common.data.HasName;
32+
import org.thingsboard.server.common.data.HasVersion;
33+
import org.thingsboard.server.common.data.StringUtils;
3134
import org.thingsboard.server.common.data.cloud.CloudEventType;
3235
import org.thingsboard.server.common.data.edge.Edge;
3336
import org.thingsboard.server.common.data.edge.EdgeEvent;
@@ -68,6 +71,7 @@
6871
import org.thingsboard.server.service.executors.DbCallbackExecutorService;
6972
import org.thingsboard.server.service.state.DefaultDeviceStateService;
7073

74+
import javax.annotation.Nullable;
7175
import java.util.ArrayList;
7276
import java.util.List;
7377
import java.util.Optional;
@@ -448,4 +452,27 @@ protected boolean isCustomerNotExists(TenantId tenantId, CustomerId customerId)
448452
return customerById == null;
449453
}
450454

455+
protected boolean isSaveRequired(HasVersion current, HasVersion updated) {
456+
updated.setVersion(null);
457+
return !updated.equals(current);
458+
}
459+
460+
protected <I extends EntityId, E extends HasName & HasId<I>> Optional<String> generateUniqueNameIfDuplicateExists(
461+
TenantId tenantId, I entityId, E entity, @Nullable E entityWithSameName) {
462+
463+
if (entityWithSameName == null || entityWithSameName.getId().equals(entityId)) {
464+
return Optional.empty();
465+
}
466+
String currentName = entity.getName();
467+
String newEntityName = generateRandomAlphabeticString(currentName);
468+
469+
log.warn("[{}] Entity with name '{}' already exists (id={}). Renaming to '{}'", tenantId, currentName, entityWithSameName.getId(), newEntityName);
470+
return Optional.of(newEntityName);
471+
}
472+
473+
protected static String generateRandomAlphabeticString(String prefix) {
474+
return prefix + "_" + StringUtils.randomAlphabetic(15);
475+
476+
}
477+
451478
}

application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/asset/BaseAssetProcessor.java

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
import org.springframework.beans.factory.annotation.Autowired;
2020
import org.springframework.data.util.Pair;
2121
import org.thingsboard.common.util.JacksonUtil;
22-
import org.thingsboard.server.common.data.StringUtils;
2322
import org.thingsboard.server.common.data.asset.Asset;
2423
import org.thingsboard.server.common.data.edge.Edge;
2524
import org.thingsboard.server.common.data.id.AssetId;
@@ -52,22 +51,14 @@ protected Pair<Boolean, Boolean> saveOrUpdateAsset(TenantId tenantId, AssetId as
5251
} else {
5352
asset.setId(assetId);
5453
}
55-
String assetName = asset.getName();
56-
Asset assetByName = edgeCtx.getAssetService().findAssetByTenantIdAndName(tenantId, assetName);
57-
if (assetByName != null && !assetByName.getId().equals(assetId)) {
58-
assetName = assetName + "_" + StringUtils.randomAlphanumeric(15);
59-
log.warn("[{}] Asset with name {} already exists. Renaming asset name to {}",
60-
tenantId, asset.getName(), assetName);
61-
assetNameUpdated = true;
54+
if (isSaveRequired(assetById, asset)) {
55+
assetNameUpdated = updateAssetNameIfDuplicateExists(tenantId, assetId, asset);
56+
assetValidator.validate(asset, Asset::getTenantId);
57+
if (created) {
58+
asset.setId(assetId);
59+
}
60+
edgeCtx.getAssetService().saveAsset(asset, false);
6261
}
63-
asset.setName(assetName);
64-
setCustomerId(tenantId, created ? null : assetById.getCustomerId(), asset, assetUpdateMsg);
65-
66-
assetValidator.validate(asset, Asset::getTenantId);
67-
if (created) {
68-
asset.setId(assetId);
69-
}
70-
edgeCtx.getAssetService().saveAsset(asset, false);
7162
} catch (Exception e) {
7263
log.error("[{}] Failed to process asset update msg [{}]", tenantId, assetUpdateMsg, e);
7364
throw e;
@@ -77,6 +68,15 @@ protected Pair<Boolean, Boolean> saveOrUpdateAsset(TenantId tenantId, AssetId as
7768
return Pair.of(created, assetNameUpdated);
7869
}
7970

71+
private boolean updateAssetNameIfDuplicateExists(TenantId tenantId, AssetId assetId, Asset asset) {
72+
Asset assetByName = edgeCtx.getAssetService().findAssetByTenantIdAndName(tenantId, asset.getName());
73+
74+
return generateUniqueNameIfDuplicateExists(tenantId, assetId, asset, assetByName).map(uniqueName -> {
75+
asset.setName(uniqueName);
76+
return true;
77+
}).orElse(false);
78+
}
79+
8080
protected abstract void setCustomerId(TenantId tenantId, CustomerId customerId, Asset asset, AssetUpdateMsg assetUpdateMsg);
8181

8282
protected void deleteAsset(TenantId tenantId, AssetId assetId) {

application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/dashboard/BaseDashboardProcessor.java

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -57,16 +57,14 @@ protected boolean saveOrUpdateDashboard(TenantId tenantId, DashboardId dashboard
5757
dashboard.setId(dashboardId);
5858
dashboard.setAssignedCustomers(dashboardById.getAssignedCustomers());
5959
}
60-
61-
dashboardValidator.validate(dashboard, Dashboard::getTenantId);
62-
if (created) {
63-
dashboard.setId(dashboardId);
60+
if (isSaveRequired(dashboardById, dashboard)) {
61+
dashboardValidator.validate(dashboard, Dashboard::getTenantId);
62+
if (created) {
63+
dashboard.setId(dashboardId);
64+
}
65+
Dashboard savedDashboard = edgeCtx.getDashboardService().saveDashboard(dashboard, false);
66+
updateDashboardAssignments(tenantId, customerId, dashboardById, savedDashboard, newAssignedCustomers);
6467
}
65-
66-
Dashboard savedDashboard = edgeCtx.getDashboardService().saveDashboard(dashboard, false);
67-
68-
updateDashboardAssignments(tenantId, customerId, dashboardById, savedDashboard, newAssignedCustomers);
69-
7068
return created;
7169
}
7270

application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/device/BaseDeviceProcessor.java

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
import org.springframework.data.util.Pair;
2121
import org.thingsboard.common.util.JacksonUtil;
2222
import org.thingsboard.server.common.data.Device;
23-
import org.thingsboard.server.common.data.StringUtils;
2423
import org.thingsboard.server.common.data.edge.Edge;
2524
import org.thingsboard.server.common.data.id.CustomerId;
2625
import org.thingsboard.server.common.data.id.DeviceId;
@@ -54,23 +53,17 @@ protected Pair<Boolean, Boolean> saveOrUpdateDevice(TenantId tenantId, DeviceId
5453
} else {
5554
device.setId(deviceId);
5655
}
57-
String deviceName = device.getName();
58-
Device deviceByName = edgeCtx.getDeviceService().findDeviceByTenantIdAndName(tenantId, deviceName);
59-
if (deviceByName != null && !deviceByName.getId().equals(deviceId)) {
60-
deviceName = deviceName + "_" + StringUtils.randomAlphabetic(15);
61-
log.warn("[{}] Device with name {} already exists. Renaming device name to {}",
62-
tenantId, device.getName(), deviceName);
63-
deviceNameUpdated = true;
64-
}
65-
device.setName(deviceName);
66-
setCustomerId(tenantId, created ? null : deviceById.getCustomerId(), device, deviceUpdateMsg);
56+
if (isSaveRequired(deviceById, device)) {
57+
deviceNameUpdated = updateDeviceNameIfDuplicateExists(tenantId, deviceId, device);
58+
setCustomerId(tenantId, created ? null : deviceById.getCustomerId(), device, deviceUpdateMsg);
6759

68-
deviceValidator.validate(device, Device::getTenantId);
69-
if (created) {
70-
device.setId(deviceId);
60+
deviceValidator.validate(device, Device::getTenantId);
61+
if (created) {
62+
device.setId(deviceId);
63+
}
64+
Device savedDevice = edgeCtx.getDeviceService().saveDevice(device, false);
65+
edgeCtx.getClusterService().onDeviceUpdated(savedDevice, created ? null : device);
7166
}
72-
Device savedDevice = edgeCtx.getDeviceService().saveDevice(device, false);
73-
edgeCtx.getClusterService().onDeviceUpdated(savedDevice, created ? null : device);
7467
} catch (Exception e) {
7568
log.error("[{}] Failed to process device update msg [{}]", tenantId, deviceUpdateMsg, e);
7669
throw e;
@@ -80,6 +73,15 @@ protected Pair<Boolean, Boolean> saveOrUpdateDevice(TenantId tenantId, DeviceId
8073
return Pair.of(created, deviceNameUpdated);
8174
}
8275

76+
private boolean updateDeviceNameIfDuplicateExists(TenantId tenantId, DeviceId deviceId, Device device) {
77+
Device deviceByName = edgeCtx.getDeviceService().findDeviceByTenantIdAndName(tenantId, device.getName());
78+
79+
return generateUniqueNameIfDuplicateExists(tenantId, deviceId, device, deviceByName).map(uniqueName -> {
80+
device.setName(uniqueName);
81+
return true;
82+
}).orElse(false);
83+
}
84+
8385
protected void updateDeviceCredentials(TenantId tenantId, DeviceCredentialsUpdateMsg deviceCredentialsUpdateMsg) {
8486
DeviceCredentials deviceCredentials = JacksonUtil.fromString(deviceCredentialsUpdateMsg.getEntity(), DeviceCredentials.class, true);
8587
if (deviceCredentials == null) {

application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/entityview/BaseEntityViewProcessor.java

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@
2121
import org.thingsboard.common.util.JacksonUtil;
2222
import org.thingsboard.server.common.data.EntityView;
2323
import org.thingsboard.server.common.data.StringUtils;
24+
import org.thingsboard.server.common.data.asset.Asset;
2425
import org.thingsboard.server.common.data.edge.Edge;
26+
import org.thingsboard.server.common.data.id.AssetId;
2527
import org.thingsboard.server.common.data.id.CustomerId;
2628
import org.thingsboard.server.common.data.id.EntityViewId;
2729
import org.thingsboard.server.common.data.id.TenantId;
@@ -50,25 +52,28 @@ protected Pair<Boolean, Boolean> saveOrUpdateEntityView(TenantId tenantId, Entit
5052
} else {
5153
entityView.setId(entityViewId);
5254
}
53-
String entityViewName = entityView.getName();
54-
EntityView entityViewByName = edgeCtx.getEntityViewService().findEntityViewByTenantIdAndName(tenantId, entityViewName);
55-
if (entityViewByName != null && !entityViewByName.getId().equals(entityViewId)) {
56-
entityViewName = entityViewName + "_" + StringUtils.randomAlphanumeric(15);
57-
log.warn("[{}] Entity view with name {} already exists. Renaming entity view name to {}",
58-
tenantId, entityView.getName(), entityViewName);
59-
entityViewNameUpdated = true;
60-
}
61-
entityView.setName(entityViewName);
62-
setCustomerId(tenantId, created ? null : entityViewById.getCustomerId(), entityView, entityViewUpdateMsg);
55+
if (isSaveRequired(entityViewById, entityView)) {
56+
entityViewNameUpdated = updateEntityViewNameIfDuplicateExists(tenantId, entityViewId, entityView);
57+
setCustomerId(tenantId, created ? null : entityViewById.getCustomerId(), entityView, entityViewUpdateMsg);
6358

64-
entityViewValidator.validate(entityView, EntityView::getTenantId);
65-
if (created) {
66-
entityView.setId(entityViewId);
59+
entityViewValidator.validate(entityView, EntityView::getTenantId);
60+
if (created) {
61+
entityView.setId(entityViewId);
62+
}
63+
edgeCtx.getEntityViewService().saveEntityView(entityView, false);
6764
}
68-
edgeCtx.getEntityViewService().saveEntityView(entityView, false);
6965
return Pair.of(created, entityViewNameUpdated);
7066
}
7167

68+
private boolean updateEntityViewNameIfDuplicateExists(TenantId tenantId, EntityViewId entityViewId, EntityView entityView) {
69+
EntityView entityViewByName = edgeCtx.getEntityViewService().findEntityViewByTenantIdAndName(tenantId, entityView.getName());
70+
71+
return generateUniqueNameIfDuplicateExists(tenantId, entityViewId, entityView, entityViewByName).map(uniqueName -> {
72+
entityView.setName(uniqueName);
73+
return true;
74+
}).orElse(false);
75+
}
76+
7277
protected abstract void setCustomerId(TenantId tenantId, CustomerId customerId, EntityView entityView, EntityViewUpdateMsg entityViewUpdateMsg);
7378

7479
protected void deleteEntityView(TenantId tenantId, EntityViewId entityViewId) {

application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/user/BaseUserProcessor.java

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -56,27 +56,18 @@ protected Pair<Boolean, Boolean> saveOrUpdateUser(TenantId tenantId, UserId user
5656
} else {
5757
user.setId(userId);
5858
}
59+
if (isSaveRequired(userById, user)) {
60+
userEmailUpdated = updateUserEmailIfDuplicateExists(tenantId, userId, user);
61+
setCustomerId(tenantId, isCreated ? null : userById.getCustomerId(), user, userUpdateMsg);
5962

60-
String userEmail = user.getEmail();
61-
User existing = edgeCtx.getUserService().findUserByTenantIdAndEmail(tenantId, user.getEmail());
63+
userValidator.validate(user, User::getTenantId);
6264

63-
if (existing != null && !existing.getId().equals(user.getId())) {
64-
String[] splitEmail = userEmail.split("@");
65-
userEmail = splitEmail[0] + "_" + StringUtils.randomAlphanumeric(15) + "@" + splitEmail[1];
66-
log.warn("[{}] User with email {} already exists. Renaming User email to {}",
67-
tenantId, user.getEmail(), userEmail);
68-
userEmailUpdated = true;
69-
}
70-
user.setEmail(userEmail);
71-
setCustomerId(tenantId, isCreated ? null : userById.getCustomerId(), user, userUpdateMsg);
72-
73-
userValidator.validate(user, User::getTenantId);
65+
if (isCreated) {
66+
user.setId(userId);
67+
}
7468

75-
if (isCreated) {
76-
user.setId(userId);
69+
edgeCtx.getUserService().saveUser(tenantId, user, false);
7770
}
78-
79-
edgeCtx.getUserService().saveUser(tenantId, user, false);
8071
} catch (Exception e) {
8172
log.error("[{}] Failed to process user update msg [{}]", tenantId, userUpdateMsg, e);
8273
throw e;
@@ -85,6 +76,20 @@ protected Pair<Boolean, Boolean> saveOrUpdateUser(TenantId tenantId, UserId user
8576
return Pair.of(isCreated, userEmailUpdated);
8677
}
8778

79+
private boolean updateUserEmailIfDuplicateExists(TenantId tenantId, UserId userId, User user) {
80+
String email = user.getEmail();
81+
User userByEmail = edgeCtx.getUserService().findUserByTenantIdAndEmail(tenantId, email);
82+
83+
if (userByEmail != null && !userByEmail.getId().equals(user.getId())) {
84+
String[] splitEmail = email.split("@");
85+
String newEmail = splitEmail[0] + "_" + StringUtils.randomAlphanumeric(15) + "@" + splitEmail[1];
86+
log.warn("[{}] User with email {} already exists. Renaming User email to {}", tenantId, user.getEmail(), newEmail);
87+
user.setEmail(newEmail);
88+
return true;
89+
}
90+
return false;
91+
}
92+
8893
protected void deleteUserAndPushEntityDeletedEventToRuleEngine(TenantId tenantId, UserId userId) {
8994
deleteUserAndPushEntityDeletedEventToRuleEngine(tenantId, userId, null);
9095
}

0 commit comments

Comments
 (0)