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
This commit is contained in:
		
						commit
						aa0d05bb44
					
				@ -97,11 +97,9 @@ import java.util.Arrays;
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.HashSet;
 | 
			
		||||
import java.util.LinkedHashMap;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
import java.util.Optional;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
import java.util.UUID;
 | 
			
		||||
import java.util.function.Consumer;
 | 
			
		||||
@ -729,20 +727,10 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
 | 
			
		||||
        edgeEvent.setBody(body);
 | 
			
		||||
 | 
			
		||||
        edgeEvent.setEdgeId(edgeId);
 | 
			
		||||
        ListenableFuture<EdgeEvent> future = systemContext.getEdgeEventService().saveAsync(edgeEvent);
 | 
			
		||||
        Futures.addCallback(future, new FutureCallback<EdgeEvent>() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onSuccess(EdgeEvent result) {
 | 
			
		||||
        systemContext.getEdgeEventService().save(edgeEvent);
 | 
			
		||||
        systemContext.getClusterService().onEdgeEventUpdate(tenantId, edgeId);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onFailure(Throwable t) {
 | 
			
		||||
                log.warn("[{}] Can't save edge event [{}] for edge [{}]", tenantId.getId(), edgeEvent, edgeId.getId(), t);
 | 
			
		||||
            }
 | 
			
		||||
        }, systemContext.getDbCallbackExecutor());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private List<TsKvProto> toTsKvProtos(@Nullable List<AttributeKvEntry> result) {
 | 
			
		||||
        List<TsKvProto> clientAttributes;
 | 
			
		||||
        if (result == null || result.isEmpty()) {
 | 
			
		||||
 | 
			
		||||
@ -16,11 +16,7 @@
 | 
			
		||||
package org.thingsboard.server.service.edge;
 | 
			
		||||
 | 
			
		||||
import com.fasterxml.jackson.databind.JsonNode;
 | 
			
		||||
import com.google.common.util.concurrent.FutureCallback;
 | 
			
		||||
import com.google.common.util.concurrent.Futures;
 | 
			
		||||
import com.google.common.util.concurrent.ListenableFuture;
 | 
			
		||||
import lombok.extern.slf4j.Slf4j;
 | 
			
		||||
import org.checkerframework.checker.nullness.qual.Nullable;
 | 
			
		||||
import org.springframework.beans.factory.annotation.Autowired;
 | 
			
		||||
import org.springframework.stereotype.Service;
 | 
			
		||||
import org.thingsboard.server.common.data.edge.Edge;
 | 
			
		||||
@ -41,7 +37,6 @@ import org.thingsboard.server.service.edge.rpc.processor.CustomerEdgeProcessor;
 | 
			
		||||
import org.thingsboard.server.service.edge.rpc.processor.EdgeProcessor;
 | 
			
		||||
import org.thingsboard.server.service.edge.rpc.processor.EntityEdgeProcessor;
 | 
			
		||||
import org.thingsboard.server.service.edge.rpc.processor.RelationEdgeProcessor;
 | 
			
		||||
import org.thingsboard.server.service.executors.DbCallbackExecutorService;
 | 
			
		||||
import org.thingsboard.server.service.queue.TbClusterService;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.PostConstruct;
 | 
			
		||||
@ -65,9 +60,6 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService {
 | 
			
		||||
    @Autowired
 | 
			
		||||
    private TbClusterService clusterService;
 | 
			
		||||
 | 
			
		||||
    @Autowired
 | 
			
		||||
    private DbCallbackExecutorService dbCallbackExecutorService;
 | 
			
		||||
 | 
			
		||||
    @Autowired
 | 
			
		||||
    private EdgeProcessor edgeProcessor;
 | 
			
		||||
 | 
			
		||||
@ -123,21 +115,10 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService {
 | 
			
		||||
            edgeEvent.setEntityId(entityId.getId());
 | 
			
		||||
        }
 | 
			
		||||
        edgeEvent.setBody(body);
 | 
			
		||||
        ListenableFuture<EdgeEvent> future = edgeEventService.saveAsync(edgeEvent);
 | 
			
		||||
        Futures.addCallback(future, new FutureCallback<EdgeEvent>() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onSuccess(@Nullable EdgeEvent result) {
 | 
			
		||||
        edgeEventService.save(edgeEvent);
 | 
			
		||||
        clusterService.onEdgeEventUpdate(tenantId, edgeId);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onFailure(Throwable t) {
 | 
			
		||||
                log.warn("[{}] Can't save edge event [{}] for edge [{}]", tenantId.getId(), edgeEvent, edgeId.getId(), t);
 | 
			
		||||
            }
 | 
			
		||||
        }, dbCallbackExecutorService);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void pushNotificationToEdge(TransportProtos.EdgeNotificationMsgProto edgeNotificationMsg, TbCallback callback) {
 | 
			
		||||
        try {
 | 
			
		||||
 | 
			
		||||
@ -259,7 +259,7 @@ public final class EdgeGrpcSession implements Closeable {
 | 
			
		||||
                log.error("[{}] Msg processing failed! Error msg: {}", edge.getRoutingKey(), msg.getErrorMsg());
 | 
			
		||||
            }
 | 
			
		||||
            if (sessionState.getPendingMsgsMap().isEmpty()) {
 | 
			
		||||
                log.debug("[{}] Pending msgs map is empty. Stopping current iteration {}", edge.getRoutingKey(), msg);
 | 
			
		||||
                log.debug("[{}] Pending msgs map is empty. Stopping current iteration", edge.getRoutingKey());
 | 
			
		||||
                if (sessionState.getScheduledSendDownlinkTask() != null) {
 | 
			
		||||
                    sessionState.getScheduledSendDownlinkTask().cancel(false);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
@ -17,11 +17,7 @@ package org.thingsboard.server.service.edge.rpc.processor;
 | 
			
		||||
 | 
			
		||||
import com.fasterxml.jackson.databind.JsonNode;
 | 
			
		||||
import com.fasterxml.jackson.databind.ObjectMapper;
 | 
			
		||||
import com.google.common.util.concurrent.FutureCallback;
 | 
			
		||||
import com.google.common.util.concurrent.Futures;
 | 
			
		||||
import com.google.common.util.concurrent.ListenableFuture;
 | 
			
		||||
import lombok.extern.slf4j.Slf4j;
 | 
			
		||||
import org.checkerframework.checker.nullness.qual.Nullable;
 | 
			
		||||
import org.springframework.beans.factory.annotation.Autowired;
 | 
			
		||||
import org.thingsboard.server.common.data.HasCustomerId;
 | 
			
		||||
import org.thingsboard.server.common.data.edge.Edge;
 | 
			
		||||
@ -178,7 +174,7 @@ public abstract class BaseEdgeProcessor {
 | 
			
		||||
    @Autowired
 | 
			
		||||
    protected DbCallbackExecutorService dbCallbackExecutorService;
 | 
			
		||||
 | 
			
		||||
    protected ListenableFuture<EdgeEvent> saveEdgeEvent(TenantId tenantId,
 | 
			
		||||
    protected void saveEdgeEvent(TenantId tenantId,
 | 
			
		||||
                                 EdgeId edgeId,
 | 
			
		||||
                                 EdgeEventType type,
 | 
			
		||||
                                 EdgeEventActionType action,
 | 
			
		||||
@ -197,21 +193,10 @@ public abstract class BaseEdgeProcessor {
 | 
			
		||||
            edgeEvent.setEntityId(entityId.getId());
 | 
			
		||||
        }
 | 
			
		||||
        edgeEvent.setBody(body);
 | 
			
		||||
        ListenableFuture<EdgeEvent> future = edgeEventService.saveAsync(edgeEvent);
 | 
			
		||||
        Futures.addCallback(future, new FutureCallback<EdgeEvent>() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onSuccess(@Nullable EdgeEvent result) {
 | 
			
		||||
        edgeEventService.save(edgeEvent);
 | 
			
		||||
        tbClusterService.onEdgeEventUpdate(tenantId, edgeId);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onFailure(Throwable t) {
 | 
			
		||||
                log.warn("[{}] Can't save edge event [{}] for edge [{}]", tenantId.getId(), edgeEvent, edgeId.getId(), t);
 | 
			
		||||
            }
 | 
			
		||||
        }, dbCallbackExecutorService);
 | 
			
		||||
        return future;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected CustomerId getCustomerIdIfEdgeAssignedToCustomer(HasCustomerId hasCustomerIdEntity, Edge edge) {
 | 
			
		||||
        if (!edge.getCustomerId().isNullUid() && edge.getCustomerId().equals(hasCustomerIdEntity.getCustomerId())) {
 | 
			
		||||
            return edge.getCustomerId();
 | 
			
		||||
 | 
			
		||||
@ -105,20 +105,9 @@ public class DeviceEdgeProcessor extends BaseEdgeProcessor {
 | 
			
		||||
                            Device newDevice = createDevice(tenantId, edge, deviceUpdateMsg, newDeviceName);
 | 
			
		||||
                            ObjectNode body = mapper.createObjectNode();
 | 
			
		||||
                            body.put("conflictName", deviceName);
 | 
			
		||||
                            ListenableFuture<EdgeEvent> future =
 | 
			
		||||
                            saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE, EdgeEventActionType.ENTITY_MERGE_REQUEST, newDevice.getId(), body);
 | 
			
		||||
                            Futures.addCallback(future, new FutureCallback<>() {
 | 
			
		||||
                                @Override
 | 
			
		||||
                                public void onSuccess(EdgeEvent edgeEvent) {
 | 
			
		||||
                            saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE, EdgeEventActionType.CREDENTIALS_REQUEST, newDevice.getId(), null);
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                                @Override
 | 
			
		||||
                                public void onFailure(Throwable t) {
 | 
			
		||||
                                    log.error("[{}] Failed to save ENTITY_MERGE_REQUEST edge event [{}][{}]", tenantId, deviceUpdateMsg, edge.getId(), t);
 | 
			
		||||
                                }
 | 
			
		||||
                            }, dbCallbackExecutorService);
 | 
			
		||||
                        }
 | 
			
		||||
                    } while (pageData != null && pageData.hasNext());
 | 
			
		||||
                } else {
 | 
			
		||||
                    log.info("[{}] Creating new device and replacing device entity on the edge [{}]", tenantId, deviceUpdateMsg);
 | 
			
		||||
 | 
			
		||||
@ -122,26 +122,13 @@ public class DefaultEdgeRequestsService implements EdgeRequestsService {
 | 
			
		||||
    @Override
 | 
			
		||||
    public ListenableFuture<Void> processRuleChainMetadataRequestMsg(TenantId tenantId, Edge edge, RuleChainMetadataRequestMsg ruleChainMetadataRequestMsg) {
 | 
			
		||||
        log.trace("[{}] processRuleChainMetadataRequestMsg [{}][{}]", tenantId, edge.getName(), ruleChainMetadataRequestMsg);
 | 
			
		||||
        SettableFuture<Void> futureToSet = SettableFuture.create();
 | 
			
		||||
        if (ruleChainMetadataRequestMsg.getRuleChainIdMSB() != 0 && ruleChainMetadataRequestMsg.getRuleChainIdLSB() != 0) {
 | 
			
		||||
            RuleChainId ruleChainId =
 | 
			
		||||
                    new RuleChainId(new UUID(ruleChainMetadataRequestMsg.getRuleChainIdMSB(), ruleChainMetadataRequestMsg.getRuleChainIdLSB()));
 | 
			
		||||
            ListenableFuture<EdgeEvent> future = saveEdgeEvent(tenantId, edge.getId(),
 | 
			
		||||
            saveEdgeEvent(tenantId, edge.getId(),
 | 
			
		||||
                    EdgeEventType.RULE_CHAIN_METADATA, EdgeEventActionType.ADDED, ruleChainId, null);
 | 
			
		||||
            Futures.addCallback(future, new FutureCallback<EdgeEvent>() {
 | 
			
		||||
                @Override
 | 
			
		||||
                public void onSuccess(@Nullable EdgeEvent result) {
 | 
			
		||||
                    futureToSet.set(null);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
                @Override
 | 
			
		||||
                public void onFailure(Throwable t) {
 | 
			
		||||
                    log.error("Can't save edge event [{}]", ruleChainMetadataRequestMsg, t);
 | 
			
		||||
                    futureToSet.setException(t);
 | 
			
		||||
                }
 | 
			
		||||
            }, dbCallbackExecutorService);
 | 
			
		||||
        }
 | 
			
		||||
        return futureToSet;
 | 
			
		||||
        return Futures.immediateFuture(null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
@ -154,8 +141,8 @@ public class DefaultEdgeRequestsService implements EdgeRequestsService {
 | 
			
		||||
        if (type != null) {
 | 
			
		||||
            SettableFuture<Void> futureToSet = SettableFuture.create();
 | 
			
		||||
            String scope = attributesRequestMsg.getScope();
 | 
			
		||||
            ListenableFuture<List<AttributeKvEntry>> ssAttrFuture = attributesService.findAll(tenantId, entityId, scope);
 | 
			
		||||
            Futures.addCallback(ssAttrFuture, new FutureCallback<List<AttributeKvEntry>>() {
 | 
			
		||||
            ListenableFuture<List<AttributeKvEntry>> findAttrFuture = attributesService.findAll(tenantId, entityId, scope);
 | 
			
		||||
            Futures.addCallback(findAttrFuture, new FutureCallback<List<AttributeKvEntry>>() {
 | 
			
		||||
                @Override
 | 
			
		||||
                public void onSuccess(@Nullable List<AttributeKvEntry> ssAttributes) {
 | 
			
		||||
                    if (ssAttributes != null && !ssAttributes.isEmpty()) {
 | 
			
		||||
@ -184,8 +171,9 @@ public class DefaultEdgeRequestsService implements EdgeRequestsService {
 | 
			
		||||
                                    entityId,
 | 
			
		||||
                                    body);
 | 
			
		||||
                        } catch (Exception e) {
 | 
			
		||||
                            log.error("[{}] Failed to send attribute updates to the edge", edge.getName(), e);
 | 
			
		||||
                            throw new RuntimeException("[" + edge.getName() + "] Failed to send attribute updates to the edge", e);
 | 
			
		||||
                            log.error("[{}] Failed to save attribute updates to the edge", edge.getName(), e);
 | 
			
		||||
                            futureToSet.setException(new RuntimeException("[" + edge.getName() + "] Failed to send attribute updates to the edge", e));
 | 
			
		||||
                            return;
 | 
			
		||||
                        }
 | 
			
		||||
                    } else {
 | 
			
		||||
                        log.trace("[{}][{}] No attributes found for entity {} [{}]", tenantId,
 | 
			
		||||
@ -198,7 +186,7 @@ public class DefaultEdgeRequestsService implements EdgeRequestsService {
 | 
			
		||||
 | 
			
		||||
                @Override
 | 
			
		||||
                public void onFailure(Throwable t) {
 | 
			
		||||
                    log.error("Can't save attributes [{}]", attributesRequestMsg, t);
 | 
			
		||||
                    log.error("Can't find attributes [{}]", attributesRequestMsg, t);
 | 
			
		||||
                    futureToSet.setException(t);
 | 
			
		||||
                }
 | 
			
		||||
            }, dbCallbackExecutorService);
 | 
			
		||||
@ -273,82 +261,39 @@ public class DefaultEdgeRequestsService implements EdgeRequestsService {
 | 
			
		||||
    @Override
 | 
			
		||||
    public ListenableFuture<Void> processDeviceCredentialsRequestMsg(TenantId tenantId, Edge edge, DeviceCredentialsRequestMsg deviceCredentialsRequestMsg) {
 | 
			
		||||
        log.trace("[{}] processDeviceCredentialsRequestMsg [{}][{}]", tenantId, edge.getName(), deviceCredentialsRequestMsg);
 | 
			
		||||
        SettableFuture<Void> futureToSet = SettableFuture.create();
 | 
			
		||||
        if (deviceCredentialsRequestMsg.getDeviceIdMSB() != 0 && deviceCredentialsRequestMsg.getDeviceIdLSB() != 0) {
 | 
			
		||||
            DeviceId deviceId = new DeviceId(new UUID(deviceCredentialsRequestMsg.getDeviceIdMSB(), deviceCredentialsRequestMsg.getDeviceIdLSB()));
 | 
			
		||||
            ListenableFuture<EdgeEvent> future = saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE,
 | 
			
		||||
            saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE,
 | 
			
		||||
                    EdgeEventActionType.CREDENTIALS_UPDATED, deviceId, null);
 | 
			
		||||
            Futures.addCallback(future, new FutureCallback<EdgeEvent>() {
 | 
			
		||||
                @Override
 | 
			
		||||
                public void onSuccess(@Nullable EdgeEvent result) {
 | 
			
		||||
                    futureToSet.set(null);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
                @Override
 | 
			
		||||
                public void onFailure(Throwable t) {
 | 
			
		||||
                    log.error("Can't save edge event [{}]", deviceCredentialsRequestMsg, t);
 | 
			
		||||
                    futureToSet.setException(t);
 | 
			
		||||
                }
 | 
			
		||||
            }, dbCallbackExecutorService);
 | 
			
		||||
        }
 | 
			
		||||
        return futureToSet;
 | 
			
		||||
        return Futures.immediateFuture(null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public ListenableFuture<Void> processUserCredentialsRequestMsg(TenantId tenantId, Edge edge, UserCredentialsRequestMsg userCredentialsRequestMsg) {
 | 
			
		||||
        log.trace("[{}] processUserCredentialsRequestMsg [{}][{}]", tenantId, edge.getName(), userCredentialsRequestMsg);
 | 
			
		||||
        SettableFuture<Void> futureToSet = SettableFuture.create();
 | 
			
		||||
        if (userCredentialsRequestMsg.getUserIdMSB() != 0 && userCredentialsRequestMsg.getUserIdLSB() != 0) {
 | 
			
		||||
            UserId userId = new UserId(new UUID(userCredentialsRequestMsg.getUserIdMSB(), userCredentialsRequestMsg.getUserIdLSB()));
 | 
			
		||||
            ListenableFuture<EdgeEvent> future = saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.USER,
 | 
			
		||||
            saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.USER,
 | 
			
		||||
                    EdgeEventActionType.CREDENTIALS_UPDATED, userId, null);
 | 
			
		||||
            Futures.addCallback(future, new FutureCallback<>() {
 | 
			
		||||
                @Override
 | 
			
		||||
                public void onSuccess(@Nullable EdgeEvent result) {
 | 
			
		||||
                    futureToSet.set(null);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
                @Override
 | 
			
		||||
                public void onFailure(Throwable t) {
 | 
			
		||||
                    log.error("Can't save edge event [{}]", userCredentialsRequestMsg, t);
 | 
			
		||||
                    futureToSet.setException(t);
 | 
			
		||||
                }
 | 
			
		||||
            }, dbCallbackExecutorService);
 | 
			
		||||
        }
 | 
			
		||||
        return futureToSet;
 | 
			
		||||
        return Futures.immediateFuture(null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public ListenableFuture<Void> processDeviceProfileDevicesRequestMsg(TenantId tenantId, Edge edge, DeviceProfileDevicesRequestMsg deviceProfileDevicesRequestMsg) {
 | 
			
		||||
        log.trace("[{}] processDeviceProfileDevicesRequestMsg [{}][{}]", tenantId, edge.getName(), deviceProfileDevicesRequestMsg);
 | 
			
		||||
        SettableFuture<Void> futureToSet = SettableFuture.create();
 | 
			
		||||
        if (deviceProfileDevicesRequestMsg.getDeviceProfileIdMSB() != 0 && deviceProfileDevicesRequestMsg.getDeviceProfileIdLSB() != 0) {
 | 
			
		||||
            DeviceProfileId deviceProfileId = new DeviceProfileId(new UUID(deviceProfileDevicesRequestMsg.getDeviceProfileIdMSB(), deviceProfileDevicesRequestMsg.getDeviceProfileIdLSB()));
 | 
			
		||||
            DeviceProfile deviceProfileById = deviceProfileService.findDeviceProfileById(tenantId, deviceProfileId);
 | 
			
		||||
            List<ListenableFuture<EdgeEvent>> futures;
 | 
			
		||||
            if (deviceProfileById != null) {
 | 
			
		||||
                futures = syncDevices(tenantId, edge, deviceProfileById.getName());
 | 
			
		||||
            } else {
 | 
			
		||||
                futures = new ArrayList<>();
 | 
			
		||||
                syncDevices(tenantId, edge, deviceProfileById.getName());
 | 
			
		||||
            }
 | 
			
		||||
            Futures.addCallback(Futures.allAsList(futures), new FutureCallback<>() {
 | 
			
		||||
                @Override
 | 
			
		||||
                public void onSuccess(@Nullable List<EdgeEvent> result) {
 | 
			
		||||
                    futureToSet.set(null);
 | 
			
		||||
        }
 | 
			
		||||
        return Futures.immediateFuture(null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
                @Override
 | 
			
		||||
                public void onFailure(Throwable t) {
 | 
			
		||||
                    log.error("Can't sync devices by device profile [{}]", deviceProfileDevicesRequestMsg, t);
 | 
			
		||||
                    futureToSet.setException(t);
 | 
			
		||||
                }
 | 
			
		||||
            }, dbCallbackExecutorService);
 | 
			
		||||
        }
 | 
			
		||||
        return futureToSet;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private List<ListenableFuture<EdgeEvent>> syncDevices(TenantId tenantId, Edge edge, String deviceType) {
 | 
			
		||||
        List<ListenableFuture<EdgeEvent>> futures = new ArrayList<>();
 | 
			
		||||
    private void syncDevices(TenantId tenantId, Edge edge, String deviceType) {
 | 
			
		||||
        log.trace("[{}] syncDevices [{}][{}]", tenantId, edge.getName(), deviceType);
 | 
			
		||||
        try {
 | 
			
		||||
            PageLink pageLink = new PageLink(DEFAULT_PAGE_SIZE);
 | 
			
		||||
@ -358,7 +303,7 @@ public class DefaultEdgeRequestsService implements EdgeRequestsService {
 | 
			
		||||
                if (pageData != null && pageData.getData() != null && !pageData.getData().isEmpty()) {
 | 
			
		||||
                    log.trace("[{}] [{}] device(s) are going to be pushed to edge.", edge.getId(), pageData.getData().size());
 | 
			
		||||
                    for (Device device : pageData.getData()) {
 | 
			
		||||
                        futures.add(saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE, EdgeEventActionType.ADDED, device.getId(), null));
 | 
			
		||||
                        saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE, EdgeEventActionType.ADDED, device.getId(), null);
 | 
			
		||||
                    }
 | 
			
		||||
                    if (pageData.hasNext()) {
 | 
			
		||||
                        pageLink = pageLink.nextPageLink();
 | 
			
		||||
@ -368,40 +313,25 @@ public class DefaultEdgeRequestsService implements EdgeRequestsService {
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            log.error("Exception during loading edge device(s) on sync!", e);
 | 
			
		||||
        }
 | 
			
		||||
        return futures;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public ListenableFuture<Void> processWidgetBundleTypesRequestMsg(TenantId tenantId, Edge edge,
 | 
			
		||||
                                                                     WidgetBundleTypesRequestMsg widgetBundleTypesRequestMsg) {
 | 
			
		||||
        log.trace("[{}] processWidgetBundleTypesRequestMsg [{}][{}]", tenantId, edge.getName(), widgetBundleTypesRequestMsg);
 | 
			
		||||
        SettableFuture<Void> futureToSet = SettableFuture.create();
 | 
			
		||||
        if (widgetBundleTypesRequestMsg.getWidgetBundleIdMSB() != 0 && widgetBundleTypesRequestMsg.getWidgetBundleIdLSB() != 0) {
 | 
			
		||||
            WidgetsBundleId widgetsBundleId = new WidgetsBundleId(new UUID(widgetBundleTypesRequestMsg.getWidgetBundleIdMSB(), widgetBundleTypesRequestMsg.getWidgetBundleIdLSB()));
 | 
			
		||||
            WidgetsBundle widgetsBundleById = widgetsBundleService.findWidgetsBundleById(tenantId, widgetsBundleId);
 | 
			
		||||
            List<ListenableFuture<EdgeEvent>> futures = new ArrayList<>();
 | 
			
		||||
            if (widgetsBundleById != null) {
 | 
			
		||||
                List<WidgetType> widgetTypesToPush =
 | 
			
		||||
                        widgetTypeService.findWidgetTypesByTenantIdAndBundleAlias(widgetsBundleById.getTenantId(), widgetsBundleById.getAlias());
 | 
			
		||||
 | 
			
		||||
                for (WidgetType widgetType : widgetTypesToPush) {
 | 
			
		||||
                    futures.add(saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.WIDGET_TYPE, EdgeEventActionType.ADDED, widgetType.getId(), null));
 | 
			
		||||
                    saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.WIDGET_TYPE, EdgeEventActionType.ADDED, widgetType.getId(), null);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            Futures.addCallback(Futures.allAsList(futures), new FutureCallback<>() {
 | 
			
		||||
                @Override
 | 
			
		||||
                public void onSuccess(@Nullable List<EdgeEvent> result) {
 | 
			
		||||
                    futureToSet.set(null);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
                @Override
 | 
			
		||||
                public void onFailure(Throwable t) {
 | 
			
		||||
                    log.error("Can't sync widget types by widget bundle [{}]", widgetBundleTypesRequestMsg, t);
 | 
			
		||||
                    futureToSet.setException(t);
 | 
			
		||||
                }
 | 
			
		||||
            }, dbCallbackExecutorService);
 | 
			
		||||
        }
 | 
			
		||||
        return futureToSet;
 | 
			
		||||
        return Futures.immediateFuture(null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
@ -416,9 +346,12 @@ public class DefaultEdgeRequestsService implements EdgeRequestsService {
 | 
			
		||||
            public void onSuccess(@Nullable List<EntityView> entityViews) {
 | 
			
		||||
                try {
 | 
			
		||||
                    if (entityViews != null && !entityViews.isEmpty()) {
 | 
			
		||||
                        List<ListenableFuture<Boolean>> futures = new ArrayList<>();
 | 
			
		||||
                        for (EntityView entityView : entityViews) {
 | 
			
		||||
                            Futures.addCallback(relationService.checkRelation(tenantId, edge.getId(), entityView.getId(),
 | 
			
		||||
                                    EntityRelation.CONTAINS_TYPE, RelationTypeGroup.EDGE), new FutureCallback<>() {
 | 
			
		||||
                            ListenableFuture<Boolean> future = relationService.checkRelation(tenantId, edge.getId(), entityView.getId(),
 | 
			
		||||
                                    EntityRelation.CONTAINS_TYPE, RelationTypeGroup.EDGE);
 | 
			
		||||
                            futures.add(future);
 | 
			
		||||
                            Futures.addCallback(future, new FutureCallback<>() {
 | 
			
		||||
                                @Override
 | 
			
		||||
                                public void onSuccess(@Nullable Boolean result) {
 | 
			
		||||
                                    if (Boolean.TRUE.equals(result)) {
 | 
			
		||||
@ -426,6 +359,17 @@ public class DefaultEdgeRequestsService implements EdgeRequestsService {
 | 
			
		||||
                                                EdgeEventActionType.ADDED, entityView.getId(), null);
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                                @Override
 | 
			
		||||
                                public void onFailure(Throwable t) {
 | 
			
		||||
                                    // Do nothing - error handles in allAsList
 | 
			
		||||
                                }
 | 
			
		||||
                            }, dbCallbackExecutorService);
 | 
			
		||||
                        }
 | 
			
		||||
                        Futures.addCallback(Futures.allAsList(futures), new FutureCallback<>() {
 | 
			
		||||
                            @Override
 | 
			
		||||
                            public void onSuccess(@Nullable List<Boolean> result) {
 | 
			
		||||
                                futureToSet.set(null);
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            @Override
 | 
			
		||||
                            public void onFailure(Throwable t) {
 | 
			
		||||
@ -433,9 +377,9 @@ public class DefaultEdgeRequestsService implements EdgeRequestsService {
 | 
			
		||||
                                futureToSet.setException(t);
 | 
			
		||||
                            }
 | 
			
		||||
                        }, dbCallbackExecutorService);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    } else {
 | 
			
		||||
                        futureToSet.set(null);
 | 
			
		||||
                    }
 | 
			
		||||
                } catch (Exception e) {
 | 
			
		||||
                    log.error("Exception during loading relation(s) to edge on sync!", e);
 | 
			
		||||
                    futureToSet.setException(e);
 | 
			
		||||
@ -451,7 +395,7 @@ public class DefaultEdgeRequestsService implements EdgeRequestsService {
 | 
			
		||||
        return futureToSet;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private ListenableFuture<EdgeEvent> saveEdgeEvent(TenantId tenantId,
 | 
			
		||||
    private void saveEdgeEvent(TenantId tenantId,
 | 
			
		||||
                               EdgeId edgeId,
 | 
			
		||||
                               EdgeEventType type,
 | 
			
		||||
                               EdgeEventActionType action,
 | 
			
		||||
@ -462,19 +406,8 @@ public class DefaultEdgeRequestsService implements EdgeRequestsService {
 | 
			
		||||
 | 
			
		||||
        EdgeEvent edgeEvent = EdgeEventUtils.constructEdgeEvent(tenantId, edgeId, type, action, entityId, body);
 | 
			
		||||
 | 
			
		||||
        ListenableFuture<EdgeEvent> future = edgeEventService.saveAsync(edgeEvent);
 | 
			
		||||
        Futures.addCallback(future, new FutureCallback<>() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onSuccess(@Nullable EdgeEvent result) {
 | 
			
		||||
        edgeEventService.save(edgeEvent);
 | 
			
		||||
        tbClusterService.onEdgeEventUpdate(tenantId, edgeId);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onFailure(Throwable t) {
 | 
			
		||||
                log.warn("[{}] Can't save edge event [{}] for edge [{}]", tenantId.getId(), edgeEvent, edgeId.getId(), t);
 | 
			
		||||
            }
 | 
			
		||||
        }, dbCallbackExecutorService);
 | 
			
		||||
        return future;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -939,7 +939,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest {
 | 
			
		||||
        String timeseriesData = "{\"data\":{\"temperature\":25},\"ts\":" + System.currentTimeMillis() + "}";
 | 
			
		||||
        JsonNode timeseriesEntityData = mapper.readTree(timeseriesData);
 | 
			
		||||
        EdgeEvent edgeEvent = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.TIMESERIES_UPDATED, device.getId().getId(), EdgeEventType.DEVICE, timeseriesEntityData);
 | 
			
		||||
        edgeEventService.saveAsync(edgeEvent);
 | 
			
		||||
        edgeEventService.save(edgeEvent);
 | 
			
		||||
        clusterService.onEdgeEventUpdate(tenantId, edge.getId());
 | 
			
		||||
        Assert.assertTrue(edgeImitator.waitForMessages());
 | 
			
		||||
 | 
			
		||||
@ -978,7 +978,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest {
 | 
			
		||||
        JsonNode attributesEntityData = mapper.readTree(attributesData);
 | 
			
		||||
        EdgeEvent edgeEvent1 = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.ATTRIBUTES_UPDATED, device.getId().getId(), EdgeEventType.DEVICE, attributesEntityData);
 | 
			
		||||
        edgeImitator.expectMessageAmount(1);
 | 
			
		||||
        edgeEventService.saveAsync(edgeEvent1);
 | 
			
		||||
        edgeEventService.save(edgeEvent1);
 | 
			
		||||
        clusterService.onEdgeEventUpdate(tenantId, edge.getId());
 | 
			
		||||
        Assert.assertTrue(edgeImitator.waitForMessages());
 | 
			
		||||
 | 
			
		||||
@ -1003,7 +1003,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest {
 | 
			
		||||
        JsonNode postAttributesEntityData = mapper.readTree(postAttributesData);
 | 
			
		||||
        EdgeEvent edgeEvent = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.POST_ATTRIBUTES, device.getId().getId(), EdgeEventType.DEVICE, postAttributesEntityData);
 | 
			
		||||
        edgeImitator.expectMessageAmount(1);
 | 
			
		||||
        edgeEventService.saveAsync(edgeEvent);
 | 
			
		||||
        edgeEventService.save(edgeEvent);
 | 
			
		||||
        clusterService.onEdgeEventUpdate(tenantId, edge.getId());
 | 
			
		||||
        Assert.assertTrue(edgeImitator.waitForMessages());
 | 
			
		||||
 | 
			
		||||
@ -1028,7 +1028,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest {
 | 
			
		||||
        JsonNode deleteAttributesEntityData = mapper.readTree(deleteAttributesData);
 | 
			
		||||
        EdgeEvent edgeEvent = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.ATTRIBUTES_DELETED, device.getId().getId(), EdgeEventType.DEVICE, deleteAttributesEntityData);
 | 
			
		||||
        edgeImitator.expectMessageAmount(1);
 | 
			
		||||
        edgeEventService.saveAsync(edgeEvent);
 | 
			
		||||
        edgeEventService.save(edgeEvent);
 | 
			
		||||
        clusterService.onEdgeEventUpdate(tenantId, edge.getId());
 | 
			
		||||
        Assert.assertTrue(edgeImitator.waitForMessages());
 | 
			
		||||
 | 
			
		||||
@ -1062,7 +1062,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest {
 | 
			
		||||
 | 
			
		||||
        EdgeEvent edgeEvent = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.RPC_CALL, device.getId().getId(), EdgeEventType.DEVICE, body);
 | 
			
		||||
        edgeImitator.expectMessageAmount(1);
 | 
			
		||||
        edgeEventService.saveAsync(edgeEvent);
 | 
			
		||||
        edgeEventService.save(edgeEvent);
 | 
			
		||||
        clusterService.onEdgeEventUpdate(tenantId, edge.getId());
 | 
			
		||||
        Assert.assertTrue(edgeImitator.waitForMessages());
 | 
			
		||||
 | 
			
		||||
@ -1088,7 +1088,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest {
 | 
			
		||||
            JsonNode timeseriesEntityData = mapper.readTree(timeseriesData);
 | 
			
		||||
            EdgeEvent edgeEvent = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.TIMESERIES_UPDATED,
 | 
			
		||||
                    device.getId().getId(), EdgeEventType.DEVICE, timeseriesEntityData);
 | 
			
		||||
            edgeEventService.saveAsync(edgeEvent);
 | 
			
		||||
            edgeEventService.save(edgeEvent);
 | 
			
		||||
            clusterService.onEdgeEventUpdate(tenantId, edge.getId());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -15,7 +15,6 @@
 | 
			
		||||
 */
 | 
			
		||||
package org.thingsboard.server.dao.edge;
 | 
			
		||||
 | 
			
		||||
import com.google.common.util.concurrent.ListenableFuture;
 | 
			
		||||
import org.thingsboard.server.common.data.edge.EdgeEvent;
 | 
			
		||||
import org.thingsboard.server.common.data.id.EdgeId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.TenantId;
 | 
			
		||||
@ -24,7 +23,7 @@ import org.thingsboard.server.common.data.page.TimePageLink;
 | 
			
		||||
 | 
			
		||||
public interface EdgeEventService {
 | 
			
		||||
 | 
			
		||||
    ListenableFuture<EdgeEvent> saveAsync(EdgeEvent edgeEvent);
 | 
			
		||||
    EdgeEvent save(EdgeEvent edgeEvent);
 | 
			
		||||
 | 
			
		||||
    PageData<EdgeEvent> findEdgeEvents(TenantId tenantId, EdgeId edgeId, TimePageLink pageLink, boolean withTsUpdate);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -15,9 +15,7 @@
 | 
			
		||||
 */
 | 
			
		||||
package org.thingsboard.server.dao.edge;
 | 
			
		||||
 | 
			
		||||
import com.google.common.util.concurrent.ListenableFuture;
 | 
			
		||||
import lombok.extern.slf4j.Slf4j;
 | 
			
		||||
import org.apache.commons.lang3.StringUtils;
 | 
			
		||||
import org.springframework.beans.factory.annotation.Autowired;
 | 
			
		||||
import org.springframework.stereotype.Service;
 | 
			
		||||
import org.thingsboard.server.common.data.edge.EdgeEvent;
 | 
			
		||||
@ -36,9 +34,9 @@ public class BaseEdgeEventService implements EdgeEventService {
 | 
			
		||||
    private EdgeEventDao edgeEventDao;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public ListenableFuture<EdgeEvent> saveAsync(EdgeEvent edgeEvent) {
 | 
			
		||||
    public EdgeEvent save(EdgeEvent edgeEvent) {
 | 
			
		||||
        edgeEventValidator.validate(edgeEvent, EdgeEvent::getTenantId);
 | 
			
		||||
        return edgeEventDao.saveAsync(edgeEvent);
 | 
			
		||||
        return edgeEventDao.save(edgeEvent);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
 | 
			
		||||
@ -30,12 +30,12 @@ import java.util.UUID;
 | 
			
		||||
public interface EdgeEventDao extends Dao<EdgeEvent> {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Save or update edge event object async
 | 
			
		||||
     * Save or update edge event object
 | 
			
		||||
     *
 | 
			
		||||
     * @param edgeEvent the event object
 | 
			
		||||
     * @return saved edge event object future
 | 
			
		||||
     */
 | 
			
		||||
    ListenableFuture<EdgeEvent> saveAsync(EdgeEvent edgeEvent);
 | 
			
		||||
    EdgeEvent save(EdgeEvent edgeEvent);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 | 
			
		||||
@ -41,6 +41,10 @@ import java.sql.ResultSet;
 | 
			
		||||
import java.sql.SQLException;
 | 
			
		||||
import java.util.Optional;
 | 
			
		||||
import java.util.UUID;
 | 
			
		||||
import java.util.concurrent.ConcurrentHashMap;
 | 
			
		||||
import java.util.concurrent.ConcurrentMap;
 | 
			
		||||
import java.util.concurrent.locks.Lock;
 | 
			
		||||
import java.util.concurrent.locks.ReentrantLock;
 | 
			
		||||
 | 
			
		||||
import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID;
 | 
			
		||||
 | 
			
		||||
@ -50,6 +54,8 @@ public class JpaBaseEdgeEventDao extends JpaAbstractSearchTextDao<EdgeEventEntit
 | 
			
		||||
 | 
			
		||||
    private final UUID systemTenantId = NULL_UUID;
 | 
			
		||||
 | 
			
		||||
    private final ConcurrentMap<EdgeId, Lock> readWriteLocks = new ConcurrentHashMap<>();
 | 
			
		||||
 | 
			
		||||
    @Autowired
 | 
			
		||||
    private EdgeEventRepository edgeEventRepository;
 | 
			
		||||
 | 
			
		||||
@ -64,7 +70,10 @@ public class JpaBaseEdgeEventDao extends JpaAbstractSearchTextDao<EdgeEventEntit
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public ListenableFuture<EdgeEvent> saveAsync(EdgeEvent edgeEvent) {
 | 
			
		||||
    public EdgeEvent save(EdgeEvent edgeEvent) {
 | 
			
		||||
        final Lock readWriteLock = readWriteLocks.computeIfAbsent(edgeEvent.getEdgeId(), id -> new ReentrantLock());
 | 
			
		||||
        readWriteLock.lock();
 | 
			
		||||
        try {
 | 
			
		||||
            log.debug("Save edge event [{}] ", edgeEvent);
 | 
			
		||||
            if (edgeEvent.getId() == null) {
 | 
			
		||||
                UUID timeBased = Uuids.timeBased();
 | 
			
		||||
@ -81,11 +90,17 @@ public class JpaBaseEdgeEventDao extends JpaAbstractSearchTextDao<EdgeEventEntit
 | 
			
		||||
            if (StringUtils.isEmpty(edgeEvent.getUid())) {
 | 
			
		||||
                edgeEvent.setUid(edgeEvent.getId().toString());
 | 
			
		||||
            }
 | 
			
		||||
        return service.submit(() -> save(new EdgeEventEntity(edgeEvent)).orElse(null));
 | 
			
		||||
            return save(new EdgeEventEntity(edgeEvent)).orElse(null);
 | 
			
		||||
        } finally {
 | 
			
		||||
            readWriteLock.unlock();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public PageData<EdgeEvent> findEdgeEvents(UUID tenantId, EdgeId edgeId, TimePageLink pageLink, boolean withTsUpdate) {
 | 
			
		||||
        final Lock readWriteLock = readWriteLocks.computeIfAbsent(edgeId, id -> new ReentrantLock());
 | 
			
		||||
        readWriteLock.lock();
 | 
			
		||||
        try {
 | 
			
		||||
            if (withTsUpdate) {
 | 
			
		||||
                return DaoUtil.toPageData(
 | 
			
		||||
                        edgeEventRepository
 | 
			
		||||
@ -106,6 +121,9 @@ public class JpaBaseEdgeEventDao extends JpaAbstractSearchTextDao<EdgeEventEntit
 | 
			
		||||
                                        DaoUtil.toPageable(pageLink)));
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
        } finally {
 | 
			
		||||
            readWriteLock.unlock();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Optional<EdgeEvent> save(EdgeEventEntity entity) {
 | 
			
		||||
 | 
			
		||||
@ -42,7 +42,7 @@ public abstract class BaseEdgeEventServiceTest extends AbstractServiceTest {
 | 
			
		||||
        EdgeId edgeId = new EdgeId(Uuids.timeBased());
 | 
			
		||||
        DeviceId deviceId = new DeviceId(Uuids.timeBased());
 | 
			
		||||
        EdgeEvent edgeEvent = generateEdgeEvent(null, edgeId, deviceId, EdgeEventActionType.ADDED);
 | 
			
		||||
        EdgeEvent saved = edgeEventService.saveAsync(edgeEvent).get();
 | 
			
		||||
        EdgeEvent saved = edgeEventService.save(edgeEvent);
 | 
			
		||||
        Assert.assertEquals(saved.getTenantId(), edgeEvent.getTenantId());
 | 
			
		||||
        Assert.assertEquals(saved.getEdgeId(), edgeEvent.getEdgeId());
 | 
			
		||||
        Assert.assertEquals(saved.getEntityId(), edgeEvent.getEntityId());
 | 
			
		||||
@ -109,7 +109,7 @@ public abstract class BaseEdgeEventServiceTest extends AbstractServiceTest {
 | 
			
		||||
        TimePageLink pageLink = new TimePageLink(1);
 | 
			
		||||
 | 
			
		||||
        EdgeEvent edgeEventWithTsUpdate = generateEdgeEvent(tenantId, edgeId, deviceId, EdgeEventActionType.TIMESERIES_UPDATED);
 | 
			
		||||
        edgeEventService.saveAsync(edgeEventWithTsUpdate).get();
 | 
			
		||||
        edgeEventService.save(edgeEventWithTsUpdate);
 | 
			
		||||
 | 
			
		||||
        PageData<EdgeEvent> allEdgeEvents = edgeEventService.findEdgeEvents(tenantId, edgeId, pageLink, true);
 | 
			
		||||
        PageData<EdgeEvent> edgeEventsWithoutTsUpdate = edgeEventService.findEdgeEvents(tenantId, edgeId, pageLink, false);
 | 
			
		||||
@ -124,6 +124,6 @@ public abstract class BaseEdgeEventServiceTest extends AbstractServiceTest {
 | 
			
		||||
    private EdgeEvent saveEdgeEventWithProvidedTime(long time, EdgeId edgeId, EntityId entityId, TenantId tenantId) throws Exception {
 | 
			
		||||
        EdgeEvent edgeEvent = generateEdgeEvent(tenantId, edgeId, entityId, EdgeEventActionType.ADDED);
 | 
			
		||||
        edgeEvent.setId(new EdgeEventId(Uuids.startOf(time)));
 | 
			
		||||
        return edgeEventService.saveAsync(edgeEvent).get();
 | 
			
		||||
        return edgeEventService.save(edgeEvent);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -149,22 +149,11 @@ public class TbMsgPushToEdgeNode implements TbNode {
 | 
			
		||||
 | 
			
		||||
    private void notifyEdge(TbContext ctx, TbMsg msg, EdgeEvent edgeEvent, EdgeId edgeId) {
 | 
			
		||||
        edgeEvent.setEdgeId(edgeId);
 | 
			
		||||
        ListenableFuture<EdgeEvent> saveFuture = ctx.getEdgeEventService().saveAsync(edgeEvent);
 | 
			
		||||
        Futures.addCallback(saveFuture, new FutureCallback<EdgeEvent>() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onSuccess(@Nullable EdgeEvent event) {
 | 
			
		||||
        ctx.getEdgeEventService().save(edgeEvent);
 | 
			
		||||
        ctx.tellNext(msg, SUCCESS);
 | 
			
		||||
        ctx.onEdgeEventUpdate(ctx.getTenantId(), edgeId);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onFailure(Throwable th) {
 | 
			
		||||
                log.warn("[{}] Can't save edge event [{}] for edge [{}]", ctx.getTenantId().getId(), edgeEvent, edgeId.getId(), th);
 | 
			
		||||
                ctx.tellFailure(msg, th);
 | 
			
		||||
            }
 | 
			
		||||
        }, ctx.getDbCallbackExecutor());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private EdgeEvent buildEdgeEvent(TbMsg msg, TbContext ctx) {
 | 
			
		||||
        String msgType = msg.getType();
 | 
			
		||||
        if (DataConstants.ALARM.equals(msgType)) {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user