Commit aa0d05bb440e30715218b6a712802ece25a2630b

Authored by Igor Kulikov
Committed by GitHub
2 parents 11c25466 2ce04c37

Merge pull request #4957 from volodymyr-babak/edge-fix-concurrent-async-issue

[3.3.0] Added lock on edge event save/read. Removed save async method
@@ -97,11 +97,9 @@ import java.util.Arrays; @@ -97,11 +97,9 @@ import java.util.Arrays;
97 import java.util.Collections; 97 import java.util.Collections;
98 import java.util.HashMap; 98 import java.util.HashMap;
99 import java.util.HashSet; 99 import java.util.HashSet;
100 -import java.util.LinkedHashMap;  
101 import java.util.List; 100 import java.util.List;
102 import java.util.Map; 101 import java.util.Map;
103 import java.util.Objects; 102 import java.util.Objects;
104 -import java.util.Optional;  
105 import java.util.Set; 103 import java.util.Set;
106 import java.util.UUID; 104 import java.util.UUID;
107 import java.util.function.Consumer; 105 import java.util.function.Consumer;
@@ -729,18 +727,8 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { @@ -729,18 +727,8 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
729 edgeEvent.setBody(body); 727 edgeEvent.setBody(body);
730 728
731 edgeEvent.setEdgeId(edgeId); 729 edgeEvent.setEdgeId(edgeId);
732 - ListenableFuture<EdgeEvent> future = systemContext.getEdgeEventService().saveAsync(edgeEvent);  
733 - Futures.addCallback(future, new FutureCallback<EdgeEvent>() {  
734 - @Override  
735 - public void onSuccess(EdgeEvent result) {  
736 - systemContext.getClusterService().onEdgeEventUpdate(tenantId, edgeId);  
737 - }  
738 -  
739 - @Override  
740 - public void onFailure(Throwable t) {  
741 - log.warn("[{}] Can't save edge event [{}] for edge [{}]", tenantId.getId(), edgeEvent, edgeId.getId(), t);  
742 - }  
743 - }, systemContext.getDbCallbackExecutor()); 730 + systemContext.getEdgeEventService().save(edgeEvent);
  731 + systemContext.getClusterService().onEdgeEventUpdate(tenantId, edgeId);
744 } 732 }
745 733
746 private List<TsKvProto> toTsKvProtos(@Nullable List<AttributeKvEntry> result) { 734 private List<TsKvProto> toTsKvProtos(@Nullable List<AttributeKvEntry> result) {
@@ -16,11 +16,7 @@ @@ -16,11 +16,7 @@
16 package org.thingsboard.server.service.edge; 16 package org.thingsboard.server.service.edge;
17 17
18 import com.fasterxml.jackson.databind.JsonNode; 18 import com.fasterxml.jackson.databind.JsonNode;
19 -import com.google.common.util.concurrent.FutureCallback;  
20 -import com.google.common.util.concurrent.Futures;  
21 -import com.google.common.util.concurrent.ListenableFuture;  
22 import lombok.extern.slf4j.Slf4j; 19 import lombok.extern.slf4j.Slf4j;
23 -import org.checkerframework.checker.nullness.qual.Nullable;  
24 import org.springframework.beans.factory.annotation.Autowired; 20 import org.springframework.beans.factory.annotation.Autowired;
25 import org.springframework.stereotype.Service; 21 import org.springframework.stereotype.Service;
26 import org.thingsboard.server.common.data.edge.Edge; 22 import org.thingsboard.server.common.data.edge.Edge;
@@ -41,7 +37,6 @@ import org.thingsboard.server.service.edge.rpc.processor.CustomerEdgeProcessor; @@ -41,7 +37,6 @@ import org.thingsboard.server.service.edge.rpc.processor.CustomerEdgeProcessor;
41 import org.thingsboard.server.service.edge.rpc.processor.EdgeProcessor; 37 import org.thingsboard.server.service.edge.rpc.processor.EdgeProcessor;
42 import org.thingsboard.server.service.edge.rpc.processor.EntityEdgeProcessor; 38 import org.thingsboard.server.service.edge.rpc.processor.EntityEdgeProcessor;
43 import org.thingsboard.server.service.edge.rpc.processor.RelationEdgeProcessor; 39 import org.thingsboard.server.service.edge.rpc.processor.RelationEdgeProcessor;
44 -import org.thingsboard.server.service.executors.DbCallbackExecutorService;  
45 import org.thingsboard.server.service.queue.TbClusterService; 40 import org.thingsboard.server.service.queue.TbClusterService;
46 41
47 import javax.annotation.PostConstruct; 42 import javax.annotation.PostConstruct;
@@ -66,9 +61,6 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService { @@ -66,9 +61,6 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService {
66 private TbClusterService clusterService; 61 private TbClusterService clusterService;
67 62
68 @Autowired 63 @Autowired
69 - private DbCallbackExecutorService dbCallbackExecutorService;  
70 -  
71 - @Autowired  
72 private EdgeProcessor edgeProcessor; 64 private EdgeProcessor edgeProcessor;
73 65
74 @Autowired 66 @Autowired
@@ -123,19 +115,8 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService { @@ -123,19 +115,8 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService {
123 edgeEvent.setEntityId(entityId.getId()); 115 edgeEvent.setEntityId(entityId.getId());
124 } 116 }
125 edgeEvent.setBody(body); 117 edgeEvent.setBody(body);
126 - ListenableFuture<EdgeEvent> future = edgeEventService.saveAsync(edgeEvent);  
127 - Futures.addCallback(future, new FutureCallback<EdgeEvent>() {  
128 - @Override  
129 - public void onSuccess(@Nullable EdgeEvent result) {  
130 - clusterService.onEdgeEventUpdate(tenantId, edgeId);  
131 - }  
132 -  
133 - @Override  
134 - public void onFailure(Throwable t) {  
135 - log.warn("[{}] Can't save edge event [{}] for edge [{}]", tenantId.getId(), edgeEvent, edgeId.getId(), t);  
136 - }  
137 - }, dbCallbackExecutorService);  
138 - 118 + edgeEventService.save(edgeEvent);
  119 + clusterService.onEdgeEventUpdate(tenantId, edgeId);
139 } 120 }
140 121
141 @Override 122 @Override
@@ -259,7 +259,7 @@ public final class EdgeGrpcSession implements Closeable { @@ -259,7 +259,7 @@ public final class EdgeGrpcSession implements Closeable {
259 log.error("[{}] Msg processing failed! Error msg: {}", edge.getRoutingKey(), msg.getErrorMsg()); 259 log.error("[{}] Msg processing failed! Error msg: {}", edge.getRoutingKey(), msg.getErrorMsg());
260 } 260 }
261 if (sessionState.getPendingMsgsMap().isEmpty()) { 261 if (sessionState.getPendingMsgsMap().isEmpty()) {
262 - log.debug("[{}] Pending msgs map is empty. Stopping current iteration {}", edge.getRoutingKey(), msg); 262 + log.debug("[{}] Pending msgs map is empty. Stopping current iteration", edge.getRoutingKey());
263 if (sessionState.getScheduledSendDownlinkTask() != null) { 263 if (sessionState.getScheduledSendDownlinkTask() != null) {
264 sessionState.getScheduledSendDownlinkTask().cancel(false); 264 sessionState.getScheduledSendDownlinkTask().cancel(false);
265 } 265 }
@@ -17,11 +17,7 @@ package org.thingsboard.server.service.edge.rpc.processor; @@ -17,11 +17,7 @@ package org.thingsboard.server.service.edge.rpc.processor;
17 17
18 import com.fasterxml.jackson.databind.JsonNode; 18 import com.fasterxml.jackson.databind.JsonNode;
19 import com.fasterxml.jackson.databind.ObjectMapper; 19 import com.fasterxml.jackson.databind.ObjectMapper;
20 -import com.google.common.util.concurrent.FutureCallback;  
21 -import com.google.common.util.concurrent.Futures;  
22 -import com.google.common.util.concurrent.ListenableFuture;  
23 import lombok.extern.slf4j.Slf4j; 20 import lombok.extern.slf4j.Slf4j;
24 -import org.checkerframework.checker.nullness.qual.Nullable;  
25 import org.springframework.beans.factory.annotation.Autowired; 21 import org.springframework.beans.factory.annotation.Autowired;
26 import org.thingsboard.server.common.data.HasCustomerId; 22 import org.thingsboard.server.common.data.HasCustomerId;
27 import org.thingsboard.server.common.data.edge.Edge; 23 import org.thingsboard.server.common.data.edge.Edge;
@@ -178,12 +174,12 @@ public abstract class BaseEdgeProcessor { @@ -178,12 +174,12 @@ public abstract class BaseEdgeProcessor {
178 @Autowired 174 @Autowired
179 protected DbCallbackExecutorService dbCallbackExecutorService; 175 protected DbCallbackExecutorService dbCallbackExecutorService;
180 176
181 - protected ListenableFuture<EdgeEvent> saveEdgeEvent(TenantId tenantId,  
182 - EdgeId edgeId,  
183 - EdgeEventType type,  
184 - EdgeEventActionType action,  
185 - EntityId entityId,  
186 - JsonNode body) { 177 + protected void saveEdgeEvent(TenantId tenantId,
  178 + EdgeId edgeId,
  179 + EdgeEventType type,
  180 + EdgeEventActionType action,
  181 + EntityId entityId,
  182 + JsonNode body) {
187 log.debug("Pushing event to edge queue. tenantId [{}], edgeId [{}], type[{}], " + 183 log.debug("Pushing event to edge queue. tenantId [{}], edgeId [{}], type[{}], " +
188 "action [{}], entityId [{}], body [{}]", 184 "action [{}], entityId [{}], body [{}]",
189 tenantId, edgeId, type, action, entityId, body); 185 tenantId, edgeId, type, action, entityId, body);
@@ -197,19 +193,8 @@ public abstract class BaseEdgeProcessor { @@ -197,19 +193,8 @@ public abstract class BaseEdgeProcessor {
197 edgeEvent.setEntityId(entityId.getId()); 193 edgeEvent.setEntityId(entityId.getId());
198 } 194 }
199 edgeEvent.setBody(body); 195 edgeEvent.setBody(body);
200 - ListenableFuture<EdgeEvent> future = edgeEventService.saveAsync(edgeEvent);  
201 - Futures.addCallback(future, new FutureCallback<EdgeEvent>() {  
202 - @Override  
203 - public void onSuccess(@Nullable EdgeEvent result) {  
204 - tbClusterService.onEdgeEventUpdate(tenantId, edgeId);  
205 - }  
206 -  
207 - @Override  
208 - public void onFailure(Throwable t) {  
209 - log.warn("[{}] Can't save edge event [{}] for edge [{}]", tenantId.getId(), edgeEvent, edgeId.getId(), t);  
210 - }  
211 - }, dbCallbackExecutorService);  
212 - return future; 196 + edgeEventService.save(edgeEvent);
  197 + tbClusterService.onEdgeEventUpdate(tenantId, edgeId);
213 } 198 }
214 199
215 protected CustomerId getCustomerIdIfEdgeAssignedToCustomer(HasCustomerId hasCustomerIdEntity, Edge edge) { 200 protected CustomerId getCustomerIdIfEdgeAssignedToCustomer(HasCustomerId hasCustomerIdEntity, Edge edge) {
@@ -105,19 +105,8 @@ public class DeviceEdgeProcessor extends BaseEdgeProcessor { @@ -105,19 +105,8 @@ public class DeviceEdgeProcessor extends BaseEdgeProcessor {
105 Device newDevice = createDevice(tenantId, edge, deviceUpdateMsg, newDeviceName); 105 Device newDevice = createDevice(tenantId, edge, deviceUpdateMsg, newDeviceName);
106 ObjectNode body = mapper.createObjectNode(); 106 ObjectNode body = mapper.createObjectNode();
107 body.put("conflictName", deviceName); 107 body.put("conflictName", deviceName);
108 - ListenableFuture<EdgeEvent> future =  
109 - saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE, EdgeEventActionType.ENTITY_MERGE_REQUEST, newDevice.getId(), body);  
110 - Futures.addCallback(future, new FutureCallback<>() {  
111 - @Override  
112 - public void onSuccess(EdgeEvent edgeEvent) {  
113 - saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE, EdgeEventActionType.CREDENTIALS_REQUEST, newDevice.getId(), null);  
114 - }  
115 -  
116 - @Override  
117 - public void onFailure(Throwable t) {  
118 - log.error("[{}] Failed to save ENTITY_MERGE_REQUEST edge event [{}][{}]", tenantId, deviceUpdateMsg, edge.getId(), t);  
119 - }  
120 - }, dbCallbackExecutorService); 108 + saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE, EdgeEventActionType.ENTITY_MERGE_REQUEST, newDevice.getId(), body);
  109 + saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE, EdgeEventActionType.CREDENTIALS_REQUEST, newDevice.getId(), null);
121 } 110 }
122 } while (pageData != null && pageData.hasNext()); 111 } while (pageData != null && pageData.hasNext());
123 } else { 112 } else {
@@ -122,26 +122,13 @@ public class DefaultEdgeRequestsService implements EdgeRequestsService { @@ -122,26 +122,13 @@ public class DefaultEdgeRequestsService implements EdgeRequestsService {
122 @Override 122 @Override
123 public ListenableFuture<Void> processRuleChainMetadataRequestMsg(TenantId tenantId, Edge edge, RuleChainMetadataRequestMsg ruleChainMetadataRequestMsg) { 123 public ListenableFuture<Void> processRuleChainMetadataRequestMsg(TenantId tenantId, Edge edge, RuleChainMetadataRequestMsg ruleChainMetadataRequestMsg) {
124 log.trace("[{}] processRuleChainMetadataRequestMsg [{}][{}]", tenantId, edge.getName(), ruleChainMetadataRequestMsg); 124 log.trace("[{}] processRuleChainMetadataRequestMsg [{}][{}]", tenantId, edge.getName(), ruleChainMetadataRequestMsg);
125 - SettableFuture<Void> futureToSet = SettableFuture.create();  
126 if (ruleChainMetadataRequestMsg.getRuleChainIdMSB() != 0 && ruleChainMetadataRequestMsg.getRuleChainIdLSB() != 0) { 125 if (ruleChainMetadataRequestMsg.getRuleChainIdMSB() != 0 && ruleChainMetadataRequestMsg.getRuleChainIdLSB() != 0) {
127 RuleChainId ruleChainId = 126 RuleChainId ruleChainId =
128 new RuleChainId(new UUID(ruleChainMetadataRequestMsg.getRuleChainIdMSB(), ruleChainMetadataRequestMsg.getRuleChainIdLSB())); 127 new RuleChainId(new UUID(ruleChainMetadataRequestMsg.getRuleChainIdMSB(), ruleChainMetadataRequestMsg.getRuleChainIdLSB()));
129 - ListenableFuture<EdgeEvent> future = saveEdgeEvent(tenantId, edge.getId(), 128 + saveEdgeEvent(tenantId, edge.getId(),
130 EdgeEventType.RULE_CHAIN_METADATA, EdgeEventActionType.ADDED, ruleChainId, null); 129 EdgeEventType.RULE_CHAIN_METADATA, EdgeEventActionType.ADDED, ruleChainId, null);
131 - Futures.addCallback(future, new FutureCallback<EdgeEvent>() {  
132 - @Override  
133 - public void onSuccess(@Nullable EdgeEvent result) {  
134 - futureToSet.set(null);  
135 - }  
136 -  
137 - @Override  
138 - public void onFailure(Throwable t) {  
139 - log.error("Can't save edge event [{}]", ruleChainMetadataRequestMsg, t);  
140 - futureToSet.setException(t);  
141 - }  
142 - }, dbCallbackExecutorService);  
143 } 130 }
144 - return futureToSet; 131 + return Futures.immediateFuture(null);
145 } 132 }
146 133
147 @Override 134 @Override
@@ -154,8 +141,8 @@ public class DefaultEdgeRequestsService implements EdgeRequestsService { @@ -154,8 +141,8 @@ public class DefaultEdgeRequestsService implements EdgeRequestsService {
154 if (type != null) { 141 if (type != null) {
155 SettableFuture<Void> futureToSet = SettableFuture.create(); 142 SettableFuture<Void> futureToSet = SettableFuture.create();
156 String scope = attributesRequestMsg.getScope(); 143 String scope = attributesRequestMsg.getScope();
157 - ListenableFuture<List<AttributeKvEntry>> ssAttrFuture = attributesService.findAll(tenantId, entityId, scope);  
158 - Futures.addCallback(ssAttrFuture, new FutureCallback<List<AttributeKvEntry>>() { 144 + ListenableFuture<List<AttributeKvEntry>> findAttrFuture = attributesService.findAll(tenantId, entityId, scope);
  145 + Futures.addCallback(findAttrFuture, new FutureCallback<List<AttributeKvEntry>>() {
159 @Override 146 @Override
160 public void onSuccess(@Nullable List<AttributeKvEntry> ssAttributes) { 147 public void onSuccess(@Nullable List<AttributeKvEntry> ssAttributes) {
161 if (ssAttributes != null && !ssAttributes.isEmpty()) { 148 if (ssAttributes != null && !ssAttributes.isEmpty()) {
@@ -184,8 +171,9 @@ public class DefaultEdgeRequestsService implements EdgeRequestsService { @@ -184,8 +171,9 @@ public class DefaultEdgeRequestsService implements EdgeRequestsService {
184 entityId, 171 entityId,
185 body); 172 body);
186 } catch (Exception e) { 173 } catch (Exception e) {
187 - log.error("[{}] Failed to send attribute updates to the edge", edge.getName(), e);  
188 - throw new RuntimeException("[" + edge.getName() + "] Failed to send attribute updates to the edge", e); 174 + log.error("[{}] Failed to save attribute updates to the edge", edge.getName(), e);
  175 + futureToSet.setException(new RuntimeException("[" + edge.getName() + "] Failed to send attribute updates to the edge", e));
  176 + return;
189 } 177 }
190 } else { 178 } else {
191 log.trace("[{}][{}] No attributes found for entity {} [{}]", tenantId, 179 log.trace("[{}][{}] No attributes found for entity {} [{}]", tenantId,
@@ -198,7 +186,7 @@ public class DefaultEdgeRequestsService implements EdgeRequestsService { @@ -198,7 +186,7 @@ public class DefaultEdgeRequestsService implements EdgeRequestsService {
198 186
199 @Override 187 @Override
200 public void onFailure(Throwable t) { 188 public void onFailure(Throwable t) {
201 - log.error("Can't save attributes [{}]", attributesRequestMsg, t); 189 + log.error("Can't find attributes [{}]", attributesRequestMsg, t);
202 futureToSet.setException(t); 190 futureToSet.setException(t);
203 } 191 }
204 }, dbCallbackExecutorService); 192 }, dbCallbackExecutorService);
@@ -273,82 +261,39 @@ public class DefaultEdgeRequestsService implements EdgeRequestsService { @@ -273,82 +261,39 @@ public class DefaultEdgeRequestsService implements EdgeRequestsService {
273 @Override 261 @Override
274 public ListenableFuture<Void> processDeviceCredentialsRequestMsg(TenantId tenantId, Edge edge, DeviceCredentialsRequestMsg deviceCredentialsRequestMsg) { 262 public ListenableFuture<Void> processDeviceCredentialsRequestMsg(TenantId tenantId, Edge edge, DeviceCredentialsRequestMsg deviceCredentialsRequestMsg) {
275 log.trace("[{}] processDeviceCredentialsRequestMsg [{}][{}]", tenantId, edge.getName(), deviceCredentialsRequestMsg); 263 log.trace("[{}] processDeviceCredentialsRequestMsg [{}][{}]", tenantId, edge.getName(), deviceCredentialsRequestMsg);
276 - SettableFuture<Void> futureToSet = SettableFuture.create();  
277 if (deviceCredentialsRequestMsg.getDeviceIdMSB() != 0 && deviceCredentialsRequestMsg.getDeviceIdLSB() != 0) { 264 if (deviceCredentialsRequestMsg.getDeviceIdMSB() != 0 && deviceCredentialsRequestMsg.getDeviceIdLSB() != 0) {
278 DeviceId deviceId = new DeviceId(new UUID(deviceCredentialsRequestMsg.getDeviceIdMSB(), deviceCredentialsRequestMsg.getDeviceIdLSB())); 265 DeviceId deviceId = new DeviceId(new UUID(deviceCredentialsRequestMsg.getDeviceIdMSB(), deviceCredentialsRequestMsg.getDeviceIdLSB()));
279 - ListenableFuture<EdgeEvent> future = saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE, 266 + saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE,
280 EdgeEventActionType.CREDENTIALS_UPDATED, deviceId, null); 267 EdgeEventActionType.CREDENTIALS_UPDATED, deviceId, null);
281 - Futures.addCallback(future, new FutureCallback<EdgeEvent>() {  
282 - @Override  
283 - public void onSuccess(@Nullable EdgeEvent result) {  
284 - futureToSet.set(null);  
285 - }  
286 -  
287 - @Override  
288 - public void onFailure(Throwable t) {  
289 - log.error("Can't save edge event [{}]", deviceCredentialsRequestMsg, t);  
290 - futureToSet.setException(t);  
291 - }  
292 - }, dbCallbackExecutorService);  
293 } 268 }
294 - return futureToSet; 269 + return Futures.immediateFuture(null);
295 } 270 }
296 271
297 @Override 272 @Override
298 public ListenableFuture<Void> processUserCredentialsRequestMsg(TenantId tenantId, Edge edge, UserCredentialsRequestMsg userCredentialsRequestMsg) { 273 public ListenableFuture<Void> processUserCredentialsRequestMsg(TenantId tenantId, Edge edge, UserCredentialsRequestMsg userCredentialsRequestMsg) {
299 log.trace("[{}] processUserCredentialsRequestMsg [{}][{}]", tenantId, edge.getName(), userCredentialsRequestMsg); 274 log.trace("[{}] processUserCredentialsRequestMsg [{}][{}]", tenantId, edge.getName(), userCredentialsRequestMsg);
300 - SettableFuture<Void> futureToSet = SettableFuture.create();  
301 if (userCredentialsRequestMsg.getUserIdMSB() != 0 && userCredentialsRequestMsg.getUserIdLSB() != 0) { 275 if (userCredentialsRequestMsg.getUserIdMSB() != 0 && userCredentialsRequestMsg.getUserIdLSB() != 0) {
302 UserId userId = new UserId(new UUID(userCredentialsRequestMsg.getUserIdMSB(), userCredentialsRequestMsg.getUserIdLSB())); 276 UserId userId = new UserId(new UUID(userCredentialsRequestMsg.getUserIdMSB(), userCredentialsRequestMsg.getUserIdLSB()));
303 - ListenableFuture<EdgeEvent> future = saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.USER, 277 + saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.USER,
304 EdgeEventActionType.CREDENTIALS_UPDATED, userId, null); 278 EdgeEventActionType.CREDENTIALS_UPDATED, userId, null);
305 - Futures.addCallback(future, new FutureCallback<>() {  
306 - @Override  
307 - public void onSuccess(@Nullable EdgeEvent result) {  
308 - futureToSet.set(null);  
309 - }  
310 -  
311 - @Override  
312 - public void onFailure(Throwable t) {  
313 - log.error("Can't save edge event [{}]", userCredentialsRequestMsg, t);  
314 - futureToSet.setException(t);  
315 - }  
316 - }, dbCallbackExecutorService);  
317 } 279 }
318 - return futureToSet; 280 + return Futures.immediateFuture(null);
319 } 281 }
320 282
321 @Override 283 @Override
322 public ListenableFuture<Void> processDeviceProfileDevicesRequestMsg(TenantId tenantId, Edge edge, DeviceProfileDevicesRequestMsg deviceProfileDevicesRequestMsg) { 284 public ListenableFuture<Void> processDeviceProfileDevicesRequestMsg(TenantId tenantId, Edge edge, DeviceProfileDevicesRequestMsg deviceProfileDevicesRequestMsg) {
323 log.trace("[{}] processDeviceProfileDevicesRequestMsg [{}][{}]", tenantId, edge.getName(), deviceProfileDevicesRequestMsg); 285 log.trace("[{}] processDeviceProfileDevicesRequestMsg [{}][{}]", tenantId, edge.getName(), deviceProfileDevicesRequestMsg);
324 - SettableFuture<Void> futureToSet = SettableFuture.create();  
325 if (deviceProfileDevicesRequestMsg.getDeviceProfileIdMSB() != 0 && deviceProfileDevicesRequestMsg.getDeviceProfileIdLSB() != 0) { 286 if (deviceProfileDevicesRequestMsg.getDeviceProfileIdMSB() != 0 && deviceProfileDevicesRequestMsg.getDeviceProfileIdLSB() != 0) {
326 DeviceProfileId deviceProfileId = new DeviceProfileId(new UUID(deviceProfileDevicesRequestMsg.getDeviceProfileIdMSB(), deviceProfileDevicesRequestMsg.getDeviceProfileIdLSB())); 287 DeviceProfileId deviceProfileId = new DeviceProfileId(new UUID(deviceProfileDevicesRequestMsg.getDeviceProfileIdMSB(), deviceProfileDevicesRequestMsg.getDeviceProfileIdLSB()));
327 DeviceProfile deviceProfileById = deviceProfileService.findDeviceProfileById(tenantId, deviceProfileId); 288 DeviceProfile deviceProfileById = deviceProfileService.findDeviceProfileById(tenantId, deviceProfileId);
328 - List<ListenableFuture<EdgeEvent>> futures;  
329 if (deviceProfileById != null) { 289 if (deviceProfileById != null) {
330 - futures = syncDevices(tenantId, edge, deviceProfileById.getName());  
331 - } else {  
332 - futures = new ArrayList<>(); 290 + syncDevices(tenantId, edge, deviceProfileById.getName());
333 } 291 }
334 - Futures.addCallback(Futures.allAsList(futures), new FutureCallback<>() {  
335 - @Override  
336 - public void onSuccess(@Nullable List<EdgeEvent> result) {  
337 - futureToSet.set(null);  
338 - }  
339 -  
340 - @Override  
341 - public void onFailure(Throwable t) {  
342 - log.error("Can't sync devices by device profile [{}]", deviceProfileDevicesRequestMsg, t);  
343 - futureToSet.setException(t);  
344 - }  
345 - }, dbCallbackExecutorService);  
346 } 292 }
347 - return futureToSet; 293 + return Futures.immediateFuture(null);
348 } 294 }
349 295
350 - private List<ListenableFuture<EdgeEvent>> syncDevices(TenantId tenantId, Edge edge, String deviceType) {  
351 - List<ListenableFuture<EdgeEvent>> futures = new ArrayList<>(); 296 + private void syncDevices(TenantId tenantId, Edge edge, String deviceType) {
352 log.trace("[{}] syncDevices [{}][{}]", tenantId, edge.getName(), deviceType); 297 log.trace("[{}] syncDevices [{}][{}]", tenantId, edge.getName(), deviceType);
353 try { 298 try {
354 PageLink pageLink = new PageLink(DEFAULT_PAGE_SIZE); 299 PageLink pageLink = new PageLink(DEFAULT_PAGE_SIZE);
@@ -358,7 +303,7 @@ public class DefaultEdgeRequestsService implements EdgeRequestsService { @@ -358,7 +303,7 @@ public class DefaultEdgeRequestsService implements EdgeRequestsService {
358 if (pageData != null && pageData.getData() != null && !pageData.getData().isEmpty()) { 303 if (pageData != null && pageData.getData() != null && !pageData.getData().isEmpty()) {
359 log.trace("[{}] [{}] device(s) are going to be pushed to edge.", edge.getId(), pageData.getData().size()); 304 log.trace("[{}] [{}] device(s) are going to be pushed to edge.", edge.getId(), pageData.getData().size());
360 for (Device device : pageData.getData()) { 305 for (Device device : pageData.getData()) {
361 - futures.add(saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE, EdgeEventActionType.ADDED, device.getId(), null)); 306 + saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE, EdgeEventActionType.ADDED, device.getId(), null);
362 } 307 }
363 if (pageData.hasNext()) { 308 if (pageData.hasNext()) {
364 pageLink = pageLink.nextPageLink(); 309 pageLink = pageLink.nextPageLink();
@@ -368,40 +313,25 @@ public class DefaultEdgeRequestsService implements EdgeRequestsService { @@ -368,40 +313,25 @@ public class DefaultEdgeRequestsService implements EdgeRequestsService {
368 } catch (Exception e) { 313 } catch (Exception e) {
369 log.error("Exception during loading edge device(s) on sync!", e); 314 log.error("Exception during loading edge device(s) on sync!", e);
370 } 315 }
371 - return futures;  
372 } 316 }
373 317
374 @Override 318 @Override
375 public ListenableFuture<Void> processWidgetBundleTypesRequestMsg(TenantId tenantId, Edge edge, 319 public ListenableFuture<Void> processWidgetBundleTypesRequestMsg(TenantId tenantId, Edge edge,
376 WidgetBundleTypesRequestMsg widgetBundleTypesRequestMsg) { 320 WidgetBundleTypesRequestMsg widgetBundleTypesRequestMsg) {
377 log.trace("[{}] processWidgetBundleTypesRequestMsg [{}][{}]", tenantId, edge.getName(), widgetBundleTypesRequestMsg); 321 log.trace("[{}] processWidgetBundleTypesRequestMsg [{}][{}]", tenantId, edge.getName(), widgetBundleTypesRequestMsg);
378 - SettableFuture<Void> futureToSet = SettableFuture.create();  
379 if (widgetBundleTypesRequestMsg.getWidgetBundleIdMSB() != 0 && widgetBundleTypesRequestMsg.getWidgetBundleIdLSB() != 0) { 322 if (widgetBundleTypesRequestMsg.getWidgetBundleIdMSB() != 0 && widgetBundleTypesRequestMsg.getWidgetBundleIdLSB() != 0) {
380 WidgetsBundleId widgetsBundleId = new WidgetsBundleId(new UUID(widgetBundleTypesRequestMsg.getWidgetBundleIdMSB(), widgetBundleTypesRequestMsg.getWidgetBundleIdLSB())); 323 WidgetsBundleId widgetsBundleId = new WidgetsBundleId(new UUID(widgetBundleTypesRequestMsg.getWidgetBundleIdMSB(), widgetBundleTypesRequestMsg.getWidgetBundleIdLSB()));
381 WidgetsBundle widgetsBundleById = widgetsBundleService.findWidgetsBundleById(tenantId, widgetsBundleId); 324 WidgetsBundle widgetsBundleById = widgetsBundleService.findWidgetsBundleById(tenantId, widgetsBundleId);
382 - List<ListenableFuture<EdgeEvent>> futures = new ArrayList<>();  
383 if (widgetsBundleById != null) { 325 if (widgetsBundleById != null) {
384 List<WidgetType> widgetTypesToPush = 326 List<WidgetType> widgetTypesToPush =
385 widgetTypeService.findWidgetTypesByTenantIdAndBundleAlias(widgetsBundleById.getTenantId(), widgetsBundleById.getAlias()); 327 widgetTypeService.findWidgetTypesByTenantIdAndBundleAlias(widgetsBundleById.getTenantId(), widgetsBundleById.getAlias());
386 328
387 for (WidgetType widgetType : widgetTypesToPush) { 329 for (WidgetType widgetType : widgetTypesToPush) {
388 - futures.add(saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.WIDGET_TYPE, EdgeEventActionType.ADDED, widgetType.getId(), null)); 330 + saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.WIDGET_TYPE, EdgeEventActionType.ADDED, widgetType.getId(), null);
389 } 331 }
390 } 332 }
391 - Futures.addCallback(Futures.allAsList(futures), new FutureCallback<>() {  
392 - @Override  
393 - public void onSuccess(@Nullable List<EdgeEvent> result) {  
394 - futureToSet.set(null);  
395 - }  
396 -  
397 - @Override  
398 - public void onFailure(Throwable t) {  
399 - log.error("Can't sync widget types by widget bundle [{}]", widgetBundleTypesRequestMsg, t);  
400 - futureToSet.setException(t);  
401 - }  
402 - }, dbCallbackExecutorService);  
403 } 333 }
404 - return futureToSet; 334 + return Futures.immediateFuture(null);
405 } 335 }
406 336
407 @Override 337 @Override
@@ -416,9 +346,12 @@ public class DefaultEdgeRequestsService implements EdgeRequestsService { @@ -416,9 +346,12 @@ public class DefaultEdgeRequestsService implements EdgeRequestsService {
416 public void onSuccess(@Nullable List<EntityView> entityViews) { 346 public void onSuccess(@Nullable List<EntityView> entityViews) {
417 try { 347 try {
418 if (entityViews != null && !entityViews.isEmpty()) { 348 if (entityViews != null && !entityViews.isEmpty()) {
  349 + List<ListenableFuture<Boolean>> futures = new ArrayList<>();
419 for (EntityView entityView : entityViews) { 350 for (EntityView entityView : entityViews) {
420 - Futures.addCallback(relationService.checkRelation(tenantId, edge.getId(), entityView.getId(),  
421 - EntityRelation.CONTAINS_TYPE, RelationTypeGroup.EDGE), new FutureCallback<>() { 351 + ListenableFuture<Boolean> future = relationService.checkRelation(tenantId, edge.getId(), entityView.getId(),
  352 + EntityRelation.CONTAINS_TYPE, RelationTypeGroup.EDGE);
  353 + futures.add(future);
  354 + Futures.addCallback(future, new FutureCallback<>() {
422 @Override 355 @Override
423 public void onSuccess(@Nullable Boolean result) { 356 public void onSuccess(@Nullable Boolean result) {
424 if (Boolean.TRUE.equals(result)) { 357 if (Boolean.TRUE.equals(result)) {
@@ -426,16 +359,27 @@ public class DefaultEdgeRequestsService implements EdgeRequestsService { @@ -426,16 +359,27 @@ public class DefaultEdgeRequestsService implements EdgeRequestsService {
426 EdgeEventActionType.ADDED, entityView.getId(), null); 359 EdgeEventActionType.ADDED, entityView.getId(), null);
427 } 360 }
428 } 361 }
429 -  
430 @Override 362 @Override
431 public void onFailure(Throwable t) { 363 public void onFailure(Throwable t) {
432 - log.error("Exception during loading relation [{}] to edge on sync!", t, t);  
433 - futureToSet.setException(t); 364 + // Do nothing - error handles in allAsList
434 } 365 }
435 }, dbCallbackExecutorService); 366 }, dbCallbackExecutorService);
436 } 367 }
  368 + Futures.addCallback(Futures.allAsList(futures), new FutureCallback<>() {
  369 + @Override
  370 + public void onSuccess(@Nullable List<Boolean> result) {
  371 + futureToSet.set(null);
  372 + }
  373 +
  374 + @Override
  375 + public void onFailure(Throwable t) {
  376 + log.error("Exception during loading relation [{}] to edge on sync!", t, t);
  377 + futureToSet.setException(t);
  378 + }
  379 + }, dbCallbackExecutorService);
  380 + } else {
  381 + futureToSet.set(null);
437 } 382 }
438 - futureToSet.set(null);  
439 } catch (Exception e) { 383 } catch (Exception e) {
440 log.error("Exception during loading relation(s) to edge on sync!", e); 384 log.error("Exception during loading relation(s) to edge on sync!", e);
441 futureToSet.setException(e); 385 futureToSet.setException(e);
@@ -451,30 +395,19 @@ public class DefaultEdgeRequestsService implements EdgeRequestsService { @@ -451,30 +395,19 @@ public class DefaultEdgeRequestsService implements EdgeRequestsService {
451 return futureToSet; 395 return futureToSet;
452 } 396 }
453 397
454 - private ListenableFuture<EdgeEvent> saveEdgeEvent(TenantId tenantId,  
455 - EdgeId edgeId,  
456 - EdgeEventType type,  
457 - EdgeEventActionType action,  
458 - EntityId entityId,  
459 - JsonNode body) { 398 + private void saveEdgeEvent(TenantId tenantId,
  399 + EdgeId edgeId,
  400 + EdgeEventType type,
  401 + EdgeEventActionType action,
  402 + EntityId entityId,
  403 + JsonNode body) {
460 log.trace("Pushing edge event to edge queue. tenantId [{}], edgeId [{}], type [{}], action[{}], entityId [{}], body [{}]", 404 log.trace("Pushing edge event to edge queue. tenantId [{}], edgeId [{}], type [{}], action[{}], entityId [{}], body [{}]",
461 tenantId, edgeId, type, action, entityId, body); 405 tenantId, edgeId, type, action, entityId, body);
462 406
463 EdgeEvent edgeEvent = EdgeEventUtils.constructEdgeEvent(tenantId, edgeId, type, action, entityId, body); 407 EdgeEvent edgeEvent = EdgeEventUtils.constructEdgeEvent(tenantId, edgeId, type, action, entityId, body);
464 408
465 - ListenableFuture<EdgeEvent> future = edgeEventService.saveAsync(edgeEvent);  
466 - Futures.addCallback(future, new FutureCallback<>() {  
467 - @Override  
468 - public void onSuccess(@Nullable EdgeEvent result) {  
469 - tbClusterService.onEdgeEventUpdate(tenantId, edgeId);  
470 - }  
471 -  
472 - @Override  
473 - public void onFailure(Throwable t) {  
474 - log.warn("[{}] Can't save edge event [{}] for edge [{}]", tenantId.getId(), edgeEvent, edgeId.getId(), t);  
475 - }  
476 - }, dbCallbackExecutorService);  
477 - return future; 409 + edgeEventService.save(edgeEvent);
  410 + tbClusterService.onEdgeEventUpdate(tenantId, edgeId);
478 } 411 }
479 412
480 } 413 }
@@ -939,7 +939,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { @@ -939,7 +939,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest {
939 String timeseriesData = "{\"data\":{\"temperature\":25},\"ts\":" + System.currentTimeMillis() + "}"; 939 String timeseriesData = "{\"data\":{\"temperature\":25},\"ts\":" + System.currentTimeMillis() + "}";
940 JsonNode timeseriesEntityData = mapper.readTree(timeseriesData); 940 JsonNode timeseriesEntityData = mapper.readTree(timeseriesData);
941 EdgeEvent edgeEvent = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.TIMESERIES_UPDATED, device.getId().getId(), EdgeEventType.DEVICE, timeseriesEntityData); 941 EdgeEvent edgeEvent = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.TIMESERIES_UPDATED, device.getId().getId(), EdgeEventType.DEVICE, timeseriesEntityData);
942 - edgeEventService.saveAsync(edgeEvent); 942 + edgeEventService.save(edgeEvent);
943 clusterService.onEdgeEventUpdate(tenantId, edge.getId()); 943 clusterService.onEdgeEventUpdate(tenantId, edge.getId());
944 Assert.assertTrue(edgeImitator.waitForMessages()); 944 Assert.assertTrue(edgeImitator.waitForMessages());
945 945
@@ -978,7 +978,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { @@ -978,7 +978,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest {
978 JsonNode attributesEntityData = mapper.readTree(attributesData); 978 JsonNode attributesEntityData = mapper.readTree(attributesData);
979 EdgeEvent edgeEvent1 = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.ATTRIBUTES_UPDATED, device.getId().getId(), EdgeEventType.DEVICE, attributesEntityData); 979 EdgeEvent edgeEvent1 = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.ATTRIBUTES_UPDATED, device.getId().getId(), EdgeEventType.DEVICE, attributesEntityData);
980 edgeImitator.expectMessageAmount(1); 980 edgeImitator.expectMessageAmount(1);
981 - edgeEventService.saveAsync(edgeEvent1); 981 + edgeEventService.save(edgeEvent1);
982 clusterService.onEdgeEventUpdate(tenantId, edge.getId()); 982 clusterService.onEdgeEventUpdate(tenantId, edge.getId());
983 Assert.assertTrue(edgeImitator.waitForMessages()); 983 Assert.assertTrue(edgeImitator.waitForMessages());
984 984
@@ -1003,7 +1003,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { @@ -1003,7 +1003,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest {
1003 JsonNode postAttributesEntityData = mapper.readTree(postAttributesData); 1003 JsonNode postAttributesEntityData = mapper.readTree(postAttributesData);
1004 EdgeEvent edgeEvent = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.POST_ATTRIBUTES, device.getId().getId(), EdgeEventType.DEVICE, postAttributesEntityData); 1004 EdgeEvent edgeEvent = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.POST_ATTRIBUTES, device.getId().getId(), EdgeEventType.DEVICE, postAttributesEntityData);
1005 edgeImitator.expectMessageAmount(1); 1005 edgeImitator.expectMessageAmount(1);
1006 - edgeEventService.saveAsync(edgeEvent); 1006 + edgeEventService.save(edgeEvent);
1007 clusterService.onEdgeEventUpdate(tenantId, edge.getId()); 1007 clusterService.onEdgeEventUpdate(tenantId, edge.getId());
1008 Assert.assertTrue(edgeImitator.waitForMessages()); 1008 Assert.assertTrue(edgeImitator.waitForMessages());
1009 1009
@@ -1028,7 +1028,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { @@ -1028,7 +1028,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest {
1028 JsonNode deleteAttributesEntityData = mapper.readTree(deleteAttributesData); 1028 JsonNode deleteAttributesEntityData = mapper.readTree(deleteAttributesData);
1029 EdgeEvent edgeEvent = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.ATTRIBUTES_DELETED, device.getId().getId(), EdgeEventType.DEVICE, deleteAttributesEntityData); 1029 EdgeEvent edgeEvent = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.ATTRIBUTES_DELETED, device.getId().getId(), EdgeEventType.DEVICE, deleteAttributesEntityData);
1030 edgeImitator.expectMessageAmount(1); 1030 edgeImitator.expectMessageAmount(1);
1031 - edgeEventService.saveAsync(edgeEvent); 1031 + edgeEventService.save(edgeEvent);
1032 clusterService.onEdgeEventUpdate(tenantId, edge.getId()); 1032 clusterService.onEdgeEventUpdate(tenantId, edge.getId());
1033 Assert.assertTrue(edgeImitator.waitForMessages()); 1033 Assert.assertTrue(edgeImitator.waitForMessages());
1034 1034
@@ -1062,7 +1062,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { @@ -1062,7 +1062,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest {
1062 1062
1063 EdgeEvent edgeEvent = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.RPC_CALL, device.getId().getId(), EdgeEventType.DEVICE, body); 1063 EdgeEvent edgeEvent = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.RPC_CALL, device.getId().getId(), EdgeEventType.DEVICE, body);
1064 edgeImitator.expectMessageAmount(1); 1064 edgeImitator.expectMessageAmount(1);
1065 - edgeEventService.saveAsync(edgeEvent); 1065 + edgeEventService.save(edgeEvent);
1066 clusterService.onEdgeEventUpdate(tenantId, edge.getId()); 1066 clusterService.onEdgeEventUpdate(tenantId, edge.getId());
1067 Assert.assertTrue(edgeImitator.waitForMessages()); 1067 Assert.assertTrue(edgeImitator.waitForMessages());
1068 1068
@@ -1088,7 +1088,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { @@ -1088,7 +1088,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest {
1088 JsonNode timeseriesEntityData = mapper.readTree(timeseriesData); 1088 JsonNode timeseriesEntityData = mapper.readTree(timeseriesData);
1089 EdgeEvent edgeEvent = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.TIMESERIES_UPDATED, 1089 EdgeEvent edgeEvent = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.TIMESERIES_UPDATED,
1090 device.getId().getId(), EdgeEventType.DEVICE, timeseriesEntityData); 1090 device.getId().getId(), EdgeEventType.DEVICE, timeseriesEntityData);
1091 - edgeEventService.saveAsync(edgeEvent); 1091 + edgeEventService.save(edgeEvent);
1092 clusterService.onEdgeEventUpdate(tenantId, edge.getId()); 1092 clusterService.onEdgeEventUpdate(tenantId, edge.getId());
1093 } 1093 }
1094 1094
@@ -15,7 +15,6 @@ @@ -15,7 +15,6 @@
15 */ 15 */
16 package org.thingsboard.server.dao.edge; 16 package org.thingsboard.server.dao.edge;
17 17
18 -import com.google.common.util.concurrent.ListenableFuture;  
19 import org.thingsboard.server.common.data.edge.EdgeEvent; 18 import org.thingsboard.server.common.data.edge.EdgeEvent;
20 import org.thingsboard.server.common.data.id.EdgeId; 19 import org.thingsboard.server.common.data.id.EdgeId;
21 import org.thingsboard.server.common.data.id.TenantId; 20 import org.thingsboard.server.common.data.id.TenantId;
@@ -24,7 +23,7 @@ import org.thingsboard.server.common.data.page.TimePageLink; @@ -24,7 +23,7 @@ import org.thingsboard.server.common.data.page.TimePageLink;
24 23
25 public interface EdgeEventService { 24 public interface EdgeEventService {
26 25
27 - ListenableFuture<EdgeEvent> saveAsync(EdgeEvent edgeEvent); 26 + EdgeEvent save(EdgeEvent edgeEvent);
28 27
29 PageData<EdgeEvent> findEdgeEvents(TenantId tenantId, EdgeId edgeId, TimePageLink pageLink, boolean withTsUpdate); 28 PageData<EdgeEvent> findEdgeEvents(TenantId tenantId, EdgeId edgeId, TimePageLink pageLink, boolean withTsUpdate);
30 29
@@ -15,9 +15,7 @@ @@ -15,9 +15,7 @@
15 */ 15 */
16 package org.thingsboard.server.dao.edge; 16 package org.thingsboard.server.dao.edge;
17 17
18 -import com.google.common.util.concurrent.ListenableFuture;  
19 import lombok.extern.slf4j.Slf4j; 18 import lombok.extern.slf4j.Slf4j;
20 -import org.apache.commons.lang3.StringUtils;  
21 import org.springframework.beans.factory.annotation.Autowired; 19 import org.springframework.beans.factory.annotation.Autowired;
22 import org.springframework.stereotype.Service; 20 import org.springframework.stereotype.Service;
23 import org.thingsboard.server.common.data.edge.EdgeEvent; 21 import org.thingsboard.server.common.data.edge.EdgeEvent;
@@ -36,9 +34,9 @@ public class BaseEdgeEventService implements EdgeEventService { @@ -36,9 +34,9 @@ public class BaseEdgeEventService implements EdgeEventService {
36 private EdgeEventDao edgeEventDao; 34 private EdgeEventDao edgeEventDao;
37 35
38 @Override 36 @Override
39 - public ListenableFuture<EdgeEvent> saveAsync(EdgeEvent edgeEvent) { 37 + public EdgeEvent save(EdgeEvent edgeEvent) {
40 edgeEventValidator.validate(edgeEvent, EdgeEvent::getTenantId); 38 edgeEventValidator.validate(edgeEvent, EdgeEvent::getTenantId);
41 - return edgeEventDao.saveAsync(edgeEvent); 39 + return edgeEventDao.save(edgeEvent);
42 } 40 }
43 41
44 @Override 42 @Override
@@ -30,12 +30,12 @@ import java.util.UUID; @@ -30,12 +30,12 @@ import java.util.UUID;
30 public interface EdgeEventDao extends Dao<EdgeEvent> { 30 public interface EdgeEventDao extends Dao<EdgeEvent> {
31 31
32 /** 32 /**
33 - * Save or update edge event object async 33 + * Save or update edge event object
34 * 34 *
35 * @param edgeEvent the event object 35 * @param edgeEvent the event object
36 * @return saved edge event object future 36 * @return saved edge event object future
37 */ 37 */
38 - ListenableFuture<EdgeEvent> saveAsync(EdgeEvent edgeEvent); 38 + EdgeEvent save(EdgeEvent edgeEvent);
39 39
40 40
41 /** 41 /**
@@ -41,6 +41,10 @@ import java.sql.ResultSet; @@ -41,6 +41,10 @@ import java.sql.ResultSet;
41 import java.sql.SQLException; 41 import java.sql.SQLException;
42 import java.util.Optional; 42 import java.util.Optional;
43 import java.util.UUID; 43 import java.util.UUID;
  44 +import java.util.concurrent.ConcurrentHashMap;
  45 +import java.util.concurrent.ConcurrentMap;
  46 +import java.util.concurrent.locks.Lock;
  47 +import java.util.concurrent.locks.ReentrantLock;
44 48
45 import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID; 49 import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID;
46 50
@@ -50,6 +54,8 @@ public class JpaBaseEdgeEventDao extends JpaAbstractSearchTextDao<EdgeEventEntit @@ -50,6 +54,8 @@ public class JpaBaseEdgeEventDao extends JpaAbstractSearchTextDao<EdgeEventEntit
50 54
51 private final UUID systemTenantId = NULL_UUID; 55 private final UUID systemTenantId = NULL_UUID;
52 56
  57 + private final ConcurrentMap<EdgeId, Lock> readWriteLocks = new ConcurrentHashMap<>();
  58 +
53 @Autowired 59 @Autowired
54 private EdgeEventRepository edgeEventRepository; 60 private EdgeEventRepository edgeEventRepository;
55 61
@@ -64,47 +70,59 @@ public class JpaBaseEdgeEventDao extends JpaAbstractSearchTextDao<EdgeEventEntit @@ -64,47 +70,59 @@ public class JpaBaseEdgeEventDao extends JpaAbstractSearchTextDao<EdgeEventEntit
64 } 70 }
65 71
66 @Override 72 @Override
67 - public ListenableFuture<EdgeEvent> saveAsync(EdgeEvent edgeEvent) {  
68 - log.debug("Save edge event [{}] ", edgeEvent);  
69 - if (edgeEvent.getId() == null) {  
70 - UUID timeBased = Uuids.timeBased();  
71 - edgeEvent.setId(new EdgeEventId(timeBased));  
72 - edgeEvent.setCreatedTime(Uuids.unixTimestamp(timeBased));  
73 - } else if (edgeEvent.getCreatedTime() == 0L) {  
74 - UUID eventId = edgeEvent.getId().getId();  
75 - if (eventId.version() == 1) {  
76 - edgeEvent.setCreatedTime(Uuids.unixTimestamp(eventId));  
77 - } else {  
78 - edgeEvent.setCreatedTime(System.currentTimeMillis()); 73 + public EdgeEvent save(EdgeEvent edgeEvent) {
  74 + final Lock readWriteLock = readWriteLocks.computeIfAbsent(edgeEvent.getEdgeId(), id -> new ReentrantLock());
  75 + readWriteLock.lock();
  76 + try {
  77 + log.debug("Save edge event [{}] ", edgeEvent);
  78 + if (edgeEvent.getId() == null) {
  79 + UUID timeBased = Uuids.timeBased();
  80 + edgeEvent.setId(new EdgeEventId(timeBased));
  81 + edgeEvent.setCreatedTime(Uuids.unixTimestamp(timeBased));
  82 + } else if (edgeEvent.getCreatedTime() == 0L) {
  83 + UUID eventId = edgeEvent.getId().getId();
  84 + if (eventId.version() == 1) {
  85 + edgeEvent.setCreatedTime(Uuids.unixTimestamp(eventId));
  86 + } else {
  87 + edgeEvent.setCreatedTime(System.currentTimeMillis());
  88 + }
79 } 89 }
  90 + if (StringUtils.isEmpty(edgeEvent.getUid())) {
  91 + edgeEvent.setUid(edgeEvent.getId().toString());
  92 + }
  93 + return save(new EdgeEventEntity(edgeEvent)).orElse(null);
  94 + } finally {
  95 + readWriteLock.unlock();
80 } 96 }
81 - if (StringUtils.isEmpty(edgeEvent.getUid())) {  
82 - edgeEvent.setUid(edgeEvent.getId().toString());  
83 - }  
84 - return service.submit(() -> save(new EdgeEventEntity(edgeEvent)).orElse(null));  
85 } 97 }
86 98
87 @Override 99 @Override
88 public PageData<EdgeEvent> findEdgeEvents(UUID tenantId, EdgeId edgeId, TimePageLink pageLink, boolean withTsUpdate) { 100 public PageData<EdgeEvent> findEdgeEvents(UUID tenantId, EdgeId edgeId, TimePageLink pageLink, boolean withTsUpdate) {
89 - if (withTsUpdate) {  
90 - return DaoUtil.toPageData(  
91 - edgeEventRepository  
92 - .findEdgeEventsByTenantIdAndEdgeId(  
93 - tenantId,  
94 - edgeId.getId(),  
95 - pageLink.getStartTime(),  
96 - pageLink.getEndTime(),  
97 - DaoUtil.toPageable(pageLink)));  
98 - } else {  
99 - return DaoUtil.toPageData(  
100 - edgeEventRepository  
101 - .findEdgeEventsByTenantIdAndEdgeIdWithoutTimeseriesUpdated(  
102 - tenantId,  
103 - edgeId.getId(),  
104 - pageLink.getStartTime(),  
105 - pageLink.getEndTime(),  
106 - DaoUtil.toPageable(pageLink))); 101 + final Lock readWriteLock = readWriteLocks.computeIfAbsent(edgeId, id -> new ReentrantLock());
  102 + readWriteLock.lock();
  103 + try {
  104 + if (withTsUpdate) {
  105 + return DaoUtil.toPageData(
  106 + edgeEventRepository
  107 + .findEdgeEventsByTenantIdAndEdgeId(
  108 + tenantId,
  109 + edgeId.getId(),
  110 + pageLink.getStartTime(),
  111 + pageLink.getEndTime(),
  112 + DaoUtil.toPageable(pageLink)));
  113 + } else {
  114 + return DaoUtil.toPageData(
  115 + edgeEventRepository
  116 + .findEdgeEventsByTenantIdAndEdgeIdWithoutTimeseriesUpdated(
  117 + tenantId,
  118 + edgeId.getId(),
  119 + pageLink.getStartTime(),
  120 + pageLink.getEndTime(),
  121 + DaoUtil.toPageable(pageLink)));
107 122
  123 + }
  124 + } finally {
  125 + readWriteLock.unlock();
108 } 126 }
109 } 127 }
110 128
@@ -42,7 +42,7 @@ public abstract class BaseEdgeEventServiceTest extends AbstractServiceTest { @@ -42,7 +42,7 @@ public abstract class BaseEdgeEventServiceTest extends AbstractServiceTest {
42 EdgeId edgeId = new EdgeId(Uuids.timeBased()); 42 EdgeId edgeId = new EdgeId(Uuids.timeBased());
43 DeviceId deviceId = new DeviceId(Uuids.timeBased()); 43 DeviceId deviceId = new DeviceId(Uuids.timeBased());
44 EdgeEvent edgeEvent = generateEdgeEvent(null, edgeId, deviceId, EdgeEventActionType.ADDED); 44 EdgeEvent edgeEvent = generateEdgeEvent(null, edgeId, deviceId, EdgeEventActionType.ADDED);
45 - EdgeEvent saved = edgeEventService.saveAsync(edgeEvent).get(); 45 + EdgeEvent saved = edgeEventService.save(edgeEvent);
46 Assert.assertEquals(saved.getTenantId(), edgeEvent.getTenantId()); 46 Assert.assertEquals(saved.getTenantId(), edgeEvent.getTenantId());
47 Assert.assertEquals(saved.getEdgeId(), edgeEvent.getEdgeId()); 47 Assert.assertEquals(saved.getEdgeId(), edgeEvent.getEdgeId());
48 Assert.assertEquals(saved.getEntityId(), edgeEvent.getEntityId()); 48 Assert.assertEquals(saved.getEntityId(), edgeEvent.getEntityId());
@@ -109,7 +109,7 @@ public abstract class BaseEdgeEventServiceTest extends AbstractServiceTest { @@ -109,7 +109,7 @@ public abstract class BaseEdgeEventServiceTest extends AbstractServiceTest {
109 TimePageLink pageLink = new TimePageLink(1); 109 TimePageLink pageLink = new TimePageLink(1);
110 110
111 EdgeEvent edgeEventWithTsUpdate = generateEdgeEvent(tenantId, edgeId, deviceId, EdgeEventActionType.TIMESERIES_UPDATED); 111 EdgeEvent edgeEventWithTsUpdate = generateEdgeEvent(tenantId, edgeId, deviceId, EdgeEventActionType.TIMESERIES_UPDATED);
112 - edgeEventService.saveAsync(edgeEventWithTsUpdate).get(); 112 + edgeEventService.save(edgeEventWithTsUpdate);
113 113
114 PageData<EdgeEvent> allEdgeEvents = edgeEventService.findEdgeEvents(tenantId, edgeId, pageLink, true); 114 PageData<EdgeEvent> allEdgeEvents = edgeEventService.findEdgeEvents(tenantId, edgeId, pageLink, true);
115 PageData<EdgeEvent> edgeEventsWithoutTsUpdate = edgeEventService.findEdgeEvents(tenantId, edgeId, pageLink, false); 115 PageData<EdgeEvent> edgeEventsWithoutTsUpdate = edgeEventService.findEdgeEvents(tenantId, edgeId, pageLink, false);
@@ -124,6 +124,6 @@ public abstract class BaseEdgeEventServiceTest extends AbstractServiceTest { @@ -124,6 +124,6 @@ public abstract class BaseEdgeEventServiceTest extends AbstractServiceTest {
124 private EdgeEvent saveEdgeEventWithProvidedTime(long time, EdgeId edgeId, EntityId entityId, TenantId tenantId) throws Exception { 124 private EdgeEvent saveEdgeEventWithProvidedTime(long time, EdgeId edgeId, EntityId entityId, TenantId tenantId) throws Exception {
125 EdgeEvent edgeEvent = generateEdgeEvent(tenantId, edgeId, entityId, EdgeEventActionType.ADDED); 125 EdgeEvent edgeEvent = generateEdgeEvent(tenantId, edgeId, entityId, EdgeEventActionType.ADDED);
126 edgeEvent.setId(new EdgeEventId(Uuids.startOf(time))); 126 edgeEvent.setId(new EdgeEventId(Uuids.startOf(time)));
127 - return edgeEventService.saveAsync(edgeEvent).get(); 127 + return edgeEventService.save(edgeEvent);
128 } 128 }
129 } 129 }
@@ -149,20 +149,9 @@ public class TbMsgPushToEdgeNode implements TbNode { @@ -149,20 +149,9 @@ public class TbMsgPushToEdgeNode implements TbNode {
149 149
150 private void notifyEdge(TbContext ctx, TbMsg msg, EdgeEvent edgeEvent, EdgeId edgeId) { 150 private void notifyEdge(TbContext ctx, TbMsg msg, EdgeEvent edgeEvent, EdgeId edgeId) {
151 edgeEvent.setEdgeId(edgeId); 151 edgeEvent.setEdgeId(edgeId);
152 - ListenableFuture<EdgeEvent> saveFuture = ctx.getEdgeEventService().saveAsync(edgeEvent);  
153 - Futures.addCallback(saveFuture, new FutureCallback<EdgeEvent>() {  
154 - @Override  
155 - public void onSuccess(@Nullable EdgeEvent event) {  
156 - ctx.tellNext(msg, SUCCESS);  
157 - ctx.onEdgeEventUpdate(ctx.getTenantId(), edgeId);  
158 - }  
159 -  
160 - @Override  
161 - public void onFailure(Throwable th) {  
162 - log.warn("[{}] Can't save edge event [{}] for edge [{}]", ctx.getTenantId().getId(), edgeEvent, edgeId.getId(), th);  
163 - ctx.tellFailure(msg, th);  
164 - }  
165 - }, ctx.getDbCallbackExecutor()); 152 + ctx.getEdgeEventService().save(edgeEvent);
  153 + ctx.tellNext(msg, SUCCESS);
  154 + ctx.onEdgeEventUpdate(ctx.getTenantId(), edgeId);
166 } 155 }
167 156
168 private EdgeEvent buildEdgeEvent(TbMsg msg, TbContext ctx) { 157 private EdgeEvent buildEdgeEvent(TbMsg msg, TbContext ctx) {