Showing
10 changed files
with
50 additions
and
6 deletions
... | ... | @@ -481,6 +481,14 @@ class DefaultTbContext implements TbContext { |
481 | 481 | } |
482 | 482 | |
483 | 483 | @Override |
484 | + public void removeRuleNodeStateForEntity(EntityId entityId) { | |
485 | + if (log.isDebugEnabled()) { | |
486 | + log.debug("[{}][{}][{}] Remove Rule Node State for entity.", getTenantId(), getSelfId(), entityId); | |
487 | + } | |
488 | + mainCtx.getRuleNodeStateService().removeByRuleNodeIdAndEntityId(getTenantId(), getSelfId(), entityId); | |
489 | + } | |
490 | + | |
491 | + @Override | |
484 | 492 | public void addDeviceProfileListeners(Consumer<DeviceProfile> profileListener, BiConsumer<DeviceId, DeviceProfile> deviceListener) { |
485 | 493 | mainCtx.getDeviceProfileCache().addListener(getTenantId(), getSelfId(), profileListener, deviceListener); |
486 | 494 | } | ... | ... |
... | ... | @@ -31,4 +31,6 @@ public interface RuleNodeStateService { |
31 | 31 | RuleNodeState save(TenantId tenantId, RuleNodeState ruleNodeState); |
32 | 32 | |
33 | 33 | void removeByRuleNodeId(TenantId tenantId, RuleNodeId selfId); |
34 | + | |
35 | + void removeByRuleNodeIdAndEntityId(TenantId tenantId, RuleNodeId selfId, EntityId entityId); | |
34 | 36 | } | ... | ... |
... | ... | @@ -18,6 +18,7 @@ package org.thingsboard.server.common.data.device.profile; |
18 | 18 | import lombok.Data; |
19 | 19 | import org.thingsboard.server.common.data.alarm.AlarmSeverity; |
20 | 20 | |
21 | +import java.util.LinkedHashMap; | |
21 | 22 | import java.util.List; |
22 | 23 | import java.util.Map; |
23 | 24 | |
... | ... | @@ -27,7 +28,7 @@ public class DeviceProfileAlarm { |
27 | 28 | private String id; |
28 | 29 | private String alarmType; |
29 | 30 | |
30 | - private Map<AlarmSeverity, AlarmRule> createRules; | |
31 | + private LinkedHashMap<AlarmSeverity, AlarmRule> createRules; | |
31 | 32 | private AlarmRule clearRule; |
32 | 33 | |
33 | 34 | // Hidden in advanced settings | ... | ... |
... | ... | @@ -79,6 +79,20 @@ public class BaseRuleNodeStateService extends AbstractEntityService implements R |
79 | 79 | ruleNodeStateDao.removeByRuleNodeId(ruleNodeId.getId()); |
80 | 80 | } |
81 | 81 | |
82 | + @Override | |
83 | + public void removeByRuleNodeIdAndEntityId(TenantId tenantId, RuleNodeId ruleNodeId, EntityId entityId) { | |
84 | + if (tenantId == null) { | |
85 | + throw new DataValidationException("Tenant id should be specified!."); | |
86 | + } | |
87 | + if (ruleNodeId == null) { | |
88 | + throw new DataValidationException("Rule node id should be specified!."); | |
89 | + } | |
90 | + if (entityId == null) { | |
91 | + throw new DataValidationException("Entity id should be specified!."); | |
92 | + } | |
93 | + ruleNodeStateDao.removeByRuleNodeIdAndEntityId(ruleNodeId.getId(), entityId.getId()); | |
94 | + } | |
95 | + | |
82 | 96 | public RuleNodeState saveOrUpdate(TenantId tenantId, RuleNodeState ruleNodeState, boolean update) { |
83 | 97 | try { |
84 | 98 | if (update) { | ... | ... |
... | ... | @@ -35,4 +35,6 @@ public interface RuleNodeStateDao extends Dao<RuleNodeState> { |
35 | 35 | RuleNodeState findByRuleNodeIdAndEntityId(UUID ruleNodeId, UUID entityId); |
36 | 36 | |
37 | 37 | void removeByRuleNodeId(UUID ruleNodeId); |
38 | + | |
39 | + void removeByRuleNodeIdAndEntityId(UUID ruleNodeId, UUID entityId); | |
38 | 40 | } | ... | ... |
... | ... | @@ -63,4 +63,10 @@ public class JpaRuleNodeStateDao extends JpaAbstractDao<RuleNodeStateEntity, Rul |
63 | 63 | public void removeByRuleNodeId(UUID ruleNodeId) { |
64 | 64 | ruleNodeStateRepository.removeByRuleNodeId(ruleNodeId); |
65 | 65 | } |
66 | + | |
67 | + @Transactional | |
68 | + @Override | |
69 | + public void removeByRuleNodeIdAndEntityId(UUID ruleNodeId, UUID entityId) { | |
70 | + ruleNodeStateRepository.removeByRuleNodeIdAndEntityId(ruleNodeId, entityId); | |
71 | + } | |
66 | 72 | } | ... | ... |
... | ... | @@ -36,4 +36,5 @@ public interface RuleNodeStateRepository extends PagingAndSortingRepository<Rule |
36 | 36 | |
37 | 37 | void removeByRuleNodeId(@Param("ruleNodeId") UUID ruleNodeId); |
38 | 38 | |
39 | + void removeByRuleNodeIdAndEntityId(@Param("ruleNodeId") UUID ruleNodeId, @Param("entityId") UUID entityId); | |
39 | 40 | } | ... | ... |
... | ... | @@ -223,6 +223,8 @@ public interface TbContext { |
223 | 223 | |
224 | 224 | RuleNodeState findRuleNodeStateForEntity(EntityId entityId); |
225 | 225 | |
226 | + void removeRuleNodeStateForEntity(EntityId entityId); | |
227 | + | |
226 | 228 | RuleNodeState saveRuleNodeState(RuleNodeState state); |
227 | 229 | |
228 | 230 | void clearRuleNodeStates(); | ... | ... |
... | ... | @@ -117,7 +117,7 @@ public class TbDeviceProfileNode implements TbNode { |
117 | 117 | if (data.has("profileId")) { |
118 | 118 | invalidateDeviceProfileCache(deviceId, new DeviceProfileId(UUID.fromString(data.get("deviceProfileId").asText()))); |
119 | 119 | } else { |
120 | - deviceStates.remove(deviceId); | |
120 | + removeDeviceState(deviceId); | |
121 | 121 | } |
122 | 122 | |
123 | 123 | } else { |
... | ... | @@ -126,7 +126,7 @@ public class TbDeviceProfileNode implements TbNode { |
126 | 126 | if (msg.getType().equals(DataConstants.ENTITY_UPDATED)) { |
127 | 127 | invalidateDeviceProfileCache(deviceId, msg.getData()); |
128 | 128 | } else if (msg.getType().equals(DataConstants.ENTITY_DELETED)) { |
129 | - deviceStates.remove(deviceId); | |
129 | + removeDeviceState(deviceId); | |
130 | 130 | } else { |
131 | 131 | DeviceState deviceState = getOrCreateDeviceState(ctx, deviceId, null); |
132 | 132 | if (deviceState != null) { |
... | ... | @@ -209,7 +209,7 @@ public class TbDeviceProfileNode implements TbNode { |
209 | 209 | DeviceProfileId currentProfileId = deviceState.getProfileId(); |
210 | 210 | Device device = JacksonUtil.fromString(deviceJson, Device.class); |
211 | 211 | if (!currentProfileId.equals(device.getDeviceProfileId())) { |
212 | - deviceStates.remove(deviceId); | |
212 | + removeDeviceState(deviceId); | |
213 | 213 | } |
214 | 214 | } |
215 | 215 | } |
... | ... | @@ -218,8 +218,15 @@ public class TbDeviceProfileNode implements TbNode { |
218 | 218 | DeviceState deviceState = deviceStates.get(deviceId); |
219 | 219 | if (deviceState != null) { |
220 | 220 | if (!deviceState.getProfileId().equals(deviceProfileId)) { |
221 | - deviceStates.remove(deviceId); | |
221 | + removeDeviceState(deviceId); | |
222 | 222 | } |
223 | 223 | } |
224 | 224 | } |
225 | + | |
226 | + private void removeDeviceState(DeviceId deviceId) { | |
227 | + DeviceState state = deviceStates.remove(deviceId); | |
228 | + if (config.isPersistAlarmRulesState() && (state != null || !config.isFetchAlarmRulesStateOnStart())) { | |
229 | + ctx.removeRuleNodeStateForEntity(deviceId); | |
230 | + } | |
231 | + } | |
225 | 232 | } | ... | ... |
... | ... | @@ -56,6 +56,7 @@ import org.thingsboard.server.dao.alarm.AlarmService; |
56 | 56 | import org.thingsboard.server.dao.timeseries.TimeseriesService; |
57 | 57 | |
58 | 58 | import java.util.Collections; |
59 | +import java.util.LinkedHashMap; | |
59 | 60 | import java.util.UUID; |
60 | 61 | |
61 | 62 | import static org.mockito.Mockito.verify; |
... | ... | @@ -139,7 +140,7 @@ public class TbDeviceProfileNodeTest { |
139 | 140 | DeviceProfileAlarm dpa = new DeviceProfileAlarm(); |
140 | 141 | dpa.setId("highTemperatureAlarmID"); |
141 | 142 | dpa.setAlarmType("highTemperatureAlarm"); |
142 | - dpa.setCreateRules(Collections.singletonMap(AlarmSeverity.CRITICAL, alarmRule)); | |
143 | + dpa.setCreateRules(new LinkedHashMap<>(Collections.singletonMap(AlarmSeverity.CRITICAL, alarmRule))); | |
143 | 144 | |
144 | 145 | KeyFilter lowTempFilter = new KeyFilter(); |
145 | 146 | lowTempFilter.setKey(new EntityKey(EntityKeyType.TIME_SERIES, "temperature")); | ... | ... |