Commit aec2d388ce860117ec9e67999d957d4d2d15cd5f
Committed by
Andrew Shvayka
1 parent
65fa1a7a
Alarm Websockets API
Showing
27 changed files
with
451 additions
and
183 deletions
... | ... | @@ -103,6 +103,7 @@ import org.thingsboard.server.service.security.permission.AccessControlService; |
103 | 103 | import org.thingsboard.server.service.security.permission.Operation; |
104 | 104 | import org.thingsboard.server.service.security.permission.Resource; |
105 | 105 | import org.thingsboard.server.service.state.DeviceStateService; |
106 | +import org.thingsboard.server.service.telemetry.AlarmSubscriptionService; | |
106 | 107 | import org.thingsboard.server.service.telemetry.TelemetrySubscriptionService; |
107 | 108 | |
108 | 109 | import javax.mail.MessagingException; |
... | ... | @@ -145,7 +146,7 @@ public abstract class BaseController { |
145 | 146 | protected AssetService assetService; |
146 | 147 | |
147 | 148 | @Autowired |
148 | - protected AlarmService alarmService; | |
149 | + protected AlarmSubscriptionService alarmService; | |
149 | 150 | |
150 | 151 | @Autowired |
151 | 152 | protected DeviceCredentialsService deviceCredentialsService; | ... | ... |
... | ... | @@ -23,6 +23,7 @@ import org.thingsboard.common.util.ThingsBoardThreadFactory; |
23 | 23 | import org.thingsboard.rule.engine.api.msg.DeviceAttributesEventNotificationMsg; |
24 | 24 | import org.thingsboard.server.common.data.DataConstants; |
25 | 25 | import org.thingsboard.server.common.data.EntityType; |
26 | +import org.thingsboard.server.common.data.alarm.Alarm; | |
26 | 27 | import org.thingsboard.server.common.data.id.DeviceId; |
27 | 28 | import org.thingsboard.server.common.data.id.EntityId; |
28 | 29 | import org.thingsboard.server.common.data.id.TenantId; |
... | ... | @@ -52,7 +53,8 @@ import org.thingsboard.server.queue.util.TbCoreComponent; |
52 | 53 | import org.thingsboard.server.service.queue.TbClusterService; |
53 | 54 | import org.thingsboard.server.service.state.DefaultDeviceStateService; |
54 | 55 | import org.thingsboard.server.service.state.DeviceStateService; |
55 | -import org.thingsboard.server.service.telemetry.sub.TsSubscriptionUpdate; | |
56 | +import org.thingsboard.server.service.telemetry.sub.AlarmSubscriptionUpdate; | |
57 | +import org.thingsboard.server.service.telemetry.sub.TelemetrySubscriptionUpdate; | |
56 | 58 | |
57 | 59 | import javax.annotation.PostConstruct; |
58 | 60 | import javax.annotation.PreDestroy; |
... | ... | @@ -195,7 +197,7 @@ public class DefaultSubscriptionManagerService implements SubscriptionManagerSer |
195 | 197 | |
196 | 198 | @Override |
197 | 199 | public void onTimeSeriesUpdate(TenantId tenantId, EntityId entityId, List<TsKvEntry> ts, TbCallback callback) { |
198 | - onLocalSubUpdate(entityId, | |
200 | + onLocalTelemetrySubUpdate(entityId, | |
199 | 201 | s -> { |
200 | 202 | if (TbSubscriptionType.TIMESERIES.equals(s.getType())) { |
201 | 203 | return (TbTimeseriesSubscription) s; |
... | ... | @@ -219,7 +221,7 @@ public class DefaultSubscriptionManagerService implements SubscriptionManagerSer |
219 | 221 | |
220 | 222 | @Override |
221 | 223 | public void onAttributesUpdate(TenantId tenantId, EntityId entityId, String scope, List<AttributeKvEntry> attributes, TbCallback callback) { |
222 | - onLocalSubUpdate(entityId, | |
224 | + onLocalTelemetrySubUpdate(entityId, | |
223 | 225 | s -> { |
224 | 226 | if (TbSubscriptionType.ATTRIBUTES.equals(s.getType())) { |
225 | 227 | return (TbAttributeSubscription) s; |
... | ... | @@ -257,8 +259,42 @@ public class DefaultSubscriptionManagerService implements SubscriptionManagerSer |
257 | 259 | } |
258 | 260 | |
259 | 261 | @Override |
262 | + public void onAlarmUpdate(TenantId tenantId, EntityId entityId, Alarm alarm, TbCallback callback) { | |
263 | + onLocalAlarmSubUpdate(entityId, | |
264 | + s -> { | |
265 | + if (TbSubscriptionType.ALARMS.equals(s.getType())) { | |
266 | + return (TbAlarmsSubscription) s; | |
267 | + } else { | |
268 | + return null; | |
269 | + } | |
270 | + }, | |
271 | + s -> alarm.getCreatedTime() >= s.getTs(), | |
272 | + s -> alarm, | |
273 | + false | |
274 | + ); | |
275 | + callback.onSuccess(); | |
276 | + } | |
277 | + | |
278 | + @Override | |
279 | + public void onAlarmDeleted(TenantId tenantId, EntityId entityId, Alarm alarm, TbCallback callback) { | |
280 | + onLocalAlarmSubUpdate(entityId, | |
281 | + s -> { | |
282 | + if (TbSubscriptionType.ALARMS.equals(s.getType())) { | |
283 | + return (TbAlarmsSubscription) s; | |
284 | + } else { | |
285 | + return null; | |
286 | + } | |
287 | + }, | |
288 | + s -> alarm.getCreatedTime() >= s.getTs(), | |
289 | + s -> alarm, | |
290 | + true | |
291 | + ); | |
292 | + callback.onSuccess(); | |
293 | + } | |
294 | + | |
295 | + @Override | |
260 | 296 | public void onAttributesDelete(TenantId tenantId, EntityId entityId, String scope, List<String> keys, TbCallback callback) { |
261 | - onLocalSubUpdate(entityId, | |
297 | + onLocalTelemetrySubUpdate(entityId, | |
262 | 298 | s -> { |
263 | 299 | if (TbSubscriptionType.ATTRIBUTES.equals(s.getType())) { |
264 | 300 | return (TbAttributeSubscription) s; |
... | ... | @@ -282,17 +318,17 @@ public class DefaultSubscriptionManagerService implements SubscriptionManagerSer |
282 | 318 | callback.onSuccess(); |
283 | 319 | } |
284 | 320 | |
285 | - private <T extends TbSubscription> void onLocalSubUpdate(EntityId entityId, | |
286 | - Function<TbSubscription, T> castFunction, | |
287 | - Predicate<T> filterFunction, | |
288 | - Function<T, List<TsKvEntry>> processFunction) { | |
321 | + private <T extends TbSubscription> void onLocalTelemetrySubUpdate(EntityId entityId, | |
322 | + Function<TbSubscription, T> castFunction, | |
323 | + Predicate<T> filterFunction, | |
324 | + Function<T, List<TsKvEntry>> processFunction) { | |
289 | 325 | Set<TbSubscription> entitySubscriptions = subscriptionsByEntityId.get(entityId); |
290 | 326 | if (entitySubscriptions != null) { |
291 | 327 | entitySubscriptions.stream().map(castFunction).filter(Objects::nonNull).filter(filterFunction).forEach(s -> { |
292 | 328 | List<TsKvEntry> subscriptionUpdate = processFunction.apply(s); |
293 | 329 | if (subscriptionUpdate != null && !subscriptionUpdate.isEmpty()) { |
294 | 330 | if (serviceId.equals(s.getServiceId())) { |
295 | - TsSubscriptionUpdate update = new TsSubscriptionUpdate(s.getSubscriptionId(), subscriptionUpdate); | |
331 | + TelemetrySubscriptionUpdate update = new TelemetrySubscriptionUpdate(s.getSubscriptionId(), subscriptionUpdate); | |
296 | 332 | localSubscriptionService.onSubscriptionUpdate(s.getSessionId(), update, TbCallback.EMPTY); |
297 | 333 | } else { |
298 | 334 | TopicPartitionInfo tpi = partitionService.getNotificationsTopic(ServiceType.TB_CORE, s.getServiceId()); |
... | ... | @@ -305,6 +341,29 @@ public class DefaultSubscriptionManagerService implements SubscriptionManagerSer |
305 | 341 | } |
306 | 342 | } |
307 | 343 | |
344 | + private void onLocalAlarmSubUpdate(EntityId entityId, | |
345 | + Function<TbSubscription, TbAlarmsSubscription> castFunction, | |
346 | + Predicate<TbAlarmsSubscription> filterFunction, | |
347 | + Function<TbAlarmsSubscription, Alarm> processFunction, boolean deleted) { | |
348 | + Set<TbSubscription> entitySubscriptions = subscriptionsByEntityId.get(entityId); | |
349 | + if (entitySubscriptions != null) { | |
350 | + entitySubscriptions.stream().map(castFunction).filter(Objects::nonNull).filter(filterFunction).forEach(s -> { | |
351 | + Alarm alarm = processFunction.apply(s); | |
352 | + if (alarm != null) { | |
353 | + if (serviceId.equals(s.getServiceId())) { | |
354 | + AlarmSubscriptionUpdate update = new AlarmSubscriptionUpdate(s.getSubscriptionId(), alarm, deleted); | |
355 | + localSubscriptionService.onSubscriptionUpdate(s.getSessionId(), update, TbCallback.EMPTY); | |
356 | + } else { | |
357 | + TopicPartitionInfo tpi = partitionService.getNotificationsTopic(ServiceType.TB_CORE, s.getServiceId()); | |
358 | + toCoreNotificationsProducer.send(tpi, toProto(s, alarm), null); | |
359 | + } | |
360 | + } | |
361 | + }); | |
362 | + } else { | |
363 | + log.debug("[{}] No device subscriptions to process!", entityId); | |
364 | + } | |
365 | + } | |
366 | + | |
308 | 367 | private boolean isInTimeRange(TbTimeseriesSubscription subscription, long kvTime) { |
309 | 368 | return (subscription.getStartTime() == 0 || subscription.getStartTime() <= kvTime) |
310 | 369 | && (subscription.getEndTime() == 0 || subscription.getEndTime() >= kvTime); |
... | ... | @@ -412,4 +471,19 @@ public class DefaultSubscriptionManagerService implements SubscriptionManagerSer |
412 | 471 | return new TbProtoQueueMsg<>(subscription.getEntityId().getId(), toCoreMsg); |
413 | 472 | } |
414 | 473 | |
474 | + private TbProtoQueueMsg<ToCoreNotificationMsg> toProto(TbSubscription subscription, Alarm alarm) { | |
475 | + TbSubscriptionUpdateProto.Builder builder = TbSubscriptionUpdateProto.newBuilder(); | |
476 | + | |
477 | + builder.setSessionId(subscription.getSessionId()); | |
478 | + builder.setSubscriptionId(subscription.getSubscriptionId()); | |
479 | + | |
480 | + //TODO 3.1 | |
481 | + throw new RuntimeException("Not implemented!"); | |
482 | +// | |
483 | +// ToCoreNotificationMsg toCoreMsg = ToCoreNotificationMsg.newBuilder().setToLocalSubscriptionServiceMsg( | |
484 | +// LocalSubscriptionServiceMsgProto.newBuilder().setSubUpdate(builder.build()).build()) | |
485 | +// .build(); | |
486 | +// return new TbProtoQueueMsg<>(subscription.getEntityId().getId(), toCoreMsg); | |
487 | + } | |
488 | + | |
415 | 489 | } | ... | ... |
... | ... | @@ -5,7 +5,7 @@ |
5 | 5 | * you may not use this file except in compliance with the License. |
6 | 6 | * You may obtain a copy of the License at |
7 | 7 | * |
8 | - * http://www.apache.org/licenses/LICENSE-2.0 | |
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | |
9 | 9 | * |
10 | 10 | * Unless required by applicable law or agreed to in writing, software |
11 | 11 | * distributed under the License is distributed on an "AS IS" BASIS, | ... | ... |
... | ... | @@ -36,7 +36,8 @@ import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; |
36 | 36 | import org.thingsboard.server.common.msg.queue.TbCallback; |
37 | 37 | import org.thingsboard.server.queue.util.TbCoreComponent; |
38 | 38 | import org.thingsboard.server.service.queue.TbClusterService; |
39 | -import org.thingsboard.server.service.telemetry.sub.TsSubscriptionUpdate; | |
39 | +import org.thingsboard.server.service.telemetry.sub.AlarmSubscriptionUpdate; | |
40 | +import org.thingsboard.server.service.telemetry.sub.TelemetrySubscriptionUpdate; | |
40 | 41 | |
41 | 42 | import javax.annotation.PostConstruct; |
42 | 43 | import javax.annotation.PreDestroy; |
... | ... | @@ -137,7 +138,7 @@ public class DefaultTbLocalSubscriptionService implements TbLocalSubscriptionSer |
137 | 138 | } |
138 | 139 | |
139 | 140 | @Override |
140 | - public void onSubscriptionUpdate(String sessionId, TsSubscriptionUpdate update, TbCallback callback) { | |
141 | + public void onSubscriptionUpdate(String sessionId, TelemetrySubscriptionUpdate update, TbCallback callback) { | |
141 | 142 | TbSubscription subscription = subscriptionsBySessionId |
142 | 143 | .getOrDefault(sessionId, Collections.emptyMap()).get(update.getSubscriptionId()); |
143 | 144 | if (subscription != null) { |
... | ... | @@ -157,6 +158,16 @@ public class DefaultTbLocalSubscriptionService implements TbLocalSubscriptionSer |
157 | 158 | } |
158 | 159 | |
159 | 160 | @Override |
161 | + public void onSubscriptionUpdate(String sessionId, AlarmSubscriptionUpdate update, TbCallback callback) { | |
162 | + TbSubscription subscription = subscriptionsBySessionId | |
163 | + .getOrDefault(sessionId, Collections.emptyMap()).get(update.getSubscriptionId()); | |
164 | + if (subscription != null && subscription.getType() == TbSubscriptionType.ALARMS) { | |
165 | + subscription.getUpdateConsumer().accept(sessionId, update); | |
166 | + } | |
167 | + callback.onSuccess(); | |
168 | + } | |
169 | + | |
170 | + @Override | |
160 | 171 | public void cancelSubscription(String sessionId, int subscriptionId) { |
161 | 172 | log.debug("[{}][{}] Going to remove subscription.", sessionId, subscriptionId); |
162 | 173 | Map<Integer, TbSubscription> sessionSubscriptions = subscriptionsBySessionId.get(sessionId); | ... | ... |
... | ... | @@ -17,6 +17,7 @@ package org.thingsboard.server.service.subscription; |
17 | 17 | |
18 | 18 | import org.springframework.context.ApplicationListener; |
19 | 19 | import org.thingsboard.server.common.data.alarm.Alarm; |
20 | +import org.thingsboard.server.common.data.id.AlarmId; | |
20 | 21 | import org.thingsboard.server.common.data.id.EntityId; |
21 | 22 | import org.thingsboard.server.common.data.id.TenantId; |
22 | 23 | import org.thingsboard.server.common.data.kv.AttributeKvEntry; |
... | ... | @@ -38,5 +39,7 @@ public interface SubscriptionManagerService extends ApplicationListener<Partitio |
38 | 39 | |
39 | 40 | void onAttributesDelete(TenantId tenantId, EntityId entityId, String scope, List<String> keys, TbCallback empty); |
40 | 41 | |
41 | - void onAlarmUpdate(TenantId tenantId, EntityId entityId, Alarm alarm); | |
42 | + void onAlarmUpdate(TenantId tenantId, EntityId entityId, Alarm alarm, TbCallback callback); | |
43 | + | |
44 | + void onAlarmDeleted(TenantId tenantId, EntityId entityId, Alarm alarm, TbCallback callback); | |
42 | 45 | } | ... | ... |
... | ... | @@ -5,7 +5,7 @@ |
5 | 5 | * you may not use this file except in compliance with the License. |
6 | 6 | * You may obtain a copy of the License at |
7 | 7 | * |
8 | - * http://www.apache.org/licenses/LICENSE-2.0 | |
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | |
9 | 9 | * |
10 | 10 | * Unless required by applicable law or agreed to in writing, software |
11 | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
... | ... | @@ -18,6 +18,9 @@ package org.thingsboard.server.service.subscription; |
18 | 18 | import lombok.Getter; |
19 | 19 | import lombok.Setter; |
20 | 20 | import lombok.extern.slf4j.Slf4j; |
21 | +import org.thingsboard.server.common.data.alarm.Alarm; | |
22 | +import org.thingsboard.server.common.data.alarm.AlarmSearchStatus; | |
23 | +import org.thingsboard.server.common.data.id.AlarmId; | |
21 | 24 | import org.thingsboard.server.common.data.id.EntityId; |
22 | 25 | import org.thingsboard.server.common.data.page.PageData; |
23 | 26 | import org.thingsboard.server.common.data.query.AlarmData; |
... | ... | @@ -26,15 +29,18 @@ import org.thingsboard.server.common.data.query.AlarmDataQuery; |
26 | 29 | import org.thingsboard.server.common.data.query.EntityData; |
27 | 30 | import org.thingsboard.server.service.telemetry.TelemetryWebSocketService; |
28 | 31 | import org.thingsboard.server.service.telemetry.TelemetryWebSocketSessionRef; |
32 | +import org.thingsboard.server.service.telemetry.cmd.v2.AlarmDataUpdate; | |
29 | 33 | import org.thingsboard.server.service.telemetry.sub.AlarmSubscriptionUpdate; |
30 | -import org.thingsboard.server.service.telemetry.sub.TsSubscriptionUpdate; | |
31 | 34 | |
32 | 35 | import java.util.ArrayList; |
33 | 36 | import java.util.Collection; |
37 | +import java.util.Collections; | |
34 | 38 | import java.util.HashMap; |
35 | 39 | import java.util.LinkedHashMap; |
36 | 40 | import java.util.List; |
37 | 41 | import java.util.Map; |
42 | +import java.util.function.Function; | |
43 | +import java.util.stream.Collectors; | |
38 | 44 | |
39 | 45 | @Slf4j |
40 | 46 | public class TbAlarmDataSubCtx extends TbAbstractDataSubCtx<AlarmDataQuery> { |
... | ... | @@ -44,6 +50,9 @@ public class TbAlarmDataSubCtx extends TbAbstractDataSubCtx<AlarmDataQuery> { |
44 | 50 | private final LinkedHashMap<EntityId, EntityData> entitiesMap; |
45 | 51 | @Getter |
46 | 52 | @Setter |
53 | + private final HashMap<AlarmId, AlarmData> alarmsMap; | |
54 | + @Getter | |
55 | + @Setter | |
47 | 56 | private PageData<AlarmData> alarms; |
48 | 57 | @Getter |
49 | 58 | @Setter |
... | ... | @@ -56,6 +65,7 @@ public class TbAlarmDataSubCtx extends TbAbstractDataSubCtx<AlarmDataQuery> { |
56 | 65 | public TbAlarmDataSubCtx(String serviceId, TelemetryWebSocketService wsService, TelemetryWebSocketSessionRef sessionRef, int cmdId) { |
57 | 66 | super(serviceId, wsService, sessionRef, cmdId); |
58 | 67 | this.entitiesMap = new LinkedHashMap<>(); |
68 | + this.alarmsMap = new HashMap<>(); | |
59 | 69 | } |
60 | 70 | |
61 | 71 | public void setEntitiesData(PageData<EntityData> entitiesData) { |
... | ... | @@ -81,6 +91,8 @@ public class TbAlarmDataSubCtx extends TbAbstractDataSubCtx<AlarmDataQuery> { |
81 | 91 | } |
82 | 92 | } |
83 | 93 | } |
94 | + alarmsMap.clear(); | |
95 | + alarmsMap.putAll(alarms.getData().stream().collect(Collectors.toMap(AlarmData::getId, Function.identity()))); | |
84 | 96 | return this.alarms; |
85 | 97 | } |
86 | 98 | |
... | ... | @@ -100,16 +112,64 @@ public class TbAlarmDataSubCtx extends TbAbstractDataSubCtx<AlarmDataQuery> { |
100 | 112 | .entityId(entityData.getEntityId()) |
101 | 113 | .updateConsumer(this::sendWsMsg) |
102 | 114 | .ts(lastFetchTs) |
103 | - .typeList(pageLink.getTypeList()) | |
104 | - .severityList(pageLink.getSeverityList()) | |
105 | - .statusList(pageLink.getStatusList()) | |
106 | - .searchPropagatedAlarms(pageLink.isSearchPropagatedAlarms()) | |
107 | 115 | .build()); |
108 | 116 | } |
109 | 117 | return result; |
110 | 118 | } |
111 | 119 | |
112 | 120 | private void sendWsMsg(String sessionId, AlarmSubscriptionUpdate subscriptionUpdate) { |
121 | + Alarm alarm = subscriptionUpdate.getAlarm(); | |
122 | + AlarmId alarmId = alarm.getId(); | |
123 | + if (subscriptionUpdate.isAlarmDeleted()) { | |
124 | + Alarm deleted = alarmsMap.remove(alarmId); | |
125 | + if (deleted != null) { | |
126 | + //TODO: invalidate current page; | |
127 | + } | |
128 | + } else { | |
129 | + AlarmData current = alarmsMap.get(alarmId); | |
130 | + boolean onCurrentPage = current != null; | |
131 | + boolean matchesFilter = filter(alarm); | |
132 | + if (onCurrentPage) { | |
133 | + if (matchesFilter) { | |
134 | + AlarmData updated = new AlarmData(alarm, current.getName(), current.getEntityId()); | |
135 | + alarmsMap.put(alarmId, updated); | |
136 | + wsService.sendWsMsg(sessionId, new AlarmDataUpdate(cmdId, null, Collections.singletonList(updated))); | |
137 | + } else { | |
138 | + //TODO: invalidate current page; | |
139 | + } | |
140 | + } else if (matchesFilter && query.getPageLink().getPage() == 0) { | |
141 | + //TODO: invalidate current page; | |
142 | + } | |
143 | + } | |
144 | + } | |
113 | 145 | |
146 | + private boolean filter(Alarm alarm) { | |
147 | + AlarmDataPageLink filter = query.getPageLink(); | |
148 | + long startTs = System.currentTimeMillis() - filter.getTimeWindow(); | |
149 | + if (alarm.getCreatedTime() < startTs) { | |
150 | + //Skip update that does not match time window. | |
151 | + return false; | |
152 | + } | |
153 | + if (filter.getTypeList() != null && !filter.getTypeList().isEmpty() && !filter.getTypeList().contains(alarm.getType())) { | |
154 | + return false; | |
155 | + } | |
156 | + if (filter.getSeverityList() != null && !filter.getSeverityList().isEmpty()) { | |
157 | + if (!filter.getSeverityList().contains(alarm.getSeverity())) { | |
158 | + return false; | |
159 | + } | |
160 | + } | |
161 | + if (filter.getStatusList() != null && !filter.getStatusList().isEmpty()) { | |
162 | + boolean matches = false; | |
163 | + for (AlarmSearchStatus status : filter.getStatusList()) { | |
164 | + if (status.getStatuses().contains(alarm.getStatus())) { | |
165 | + matches = true; | |
166 | + break; | |
167 | + } | |
168 | + } | |
169 | + if (!matches) { | |
170 | + return false; | |
171 | + } | |
172 | + } | |
173 | + return true; | |
114 | 174 | } |
115 | 175 | } | ... | ... |
... | ... | @@ -5,7 +5,7 @@ |
5 | 5 | * you may not use this file except in compliance with the License. |
6 | 6 | * You may obtain a copy of the License at |
7 | 7 | * |
8 | - * http://www.apache.org/licenses/LICENSE-2.0 | |
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | |
9 | 9 | * |
10 | 10 | * Unless required by applicable law or agreed to in writing, software |
11 | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
... | ... | @@ -16,35 +16,26 @@ |
16 | 16 | package org.thingsboard.server.service.subscription; |
17 | 17 | |
18 | 18 | import lombok.Builder; |
19 | +import lombok.Getter; | |
19 | 20 | import org.thingsboard.server.common.data.alarm.AlarmSearchStatus; |
20 | 21 | import org.thingsboard.server.common.data.alarm.AlarmSeverity; |
21 | 22 | import org.thingsboard.server.common.data.id.EntityId; |
22 | 23 | import org.thingsboard.server.common.data.id.TenantId; |
23 | 24 | import org.thingsboard.server.service.telemetry.sub.AlarmSubscriptionUpdate; |
24 | -import org.thingsboard.server.service.telemetry.sub.TsSubscriptionUpdate; | |
25 | 25 | |
26 | 26 | import java.util.List; |
27 | 27 | import java.util.function.BiConsumer; |
28 | 28 | |
29 | 29 | public class TbAlarmsSubscription extends TbSubscription<AlarmSubscriptionUpdate> { |
30 | 30 | |
31 | + @Getter | |
31 | 32 | private final long ts; |
32 | - private final List<String> typeList; | |
33 | - private final List<AlarmSearchStatus> statusList; | |
34 | - private final List<AlarmSeverity> severityList; | |
35 | - private final boolean searchPropagatedAlarms; | |
36 | 33 | |
37 | 34 | @Builder |
38 | 35 | public TbAlarmsSubscription(String serviceId, String sessionId, int subscriptionId, TenantId tenantId, EntityId entityId, |
39 | - TbSubscriptionType type, BiConsumer<String, AlarmSubscriptionUpdate> updateConsumer, | |
40 | - long ts, List<String> typeList, List<AlarmSearchStatus> statusList, | |
41 | - List<AlarmSeverity> severityList, boolean searchPropagatedAlarms) { | |
36 | + TbSubscriptionType type, BiConsumer<String, AlarmSubscriptionUpdate> updateConsumer, long ts) { | |
42 | 37 | super(serviceId, sessionId, subscriptionId, tenantId, entityId, type, updateConsumer); |
43 | 38 | this.ts = ts; |
44 | - this.typeList = typeList; | |
45 | - this.statusList = statusList; | |
46 | - this.severityList = severityList; | |
47 | - this.searchPropagatedAlarms = searchPropagatedAlarms; | |
48 | 39 | } |
49 | 40 | |
50 | 41 | @Override | ... | ... |
... | ... | @@ -19,12 +19,12 @@ import lombok.Builder; |
19 | 19 | import lombok.Getter; |
20 | 20 | import org.thingsboard.server.common.data.id.EntityId; |
21 | 21 | import org.thingsboard.server.common.data.id.TenantId; |
22 | -import org.thingsboard.server.service.telemetry.sub.TsSubscriptionUpdate; | |
22 | +import org.thingsboard.server.service.telemetry.sub.TelemetrySubscriptionUpdate; | |
23 | 23 | |
24 | 24 | import java.util.Map; |
25 | 25 | import java.util.function.BiConsumer; |
26 | 26 | |
27 | -public class TbAttributeSubscription extends TbSubscription<TsSubscriptionUpdate> { | |
27 | +public class TbAttributeSubscription extends TbSubscription<TelemetrySubscriptionUpdate> { | |
28 | 28 | |
29 | 29 | @Getter private final boolean allKeys; |
30 | 30 | @Getter private final Map<String, Long> keyStates; |
... | ... | @@ -32,7 +32,7 @@ public class TbAttributeSubscription extends TbSubscription<TsSubscriptionUpdate |
32 | 32 | |
33 | 33 | @Builder |
34 | 34 | public TbAttributeSubscription(String serviceId, String sessionId, int subscriptionId, TenantId tenantId, EntityId entityId, |
35 | - BiConsumer<String, TsSubscriptionUpdate> updateConsumer, | |
35 | + BiConsumer<String, TelemetrySubscriptionUpdate> updateConsumer, | |
36 | 36 | boolean allKeys, Map<String, Long> keyStates, TbAttributeSubscriptionScope scope) { |
37 | 37 | super(serviceId, sessionId, subscriptionId, tenantId, entityId, TbSubscriptionType.ATTRIBUTES, updateConsumer); |
38 | 38 | this.allKeys = allKeys; | ... | ... |
... | ... | @@ -5,7 +5,7 @@ |
5 | 5 | * you may not use this file except in compliance with the License. |
6 | 6 | * You may obtain a copy of the License at |
7 | 7 | * |
8 | - * http://www.apache.org/licenses/LICENSE-2.0 | |
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | |
9 | 9 | * |
10 | 10 | * Unless required by applicable law or agreed to in writing, software |
11 | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
... | ... | @@ -33,7 +33,7 @@ import org.thingsboard.server.service.telemetry.cmd.v2.EntityDataCmd; |
33 | 33 | import org.thingsboard.server.service.telemetry.cmd.v2.EntityDataUpdate; |
34 | 34 | import org.thingsboard.server.service.telemetry.cmd.v2.LatestValueCmd; |
35 | 35 | import org.thingsboard.server.service.telemetry.cmd.v2.TimeSeriesCmd; |
36 | -import org.thingsboard.server.service.telemetry.sub.TsSubscriptionUpdate; | |
36 | +import org.thingsboard.server.service.telemetry.sub.TelemetrySubscriptionUpdate; | |
37 | 37 | |
38 | 38 | import java.util.ArrayList; |
39 | 39 | import java.util.Arrays; |
... | ... | @@ -169,11 +169,11 @@ public class TbEntityDataSubCtx extends TbAbstractDataSubCtx<EntityDataQuery> { |
169 | 169 | return keyStates; |
170 | 170 | } |
171 | 171 | |
172 | - private void sendWsMsg(String sessionId, TsSubscriptionUpdate subscriptionUpdate, EntityKeyType keyType) { | |
172 | + private void sendWsMsg(String sessionId, TelemetrySubscriptionUpdate subscriptionUpdate, EntityKeyType keyType) { | |
173 | 173 | sendWsMsg(sessionId, subscriptionUpdate, keyType, true); |
174 | 174 | } |
175 | 175 | |
176 | - private void sendWsMsg(String sessionId, TsSubscriptionUpdate subscriptionUpdate, EntityKeyType keyType, boolean resultToLatestValues) { | |
176 | + private void sendWsMsg(String sessionId, TelemetrySubscriptionUpdate subscriptionUpdate, EntityKeyType keyType, boolean resultToLatestValues) { | |
177 | 177 | EntityId entityId = subToEntityIdMap.get(subscriptionUpdate.getSubscriptionId()); |
178 | 178 | if (entityId != null) { |
179 | 179 | log.trace("[{}][{}][{}][{}] Received subscription update: {}", sessionId, cmdId, subscriptionUpdate.getSubscriptionId(), keyType, subscriptionUpdate); |
... | ... | @@ -187,7 +187,7 @@ public class TbEntityDataSubCtx extends TbAbstractDataSubCtx<EntityDataQuery> { |
187 | 187 | } |
188 | 188 | } |
189 | 189 | |
190 | - private void sendLatestWsMsg(EntityId entityId, String sessionId, TsSubscriptionUpdate subscriptionUpdate, EntityKeyType keyType) { | |
190 | + private void sendLatestWsMsg(EntityId entityId, String sessionId, TelemetrySubscriptionUpdate subscriptionUpdate, EntityKeyType keyType) { | |
191 | 191 | Map<String, TsValue> latestUpdate = new HashMap<>(); |
192 | 192 | subscriptionUpdate.getData().forEach((k, v) -> { |
193 | 193 | Object[] data = (Object[]) v.get(0); |
... | ... | @@ -226,7 +226,7 @@ public class TbEntityDataSubCtx extends TbAbstractDataSubCtx<EntityDataQuery> { |
226 | 226 | } |
227 | 227 | } |
228 | 228 | |
229 | - private void sendTsWsMsg(EntityId entityId, String sessionId, TsSubscriptionUpdate subscriptionUpdate, EntityKeyType keyType) { | |
229 | + private void sendTsWsMsg(EntityId entityId, String sessionId, TelemetrySubscriptionUpdate subscriptionUpdate, EntityKeyType keyType) { | |
230 | 230 | Map<String, List<TsValue>> tsUpdate = new HashMap<>(); |
231 | 231 | subscriptionUpdate.getData().forEach((k, v) -> { |
232 | 232 | Object[] data = (Object[]) v.get(0); | ... | ... |
... | ... | @@ -18,7 +18,8 @@ package org.thingsboard.server.service.subscription; |
18 | 18 | import org.thingsboard.server.queue.discovery.ClusterTopologyChangeEvent; |
19 | 19 | import org.thingsboard.server.queue.discovery.PartitionChangeEvent; |
20 | 20 | import org.thingsboard.server.common.msg.queue.TbCallback; |
21 | -import org.thingsboard.server.service.telemetry.sub.TsSubscriptionUpdate; | |
21 | +import org.thingsboard.server.service.telemetry.sub.AlarmSubscriptionUpdate; | |
22 | +import org.thingsboard.server.service.telemetry.sub.TelemetrySubscriptionUpdate; | |
22 | 23 | |
23 | 24 | public interface TbLocalSubscriptionService { |
24 | 25 | |
... | ... | @@ -28,7 +29,9 @@ public interface TbLocalSubscriptionService { |
28 | 29 | |
29 | 30 | void cancelAllSessionSubscriptions(String sessionId); |
30 | 31 | |
31 | - void onSubscriptionUpdate(String sessionId, TsSubscriptionUpdate update, TbCallback callback); | |
32 | + void onSubscriptionUpdate(String sessionId, TelemetrySubscriptionUpdate update, TbCallback callback); | |
33 | + | |
34 | + void onSubscriptionUpdate(String sessionId, AlarmSubscriptionUpdate update, TbCallback callback); | |
32 | 35 | |
33 | 36 | void onApplicationEvent(PartitionChangeEvent event); |
34 | 37 | ... | ... |
... | ... | @@ -15,6 +15,7 @@ |
15 | 15 | */ |
16 | 16 | package org.thingsboard.server.service.subscription; |
17 | 17 | |
18 | +import org.thingsboard.server.common.data.alarm.Alarm; | |
18 | 19 | import org.thingsboard.server.common.data.id.EntityId; |
19 | 20 | import org.thingsboard.server.common.data.id.EntityIdFactory; |
20 | 21 | import org.thingsboard.server.common.data.id.TenantId; |
... | ... | @@ -44,7 +45,7 @@ import org.thingsboard.server.gen.transport.TransportProtos.TbTimeSeriesUpdatePr |
44 | 45 | import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg; |
45 | 46 | import org.thingsboard.server.gen.transport.TransportProtos.TsKvProto; |
46 | 47 | import org.thingsboard.server.service.telemetry.sub.SubscriptionErrorCode; |
47 | -import org.thingsboard.server.service.telemetry.sub.TsSubscriptionUpdate; | |
48 | +import org.thingsboard.server.service.telemetry.sub.TelemetrySubscriptionUpdate; | |
48 | 49 | |
49 | 50 | import java.util.ArrayList; |
50 | 51 | import java.util.HashMap; |
... | ... | @@ -137,9 +138,9 @@ public class TbSubscriptionUtils { |
137 | 138 | return builder.build(); |
138 | 139 | } |
139 | 140 | |
140 | - public static TsSubscriptionUpdate fromProto(TbSubscriptionUpdateProto proto) { | |
141 | + public static TelemetrySubscriptionUpdate fromProto(TbSubscriptionUpdateProto proto) { | |
141 | 142 | if (proto.getErrorCode() > 0) { |
142 | - return new TsSubscriptionUpdate(proto.getSubscriptionId(), SubscriptionErrorCode.forCode(proto.getErrorCode()), proto.getErrorMsg()); | |
143 | + return new TelemetrySubscriptionUpdate(proto.getSubscriptionId(), SubscriptionErrorCode.forCode(proto.getErrorCode()), proto.getErrorMsg()); | |
143 | 144 | } else { |
144 | 145 | Map<String, List<Object>> data = new TreeMap<>(); |
145 | 146 | proto.getDataList().forEach(v -> { |
... | ... | @@ -151,7 +152,7 @@ public class TbSubscriptionUtils { |
151 | 152 | values.add(value); |
152 | 153 | } |
153 | 154 | }); |
154 | - return new TsSubscriptionUpdate(proto.getSubscriptionId(), data); | |
155 | + return new TelemetrySubscriptionUpdate(proto.getSubscriptionId(), data); | |
155 | 156 | } |
156 | 157 | } |
157 | 158 | |
... | ... | @@ -261,4 +262,14 @@ public class TbSubscriptionUtils { |
261 | 262 | } |
262 | 263 | return entry; |
263 | 264 | } |
265 | + | |
266 | + public static ToCoreMsg toAlarmUpdateProto(TenantId tenantId, EntityId entityId, Alarm alarm) { | |
267 | +// TODO: 3.1 | |
268 | + throw new RuntimeException("Not implemented!"); | |
269 | + } | |
270 | + | |
271 | + public static ToCoreMsg toAlarmDeletedProto(TenantId tenantId, EntityId entityId, Alarm alarm) { | |
272 | +// TODO: 3.1 | |
273 | + throw new RuntimeException("Not implemented!"); | |
274 | + } | |
264 | 275 | } | ... | ... |
... | ... | @@ -19,12 +19,12 @@ import lombok.Builder; |
19 | 19 | import lombok.Getter; |
20 | 20 | import org.thingsboard.server.common.data.id.EntityId; |
21 | 21 | import org.thingsboard.server.common.data.id.TenantId; |
22 | -import org.thingsboard.server.service.telemetry.sub.TsSubscriptionUpdate; | |
22 | +import org.thingsboard.server.service.telemetry.sub.TelemetrySubscriptionUpdate; | |
23 | 23 | |
24 | 24 | import java.util.Map; |
25 | 25 | import java.util.function.BiConsumer; |
26 | 26 | |
27 | -public class TbTimeseriesSubscription extends TbSubscription<TsSubscriptionUpdate> { | |
27 | +public class TbTimeseriesSubscription extends TbSubscription<TelemetrySubscriptionUpdate> { | |
28 | 28 | |
29 | 29 | @Getter |
30 | 30 | private final boolean allKeys; |
... | ... | @@ -37,7 +37,7 @@ public class TbTimeseriesSubscription extends TbSubscription<TsSubscriptionUpdat |
37 | 37 | |
38 | 38 | @Builder |
39 | 39 | public TbTimeseriesSubscription(String serviceId, String sessionId, int subscriptionId, TenantId tenantId, EntityId entityId, |
40 | - BiConsumer<String, TsSubscriptionUpdate> updateConsumer, | |
40 | + BiConsumer<String, TelemetrySubscriptionUpdate> updateConsumer, | |
41 | 41 | boolean allKeys, Map<String, Long> keyStates, long startTime, long endTime) { |
42 | 42 | super(serviceId, sessionId, subscriptionId, tenantId, entityId, TbSubscriptionType.TIMESERIES, updateConsumer); |
43 | 43 | this.allKeys = allKeys; | ... | ... |
... | ... | @@ -5,7 +5,7 @@ |
5 | 5 | * you may not use this file except in compliance with the License. |
6 | 6 | * You may obtain a copy of the License at |
7 | 7 | * |
8 | - * http://www.apache.org/licenses/LICENSE-2.0 | |
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | |
9 | 9 | * |
10 | 10 | * Unless required by applicable law or agreed to in writing, software |
11 | 11 | * distributed under the License is distributed on an "AS IS" BASIS, | ... | ... |
... | ... | @@ -5,7 +5,7 @@ |
5 | 5 | * you may not use this file except in compliance with the License. |
6 | 6 | * You may obtain a copy of the License at |
7 | 7 | * |
8 | - * http://www.apache.org/licenses/LICENSE-2.0 | |
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | |
9 | 9 | * |
10 | 10 | * Unless required by applicable law or agreed to in writing, software |
11 | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
... | ... | @@ -20,6 +20,7 @@ import com.google.common.util.concurrent.FutureCallback; |
20 | 20 | import com.google.common.util.concurrent.Futures; |
21 | 21 | import com.google.common.util.concurrent.ListenableFuture; |
22 | 22 | import lombok.extern.slf4j.Slf4j; |
23 | +import org.checkerframework.checker.nullness.qual.Nullable; | |
23 | 24 | import org.springframework.beans.factory.annotation.Autowired; |
24 | 25 | import org.springframework.context.event.EventListener; |
25 | 26 | import org.springframework.stereotype.Service; |
... | ... | @@ -47,6 +48,7 @@ import org.thingsboard.server.common.data.query.AlarmDataPageLink; |
47 | 48 | import org.thingsboard.server.common.msg.queue.ServiceType; |
48 | 49 | import org.thingsboard.server.common.msg.queue.TbCallback; |
49 | 50 | import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; |
51 | +import org.thingsboard.server.dao.alarm.AlarmOperationResult; | |
50 | 52 | import org.thingsboard.server.dao.alarm.AlarmService; |
51 | 53 | import org.thingsboard.server.dao.attributes.AttributesService; |
52 | 54 | import org.thingsboard.server.dao.timeseries.TimeseriesService; |
... | ... | @@ -58,7 +60,6 @@ import org.thingsboard.server.service.subscription.SubscriptionManagerService; |
58 | 60 | import org.thingsboard.server.service.subscription.TbSubscriptionUtils; |
59 | 61 | import org.thingsboard.server.service.telemetry.sub.AlarmSubscriptionUpdate; |
60 | 62 | |
61 | -import javax.annotation.Nullable; | |
62 | 63 | import javax.annotation.PostConstruct; |
63 | 64 | import javax.annotation.PreDestroy; |
64 | 65 | import java.util.Collection; |
... | ... | @@ -99,46 +100,32 @@ public class DefaultAlarmSubscriptionService extends AbstractSubscriptionService |
99 | 100 | |
100 | 101 | @Override |
101 | 102 | public Alarm createOrUpdateAlarm(Alarm alarm) { |
102 | - //TODO 3.1: we also need a list of related entities if this is propagated alarm; | |
103 | - Alarm result = alarmService.createOrUpdateAlarm(alarm); | |
104 | - List<EntityId> relatedEntities = Collections.singletonList(result.getOriginator()); | |
105 | - pushAlarmToSubService(result, relatedEntities); | |
106 | - return result; | |
107 | - } | |
108 | - | |
109 | - private void pushAlarmToSubService(Alarm result, List<EntityId> entityIds) { | |
110 | - wsCallBackExecutor.submit(() -> { | |
111 | - TenantId tenantId = result.getTenantId(); | |
112 | - for (EntityId entityId : entityIds) { | |
113 | - TopicPartitionInfo tpi = partitionService.resolve(ServiceType.TB_CORE, tenantId, entityId); | |
114 | - if (currentPartitions.contains(tpi)) { | |
115 | - if (subscriptionManagerService.isPresent()) { | |
116 | - subscriptionManagerService.get().onAlarmUpdate(tenantId, entityId, result); | |
117 | - } else { | |
118 | - log.warn("Possible misconfiguration because subscriptionManagerService is null!"); | |
119 | - } | |
120 | - } else { | |
121 | - //TODO 3.1: cluster mode notification | |
122 | -// TransportProtos.ToCoreMsg toCoreMsg = TbSubscriptionUtils.toTimeseriesUpdateProto(tenantId, entityId, ts); | |
123 | -// clusterService.pushMsgToCore(tpi, entityId.getId(), toCoreMsg, null); | |
124 | - } | |
125 | - } | |
126 | - }); | |
103 | + AlarmOperationResult result = alarmService.createOrUpdateAlarm(alarm); | |
104 | + if (result.isSuccessful()) { | |
105 | + onAlarmUpdated(result); | |
106 | + } | |
107 | + return result.getAlarm(); | |
127 | 108 | } |
128 | 109 | |
129 | 110 | @Override |
130 | 111 | public Boolean deleteAlarm(TenantId tenantId, AlarmId alarmId) { |
131 | - return alarmService.deleteAlarm(tenantId, alarmId); | |
112 | + AlarmOperationResult result = alarmService.deleteAlarm(tenantId, alarmId); | |
113 | + onAlarmDeleted(result); | |
114 | + return result.isSuccessful(); | |
132 | 115 | } |
133 | 116 | |
134 | 117 | @Override |
135 | 118 | public ListenableFuture<Boolean> ackAlarm(TenantId tenantId, AlarmId alarmId, long ackTs) { |
136 | - return alarmService.ackAlarm(tenantId, alarmId, ackTs); | |
119 | + ListenableFuture<AlarmOperationResult> result = alarmService.ackAlarm(tenantId, alarmId, ackTs); | |
120 | + Futures.addCallback(result, new AlarmUpdateCallback(), wsCallBackExecutor); | |
121 | + return Futures.transform(result, AlarmOperationResult::isSuccessful, wsCallBackExecutor); | |
137 | 122 | } |
138 | 123 | |
139 | 124 | @Override |
140 | 125 | public ListenableFuture<Boolean> clearAlarm(TenantId tenantId, AlarmId alarmId, JsonNode details, long clearTs) { |
141 | - return alarmService.clearAlarm(tenantId, alarmId, details, clearTs); | |
126 | + ListenableFuture<AlarmOperationResult> result = alarmService.clearAlarm(tenantId, alarmId, details, clearTs); | |
127 | + Futures.addCallback(result, new AlarmUpdateCallback(), wsCallBackExecutor); | |
128 | + return Futures.transform(result, AlarmOperationResult::isSuccessful, wsCallBackExecutor); | |
142 | 129 | } |
143 | 130 | |
144 | 131 | @Override |
... | ... | @@ -147,9 +134,80 @@ public class DefaultAlarmSubscriptionService extends AbstractSubscriptionService |
147 | 134 | } |
148 | 135 | |
149 | 136 | @Override |
137 | + public ListenableFuture<AlarmInfo> findAlarmInfoByIdAsync(TenantId tenantId, AlarmId alarmId) { | |
138 | + return alarmService.findAlarmInfoByIdAsync(tenantId, alarmId); | |
139 | + } | |
140 | + | |
141 | + @Override | |
142 | + public ListenableFuture<PageData<AlarmInfo>> findAlarms(TenantId tenantId, AlarmQuery query) { | |
143 | + return alarmService.findAlarms(tenantId, query); | |
144 | + } | |
145 | + | |
146 | + @Override | |
147 | + public AlarmSeverity findHighestAlarmSeverity(TenantId tenantId, EntityId entityId, AlarmSearchStatus alarmSearchStatus, AlarmStatus alarmStatus) { | |
148 | + return alarmService.findHighestAlarmSeverity(tenantId, entityId, alarmSearchStatus, alarmStatus); | |
149 | + } | |
150 | + | |
151 | + @Override | |
152 | + public PageData<AlarmData> findAlarmDataByQueryForEntities(TenantId tenantId, CustomerId customerId, AlarmDataPageLink pageLink, Collection<EntityId> orderedEntityIds) { | |
153 | + return alarmService.findAlarmDataByQueryForEntities(tenantId, customerId, pageLink, orderedEntityIds); | |
154 | + } | |
155 | + | |
156 | + @Override | |
150 | 157 | public ListenableFuture<Alarm> findLatestByOriginatorAndType(TenantId tenantId, EntityId originator, String type) { |
151 | 158 | return alarmService.findLatestByOriginatorAndType(tenantId, originator, type); |
152 | 159 | } |
153 | 160 | |
161 | + private void onAlarmUpdated(AlarmOperationResult result) { | |
162 | + wsCallBackExecutor.submit(() -> { | |
163 | + Alarm alarm = result.getAlarm(); | |
164 | + TenantId tenantId = result.getAlarm().getTenantId(); | |
165 | + for (EntityId entityId : result.getPropagatedEntitiesList()) { | |
166 | + TopicPartitionInfo tpi = partitionService.resolve(ServiceType.TB_CORE, tenantId, entityId); | |
167 | + if (currentPartitions.contains(tpi)) { | |
168 | + if (subscriptionManagerService.isPresent()) { | |
169 | + subscriptionManagerService.get().onAlarmUpdate(tenantId, entityId, alarm); | |
170 | + } else { | |
171 | + log.warn("Possible misconfiguration because subscriptionManagerService is null!"); | |
172 | + } | |
173 | + } else { | |
174 | + TransportProtos.ToCoreMsg toCoreMsg = TbSubscriptionUtils.toAlarmUpdateProto(tenantId, entityId, alarm); | |
175 | + clusterService.pushMsgToCore(tpi, entityId.getId(), toCoreMsg, null); | |
176 | + } | |
177 | + } | |
178 | + }); | |
179 | + } | |
180 | + | |
181 | + private void onAlarmDeleted(AlarmOperationResult result) { | |
182 | + wsCallBackExecutor.submit(() -> { | |
183 | + Alarm alarm = result.getAlarm(); | |
184 | + TenantId tenantId = result.getAlarm().getTenantId(); | |
185 | + for (EntityId entityId : result.getPropagatedEntitiesList()) { | |
186 | + TopicPartitionInfo tpi = partitionService.resolve(ServiceType.TB_CORE, tenantId, entityId); | |
187 | + if (currentPartitions.contains(tpi)) { | |
188 | + if (subscriptionManagerService.isPresent()) { | |
189 | + subscriptionManagerService.get().onAlarmDeleted(tenantId, entityId, alarm); | |
190 | + } else { | |
191 | + log.warn("Possible misconfiguration because subscriptionManagerService is null!"); | |
192 | + } | |
193 | + } else { | |
194 | + TransportProtos.ToCoreMsg toCoreMsg = TbSubscriptionUtils.toAlarmDeletedProto(tenantId, entityId, alarm); | |
195 | + clusterService.pushMsgToCore(tpi, entityId.getId(), toCoreMsg, null); | |
196 | + } | |
197 | + } | |
198 | + }); | |
199 | + } | |
200 | + | |
201 | + private class AlarmUpdateCallback implements FutureCallback<AlarmOperationResult> { | |
202 | + @Override | |
203 | + public void onSuccess(@Nullable AlarmOperationResult result) { | |
204 | + onAlarmUpdated(result); | |
205 | + } | |
206 | + | |
207 | + @Override | |
208 | + public void onFailure(Throwable t) { | |
209 | + log.warn("Failed to update alarm", t); | |
210 | + } | |
211 | + } | |
154 | 212 | |
155 | 213 | } | ... | ... |
... | ... | @@ -5,7 +5,7 @@ |
5 | 5 | * you may not use this file except in compliance with the License. |
6 | 6 | * You may obtain a copy of the License at |
7 | 7 | * |
8 | - * http://www.apache.org/licenses/LICENSE-2.0 | |
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | |
9 | 9 | * |
10 | 10 | * Unless required by applicable law or agreed to in writing, software |
11 | 11 | * distributed under the License is distributed on an "AS IS" BASIS, | ... | ... |
... | ... | @@ -69,7 +69,7 @@ import org.thingsboard.server.service.telemetry.cmd.v2.EntityDataUnsubscribeCmd; |
69 | 69 | import org.thingsboard.server.service.telemetry.cmd.v2.EntityDataUpdate; |
70 | 70 | import org.thingsboard.server.service.telemetry.exception.UnauthorizedException; |
71 | 71 | import org.thingsboard.server.service.telemetry.sub.SubscriptionErrorCode; |
72 | -import org.thingsboard.server.service.telemetry.sub.TsSubscriptionUpdate; | |
72 | +import org.thingsboard.server.service.telemetry.sub.TelemetrySubscriptionUpdate; | |
73 | 73 | |
74 | 74 | import javax.annotation.Nullable; |
75 | 75 | import javax.annotation.PostConstruct; |
... | ... | @@ -219,7 +219,7 @@ public class DefaultTelemetryWebSocketService implements TelemetryWebSocketServi |
219 | 219 | } |
220 | 220 | } catch (IOException e) { |
221 | 221 | log.warn("Failed to decode subscription cmd: {}", e.getMessage(), e); |
222 | - TsSubscriptionUpdate update = new TsSubscriptionUpdate(UNKNOWN_SUBSCRIPTION_ID, SubscriptionErrorCode.INTERNAL_ERROR, SESSION_META_DATA_NOT_FOUND); | |
222 | + TelemetrySubscriptionUpdate update = new TelemetrySubscriptionUpdate(UNKNOWN_SUBSCRIPTION_ID, SubscriptionErrorCode.INTERNAL_ERROR, SESSION_META_DATA_NOT_FOUND); | |
223 | 223 | sendWsMsg(sessionRef, update); |
224 | 224 | } |
225 | 225 | } |
... | ... | @@ -254,7 +254,7 @@ public class DefaultTelemetryWebSocketService implements TelemetryWebSocketServi |
254 | 254 | } |
255 | 255 | |
256 | 256 | @Override |
257 | - public void sendWsMsg(String sessionId, TsSubscriptionUpdate update) { | |
257 | + public void sendWsMsg(String sessionId, TelemetrySubscriptionUpdate update) { | |
258 | 258 | sendWsMsg(sessionId, update.getSubscriptionId(), update); |
259 | 259 | } |
260 | 260 | |
... | ... | @@ -397,7 +397,7 @@ public class DefaultTelemetryWebSocketService implements TelemetryWebSocketServi |
397 | 397 | @Override |
398 | 398 | public void onSuccess(List<AttributeKvEntry> data) { |
399 | 399 | List<TsKvEntry> attributesData = data.stream().map(d -> new BasicTsKvEntry(d.getLastUpdateTs(), d)).collect(Collectors.toList()); |
400 | - sendWsMsg(sessionRef, new TsSubscriptionUpdate(cmd.getCmdId(), attributesData)); | |
400 | + sendWsMsg(sessionRef, new TelemetrySubscriptionUpdate(cmd.getCmdId(), attributesData)); | |
401 | 401 | |
402 | 402 | Map<String, Long> subState = new HashMap<>(keys.size()); |
403 | 403 | keys.forEach(key -> subState.put(key, 0L)); |
... | ... | @@ -422,12 +422,12 @@ public class DefaultTelemetryWebSocketService implements TelemetryWebSocketServi |
422 | 422 | @Override |
423 | 423 | public void onFailure(Throwable e) { |
424 | 424 | log.error(FAILED_TO_FETCH_ATTRIBUTES, e); |
425 | - TsSubscriptionUpdate update; | |
425 | + TelemetrySubscriptionUpdate update; | |
426 | 426 | if (e instanceof UnauthorizedException) { |
427 | - update = new TsSubscriptionUpdate(cmd.getCmdId(), SubscriptionErrorCode.UNAUTHORIZED, | |
427 | + update = new TelemetrySubscriptionUpdate(cmd.getCmdId(), SubscriptionErrorCode.UNAUTHORIZED, | |
428 | 428 | SubscriptionErrorCode.UNAUTHORIZED.getDefaultMsg()); |
429 | 429 | } else { |
430 | - update = new TsSubscriptionUpdate(cmd.getCmdId(), SubscriptionErrorCode.INTERNAL_ERROR, | |
430 | + update = new TelemetrySubscriptionUpdate(cmd.getCmdId(), SubscriptionErrorCode.INTERNAL_ERROR, | |
431 | 431 | FAILED_TO_FETCH_ATTRIBUTES); |
432 | 432 | } |
433 | 433 | sendWsMsg(sessionRef, update); |
... | ... | @@ -446,19 +446,19 @@ public class DefaultTelemetryWebSocketService implements TelemetryWebSocketServi |
446 | 446 | WsSessionMetaData sessionMD = wsSessionsMap.get(sessionId); |
447 | 447 | if (sessionMD == null) { |
448 | 448 | log.warn("[{}] Session meta data not found. ", sessionId); |
449 | - TsSubscriptionUpdate update = new TsSubscriptionUpdate(cmd.getCmdId(), SubscriptionErrorCode.INTERNAL_ERROR, | |
449 | + TelemetrySubscriptionUpdate update = new TelemetrySubscriptionUpdate(cmd.getCmdId(), SubscriptionErrorCode.INTERNAL_ERROR, | |
450 | 450 | SESSION_META_DATA_NOT_FOUND); |
451 | 451 | sendWsMsg(sessionRef, update); |
452 | 452 | return; |
453 | 453 | } |
454 | 454 | if (cmd.getEntityId() == null || cmd.getEntityId().isEmpty() || cmd.getEntityType() == null || cmd.getEntityType().isEmpty()) { |
455 | - TsSubscriptionUpdate update = new TsSubscriptionUpdate(cmd.getCmdId(), SubscriptionErrorCode.BAD_REQUEST, | |
455 | + TelemetrySubscriptionUpdate update = new TelemetrySubscriptionUpdate(cmd.getCmdId(), SubscriptionErrorCode.BAD_REQUEST, | |
456 | 456 | "Device id is empty!"); |
457 | 457 | sendWsMsg(sessionRef, update); |
458 | 458 | return; |
459 | 459 | } |
460 | 460 | if (cmd.getKeys() == null || cmd.getKeys().isEmpty()) { |
461 | - TsSubscriptionUpdate update = new TsSubscriptionUpdate(cmd.getCmdId(), SubscriptionErrorCode.BAD_REQUEST, | |
461 | + TelemetrySubscriptionUpdate update = new TelemetrySubscriptionUpdate(cmd.getCmdId(), SubscriptionErrorCode.BAD_REQUEST, | |
462 | 462 | "Keys are empty!"); |
463 | 463 | sendWsMsg(sessionRef, update); |
464 | 464 | return; |
... | ... | @@ -471,17 +471,17 @@ public class DefaultTelemetryWebSocketService implements TelemetryWebSocketServi |
471 | 471 | FutureCallback<List<TsKvEntry>> callback = new FutureCallback<List<TsKvEntry>>() { |
472 | 472 | @Override |
473 | 473 | public void onSuccess(List<TsKvEntry> data) { |
474 | - sendWsMsg(sessionRef, new TsSubscriptionUpdate(cmd.getCmdId(), data)); | |
474 | + sendWsMsg(sessionRef, new TelemetrySubscriptionUpdate(cmd.getCmdId(), data)); | |
475 | 475 | } |
476 | 476 | |
477 | 477 | @Override |
478 | 478 | public void onFailure(Throwable e) { |
479 | - TsSubscriptionUpdate update; | |
479 | + TelemetrySubscriptionUpdate update; | |
480 | 480 | if (UnauthorizedException.class.isInstance(e)) { |
481 | - update = new TsSubscriptionUpdate(cmd.getCmdId(), SubscriptionErrorCode.UNAUTHORIZED, | |
481 | + update = new TelemetrySubscriptionUpdate(cmd.getCmdId(), SubscriptionErrorCode.UNAUTHORIZED, | |
482 | 482 | SubscriptionErrorCode.UNAUTHORIZED.getDefaultMsg()); |
483 | 483 | } else { |
484 | - update = new TsSubscriptionUpdate(cmd.getCmdId(), SubscriptionErrorCode.INTERNAL_ERROR, | |
484 | + update = new TelemetrySubscriptionUpdate(cmd.getCmdId(), SubscriptionErrorCode.INTERNAL_ERROR, | |
485 | 485 | FAILED_TO_FETCH_DATA); |
486 | 486 | } |
487 | 487 | sendWsMsg(sessionRef, update); |
... | ... | @@ -497,7 +497,7 @@ public class DefaultTelemetryWebSocketService implements TelemetryWebSocketServi |
497 | 497 | @Override |
498 | 498 | public void onSuccess(List<AttributeKvEntry> data) { |
499 | 499 | List<TsKvEntry> attributesData = data.stream().map(d -> new BasicTsKvEntry(d.getLastUpdateTs(), d)).collect(Collectors.toList()); |
500 | - sendWsMsg(sessionRef, new TsSubscriptionUpdate(cmd.getCmdId(), attributesData)); | |
500 | + sendWsMsg(sessionRef, new TelemetrySubscriptionUpdate(cmd.getCmdId(), attributesData)); | |
501 | 501 | |
502 | 502 | Map<String, Long> subState = new HashMap<>(attributesData.size()); |
503 | 503 | attributesData.forEach(v -> subState.put(v.getKey(), v.getTs())); |
... | ... | @@ -520,7 +520,7 @@ public class DefaultTelemetryWebSocketService implements TelemetryWebSocketServi |
520 | 520 | @Override |
521 | 521 | public void onFailure(Throwable e) { |
522 | 522 | log.error(FAILED_TO_FETCH_ATTRIBUTES, e); |
523 | - TsSubscriptionUpdate update = new TsSubscriptionUpdate(cmd.getCmdId(), SubscriptionErrorCode.INTERNAL_ERROR, | |
523 | + TelemetrySubscriptionUpdate update = new TelemetrySubscriptionUpdate(cmd.getCmdId(), SubscriptionErrorCode.INTERNAL_ERROR, | |
524 | 524 | FAILED_TO_FETCH_ATTRIBUTES); |
525 | 525 | sendWsMsg(sessionRef, update); |
526 | 526 | } |
... | ... | @@ -583,7 +583,7 @@ public class DefaultTelemetryWebSocketService implements TelemetryWebSocketServi |
583 | 583 | FutureCallback<List<TsKvEntry>> callback = new FutureCallback<List<TsKvEntry>>() { |
584 | 584 | @Override |
585 | 585 | public void onSuccess(List<TsKvEntry> data) { |
586 | - sendWsMsg(sessionRef, new TsSubscriptionUpdate(cmd.getCmdId(), data)); | |
586 | + sendWsMsg(sessionRef, new TelemetrySubscriptionUpdate(cmd.getCmdId(), data)); | |
587 | 587 | Map<String, Long> subState = new HashMap<>(data.size()); |
588 | 588 | data.forEach(v -> subState.put(v.getKey(), v.getTs())); |
589 | 589 | |
... | ... | @@ -601,12 +601,12 @@ public class DefaultTelemetryWebSocketService implements TelemetryWebSocketServi |
601 | 601 | |
602 | 602 | @Override |
603 | 603 | public void onFailure(Throwable e) { |
604 | - TsSubscriptionUpdate update; | |
604 | + TelemetrySubscriptionUpdate update; | |
605 | 605 | if (UnauthorizedException.class.isInstance(e)) { |
606 | - update = new TsSubscriptionUpdate(cmd.getCmdId(), SubscriptionErrorCode.UNAUTHORIZED, | |
606 | + update = new TelemetrySubscriptionUpdate(cmd.getCmdId(), SubscriptionErrorCode.UNAUTHORIZED, | |
607 | 607 | SubscriptionErrorCode.UNAUTHORIZED.getDefaultMsg()); |
608 | 608 | } else { |
609 | - update = new TsSubscriptionUpdate(cmd.getCmdId(), SubscriptionErrorCode.INTERNAL_ERROR, | |
609 | + update = new TelemetrySubscriptionUpdate(cmd.getCmdId(), SubscriptionErrorCode.INTERNAL_ERROR, | |
610 | 610 | FAILED_TO_FETCH_DATA); |
611 | 611 | } |
612 | 612 | sendWsMsg(sessionRef, update); |
... | ... | @@ -620,7 +620,7 @@ public class DefaultTelemetryWebSocketService implements TelemetryWebSocketServi |
620 | 620 | return new FutureCallback<List<TsKvEntry>>() { |
621 | 621 | @Override |
622 | 622 | public void onSuccess(List<TsKvEntry> data) { |
623 | - sendWsMsg(sessionRef, new TsSubscriptionUpdate(cmd.getCmdId(), data)); | |
623 | + sendWsMsg(sessionRef, new TelemetrySubscriptionUpdate(cmd.getCmdId(), data)); | |
624 | 624 | Map<String, Long> subState = new HashMap<>(keys.size()); |
625 | 625 | keys.forEach(key -> subState.put(key, startTs)); |
626 | 626 | data.forEach(v -> subState.put(v.getKey(), v.getTs())); |
... | ... | @@ -644,7 +644,7 @@ public class DefaultTelemetryWebSocketService implements TelemetryWebSocketServi |
644 | 644 | } else { |
645 | 645 | log.info(FAILED_TO_FETCH_DATA, e); |
646 | 646 | } |
647 | - TsSubscriptionUpdate update = new TsSubscriptionUpdate(cmd.getCmdId(), SubscriptionErrorCode.INTERNAL_ERROR, | |
647 | + TelemetrySubscriptionUpdate update = new TelemetrySubscriptionUpdate(cmd.getCmdId(), SubscriptionErrorCode.INTERNAL_ERROR, | |
648 | 648 | FAILED_TO_FETCH_DATA); |
649 | 649 | sendWsMsg(sessionRef, update); |
650 | 650 | } |
... | ... | @@ -661,12 +661,12 @@ public class DefaultTelemetryWebSocketService implements TelemetryWebSocketServi |
661 | 661 | |
662 | 662 | private boolean validateSubscriptionCmd(TelemetryWebSocketSessionRef sessionRef, EntityDataCmd cmd) { |
663 | 663 | if (cmd.getCmdId() < 0) { |
664 | - TsSubscriptionUpdate update = new TsSubscriptionUpdate(cmd.getCmdId(), SubscriptionErrorCode.BAD_REQUEST, | |
664 | + TelemetrySubscriptionUpdate update = new TelemetrySubscriptionUpdate(cmd.getCmdId(), SubscriptionErrorCode.BAD_REQUEST, | |
665 | 665 | "Cmd id is negative value!"); |
666 | 666 | sendWsMsg(sessionRef, update); |
667 | 667 | return false; |
668 | 668 | } else if (cmd.getQuery() == null && cmd.getLatestCmd() == null && cmd.getHistoryCmd() == null && cmd.getTsCmd() == null) { |
669 | - TsSubscriptionUpdate update = new TsSubscriptionUpdate(cmd.getCmdId(), SubscriptionErrorCode.BAD_REQUEST, | |
669 | + TelemetrySubscriptionUpdate update = new TelemetrySubscriptionUpdate(cmd.getCmdId(), SubscriptionErrorCode.BAD_REQUEST, | |
670 | 670 | "Query is empty!"); |
671 | 671 | sendWsMsg(sessionRef, update); |
672 | 672 | return false; |
... | ... | @@ -676,12 +676,12 @@ public class DefaultTelemetryWebSocketService implements TelemetryWebSocketServi |
676 | 676 | |
677 | 677 | private boolean validateSubscriptionCmd(TelemetryWebSocketSessionRef sessionRef, AlarmDataCmd cmd) { |
678 | 678 | if (cmd.getCmdId() < 0) { |
679 | - TsSubscriptionUpdate update = new TsSubscriptionUpdate(cmd.getCmdId(), SubscriptionErrorCode.BAD_REQUEST, | |
679 | + TelemetrySubscriptionUpdate update = new TelemetrySubscriptionUpdate(cmd.getCmdId(), SubscriptionErrorCode.BAD_REQUEST, | |
680 | 680 | "Cmd id is negative value!"); |
681 | 681 | sendWsMsg(sessionRef, update); |
682 | 682 | return false; |
683 | 683 | } else if (cmd.getQuery() == null) { |
684 | - TsSubscriptionUpdate update = new TsSubscriptionUpdate(cmd.getCmdId(), SubscriptionErrorCode.BAD_REQUEST, | |
684 | + TelemetrySubscriptionUpdate update = new TelemetrySubscriptionUpdate(cmd.getCmdId(), SubscriptionErrorCode.BAD_REQUEST, | |
685 | 685 | "Query is empty!"); |
686 | 686 | sendWsMsg(sessionRef, update); |
687 | 687 | return false; |
... | ... | @@ -691,7 +691,7 @@ public class DefaultTelemetryWebSocketService implements TelemetryWebSocketServi |
691 | 691 | |
692 | 692 | private boolean validateSubscriptionCmd(TelemetryWebSocketSessionRef sessionRef, SubscriptionCmd cmd) { |
693 | 693 | if (cmd.getEntityId() == null || cmd.getEntityId().isEmpty()) { |
694 | - TsSubscriptionUpdate update = new TsSubscriptionUpdate(cmd.getCmdId(), SubscriptionErrorCode.BAD_REQUEST, | |
694 | + TelemetrySubscriptionUpdate update = new TelemetrySubscriptionUpdate(cmd.getCmdId(), SubscriptionErrorCode.BAD_REQUEST, | |
695 | 695 | "Device id is empty!"); |
696 | 696 | sendWsMsg(sessionRef, update); |
697 | 697 | return false; |
... | ... | @@ -707,7 +707,7 @@ public class DefaultTelemetryWebSocketService implements TelemetryWebSocketServi |
707 | 707 | WsSessionMetaData sessionMD = wsSessionsMap.get(sessionId); |
708 | 708 | if (sessionMD == null) { |
709 | 709 | log.warn("[{}] Session meta data not found. ", sessionId); |
710 | - TsSubscriptionUpdate update = new TsSubscriptionUpdate(cmdId, SubscriptionErrorCode.INTERNAL_ERROR, | |
710 | + TelemetrySubscriptionUpdate update = new TelemetrySubscriptionUpdate(cmdId, SubscriptionErrorCode.INTERNAL_ERROR, | |
711 | 711 | SESSION_META_DATA_NOT_FOUND); |
712 | 712 | sendWsMsg(sessionRef, update); |
713 | 713 | return false; |
... | ... | @@ -720,7 +720,7 @@ public class DefaultTelemetryWebSocketService implements TelemetryWebSocketServi |
720 | 720 | sendWsMsg(sessionRef, update.getCmdId(), update); |
721 | 721 | } |
722 | 722 | |
723 | - private void sendWsMsg(TelemetryWebSocketSessionRef sessionRef, TsSubscriptionUpdate update) { | |
723 | + private void sendWsMsg(TelemetryWebSocketSessionRef sessionRef, TelemetrySubscriptionUpdate update) { | |
724 | 724 | sendWsMsg(sessionRef, update.getSubscriptionId(), update); |
725 | 725 | } |
726 | 726 | ... | ... |
... | ... | @@ -16,7 +16,7 @@ |
16 | 16 | package org.thingsboard.server.service.telemetry; |
17 | 17 | |
18 | 18 | import org.thingsboard.server.service.telemetry.cmd.v2.DataUpdate; |
19 | -import org.thingsboard.server.service.telemetry.sub.TsSubscriptionUpdate; | |
19 | +import org.thingsboard.server.service.telemetry.sub.TelemetrySubscriptionUpdate; | |
20 | 20 | |
21 | 21 | /** |
22 | 22 | * Created by ashvayka on 27.03.18. |
... | ... | @@ -27,7 +27,7 @@ public interface TelemetryWebSocketService { |
27 | 27 | |
28 | 28 | void handleWebSocketMsg(TelemetryWebSocketSessionRef sessionRef, String msg); |
29 | 29 | |
30 | - void sendWsMsg(String sessionId, TsSubscriptionUpdate update); | |
30 | + void sendWsMsg(String sessionId, TelemetrySubscriptionUpdate update); | |
31 | 31 | |
32 | 32 | void sendWsMsg(String sessionId, DataUpdate update); |
33 | 33 | ... | ... |
... | ... | @@ -15,6 +15,7 @@ |
15 | 15 | */ |
16 | 16 | package org.thingsboard.server.service.telemetry.sub; |
17 | 17 | |
18 | +import lombok.Getter; | |
18 | 19 | import org.thingsboard.server.common.data.alarm.Alarm; |
19 | 20 | import org.thingsboard.server.common.data.kv.TsKvEntry; |
20 | 21 | import org.thingsboard.server.common.data.query.AlarmData; |
... | ... | @@ -28,15 +29,26 @@ import java.util.stream.Collectors; |
28 | 29 | |
29 | 30 | public class AlarmSubscriptionUpdate { |
30 | 31 | |
32 | + @Getter | |
31 | 33 | private int subscriptionId; |
34 | + @Getter | |
32 | 35 | private int errorCode; |
36 | + @Getter | |
33 | 37 | private String errorMsg; |
38 | + @Getter | |
34 | 39 | private Alarm alarm; |
40 | + @Getter | |
41 | + private boolean alarmDeleted; | |
35 | 42 | |
36 | 43 | public AlarmSubscriptionUpdate(int subscriptionId, Alarm alarm) { |
44 | + this(subscriptionId, alarm, false); | |
45 | + } | |
46 | + | |
47 | + public AlarmSubscriptionUpdate(int subscriptionId, Alarm alarm, boolean alarmDeleted) { | |
37 | 48 | super(); |
38 | 49 | this.subscriptionId = subscriptionId; |
39 | 50 | this.alarm = alarm; |
51 | + this.alarmDeleted = alarmDeleted; | |
40 | 52 | } |
41 | 53 | |
42 | 54 | public AlarmSubscriptionUpdate(int subscriptionId, SubscriptionErrorCode errorCode) { |
... | ... | @@ -50,19 +62,6 @@ public class AlarmSubscriptionUpdate { |
50 | 62 | this.errorMsg = errorMsg != null ? errorMsg : errorCode.getDefaultMsg(); |
51 | 63 | } |
52 | 64 | |
53 | - public int getSubscriptionId() { | |
54 | - return subscriptionId; | |
55 | - } | |
56 | - | |
57 | - | |
58 | - public int getErrorCode() { | |
59 | - return errorCode; | |
60 | - } | |
61 | - | |
62 | - public String getErrorMsg() { | |
63 | - return errorMsg; | |
64 | - } | |
65 | - | |
66 | 65 | @Override |
67 | 66 | public String toString() { |
68 | 67 | return "AlarmUpdate [subscriptionId=" + subscriptionId + ", errorCode=" + errorCode + ", errorMsg=" + errorMsg + ", alarm=" | ... | ... |
application/src/main/java/org/thingsboard/server/service/telemetry/sub/TelemetrySubscriptionUpdate.java
renamed from
application/src/main/java/org/thingsboard/server/service/telemetry/sub/TsSubscriptionUpdate.java
... | ... | @@ -24,14 +24,14 @@ import java.util.Map; |
24 | 24 | import java.util.TreeMap; |
25 | 25 | import java.util.stream.Collectors; |
26 | 26 | |
27 | -public class TsSubscriptionUpdate { | |
27 | +public class TelemetrySubscriptionUpdate { | |
28 | 28 | |
29 | 29 | private int subscriptionId; |
30 | 30 | private int errorCode; |
31 | 31 | private String errorMsg; |
32 | 32 | private Map<String, List<Object>> data; |
33 | 33 | |
34 | - public TsSubscriptionUpdate(int subscriptionId, List<TsKvEntry> data) { | |
34 | + public TelemetrySubscriptionUpdate(int subscriptionId, List<TsKvEntry> data) { | |
35 | 35 | super(); |
36 | 36 | this.subscriptionId = subscriptionId; |
37 | 37 | this.data = new TreeMap<>(); |
... | ... | @@ -46,17 +46,17 @@ public class TsSubscriptionUpdate { |
46 | 46 | } |
47 | 47 | } |
48 | 48 | |
49 | - public TsSubscriptionUpdate(int subscriptionId, Map<String, List<Object>> data) { | |
49 | + public TelemetrySubscriptionUpdate(int subscriptionId, Map<String, List<Object>> data) { | |
50 | 50 | super(); |
51 | 51 | this.subscriptionId = subscriptionId; |
52 | 52 | this.data = data; |
53 | 53 | } |
54 | 54 | |
55 | - public TsSubscriptionUpdate(int subscriptionId, SubscriptionErrorCode errorCode) { | |
55 | + public TelemetrySubscriptionUpdate(int subscriptionId, SubscriptionErrorCode errorCode) { | |
56 | 56 | this(subscriptionId, errorCode, null); |
57 | 57 | } |
58 | 58 | |
59 | - public TsSubscriptionUpdate(int subscriptionId, SubscriptionErrorCode errorCode, String errorMsg) { | |
59 | + public TelemetrySubscriptionUpdate(int subscriptionId, SubscriptionErrorCode errorCode, String errorMsg) { | |
60 | 60 | super(); |
61 | 61 | this.subscriptionId = subscriptionId; |
62 | 62 | this.errorCode = errorCode.getCode(); | ... | ... |
1 | +/** | |
2 | + * Copyright © 2016-2020 The Thingsboard Authors | |
3 | + * | |
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | |
5 | + * you may not use this file except in compliance with the License. | |
6 | + * You may obtain a copy of the License at | |
7 | + * | |
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | |
9 | + * | |
10 | + * Unless required by applicable law or agreed to in writing, software | |
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | |
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 | + * See the License for the specific language governing permissions and | |
14 | + * limitations under the License. | |
15 | + */ | |
1 | 16 | package org.thingsboard.server.dao.alarm; |
2 | 17 | |
18 | +import lombok.AllArgsConstructor; | |
3 | 19 | import lombok.Data; |
4 | 20 | import org.thingsboard.server.common.data.alarm.Alarm; |
5 | 21 | import org.thingsboard.server.common.data.id.EntityId; |
6 | 22 | |
23 | +import java.util.Collections; | |
7 | 24 | import java.util.List; |
8 | 25 | |
9 | 26 | @Data |
... | ... | @@ -11,4 +28,16 @@ public class AlarmOperationResult { |
11 | 28 | private final Alarm alarm; |
12 | 29 | private final boolean successful; |
13 | 30 | private final List<EntityId> propagatedEntitiesList; |
31 | + | |
32 | + public AlarmOperationResult(Alarm alarm, boolean successful) { | |
33 | + this.alarm = alarm; | |
34 | + this.successful = successful; | |
35 | + this.propagatedEntitiesList = Collections.emptyList(); | |
36 | + } | |
37 | + | |
38 | + public AlarmOperationResult(Alarm alarm, boolean successful, List<EntityId> propagatedEntitiesList) { | |
39 | + this.alarm = alarm; | |
40 | + this.successful = successful; | |
41 | + this.propagatedEntitiesList = propagatedEntitiesList; | |
42 | + } | |
14 | 43 | } | ... | ... |
... | ... | @@ -5,7 +5,7 @@ |
5 | 5 | * you may not use this file except in compliance with the License. |
6 | 6 | * You may obtain a copy of the License at |
7 | 7 | * |
8 | - * http://www.apache.org/licenses/LICENSE-2.0 | |
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | |
9 | 9 | * |
10 | 10 | * Unless required by applicable law or agreed to in writing, software |
11 | 11 | * distributed under the License is distributed on an "AS IS" BASIS, | ... | ... |
... | ... | @@ -5,7 +5,7 @@ |
5 | 5 | * you may not use this file except in compliance with the License. |
6 | 6 | * You may obtain a copy of the License at |
7 | 7 | * |
8 | - * http://www.apache.org/licenses/LICENSE-2.0 | |
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | |
9 | 9 | * |
10 | 10 | * Unless required by applicable law or agreed to in writing, software |
11 | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
... | ... | @@ -140,15 +140,17 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ |
140 | 140 | } |
141 | 141 | |
142 | 142 | @Override |
143 | - public Boolean deleteAlarm(TenantId tenantId, AlarmId alarmId) { | |
143 | + public AlarmOperationResult deleteAlarm(TenantId tenantId, AlarmId alarmId) { | |
144 | 144 | try { |
145 | 145 | log.debug("Deleting Alarm Id: {}", alarmId); |
146 | 146 | Alarm alarm = alarmDao.findAlarmByIdAsync(tenantId, alarmId.getId()).get(); |
147 | 147 | if (alarm == null) { |
148 | - return false; | |
148 | + return new AlarmOperationResult(alarm, false); | |
149 | 149 | } |
150 | + AlarmOperationResult result = new AlarmOperationResult(alarm, true, new ArrayList<>(getPropagationEntityIds(alarm))); | |
150 | 151 | deleteEntityRelations(tenantId, alarm.getId()); |
151 | - return alarmDao.deleteAlarm(tenantId, alarm); | |
152 | + alarmDao.deleteAlarm(tenantId, alarm); | |
153 | + return result; | |
152 | 154 | } catch (ExecutionException | InterruptedException e) { |
153 | 155 | throw new RuntimeException(e); |
154 | 156 | } |
... | ... | @@ -158,7 +160,7 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ |
158 | 160 | log.debug("New Alarm : {}", alarm); |
159 | 161 | Alarm saved = alarmDao.save(alarm.getTenantId(), alarm); |
160 | 162 | List<EntityId> propagatedEntitiesList = createAlarmRelations(saved); |
161 | - return new AlarmOperationResult(alarm, true, propagatedEntitiesList); | |
163 | + return new AlarmOperationResult(saved, true, propagatedEntitiesList); | |
162 | 164 | } |
163 | 165 | |
164 | 166 | private List<EntityId> createAlarmRelations(Alarm alarm) throws InterruptedException, ExecutionException { |
... | ... | @@ -168,13 +170,13 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ |
168 | 170 | propagatedEntitiesList = new ArrayList<>(parentEntities.size() + 1); |
169 | 171 | for (EntityId parentId : parentEntities) { |
170 | 172 | propagatedEntitiesList.add(parentId); |
171 | - createAlarmRelation(alarm.getTenantId(), parentId, alarm.getId(), alarm.getStatus(), true); | |
173 | + createAlarmRelation(alarm.getTenantId(), parentId, alarm.getId()); | |
172 | 174 | } |
173 | 175 | propagatedEntitiesList.add(alarm.getOriginator()); |
174 | 176 | } else { |
175 | 177 | propagatedEntitiesList = Collections.singletonList(alarm.getOriginator()); |
176 | 178 | } |
177 | - createAlarmRelation(alarm.getTenantId(), alarm.getOriginator(), alarm.getId(), alarm.getStatus(), true); | |
179 | + createAlarmRelation(alarm.getTenantId(), alarm.getOriginator(), alarm.getId()); | |
178 | 180 | return propagatedEntitiesList; |
179 | 181 | } |
180 | 182 | |
... | ... | @@ -225,34 +227,33 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ |
225 | 227 | } |
226 | 228 | |
227 | 229 | @Override |
228 | - public ListenableFuture<Boolean> ackAlarm(TenantId tenantId, AlarmId alarmId, long ackTime) { | |
229 | - return getAndUpdate(tenantId, alarmId, new Function<Alarm, Boolean>() { | |
230 | + public ListenableFuture<AlarmOperationResult> ackAlarm(TenantId tenantId, AlarmId alarmId, long ackTime) { | |
231 | + return getAndUpdate(tenantId, alarmId, new Function<Alarm, AlarmOperationResult>() { | |
230 | 232 | @Nullable |
231 | 233 | @Override |
232 | - public Boolean apply(@Nullable Alarm alarm) { | |
234 | + public AlarmOperationResult apply(@Nullable Alarm alarm) { | |
233 | 235 | if (alarm == null || alarm.getStatus().isAck()) { |
234 | - return false; | |
236 | + return new AlarmOperationResult(alarm, false); | |
235 | 237 | } else { |
236 | 238 | AlarmStatus oldStatus = alarm.getStatus(); |
237 | 239 | AlarmStatus newStatus = oldStatus.isCleared() ? AlarmStatus.CLEARED_ACK : AlarmStatus.ACTIVE_ACK; |
238 | 240 | alarm.setStatus(newStatus); |
239 | 241 | alarm.setAckTs(ackTime); |
240 | - alarmDao.save(alarm.getTenantId(), alarm); | |
241 | - updateRelations(alarm, oldStatus, newStatus); | |
242 | - return true; | |
242 | + alarm = alarmDao.save(alarm.getTenantId(), alarm); | |
243 | + return new AlarmOperationResult(alarm, true, new ArrayList<>(getPropagationEntityIds(alarm))); | |
243 | 244 | } |
244 | 245 | } |
245 | 246 | }); |
246 | 247 | } |
247 | 248 | |
248 | 249 | @Override |
249 | - public ListenableFuture<Boolean> clearAlarm(TenantId tenantId, AlarmId alarmId, JsonNode details, long clearTime) { | |
250 | - return getAndUpdate(tenantId, alarmId, new Function<Alarm, Boolean>() { | |
250 | + public ListenableFuture<AlarmOperationResult> clearAlarm(TenantId tenantId, AlarmId alarmId, JsonNode details, long clearTime) { | |
251 | + return getAndUpdate(tenantId, alarmId, new Function<Alarm, AlarmOperationResult>() { | |
251 | 252 | @Nullable |
252 | 253 | @Override |
253 | - public Boolean apply(@Nullable Alarm alarm) { | |
254 | + public AlarmOperationResult apply(@Nullable Alarm alarm) { | |
254 | 255 | if (alarm == null || alarm.getStatus().isCleared()) { |
255 | - return false; | |
256 | + return new AlarmOperationResult(alarm, false); | |
256 | 257 | } else { |
257 | 258 | AlarmStatus oldStatus = alarm.getStatus(); |
258 | 259 | AlarmStatus newStatus = oldStatus.isAck() ? AlarmStatus.CLEARED_ACK : AlarmStatus.CLEARED_UNACK; |
... | ... | @@ -261,9 +262,8 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ |
261 | 262 | if (details != null) { |
262 | 263 | alarm.setDetails(details); |
263 | 264 | } |
264 | - alarmDao.save(alarm.getTenantId(), alarm); | |
265 | - updateRelations(alarm, oldStatus, newStatus); | |
266 | - return true; | |
265 | + alarm = alarmDao.save(alarm.getTenantId(), alarm); | |
266 | + return new AlarmOperationResult(alarm, true, new ArrayList<>(getPropagationEntityIds(alarm))); | |
267 | 267 | } |
268 | 268 | } |
269 | 269 | }); | ... | ... |
... | ... | @@ -102,15 +102,17 @@ public class JpaAlarmDao extends JpaAbstractDao<AlarmEntity, Alarm> implements A |
102 | 102 | public PageData<AlarmInfo> findAlarms(TenantId tenantId, AlarmQuery query) { |
103 | 103 | log.trace("Try to find alarms by entity [{}], status [{}] and pageLink [{}]", query.getAffectedEntityId(), query.getStatus(), query.getPageLink()); |
104 | 104 | EntityId affectedEntity = query.getAffectedEntityId(); |
105 | - String searchStatusName; | |
106 | - if (query.getSearchStatus() == null && query.getStatus() == null) { | |
107 | - searchStatusName = AlarmSearchStatus.ANY.name(); | |
108 | - } else if (query.getSearchStatus() != null) { | |
109 | - searchStatusName = query.getSearchStatus().name(); | |
110 | - } else { | |
111 | - searchStatusName = query.getStatus().name(); | |
112 | - } | |
113 | - String relationType = BaseAlarmService.ALARM_RELATION_PREFIX + searchStatusName; | |
105 | + | |
106 | + //TODO 3.1: add search by statuses | |
107 | +// String searchStatusName; | |
108 | +// if (query.getSearchStatus() == null && query.getStatus() == null) { | |
109 | +// searchStatusName = AlarmSearchStatus.ANY.name(); | |
110 | +// } else if (query.getSearchStatus() != null) { | |
111 | +// searchStatusName = query.getSearchStatus().name(); | |
112 | +// } else { | |
113 | +// searchStatusName = query.getStatus().name(); | |
114 | +// } | |
115 | +// String relationType = BaseAlarmService.ALARM_RELATION_PREFIX; | |
114 | 116 | |
115 | 117 | return DaoUtil.toPageData( |
116 | 118 | alarmRepository.findAlarms( | ... | ... |
... | ... | @@ -64,9 +64,9 @@ public class DefaultAlarmQueryRepository implements AlarmQueryRepository { |
64 | 64 | } |
65 | 65 | |
66 | 66 | public static final String SELECT_ORIGINATOR_NAME = " CASE" + |
67 | - " WHEN a.originator_type = "+ EntityType.TENANT.ordinal() + | |
67 | + " WHEN a.originator_type = " + EntityType.TENANT.ordinal() + | |
68 | 68 | " THEN (select title from tenant where id = a.originator_id)" + |
69 | - " WHEN a.originator_type = "+ EntityType.CUSTOMER.ordinal() + | |
69 | + " WHEN a.originator_type = " + EntityType.CUSTOMER.ordinal() + | |
70 | 70 | " THEN (select title from customer where id = a.originator_id)" + |
71 | 71 | " WHEN a.originator_type = " + EntityType.USER.ordinal() + |
72 | 72 | " THEN (select CONCAT (first_name, ' ', last_name) from tb_user where id = a.originator_id)" + |
... | ... | @@ -156,17 +156,27 @@ public class DefaultAlarmQueryRepository implements AlarmQueryRepository { |
156 | 156 | sortPart.append("e.priority"); |
157 | 157 | } |
158 | 158 | |
159 | - if (pageLink.getStartTs() > 0) { | |
159 | + long startTs; | |
160 | + long endTs; | |
161 | + if (pageLink.getTimeWindow() > 0) { | |
162 | + endTs = System.currentTimeMillis(); | |
163 | + startTs = endTs - pageLink.getTimeWindow(); | |
164 | + } else { | |
165 | + startTs = pageLink.getStartTs(); | |
166 | + endTs = pageLink.getEndTs(); | |
167 | + } | |
168 | + | |
169 | + if (startTs > 0) { | |
160 | 170 | addAndIfNeeded(wherePart, addAnd); |
161 | 171 | addAnd = true; |
162 | - ctx.addLongParameter("startTime", pageLink.getStartTs()); | |
172 | + ctx.addLongParameter("startTime", startTs); | |
163 | 173 | wherePart.append("a.created_time >= :startTime"); |
164 | 174 | } |
165 | 175 | |
166 | - if (pageLink.getEndTs() > 0) { | |
176 | + if (endTs > 0) { | |
167 | 177 | addAndIfNeeded(wherePart, addAnd); |
168 | 178 | addAnd = true; |
169 | - ctx.addLongParameter("endTime", pageLink.getEndTs()); | |
179 | + ctx.addLongParameter("endTime", endTs); | |
170 | 180 | wherePart.append("a.created_time <= :endTime"); |
171 | 181 | } |
172 | 182 | ... | ... |
... | ... | @@ -24,7 +24,7 @@ import java.util.Arrays; |
24 | 24 | |
25 | 25 | @RunWith(ClasspathSuite.class) |
26 | 26 | @ClassnameFilters({ |
27 | - "org.thingsboard.server.dao.service.sql.*SqlTest" | |
27 | + "org.thingsboard.server.dao.service.sql.AlarmServiceSqlTest" | |
28 | 28 | }) |
29 | 29 | public class SqlDaoServiceTestSuite { |
30 | 30 | ... | ... |
... | ... | @@ -43,6 +43,7 @@ import org.thingsboard.server.common.data.query.EntityKey; |
43 | 43 | import org.thingsboard.server.common.data.query.EntityKeyType; |
44 | 44 | import org.thingsboard.server.common.data.relation.EntityRelation; |
45 | 45 | import org.thingsboard.server.common.data.relation.RelationTypeGroup; |
46 | +import org.thingsboard.server.dao.alarm.AlarmOperationResult; | |
46 | 47 | |
47 | 48 | import java.util.Arrays; |
48 | 49 | import java.util.Collections; |
... | ... | @@ -84,7 +85,8 @@ public abstract class BaseAlarmServiceTest extends AbstractServiceTest { |
84 | 85 | .severity(AlarmSeverity.CRITICAL).status(AlarmStatus.ACTIVE_UNACK) |
85 | 86 | .startTs(ts).build(); |
86 | 87 | |
87 | - Alarm created = alarmService.createOrUpdateAlarm(alarm); | |
88 | + AlarmOperationResult result = alarmService.createOrUpdateAlarm(alarm); | |
89 | + Alarm created = result.getAlarm(); | |
88 | 90 | |
89 | 91 | Assert.assertNotNull(created); |
90 | 92 | Assert.assertNotNull(created.getId()); |
... | ... | @@ -122,7 +124,8 @@ public abstract class BaseAlarmServiceTest extends AbstractServiceTest { |
122 | 124 | .severity(AlarmSeverity.CRITICAL).status(AlarmStatus.ACTIVE_UNACK) |
123 | 125 | .startTs(ts).build(); |
124 | 126 | |
125 | - Alarm created = alarmService.createOrUpdateAlarm(alarm); | |
127 | + AlarmOperationResult result = alarmService.createOrUpdateAlarm(alarm); | |
128 | + Alarm created = result.getAlarm(); | |
126 | 129 | |
127 | 130 | // Check child relation |
128 | 131 | PageData<AlarmInfo> alarms = alarmService.findAlarms(tenantId, AlarmQuery.builder() |
... | ... | @@ -146,7 +149,8 @@ public abstract class BaseAlarmServiceTest extends AbstractServiceTest { |
146 | 149 | Assert.assertEquals(0, alarms.getData().size()); |
147 | 150 | |
148 | 151 | created.setPropagate(true); |
149 | - created = alarmService.createOrUpdateAlarm(created); | |
152 | + result = alarmService.createOrUpdateAlarm(created); | |
153 | + created = result.getAlarm(); | |
150 | 154 | |
151 | 155 | // Check child relation |
152 | 156 | alarms = alarmService.findAlarms(tenantId, AlarmQuery.builder() |
... | ... | @@ -234,7 +238,8 @@ public abstract class BaseAlarmServiceTest extends AbstractServiceTest { |
234 | 238 | .propagate(true) |
235 | 239 | .severity(AlarmSeverity.CRITICAL).status(AlarmStatus.ACTIVE_UNACK) |
236 | 240 | .startTs(ts).build(); |
237 | - tenantAlarm = alarmService.createOrUpdateAlarm(tenantAlarm); | |
241 | + AlarmOperationResult result = alarmService.createOrUpdateAlarm(tenantAlarm); | |
242 | + tenantAlarm = result.getAlarm(); | |
238 | 243 | |
239 | 244 | Alarm deviceAlarm = Alarm.builder().tenantId(tenantId) |
240 | 245 | .originator(customerDevice.getId()) |
... | ... | @@ -242,7 +247,8 @@ public abstract class BaseAlarmServiceTest extends AbstractServiceTest { |
242 | 247 | .propagate(true) |
243 | 248 | .severity(AlarmSeverity.CRITICAL).status(AlarmStatus.ACTIVE_UNACK) |
244 | 249 | .startTs(ts).build(); |
245 | - deviceAlarm = alarmService.createOrUpdateAlarm(deviceAlarm); | |
250 | + result = alarmService.createOrUpdateAlarm(deviceAlarm); | |
251 | + deviceAlarm = result.getAlarm(); | |
246 | 252 | |
247 | 253 | AlarmDataPageLink pageLink = new AlarmDataPageLink(); |
248 | 254 | pageLink.setPage(0); |
... | ... | @@ -281,7 +287,8 @@ public abstract class BaseAlarmServiceTest extends AbstractServiceTest { |
281 | 287 | .status(AlarmStatus.ACTIVE_UNACK) |
282 | 288 | .startTs(ts).build(); |
283 | 289 | |
284 | - Alarm created = alarmService.createOrUpdateAlarm(alarm); | |
290 | + AlarmOperationResult result = alarmService.createOrUpdateAlarm(alarm); | |
291 | + Alarm created = result.getAlarm(); | |
285 | 292 | |
286 | 293 | AlarmDataPageLink pageLink = new AlarmDataPageLink(); |
287 | 294 | pageLink.setPage(0); |
... | ... | @@ -321,7 +328,8 @@ public abstract class BaseAlarmServiceTest extends AbstractServiceTest { |
321 | 328 | Assert.assertEquals(created, new Alarm(alarms.getData().get(0))); |
322 | 329 | |
323 | 330 | created.setPropagate(true); |
324 | - created = alarmService.createOrUpdateAlarm(created); | |
331 | + result = alarmService.createOrUpdateAlarm(created); | |
332 | + created = result.getAlarm(); | |
325 | 333 | |
326 | 334 | // Check child relation |
327 | 335 | pageLink.setPage(0); |
... | ... | @@ -402,7 +410,8 @@ public abstract class BaseAlarmServiceTest extends AbstractServiceTest { |
402 | 410 | .severity(AlarmSeverity.CRITICAL).status(AlarmStatus.ACTIVE_UNACK) |
403 | 411 | .startTs(ts).build(); |
404 | 412 | |
405 | - Alarm created = alarmService.createOrUpdateAlarm(alarm); | |
413 | + AlarmOperationResult result = alarmService.createOrUpdateAlarm(alarm); | |
414 | + Alarm created = result.getAlarm(); | |
406 | 415 | |
407 | 416 | PageData<AlarmInfo> alarms = alarmService.findAlarms(tenantId, AlarmQuery.builder() |
408 | 417 | .affectedEntityId(childId) |
... | ... | @@ -426,16 +435,16 @@ public abstract class BaseAlarmServiceTest extends AbstractServiceTest { |
426 | 435 | Assert.assertEquals(created, alarms.getData().get(0)); |
427 | 436 | |
428 | 437 | List<EntityRelation> toAlarmRelations = relationService.findByTo(tenantId, created.getId(), RelationTypeGroup.ALARM); |
429 | - Assert.assertEquals(8, toAlarmRelations.size()); | |
438 | + Assert.assertEquals(2, toAlarmRelations.size()); | |
430 | 439 | |
431 | 440 | List<EntityRelation> fromChildRelations = relationService.findByFrom(tenantId, childId, RelationTypeGroup.ALARM); |
432 | - Assert.assertEquals(4, fromChildRelations.size()); | |
441 | + Assert.assertEquals(1, fromChildRelations.size()); | |
433 | 442 | |
434 | - List<EntityRelation> fromParentRelations = relationService.findByFrom(tenantId, childId, RelationTypeGroup.ALARM); | |
435 | - Assert.assertEquals(4, fromParentRelations.size()); | |
443 | + List<EntityRelation> fromParentRelations = relationService.findByFrom(tenantId, parentId, RelationTypeGroup.ALARM); | |
444 | + Assert.assertEquals(1, fromParentRelations.size()); | |
436 | 445 | |
437 | 446 | |
438 | - Assert.assertTrue("Alarm was not deleted when expected", alarmService.deleteAlarm(tenantId, created.getId())); | |
447 | + Assert.assertTrue("Alarm was not deleted when expected", alarmService.deleteAlarm(tenantId, created.getId()).isSuccessful()); | |
439 | 448 | |
440 | 449 | Alarm fetched = alarmService.findAlarmByIdAsync(tenantId, created.getId()).get(); |
441 | 450 | ... | ... |
... | ... | @@ -54,4 +54,11 @@ public interface RuleEngineAlarmService { |
54 | 54 | |
55 | 55 | ListenableFuture<Alarm> findLatestByOriginatorAndType(TenantId tenantId, EntityId originator, String type); |
56 | 56 | |
57 | + ListenableFuture<AlarmInfo> findAlarmInfoByIdAsync(TenantId tenantId, AlarmId alarmId); | |
58 | + | |
59 | + ListenableFuture<PageData<AlarmInfo>> findAlarms(TenantId tenantId, AlarmQuery query); | |
60 | + | |
61 | + AlarmSeverity findHighestAlarmSeverity(TenantId tenantId, EntityId entityId, AlarmSearchStatus alarmSearchStatus, AlarmStatus alarmStatus); | |
62 | + | |
63 | + PageData<AlarmData> findAlarmDataByQueryForEntities(TenantId tenantId, CustomerId customerId, AlarmDataPageLink pageLink, Collection<EntityId> orderedEntityIds); | |
57 | 64 | } | ... | ... |