Commit 3e42f00cf789797737e21d9504d8fc14fd91e631

Authored by Volodymyr Babak
1 parent ab14bcb9

Ack cloud messages

@@ -24,6 +24,7 @@ import com.fasterxml.jackson.databind.node.ObjectNode; @@ -24,6 +24,7 @@ import com.fasterxml.jackson.databind.node.ObjectNode;
24 import com.google.common.util.concurrent.FutureCallback; 24 import com.google.common.util.concurrent.FutureCallback;
25 import com.google.common.util.concurrent.Futures; 25 import com.google.common.util.concurrent.Futures;
26 import com.google.common.util.concurrent.ListenableFuture; 26 import com.google.common.util.concurrent.ListenableFuture;
  27 +import com.google.common.util.concurrent.MoreExecutors;
27 import com.google.gson.Gson; 28 import com.google.gson.Gson;
28 import com.google.gson.JsonElement; 29 import com.google.gson.JsonElement;
29 import com.google.gson.JsonObject; 30 import com.google.gson.JsonObject;
@@ -81,6 +82,7 @@ import org.thingsboard.server.common.msg.queue.ServiceType; @@ -81,6 +82,7 @@ import org.thingsboard.server.common.msg.queue.ServiceType;
81 import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; 82 import org.thingsboard.server.common.msg.queue.TopicPartitionInfo;
82 import org.thingsboard.server.common.msg.session.SessionMsgType; 83 import org.thingsboard.server.common.msg.session.SessionMsgType;
83 import org.thingsboard.server.common.transport.util.JsonUtils; 84 import org.thingsboard.server.common.transport.util.JsonUtils;
  85 +import org.thingsboard.server.gen.edge.AdminSettingsUpdateMsg;
84 import org.thingsboard.server.gen.edge.AlarmUpdateMsg; 86 import org.thingsboard.server.gen.edge.AlarmUpdateMsg;
85 import org.thingsboard.server.gen.edge.AssetUpdateMsg; 87 import org.thingsboard.server.gen.edge.AssetUpdateMsg;
86 import org.thingsboard.server.gen.edge.AttributesRequestMsg; 88 import org.thingsboard.server.gen.edge.AttributesRequestMsg;
@@ -93,11 +95,12 @@ import org.thingsboard.server.gen.edge.DeviceCredentialsRequestMsg; @@ -93,11 +95,12 @@ import org.thingsboard.server.gen.edge.DeviceCredentialsRequestMsg;
93 import org.thingsboard.server.gen.edge.DeviceCredentialsUpdateMsg; 95 import org.thingsboard.server.gen.edge.DeviceCredentialsUpdateMsg;
94 import org.thingsboard.server.gen.edge.DeviceUpdateMsg; 96 import org.thingsboard.server.gen.edge.DeviceUpdateMsg;
95 import org.thingsboard.server.gen.edge.DownlinkMsg; 97 import org.thingsboard.server.gen.edge.DownlinkMsg;
  98 +import org.thingsboard.server.gen.edge.DownlinkResponseMsg;
96 import org.thingsboard.server.gen.edge.EdgeConfiguration; 99 import org.thingsboard.server.gen.edge.EdgeConfiguration;
97 import org.thingsboard.server.gen.edge.EntityDataProto; 100 import org.thingsboard.server.gen.edge.EntityDataProto;
98 -import org.thingsboard.server.gen.edge.EntityUpdateMsg;  
99 import org.thingsboard.server.gen.edge.EntityViewUpdateMsg; 101 import org.thingsboard.server.gen.edge.EntityViewUpdateMsg;
100 import org.thingsboard.server.gen.edge.RelationRequestMsg; 102 import org.thingsboard.server.gen.edge.RelationRequestMsg;
  103 +import org.thingsboard.server.gen.edge.RelationUpdateMsg;
101 import org.thingsboard.server.gen.edge.RequestMsg; 104 import org.thingsboard.server.gen.edge.RequestMsg;
102 import org.thingsboard.server.gen.edge.RequestMsgType; 105 import org.thingsboard.server.gen.edge.RequestMsgType;
103 import org.thingsboard.server.gen.edge.ResponseMsg; 106 import org.thingsboard.server.gen.edge.ResponseMsg;
@@ -120,11 +123,14 @@ import org.thingsboard.server.service.edge.EdgeContextComponent; @@ -120,11 +123,14 @@ import org.thingsboard.server.service.edge.EdgeContextComponent;
120 123
121 import java.io.Closeable; 124 import java.io.Closeable;
122 import java.io.IOException; 125 import java.io.IOException;
  126 +import java.util.ArrayList;
123 import java.util.Collections; 127 import java.util.Collections;
124 import java.util.List; 128 import java.util.List;
125 import java.util.Optional; 129 import java.util.Optional;
126 import java.util.UUID; 130 import java.util.UUID;
  131 +import java.util.concurrent.CountDownLatch;
127 import java.util.concurrent.ExecutionException; 132 import java.util.concurrent.ExecutionException;
  133 +import java.util.concurrent.TimeUnit;
128 import java.util.concurrent.locks.ReentrantLock; 134 import java.util.concurrent.locks.ReentrantLock;
129 import java.util.function.BiConsumer; 135 import java.util.function.BiConsumer;
130 import java.util.function.Consumer; 136 import java.util.function.Consumer;
@@ -137,6 +143,8 @@ public final class EdgeGrpcSession implements Closeable { @@ -137,6 +143,8 @@ public final class EdgeGrpcSession implements Closeable {
137 143
138 private static final ReentrantLock deviceCreationLock = new ReentrantLock(); 144 private static final ReentrantLock deviceCreationLock = new ReentrantLock();
139 145
  146 + private static final ReentrantLock responseMsgLock = new ReentrantLock();
  147 +
140 private final Gson gson = new Gson(); 148 private final Gson gson = new Gson();
141 149
142 private static final String QUEUE_START_TS_ATTR_KEY = "queueStartTs"; 150 private static final String QUEUE_START_TS_ATTR_KEY = "queueStartTs";
@@ -152,6 +160,8 @@ public final class EdgeGrpcSession implements Closeable { @@ -152,6 +160,8 @@ public final class EdgeGrpcSession implements Closeable {
152 private StreamObserver<ResponseMsg> outputStream; 160 private StreamObserver<ResponseMsg> outputStream;
153 private boolean connected; 161 private boolean connected;
154 162
  163 + private CountDownLatch latch;
  164 +
155 private TbQueueProducer<TbProtoQueueMsg<TransportProtos.ToRuleEngineMsg>> ruleEngineMsgProducer; 165 private TbQueueProducer<TbProtoQueueMsg<TransportProtos.ToRuleEngineMsg>> ruleEngineMsgProducer;
156 166
157 EdgeGrpcSession(EdgeContextComponent ctx, StreamObserver<ResponseMsg> outputStream, BiConsumer<EdgeId, EdgeGrpcSession> sessionOpenListener, 167 EdgeGrpcSession(EdgeContextComponent ctx, StreamObserver<ResponseMsg> outputStream, BiConsumer<EdgeId, EdgeGrpcSession> sessionOpenListener,
@@ -172,7 +182,7 @@ public final class EdgeGrpcSession implements Closeable { @@ -172,7 +182,7 @@ public final class EdgeGrpcSession implements Closeable {
172 public void onNext(RequestMsg requestMsg) { 182 public void onNext(RequestMsg requestMsg) {
173 if (!connected && requestMsg.getMsgType().equals(RequestMsgType.CONNECT_RPC_MESSAGE)) { 183 if (!connected && requestMsg.getMsgType().equals(RequestMsgType.CONNECT_RPC_MESSAGE)) {
174 ConnectResponseMsg responseMsg = processConnect(requestMsg.getConnectRequestMsg()); 184 ConnectResponseMsg responseMsg = processConnect(requestMsg.getConnectRequestMsg());
175 - outputStream.onNext(ResponseMsg.newBuilder() 185 + sendResponseMsg(ResponseMsg.newBuilder()
176 .setConnectResponseMsg(responseMsg) 186 .setConnectResponseMsg(responseMsg)
177 .build()); 187 .build());
178 if (ConnectResponseCode.ACCEPTED != responseMsg.getResponseCode()) { 188 if (ConnectResponseCode.ACCEPTED != responseMsg.getResponseCode()) {
@@ -184,9 +194,10 @@ public final class EdgeGrpcSession implements Closeable { @@ -184,9 +194,10 @@ public final class EdgeGrpcSession implements Closeable {
184 } 194 }
185 if (connected) { 195 if (connected) {
186 if (requestMsg.getMsgType().equals(RequestMsgType.UPLINK_RPC_MESSAGE) && requestMsg.hasUplinkMsg()) { 196 if (requestMsg.getMsgType().equals(RequestMsgType.UPLINK_RPC_MESSAGE) && requestMsg.hasUplinkMsg()) {
187 - outputStream.onNext(ResponseMsg.newBuilder()  
188 - .setUplinkResponseMsg(processUplinkMsg(requestMsg.getUplinkMsg()))  
189 - .build()); 197 + onUplinkMsg(requestMsg.getUplinkMsg());
  198 + }
  199 + if (requestMsg.getMsgType().equals(RequestMsgType.UPLINK_RPC_MESSAGE) && requestMsg.hasDownlinkResponseMsg()) {
  200 + onDownlinkResponse(requestMsg.getDownlinkResponseMsg());
190 } 201 }
191 } 202 }
192 } 203 }
@@ -204,11 +215,54 @@ public final class EdgeGrpcSession implements Closeable { @@ -204,11 +215,54 @@ public final class EdgeGrpcSession implements Closeable {
204 }; 215 };
205 } 216 }
206 217
  218 + private void onUplinkMsg(UplinkMsg uplinkMsg) {
  219 + ListenableFuture<List<Void>> future = processUplinkMsg(uplinkMsg);
  220 + Futures.addCallback(future, new FutureCallback<List<Void>>() {
  221 + @Override
  222 + public void onSuccess(@Nullable List<Void> result) {
  223 + UplinkResponseMsg uplinkResponseMsg = UplinkResponseMsg.newBuilder().setSuccess(true).build();
  224 + sendResponseMsg(ResponseMsg.newBuilder()
  225 + .setUplinkResponseMsg(uplinkResponseMsg)
  226 + .build());
  227 + }
  228 +
  229 + @Override
  230 + public void onFailure(Throwable t) {
  231 + UplinkResponseMsg uplinkResponseMsg = UplinkResponseMsg.newBuilder().setSuccess(false).setErrorMsg(t.getMessage()).build();
  232 + sendResponseMsg(ResponseMsg.newBuilder()
  233 + .setUplinkResponseMsg(uplinkResponseMsg)
  234 + .build());
  235 + }
  236 + }, MoreExecutors.directExecutor());
  237 + }
  238 +
  239 + private void onDownlinkResponse(DownlinkResponseMsg msg) {
  240 + try {
  241 + if (msg.getSuccess()) {
  242 + log.debug("[{}] Msg has been processed successfully! {}", edge.getRoutingKey(), msg);
  243 + } else {
  244 + log.error("[{}] Msg processing failed! Error msg: {}", edge.getRoutingKey(), msg.getErrorMsg());
  245 + }
  246 + latch.countDown();
  247 + } catch (Exception e) {
  248 + log.error("Can't process downlink response message [{}]", msg, e);
  249 + }
  250 + }
  251 +
  252 + private void sendResponseMsg(ResponseMsg responseMsg) {
  253 + try {
  254 + responseMsgLock.lock();
  255 + outputStream.onNext(responseMsg);
  256 + } finally {
  257 + responseMsgLock.unlock();
  258 + }
  259 + }
  260 +
207 void onConfigurationUpdate(Edge edge) { 261 void onConfigurationUpdate(Edge edge) {
208 try { 262 try {
209 this.edge = edge; 263 this.edge = edge;
210 // TODO: voba - push edge configuration update to edge 264 // TODO: voba - push edge configuration update to edge
211 -// outputStream.onNext(org.thingsboard.server.gen.integration.ResponseMsg.newBuilder() 265 +// sendResponseMsg(org.thingsboard.server.gen.integration.ResponseMsg.newBuilder()
212 // .setIntegrationUpdateMsg(IntegrationUpdateMsg.newBuilder() 266 // .setIntegrationUpdateMsg(IntegrationUpdateMsg.newBuilder()
213 // .setConfiguration(constructIntegrationConfigProto(configuration, defaultConverterProto, downLinkConverterProto)) 267 // .setConfiguration(constructIntegrationConfigProto(configuration, defaultConverterProto, downLinkConverterProto))
214 // .build()) 268 // .build())
@@ -223,48 +277,39 @@ public final class EdgeGrpcSession implements Closeable { @@ -223,48 +277,39 @@ public final class EdgeGrpcSession implements Closeable {
223 TimePageLink pageLink = new TimePageLink(ctx.getEdgeEventStorageSettings().getMaxReadRecordsCount(), queueStartTs, null, true); 277 TimePageLink pageLink = new TimePageLink(ctx.getEdgeEventStorageSettings().getMaxReadRecordsCount(), queueStartTs, null, true);
224 TimePageData<EdgeEvent> pageData; 278 TimePageData<EdgeEvent> pageData;
225 UUID ifOffset = null; 279 UUID ifOffset = null;
  280 + boolean success = true;
226 do { 281 do {
227 pageData = ctx.getEdgeNotificationService().findEdgeEvents(edge.getTenantId(), edge.getId(), pageLink); 282 pageData = ctx.getEdgeNotificationService().findEdgeEvents(edge.getTenantId(), edge.getId(), pageLink);
228 if (isConnected() && !pageData.getData().isEmpty()) { 283 if (isConnected() && !pageData.getData().isEmpty()) {
229 log.trace("[{}] [{}] event(s) are going to be processed.", this.sessionId, pageData.getData().size()); 284 log.trace("[{}] [{}] event(s) are going to be processed.", this.sessionId, pageData.getData().size());
230 - for (EdgeEvent edgeEvent : pageData.getData()) {  
231 - log.trace("[{}] Processing edge event [{}]", this.sessionId, edgeEvent);  
232 - try {  
233 - ActionType edgeEventAction = ActionType.valueOf(edgeEvent.getEdgeEventAction());  
234 - switch (edgeEventAction) {  
235 - case UPDATED:  
236 - case ADDED:  
237 - case ASSIGNED_TO_EDGE:  
238 - case DELETED:  
239 - case UNASSIGNED_FROM_EDGE:  
240 - case ALARM_ACK:  
241 - case ALARM_CLEAR:  
242 - case CREDENTIALS_UPDATED:  
243 - case RELATION_ADD_OR_UPDATE:  
244 - case RELATION_DELETED:  
245 - processEntityMessage(edgeEvent, edgeEventAction);  
246 - break;  
247 - case ATTRIBUTES_UPDATED:  
248 - case ATTRIBUTES_DELETED:  
249 - case TIMESERIES_UPDATED:  
250 - processTelemetryMessage(edgeEvent);  
251 - break;  
252 - }  
253 - } catch (Exception e) {  
254 - log.error("Exception during processing records from queue", e);  
255 - }  
256 - ifOffset = edgeEvent.getUuidId(); 285 + List<DownlinkMsg> downlinkMsgsPack = convertToDownlinkMsgsPack(pageData.getData());
  286 + log.trace("[{}] downlink msg(s) are going to be send.", downlinkMsgsPack.size());
  287 +
  288 + latch = new CountDownLatch(downlinkMsgsPack.size());
  289 + for (DownlinkMsg downlinkMsg : downlinkMsgsPack) {
  290 + sendResponseMsg(ResponseMsg.newBuilder()
  291 + .setDownlinkMsg(downlinkMsg)
  292 + .build());
  293 + }
  294 +
  295 + ifOffset = pageData.getData().get(pageData.getData().size() - 1).getUuidId();
  296 +
  297 + success = latch.await(10, TimeUnit.SECONDS);
  298 + if (!success) {
  299 + log.warn("Failed to deliver the batch: {}", downlinkMsgsPack);
257 } 300 }
258 } 301 }
259 - if (isConnected() && pageData.hasNext()) {  
260 - pageLink = pageData.getNextPageLink(); 302 + if (isConnected() && (!success || pageData.hasNext())) {
261 try { 303 try {
262 Thread.sleep(ctx.getEdgeEventStorageSettings().getSleepIntervalBetweenBatches()); 304 Thread.sleep(ctx.getEdgeEventStorageSettings().getSleepIntervalBetweenBatches());
263 } catch (InterruptedException e) { 305 } catch (InterruptedException e) {
264 log.error("Error during sleep between batches", e); 306 log.error("Error during sleep between batches", e);
265 } 307 }
  308 + if (success) {
  309 + pageLink = pageData.getNextPageLink();
  310 + }
266 } 311 }
267 - } while (isConnected() && pageData.hasNext()); 312 + } while (isConnected() && (!success || pageData.hasNext()));
268 313
269 if (ifOffset != null) { 314 if (ifOffset != null) {
270 Long newStartTs = UUIDs.unixTimestamp(ifOffset); 315 Long newStartTs = UUIDs.unixTimestamp(ifOffset);
@@ -277,6 +322,42 @@ public final class EdgeGrpcSession implements Closeable { @@ -277,6 +322,42 @@ public final class EdgeGrpcSession implements Closeable {
277 } 322 }
278 } 323 }
279 324
  325 + private List<DownlinkMsg> convertToDownlinkMsgsPack(List<EdgeEvent> edgeEvents) {
  326 + List<DownlinkMsg> result = new ArrayList<>();
  327 + for (EdgeEvent edgeEvent : edgeEvents) {
  328 + log.trace("Processing edge event [{}]", edgeEvent);
  329 + try {
  330 + DownlinkMsg downlinkMsg = null;
  331 + ActionType edgeEventAction = ActionType.valueOf(edgeEvent.getEdgeEventAction());
  332 + switch (edgeEventAction) {
  333 + case UPDATED:
  334 + case ADDED:
  335 + case ASSIGNED_TO_EDGE:
  336 + case DELETED:
  337 + case UNASSIGNED_FROM_EDGE:
  338 + case ALARM_ACK:
  339 + case ALARM_CLEAR:
  340 + case CREDENTIALS_UPDATED:
  341 + case RELATION_ADD_OR_UPDATE:
  342 + case RELATION_DELETED:
  343 + downlinkMsg = processEntityMessage(edgeEvent, edgeEventAction);
  344 + break;
  345 + case ATTRIBUTES_UPDATED:
  346 + case ATTRIBUTES_DELETED:
  347 + case TIMESERIES_UPDATED:
  348 + downlinkMsg = processTelemetryMessage(edgeEvent);
  349 + break;
  350 + }
  351 + if (downlinkMsg != null) {
  352 + result.add(downlinkMsg);
  353 + }
  354 + } catch (Exception e) {
  355 + log.error("Exception during processing records from queue", e);
  356 + }
  357 + }
  358 + return result;
  359 + }
  360 +
280 private ListenableFuture<Long> getQueueStartTs() { 361 private ListenableFuture<Long> getQueueStartTs() {
281 ListenableFuture<Optional<AttributeKvEntry>> future = 362 ListenableFuture<Optional<AttributeKvEntry>> future =
282 ctx.getAttributesService().find(edge.getTenantId(), edge.getId(), DataConstants.SERVER_SCOPE, QUEUE_START_TS_ATTR_KEY); 363 ctx.getAttributesService().find(edge.getTenantId(), edge.getId(), DataConstants.SERVER_SCOPE, QUEUE_START_TS_ATTR_KEY);
@@ -296,7 +377,7 @@ public final class EdgeGrpcSession implements Closeable { @@ -296,7 +377,7 @@ public final class EdgeGrpcSession implements Closeable {
296 ctx.getAttributesService().save(edge.getTenantId(), edge.getId(), DataConstants.SERVER_SCOPE, attributes); 377 ctx.getAttributesService().save(edge.getTenantId(), edge.getId(), DataConstants.SERVER_SCOPE, attributes);
297 } 378 }
298 379
299 - private void processTelemetryMessage(EdgeEvent edgeEvent) throws IOException { 380 + private DownlinkMsg processTelemetryMessage(EdgeEvent edgeEvent) throws IOException {
300 log.trace("Executing processTelemetryMessage, edgeEvent [{}]", edgeEvent); 381 log.trace("Executing processTelemetryMessage, edgeEvent [{}]", edgeEvent);
301 EntityId entityId = null; 382 EntityId entityId = null;
302 switch (edgeEvent.getEdgeEventType()) { 383 switch (edgeEvent.getEdgeEventType()) {
@@ -319,74 +400,61 @@ public final class EdgeGrpcSession implements Closeable { @@ -319,74 +400,61 @@ public final class EdgeGrpcSession implements Closeable {
319 entityId = new CustomerId(edgeEvent.getEntityId()); 400 entityId = new CustomerId(edgeEvent.getEntityId());
320 break; 401 break;
321 } 402 }
  403 + DownlinkMsg downlinkMsg = null;
322 if (entityId != null) { 404 if (entityId != null) {
323 log.debug("Sending telemetry data msg, entityId [{}], body [{}]", edgeEvent.getEntityId(), edgeEvent.getEntityBody()); 405 log.debug("Sending telemetry data msg, entityId [{}], body [{}]", edgeEvent.getEntityId(), edgeEvent.getEntityBody());
324 - DownlinkMsg downlinkMsg;  
325 try { 406 try {
326 ActionType actionType = ActionType.valueOf(edgeEvent.getEdgeEventAction()); 407 ActionType actionType = ActionType.valueOf(edgeEvent.getEdgeEventAction());
327 downlinkMsg = constructEntityDataProtoMsg(entityId, actionType, JsonUtils.parse(mapper.writeValueAsString(edgeEvent.getEntityBody()))); 408 downlinkMsg = constructEntityDataProtoMsg(entityId, actionType, JsonUtils.parse(mapper.writeValueAsString(edgeEvent.getEntityBody())));
328 - outputStream.onNext(ResponseMsg.newBuilder()  
329 - .setDownlinkMsg(downlinkMsg)  
330 - .build());  
331 } catch (Exception e) { 409 } catch (Exception e) {
332 log.warn("Can't send telemetry data msg, entityId [{}], body [{}]", edgeEvent.getEntityId(), edgeEvent.getEntityBody(), e); 410 log.warn("Can't send telemetry data msg, entityId [{}], body [{}]", edgeEvent.getEntityId(), edgeEvent.getEntityBody(), e);
333 } 411 }
334 -  
335 } 412 }
  413 + return downlinkMsg;
336 } 414 }
337 415
338 - private void processEntityMessage(EdgeEvent edgeEvent, ActionType edgeEventAction) { 416 + private DownlinkMsg processEntityMessage(EdgeEvent edgeEvent, ActionType edgeEventAction) {
339 UpdateMsgType msgType = getResponseMsgType(ActionType.valueOf(edgeEvent.getEdgeEventAction())); 417 UpdateMsgType msgType = getResponseMsgType(ActionType.valueOf(edgeEvent.getEdgeEventAction()));
340 log.trace("Executing processEntityMessage, edgeEvent [{}], edgeEventAction [{}], msgType [{}]", edgeEvent, edgeEventAction, msgType); 418 log.trace("Executing processEntityMessage, edgeEvent [{}], edgeEventAction [{}], msgType [{}]", edgeEvent, edgeEventAction, msgType);
341 switch (edgeEvent.getEdgeEventType()) { 419 switch (edgeEvent.getEdgeEventType()) {
342 case EDGE: 420 case EDGE:
343 // TODO: voba - add edge update logic 421 // TODO: voba - add edge update logic
344 - break; 422 + return null;
345 case DEVICE: 423 case DEVICE:
346 - processDevice(edgeEvent, msgType, edgeEventAction);  
347 - break; 424 + return processDevice(edgeEvent, msgType, edgeEventAction);
348 case ASSET: 425 case ASSET:
349 - processAsset(edgeEvent, msgType, edgeEventAction);  
350 - break; 426 + return processAsset(edgeEvent, msgType, edgeEventAction);
351 case ENTITY_VIEW: 427 case ENTITY_VIEW:
352 - processEntityView(edgeEvent, msgType, edgeEventAction);  
353 - break; 428 + return processEntityView(edgeEvent, msgType, edgeEventAction);
354 case DASHBOARD: 429 case DASHBOARD:
355 - processDashboard(edgeEvent, msgType, edgeEventAction);  
356 - break; 430 + return processDashboard(edgeEvent, msgType, edgeEventAction);
357 case CUSTOMER: 431 case CUSTOMER:
358 - processCustomer(edgeEvent, msgType, edgeEventAction);  
359 - break; 432 + return processCustomer(edgeEvent, msgType, edgeEventAction);
360 case RULE_CHAIN: 433 case RULE_CHAIN:
361 - processRuleChain(edgeEvent, msgType, edgeEventAction);  
362 - break; 434 + return processRuleChain(edgeEvent, msgType, edgeEventAction);
363 case RULE_CHAIN_METADATA: 435 case RULE_CHAIN_METADATA:
364 - processRuleChainMetadata(edgeEvent, msgType);  
365 - break; 436 + return processRuleChainMetadata(edgeEvent, msgType);
366 case ALARM: 437 case ALARM:
367 - processAlarm(edgeEvent, msgType);  
368 - break; 438 + return processAlarm(edgeEvent, msgType);
369 case USER: 439 case USER:
370 - processUser(edgeEvent, msgType, edgeEventAction);  
371 - break; 440 + return processUser(edgeEvent, msgType, edgeEventAction);
372 case RELATION: 441 case RELATION:
373 - processRelation(edgeEvent, msgType);  
374 - break; 442 + return processRelation(edgeEvent, msgType);
375 case WIDGETS_BUNDLE: 443 case WIDGETS_BUNDLE:
376 - processWidgetsBundle(edgeEvent, msgType, edgeEventAction);  
377 - break; 444 + return processWidgetsBundle(edgeEvent, msgType, edgeEventAction);
378 case WIDGET_TYPE: 445 case WIDGET_TYPE:
379 - processWidgetType(edgeEvent, msgType, edgeEventAction);  
380 - break; 446 + return processWidgetType(edgeEvent, msgType, edgeEventAction);
381 case ADMIN_SETTINGS: 447 case ADMIN_SETTINGS:
382 - processAdminSettings(edgeEvent);  
383 - break; 448 + return processAdminSettings(edgeEvent);
  449 + default:
  450 + log.warn("Unsupported edge event type [{}]", edgeEvent);
  451 + return null;
384 } 452 }
385 } 453 }
386 454
387 - private void processDevice(EdgeEvent edgeEvent, UpdateMsgType msgType, ActionType edgeActionType) { 455 + private DownlinkMsg processDevice(EdgeEvent edgeEvent, UpdateMsgType msgType, ActionType edgeActionType) {
388 DeviceId deviceId = new DeviceId(edgeEvent.getEntityId()); 456 DeviceId deviceId = new DeviceId(edgeEvent.getEntityId());
389 - EntityUpdateMsg entityUpdateMsg = null; 457 + DownlinkMsg downlinkMsg = null;
390 switch (edgeActionType) { 458 switch (edgeActionType) {
391 case ADDED: 459 case ADDED:
392 case UPDATED: 460 case UPDATED:
@@ -395,8 +463,8 @@ public final class EdgeGrpcSession implements Closeable { @@ -395,8 +463,8 @@ public final class EdgeGrpcSession implements Closeable {
395 if (device != null) { 463 if (device != null) {
396 DeviceUpdateMsg deviceUpdateMsg = 464 DeviceUpdateMsg deviceUpdateMsg =
397 ctx.getDeviceUpdateMsgConstructor().constructDeviceUpdatedMsg(msgType, device); 465 ctx.getDeviceUpdateMsgConstructor().constructDeviceUpdatedMsg(msgType, device);
398 - entityUpdateMsg = EntityUpdateMsg.newBuilder()  
399 - .setDeviceUpdateMsg(deviceUpdateMsg) 466 + downlinkMsg = DownlinkMsg.newBuilder()
  467 + .addAllDeviceUpdateMsg(Collections.singletonList(deviceUpdateMsg))
400 .build(); 468 .build();
401 } 469 }
402 break; 470 break;
@@ -404,8 +472,8 @@ public final class EdgeGrpcSession implements Closeable { @@ -404,8 +472,8 @@ public final class EdgeGrpcSession implements Closeable {
404 case UNASSIGNED_FROM_EDGE: 472 case UNASSIGNED_FROM_EDGE:
405 DeviceUpdateMsg deviceUpdateMsg = 473 DeviceUpdateMsg deviceUpdateMsg =
406 ctx.getDeviceUpdateMsgConstructor().constructDeviceDeleteMsg(deviceId); 474 ctx.getDeviceUpdateMsgConstructor().constructDeviceDeleteMsg(deviceId);
407 - entityUpdateMsg = EntityUpdateMsg.newBuilder()  
408 - .setDeviceUpdateMsg(deviceUpdateMsg) 475 + downlinkMsg = DownlinkMsg.newBuilder()
  476 + .addAllDeviceUpdateMsg(Collections.singletonList(deviceUpdateMsg))
409 .build(); 477 .build();
410 break; 478 break;
411 case CREDENTIALS_UPDATED: 479 case CREDENTIALS_UPDATED:
@@ -413,22 +481,18 @@ public final class EdgeGrpcSession implements Closeable { @@ -413,22 +481,18 @@ public final class EdgeGrpcSession implements Closeable {
413 if (deviceCredentials != null) { 481 if (deviceCredentials != null) {
414 DeviceCredentialsUpdateMsg deviceCredentialsUpdateMsg = 482 DeviceCredentialsUpdateMsg deviceCredentialsUpdateMsg =
415 ctx.getDeviceUpdateMsgConstructor().constructDeviceCredentialsUpdatedMsg(deviceCredentials); 483 ctx.getDeviceUpdateMsgConstructor().constructDeviceCredentialsUpdatedMsg(deviceCredentials);
416 - entityUpdateMsg = EntityUpdateMsg.newBuilder()  
417 - .setDeviceCredentialsUpdateMsg(deviceCredentialsUpdateMsg) 484 + downlinkMsg = DownlinkMsg.newBuilder()
  485 + .addAllDeviceCredentialsUpdateMsg(Collections.singletonList(deviceCredentialsUpdateMsg))
418 .build(); 486 .build();
419 } 487 }
420 break; 488 break;
421 } 489 }
422 - if (entityUpdateMsg != null) {  
423 - outputStream.onNext(ResponseMsg.newBuilder()  
424 - .setEntityUpdateMsg(entityUpdateMsg)  
425 - .build());  
426 - } 490 + return downlinkMsg;
427 } 491 }
428 492
429 - private void processAsset(EdgeEvent edgeEvent, UpdateMsgType msgType, ActionType edgeEventAction) { 493 + private DownlinkMsg processAsset(EdgeEvent edgeEvent, UpdateMsgType msgType, ActionType edgeEventAction) {
430 AssetId assetId = new AssetId(edgeEvent.getEntityId()); 494 AssetId assetId = new AssetId(edgeEvent.getEntityId());
431 - EntityUpdateMsg entityUpdateMsg = null; 495 + DownlinkMsg downlinkMsg = null;
432 switch (edgeEventAction) { 496 switch (edgeEventAction) {
433 case ADDED: 497 case ADDED:
434 case UPDATED: 498 case UPDATED:
@@ -437,8 +501,8 @@ public final class EdgeGrpcSession implements Closeable { @@ -437,8 +501,8 @@ public final class EdgeGrpcSession implements Closeable {
437 if (asset != null) { 501 if (asset != null) {
438 AssetUpdateMsg assetUpdateMsg = 502 AssetUpdateMsg assetUpdateMsg =
439 ctx.getAssetUpdateMsgConstructor().constructAssetUpdatedMsg(msgType, asset); 503 ctx.getAssetUpdateMsgConstructor().constructAssetUpdatedMsg(msgType, asset);
440 - entityUpdateMsg = EntityUpdateMsg.newBuilder()  
441 - .setAssetUpdateMsg(assetUpdateMsg) 504 + downlinkMsg = DownlinkMsg.newBuilder()
  505 + .addAllAssetUpdateMsg(Collections.singletonList(assetUpdateMsg))
442 .build(); 506 .build();
443 } 507 }
444 break; 508 break;
@@ -446,21 +510,17 @@ public final class EdgeGrpcSession implements Closeable { @@ -446,21 +510,17 @@ public final class EdgeGrpcSession implements Closeable {
446 case UNASSIGNED_FROM_EDGE: 510 case UNASSIGNED_FROM_EDGE:
447 AssetUpdateMsg assetUpdateMsg = 511 AssetUpdateMsg assetUpdateMsg =
448 ctx.getAssetUpdateMsgConstructor().constructAssetDeleteMsg(assetId); 512 ctx.getAssetUpdateMsgConstructor().constructAssetDeleteMsg(assetId);
449 - entityUpdateMsg = EntityUpdateMsg.newBuilder()  
450 - .setAssetUpdateMsg(assetUpdateMsg) 513 + downlinkMsg = DownlinkMsg.newBuilder()
  514 + .addAllAssetUpdateMsg(Collections.singletonList(assetUpdateMsg))
451 .build(); 515 .build();
452 break; 516 break;
453 } 517 }
454 - if (entityUpdateMsg != null) {  
455 - outputStream.onNext(ResponseMsg.newBuilder()  
456 - .setEntityUpdateMsg(entityUpdateMsg)  
457 - .build());  
458 - } 518 + return downlinkMsg;
459 } 519 }
460 520
461 - private void processEntityView(EdgeEvent edgeEvent, UpdateMsgType msgType, ActionType edgeEventAction) { 521 + private DownlinkMsg processEntityView(EdgeEvent edgeEvent, UpdateMsgType msgType, ActionType edgeEventAction) {
462 EntityViewId entityViewId = new EntityViewId(edgeEvent.getEntityId()); 522 EntityViewId entityViewId = new EntityViewId(edgeEvent.getEntityId());
463 - EntityUpdateMsg entityUpdateMsg = null; 523 + DownlinkMsg downlinkMsg = null;
464 switch (edgeEventAction) { 524 switch (edgeEventAction) {
465 case ADDED: 525 case ADDED:
466 case UPDATED: 526 case UPDATED:
@@ -469,8 +529,8 @@ public final class EdgeGrpcSession implements Closeable { @@ -469,8 +529,8 @@ public final class EdgeGrpcSession implements Closeable {
469 if (entityView != null) { 529 if (entityView != null) {
470 EntityViewUpdateMsg entityViewUpdateMsg = 530 EntityViewUpdateMsg entityViewUpdateMsg =
471 ctx.getEntityViewUpdateMsgConstructor().constructEntityViewUpdatedMsg(msgType, entityView); 531 ctx.getEntityViewUpdateMsgConstructor().constructEntityViewUpdatedMsg(msgType, entityView);
472 - entityUpdateMsg = EntityUpdateMsg.newBuilder()  
473 - .setEntityViewUpdateMsg(entityViewUpdateMsg) 532 + downlinkMsg = DownlinkMsg.newBuilder()
  533 + .addAllEntityViewUpdateMsg(Collections.singletonList(entityViewUpdateMsg))
474 .build(); 534 .build();
475 } 535 }
476 break; 536 break;
@@ -478,21 +538,17 @@ public final class EdgeGrpcSession implements Closeable { @@ -478,21 +538,17 @@ public final class EdgeGrpcSession implements Closeable {
478 case UNASSIGNED_FROM_EDGE: 538 case UNASSIGNED_FROM_EDGE:
479 EntityViewUpdateMsg entityViewUpdateMsg = 539 EntityViewUpdateMsg entityViewUpdateMsg =
480 ctx.getEntityViewUpdateMsgConstructor().constructEntityViewDeleteMsg(entityViewId); 540 ctx.getEntityViewUpdateMsgConstructor().constructEntityViewDeleteMsg(entityViewId);
481 - entityUpdateMsg = EntityUpdateMsg.newBuilder()  
482 - .setEntityViewUpdateMsg(entityViewUpdateMsg) 541 + downlinkMsg = DownlinkMsg.newBuilder()
  542 + .addAllEntityViewUpdateMsg(Collections.singletonList(entityViewUpdateMsg))
483 .build(); 543 .build();
484 break; 544 break;
485 } 545 }
486 - if (entityUpdateMsg != null) {  
487 - outputStream.onNext(ResponseMsg.newBuilder()  
488 - .setEntityUpdateMsg(entityUpdateMsg)  
489 - .build());  
490 - } 546 + return downlinkMsg;
491 } 547 }
492 548
493 - private void processDashboard(EdgeEvent edgeEvent, UpdateMsgType msgType, ActionType edgeEventAction) { 549 + private DownlinkMsg processDashboard(EdgeEvent edgeEvent, UpdateMsgType msgType, ActionType edgeEventAction) {
494 DashboardId dashboardId = new DashboardId(edgeEvent.getEntityId()); 550 DashboardId dashboardId = new DashboardId(edgeEvent.getEntityId());
495 - EntityUpdateMsg entityUpdateMsg = null; 551 + DownlinkMsg downlinkMsg = null;
496 switch (edgeEventAction) { 552 switch (edgeEventAction) {
497 case ADDED: 553 case ADDED:
498 case UPDATED: 554 case UPDATED:
@@ -501,8 +557,8 @@ public final class EdgeGrpcSession implements Closeable { @@ -501,8 +557,8 @@ public final class EdgeGrpcSession implements Closeable {
501 if (dashboard != null) { 557 if (dashboard != null) {
502 DashboardUpdateMsg dashboardUpdateMsg = 558 DashboardUpdateMsg dashboardUpdateMsg =
503 ctx.getDashboardUpdateMsgConstructor().constructDashboardUpdatedMsg(msgType, dashboard); 559 ctx.getDashboardUpdateMsgConstructor().constructDashboardUpdatedMsg(msgType, dashboard);
504 - entityUpdateMsg = EntityUpdateMsg.newBuilder()  
505 - .setDashboardUpdateMsg(dashboardUpdateMsg) 560 + downlinkMsg = DownlinkMsg.newBuilder()
  561 + .addAllDashboardUpdateMsg(Collections.singletonList(dashboardUpdateMsg))
506 .build(); 562 .build();
507 } 563 }
508 break; 564 break;
@@ -510,21 +566,17 @@ public final class EdgeGrpcSession implements Closeable { @@ -510,21 +566,17 @@ public final class EdgeGrpcSession implements Closeable {
510 case UNASSIGNED_FROM_EDGE: 566 case UNASSIGNED_FROM_EDGE:
511 DashboardUpdateMsg dashboardUpdateMsg = 567 DashboardUpdateMsg dashboardUpdateMsg =
512 ctx.getDashboardUpdateMsgConstructor().constructDashboardDeleteMsg(dashboardId); 568 ctx.getDashboardUpdateMsgConstructor().constructDashboardDeleteMsg(dashboardId);
513 - entityUpdateMsg = EntityUpdateMsg.newBuilder()  
514 - .setDashboardUpdateMsg(dashboardUpdateMsg) 569 + downlinkMsg = DownlinkMsg.newBuilder()
  570 + .addAllDashboardUpdateMsg(Collections.singletonList(dashboardUpdateMsg))
515 .build(); 571 .build();
516 break; 572 break;
517 } 573 }
518 - if (entityUpdateMsg != null) {  
519 - outputStream.onNext(ResponseMsg.newBuilder()  
520 - .setEntityUpdateMsg(entityUpdateMsg)  
521 - .build());  
522 - } 574 + return downlinkMsg;
523 } 575 }
524 576
525 - private void processCustomer(EdgeEvent edgeEvent, UpdateMsgType msgType, ActionType edgeEventAction) { 577 + private DownlinkMsg processCustomer(EdgeEvent edgeEvent, UpdateMsgType msgType, ActionType edgeEventAction) {
526 CustomerId customerId = new CustomerId(edgeEvent.getEntityId()); 578 CustomerId customerId = new CustomerId(edgeEvent.getEntityId());
527 - EntityUpdateMsg entityUpdateMsg = null; 579 + DownlinkMsg downlinkMsg = null;
528 switch (edgeEventAction) { 580 switch (edgeEventAction) {
529 case ADDED: 581 case ADDED:
530 case UPDATED: 582 case UPDATED:
@@ -532,29 +584,25 @@ public final class EdgeGrpcSession implements Closeable { @@ -532,29 +584,25 @@ public final class EdgeGrpcSession implements Closeable {
532 if (customer != null) { 584 if (customer != null) {
533 CustomerUpdateMsg customerUpdateMsg = 585 CustomerUpdateMsg customerUpdateMsg =
534 ctx.getCustomerUpdateMsgConstructor().constructCustomerUpdatedMsg(msgType, customer); 586 ctx.getCustomerUpdateMsgConstructor().constructCustomerUpdatedMsg(msgType, customer);
535 - entityUpdateMsg = EntityUpdateMsg.newBuilder()  
536 - .setCustomerUpdateMsg(customerUpdateMsg) 587 + downlinkMsg = DownlinkMsg.newBuilder()
  588 + .addAllCustomerUpdateMsg(Collections.singletonList(customerUpdateMsg))
537 .build(); 589 .build();
538 } 590 }
539 break; 591 break;
540 case DELETED: 592 case DELETED:
541 CustomerUpdateMsg customerUpdateMsg = 593 CustomerUpdateMsg customerUpdateMsg =
542 ctx.getCustomerUpdateMsgConstructor().constructCustomerDeleteMsg(customerId); 594 ctx.getCustomerUpdateMsgConstructor().constructCustomerDeleteMsg(customerId);
543 - entityUpdateMsg = EntityUpdateMsg.newBuilder()  
544 - .setCustomerUpdateMsg(customerUpdateMsg) 595 + downlinkMsg = DownlinkMsg.newBuilder()
  596 + .addAllCustomerUpdateMsg(Collections.singletonList(customerUpdateMsg))
545 .build(); 597 .build();
546 break; 598 break;
547 } 599 }
548 - if (entityUpdateMsg != null) {  
549 - outputStream.onNext(ResponseMsg.newBuilder()  
550 - .setEntityUpdateMsg(entityUpdateMsg)  
551 - .build());  
552 - } 600 + return downlinkMsg;
553 } 601 }
554 602
555 - private void processRuleChain(EdgeEvent edgeEvent, UpdateMsgType msgType, ActionType edgeEventAction) { 603 + private DownlinkMsg processRuleChain(EdgeEvent edgeEvent, UpdateMsgType msgType, ActionType edgeEventAction) {
556 RuleChainId ruleChainId = new RuleChainId(edgeEvent.getEntityId()); 604 RuleChainId ruleChainId = new RuleChainId(edgeEvent.getEntityId());
557 - EntityUpdateMsg entityUpdateMsg = null; 605 + DownlinkMsg downlinkMsg = null;
558 switch (edgeEventAction) { 606 switch (edgeEventAction) {
559 case ADDED: 607 case ADDED:
560 case UPDATED: 608 case UPDATED:
@@ -563,46 +611,41 @@ public final class EdgeGrpcSession implements Closeable { @@ -563,46 +611,41 @@ public final class EdgeGrpcSession implements Closeable {
563 if (ruleChain != null) { 611 if (ruleChain != null) {
564 RuleChainUpdateMsg ruleChainUpdateMsg = 612 RuleChainUpdateMsg ruleChainUpdateMsg =
565 ctx.getRuleChainUpdateMsgConstructor().constructRuleChainUpdatedMsg(edge.getRootRuleChainId(), msgType, ruleChain); 613 ctx.getRuleChainUpdateMsgConstructor().constructRuleChainUpdatedMsg(edge.getRootRuleChainId(), msgType, ruleChain);
566 - entityUpdateMsg = EntityUpdateMsg.newBuilder()  
567 - .setRuleChainUpdateMsg(ruleChainUpdateMsg) 614 + downlinkMsg = DownlinkMsg.newBuilder()
  615 + .addAllRuleChainUpdateMsg(Collections.singletonList(ruleChainUpdateMsg))
568 .build(); 616 .build();
569 } 617 }
570 break; 618 break;
571 case DELETED: 619 case DELETED:
572 case UNASSIGNED_FROM_EDGE: 620 case UNASSIGNED_FROM_EDGE:
573 - entityUpdateMsg = EntityUpdateMsg.newBuilder()  
574 - .setRuleChainUpdateMsg(ctx.getRuleChainUpdateMsgConstructor().constructRuleChainDeleteMsg(ruleChainId)) 621 + downlinkMsg = DownlinkMsg.newBuilder()
  622 + .addAllRuleChainUpdateMsg(Collections.singletonList(ctx.getRuleChainUpdateMsgConstructor().constructRuleChainDeleteMsg(ruleChainId)))
575 .build(); 623 .build();
576 break; 624 break;
577 } 625 }
578 - if (entityUpdateMsg != null) {  
579 - outputStream.onNext(ResponseMsg.newBuilder()  
580 - .setEntityUpdateMsg(entityUpdateMsg)  
581 - .build());  
582 - } 626 + return downlinkMsg;
583 } 627 }
584 628
585 - private void processRuleChainMetadata(EdgeEvent edgeEvent, UpdateMsgType msgType) { 629 + private DownlinkMsg processRuleChainMetadata(EdgeEvent edgeEvent, UpdateMsgType msgType) {
586 RuleChainId ruleChainId = new RuleChainId(edgeEvent.getEntityId()); 630 RuleChainId ruleChainId = new RuleChainId(edgeEvent.getEntityId());
587 RuleChain ruleChain = ctx.getRuleChainService().findRuleChainById(edgeEvent.getTenantId(), ruleChainId); 631 RuleChain ruleChain = ctx.getRuleChainService().findRuleChainById(edgeEvent.getTenantId(), ruleChainId);
  632 + DownlinkMsg downlinkMsg = null;
588 if (ruleChain != null) { 633 if (ruleChain != null) {
589 RuleChainMetaData ruleChainMetaData = ctx.getRuleChainService().loadRuleChainMetaData(edgeEvent.getTenantId(), ruleChainId); 634 RuleChainMetaData ruleChainMetaData = ctx.getRuleChainService().loadRuleChainMetaData(edgeEvent.getTenantId(), ruleChainId);
590 RuleChainMetadataUpdateMsg ruleChainMetadataUpdateMsg = 635 RuleChainMetadataUpdateMsg ruleChainMetadataUpdateMsg =
591 ctx.getRuleChainUpdateMsgConstructor().constructRuleChainMetadataUpdatedMsg(msgType, ruleChainMetaData); 636 ctx.getRuleChainUpdateMsgConstructor().constructRuleChainMetadataUpdatedMsg(msgType, ruleChainMetaData);
592 if (ruleChainMetadataUpdateMsg != null) { 637 if (ruleChainMetadataUpdateMsg != null) {
593 - EntityUpdateMsg entityUpdateMsg = EntityUpdateMsg.newBuilder()  
594 - .setRuleChainMetadataUpdateMsg(ruleChainMetadataUpdateMsg) 638 + downlinkMsg = DownlinkMsg.newBuilder()
  639 + .addAllRuleChainMetadataUpdateMsg(Collections.singletonList(ruleChainMetadataUpdateMsg))
595 .build(); 640 .build();
596 - outputStream.onNext(ResponseMsg.newBuilder()  
597 - .setEntityUpdateMsg(entityUpdateMsg)  
598 - .build());  
599 } 641 }
600 } 642 }
  643 + return downlinkMsg;
601 } 644 }
602 645
603 - private void processUser(EdgeEvent edgeEvent, UpdateMsgType msgType, ActionType edgeActionType) { 646 + private DownlinkMsg processUser(EdgeEvent edgeEvent, UpdateMsgType msgType, ActionType edgeActionType) {
604 UserId userId = new UserId(edgeEvent.getEntityId()); 647 UserId userId = new UserId(edgeEvent.getEntityId());
605 - EntityUpdateMsg entityUpdateMsg = null; 648 + DownlinkMsg downlinkMsg = null;
606 switch (edgeActionType) { 649 switch (edgeActionType) {
607 case ADDED: 650 case ADDED:
608 case UPDATED: 651 case UPDATED:
@@ -612,15 +655,15 @@ public final class EdgeGrpcSession implements Closeable { @@ -612,15 +655,15 @@ public final class EdgeGrpcSession implements Closeable {
612 boolean fullAccess = Authority.TENANT_ADMIN.equals(user.getAuthority()); 655 boolean fullAccess = Authority.TENANT_ADMIN.equals(user.getAuthority());
613 setFullAccess(user, fullAccess); 656 setFullAccess(user, fullAccess);
614 657
615 - entityUpdateMsg = EntityUpdateMsg.newBuilder()  
616 - .setUserUpdateMsg(ctx.getUserUpdateMsgConstructor().constructUserUpdatedMsg(msgType, user)) 658 + downlinkMsg = DownlinkMsg.newBuilder()
  659 + .addAllUserUpdateMsg(Collections.singletonList(ctx.getUserUpdateMsgConstructor().constructUserUpdatedMsg(msgType, user)))
617 .build(); 660 .build();
618 } 661 }
619 break; 662 break;
620 case DELETED: 663 case DELETED:
621 case UNASSIGNED_FROM_EDGE: 664 case UNASSIGNED_FROM_EDGE:
622 - entityUpdateMsg = EntityUpdateMsg.newBuilder()  
623 - .setUserUpdateMsg(ctx.getUserUpdateMsgConstructor().constructUserDeleteMsg(userId)) 665 + downlinkMsg = DownlinkMsg.newBuilder()
  666 + .addAllUserUpdateMsg(Collections.singletonList(ctx.getUserUpdateMsgConstructor().constructUserDeleteMsg(userId)))
624 .build(); 667 .build();
625 break; 668 break;
626 case CREDENTIALS_UPDATED: 669 case CREDENTIALS_UPDATED:
@@ -628,16 +671,12 @@ public final class EdgeGrpcSession implements Closeable { @@ -628,16 +671,12 @@ public final class EdgeGrpcSession implements Closeable {
628 if (userCredentialsByUserId != null && userCredentialsByUserId.isEnabled()) { 671 if (userCredentialsByUserId != null && userCredentialsByUserId.isEnabled()) {
629 UserCredentialsUpdateMsg userCredentialsUpdateMsg = 672 UserCredentialsUpdateMsg userCredentialsUpdateMsg =
630 ctx.getUserUpdateMsgConstructor().constructUserCredentialsUpdatedMsg(userCredentialsByUserId); 673 ctx.getUserUpdateMsgConstructor().constructUserCredentialsUpdatedMsg(userCredentialsByUserId);
631 - entityUpdateMsg = EntityUpdateMsg.newBuilder()  
632 - .setUserCredentialsUpdateMsg(userCredentialsUpdateMsg) 674 + downlinkMsg = DownlinkMsg.newBuilder()
  675 + .addAllUserCredentialsUpdateMsg(Collections.singletonList(userCredentialsUpdateMsg))
633 .build(); 676 .build();
634 } 677 }
635 } 678 }
636 - if (entityUpdateMsg != null) {  
637 - outputStream.onNext(ResponseMsg.newBuilder()  
638 - .setEntityUpdateMsg(entityUpdateMsg)  
639 - .build());  
640 - } 679 + return downlinkMsg;
641 } 680 }
642 681
643 private void setFullAccess(User user, boolean isFullAccess) { 682 private void setFullAccess(User user, boolean isFullAccess) {
@@ -649,36 +688,33 @@ public final class EdgeGrpcSession implements Closeable { @@ -649,36 +688,33 @@ public final class EdgeGrpcSession implements Closeable {
649 user.setAdditionalInfo(additionalInfo); 688 user.setAdditionalInfo(additionalInfo);
650 } 689 }
651 690
652 - private void processRelation(EdgeEvent edgeEvent, UpdateMsgType msgType) { 691 + private DownlinkMsg processRelation(EdgeEvent edgeEvent, UpdateMsgType msgType) {
653 EntityRelation entityRelation = mapper.convertValue(edgeEvent.getEntityBody(), EntityRelation.class); 692 EntityRelation entityRelation = mapper.convertValue(edgeEvent.getEntityBody(), EntityRelation.class);
654 - EntityUpdateMsg entityUpdateMsg = EntityUpdateMsg.newBuilder()  
655 - .setRelationUpdateMsg(ctx.getRelationUpdateMsgConstructor().constructRelationUpdatedMsg(msgType, entityRelation)) 693 + RelationUpdateMsg r = ctx.getRelationUpdateMsgConstructor().constructRelationUpdatedMsg(msgType, entityRelation);
  694 + return DownlinkMsg.newBuilder()
  695 + .addAllRelationUpdateMsg(Collections.singletonList(r))
656 .build(); 696 .build();
657 - outputStream.onNext(ResponseMsg.newBuilder()  
658 - .setEntityUpdateMsg(entityUpdateMsg)  
659 - .build());  
660 } 697 }
661 698
662 - private void processAlarm(EdgeEvent edgeEvent, UpdateMsgType msgType) { 699 + private DownlinkMsg processAlarm(EdgeEvent edgeEvent, UpdateMsgType msgType) {
  700 + DownlinkMsg downlinkMsg = null;
663 try { 701 try {
664 AlarmId alarmId = new AlarmId(edgeEvent.getEntityId()); 702 AlarmId alarmId = new AlarmId(edgeEvent.getEntityId());
665 Alarm alarm = ctx.getAlarmService().findAlarmByIdAsync(edgeEvent.getTenantId(), alarmId).get(); 703 Alarm alarm = ctx.getAlarmService().findAlarmByIdAsync(edgeEvent.getTenantId(), alarmId).get();
666 if (alarm != null) { 704 if (alarm != null) {
667 - EntityUpdateMsg entityUpdateMsg = EntityUpdateMsg.newBuilder()  
668 - .setAlarmUpdateMsg(ctx.getAlarmUpdateMsgConstructor().constructAlarmUpdatedMsg(edge.getTenantId(), msgType, alarm)) 705 + downlinkMsg = DownlinkMsg.newBuilder()
  706 + .addAllAlarmUpdateMsg(Collections.singletonList(ctx.getAlarmUpdateMsgConstructor().constructAlarmUpdatedMsg(edge.getTenantId(), msgType, alarm)))
669 .build(); 707 .build();
670 - outputStream.onNext(ResponseMsg.newBuilder()  
671 - .setEntityUpdateMsg(entityUpdateMsg)  
672 - .build());  
673 } 708 }
674 } catch (Exception e) { 709 } catch (Exception e) {
675 log.error("Can't process alarm msg [{}] [{}]", edgeEvent, msgType, e); 710 log.error("Can't process alarm msg [{}] [{}]", edgeEvent, msgType, e);
676 } 711 }
  712 + return downlinkMsg;
677 } 713 }
678 714
679 - private void processWidgetsBundle(EdgeEvent edgeEvent, UpdateMsgType msgType, ActionType edgeActionType) { 715 + private DownlinkMsg processWidgetsBundle(EdgeEvent edgeEvent, UpdateMsgType msgType, ActionType edgeActionType) {
680 WidgetsBundleId widgetsBundleId = new WidgetsBundleId(edgeEvent.getEntityId()); 716 WidgetsBundleId widgetsBundleId = new WidgetsBundleId(edgeEvent.getEntityId());
681 - EntityUpdateMsg entityUpdateMsg = null; 717 + DownlinkMsg downlinkMsg = null;
682 switch (edgeActionType) { 718 switch (edgeActionType) {
683 case ADDED: 719 case ADDED:
684 case UPDATED: 720 case UPDATED:
@@ -686,29 +722,25 @@ public final class EdgeGrpcSession implements Closeable { @@ -686,29 +722,25 @@ public final class EdgeGrpcSession implements Closeable {
686 if (widgetsBundle != null) { 722 if (widgetsBundle != null) {
687 WidgetsBundleUpdateMsg widgetsBundleUpdateMsg = 723 WidgetsBundleUpdateMsg widgetsBundleUpdateMsg =
688 ctx.getWidgetsBundleUpdateMsgConstructor().constructWidgetsBundleUpdateMsg(msgType, widgetsBundle); 724 ctx.getWidgetsBundleUpdateMsgConstructor().constructWidgetsBundleUpdateMsg(msgType, widgetsBundle);
689 - entityUpdateMsg = EntityUpdateMsg.newBuilder()  
690 - .setWidgetsBundleUpdateMsg(widgetsBundleUpdateMsg) 725 + downlinkMsg = DownlinkMsg.newBuilder()
  726 + .addAllWidgetsBundleUpdateMsg(Collections.singletonList(widgetsBundleUpdateMsg))
691 .build(); 727 .build();
692 } 728 }
693 break; 729 break;
694 case DELETED: 730 case DELETED:
695 WidgetsBundleUpdateMsg widgetsBundleUpdateMsg = 731 WidgetsBundleUpdateMsg widgetsBundleUpdateMsg =
696 ctx.getWidgetsBundleUpdateMsgConstructor().constructWidgetsBundleDeleteMsg(widgetsBundleId); 732 ctx.getWidgetsBundleUpdateMsgConstructor().constructWidgetsBundleDeleteMsg(widgetsBundleId);
697 - entityUpdateMsg = EntityUpdateMsg.newBuilder()  
698 - .setWidgetsBundleUpdateMsg(widgetsBundleUpdateMsg) 733 + downlinkMsg = DownlinkMsg.newBuilder()
  734 + .addAllWidgetsBundleUpdateMsg(Collections.singletonList(widgetsBundleUpdateMsg))
699 .build(); 735 .build();
700 break; 736 break;
701 } 737 }
702 - if (entityUpdateMsg != null) {  
703 - outputStream.onNext(ResponseMsg.newBuilder()  
704 - .setEntityUpdateMsg(entityUpdateMsg)  
705 - .build());  
706 - } 738 + return downlinkMsg;
707 } 739 }
708 740
709 - private void processWidgetType(EdgeEvent edgeEvent, UpdateMsgType msgType, ActionType edgeActionType) { 741 + private DownlinkMsg processWidgetType(EdgeEvent edgeEvent, UpdateMsgType msgType, ActionType edgeActionType) {
710 WidgetTypeId widgetTypeId = new WidgetTypeId(edgeEvent.getEntityId()); 742 WidgetTypeId widgetTypeId = new WidgetTypeId(edgeEvent.getEntityId());
711 - EntityUpdateMsg entityUpdateMsg = null; 743 + DownlinkMsg downlinkMsg = null;
712 switch (edgeActionType) { 744 switch (edgeActionType) {
713 case ADDED: 745 case ADDED:
714 case UPDATED: 746 case UPDATED:
@@ -716,34 +748,28 @@ public final class EdgeGrpcSession implements Closeable { @@ -716,34 +748,28 @@ public final class EdgeGrpcSession implements Closeable {
716 if (widgetType != null) { 748 if (widgetType != null) {
717 WidgetTypeUpdateMsg widgetTypeUpdateMsg = 749 WidgetTypeUpdateMsg widgetTypeUpdateMsg =
718 ctx.getWidgetTypeUpdateMsgConstructor().constructWidgetTypeUpdateMsg(msgType, widgetType); 750 ctx.getWidgetTypeUpdateMsgConstructor().constructWidgetTypeUpdateMsg(msgType, widgetType);
719 - entityUpdateMsg = EntityUpdateMsg.newBuilder()  
720 - .setWidgetTypeUpdateMsg(widgetTypeUpdateMsg) 751 + downlinkMsg = DownlinkMsg.newBuilder()
  752 + .addAllWidgetTypeUpdateMsg(Collections.singletonList(widgetTypeUpdateMsg))
721 .build(); 753 .build();
722 } 754 }
723 break; 755 break;
724 case DELETED: 756 case DELETED:
725 WidgetTypeUpdateMsg widgetTypeUpdateMsg = 757 WidgetTypeUpdateMsg widgetTypeUpdateMsg =
726 ctx.getWidgetTypeUpdateMsgConstructor().constructWidgetTypeDeleteMsg(widgetTypeId); 758 ctx.getWidgetTypeUpdateMsgConstructor().constructWidgetTypeDeleteMsg(widgetTypeId);
727 - entityUpdateMsg = EntityUpdateMsg.newBuilder()  
728 - .setWidgetTypeUpdateMsg(widgetTypeUpdateMsg) 759 + downlinkMsg = DownlinkMsg.newBuilder()
  760 + .addAllWidgetTypeUpdateMsg(Collections.singletonList(widgetTypeUpdateMsg))
729 .build(); 761 .build();
730 break; 762 break;
731 } 763 }
732 - if (entityUpdateMsg != null) {  
733 - outputStream.onNext(ResponseMsg.newBuilder()  
734 - .setEntityUpdateMsg(entityUpdateMsg)  
735 - .build());  
736 - } 764 + return downlinkMsg;
737 } 765 }
738 766
739 - private void processAdminSettings(EdgeEvent edgeEvent) { 767 + private DownlinkMsg processAdminSettings(EdgeEvent edgeEvent) {
740 AdminSettings adminSettings = mapper.convertValue(edgeEvent.getEntityBody(), AdminSettings.class); 768 AdminSettings adminSettings = mapper.convertValue(edgeEvent.getEntityBody(), AdminSettings.class);
741 - EntityUpdateMsg entityUpdateMsg = EntityUpdateMsg.newBuilder()  
742 - .setAdminSettingsUpdateMsg(ctx.getAdminSettingsUpdateMsgConstructor().constructAdminSettingsUpdateMsg(adminSettings)) 769 + AdminSettingsUpdateMsg t = ctx.getAdminSettingsUpdateMsgConstructor().constructAdminSettingsUpdateMsg(adminSettings);
  770 + return DownlinkMsg.newBuilder()
  771 + .addAllAdminSettingsUpdateMsg(Collections.singletonList(t))
743 .build(); 772 .build();
744 - outputStream.onNext(ResponseMsg.newBuilder()  
745 - .setEntityUpdateMsg(entityUpdateMsg)  
746 - .build());  
747 } 773 }
748 774
749 private UpdateMsgType getResponseMsgType(ActionType actionType) { 775 private UpdateMsgType getResponseMsgType(ActionType actionType) {
@@ -775,112 +801,101 @@ public final class EdgeGrpcSession implements Closeable { @@ -775,112 +801,101 @@ public final class EdgeGrpcSession implements Closeable {
775 return builder.build(); 801 return builder.build();
776 } 802 }
777 803
778 - private UplinkResponseMsg processUplinkMsg(UplinkMsg uplinkMsg) { 804 + private ListenableFuture<List<Void>> processUplinkMsg(UplinkMsg uplinkMsg) {
  805 + List<ListenableFuture<Void>> result = new ArrayList<>();
779 try { 806 try {
780 if (uplinkMsg.getEntityDataList() != null && !uplinkMsg.getEntityDataList().isEmpty()) { 807 if (uplinkMsg.getEntityDataList() != null && !uplinkMsg.getEntityDataList().isEmpty()) {
781 for (EntityDataProto entityData : uplinkMsg.getEntityDataList()) { 808 for (EntityDataProto entityData : uplinkMsg.getEntityDataList()) {
782 EntityId entityId = constructEntityId(entityData); 809 EntityId entityId = constructEntityId(entityData);
783 if ((entityData.hasPostAttributesMsg() || entityData.hasPostTelemetryMsg()) && entityId != null) { 810 if ((entityData.hasPostAttributesMsg() || entityData.hasPostTelemetryMsg()) && entityId != null) {
784 - ListenableFuture<TbMsgMetaData> metaDataFuture = constructBaseMsgMetadata(entityId);  
785 - Futures.transform(metaDataFuture, metaData -> {  
786 - if (metaData != null) {  
787 - metaData.putValue(DataConstants.MSG_SOURCE_KEY, DataConstants.EDGE_MSG_SOURCE);  
788 - if (entityData.hasPostAttributesMsg()) {  
789 - processPostAttributes(entityId, entityData.getPostAttributesMsg(), metaData);  
790 - }  
791 - if (entityData.hasPostTelemetryMsg()) {  
792 - processPostTelemetry(entityId, entityData.getPostTelemetryMsg(), metaData);  
793 - }  
794 - }  
795 - return null;  
796 - }, ctx.getDbCallbackExecutor()); 811 + TbMsgMetaData metaData = constructBaseMsgMetadata(entityId);
  812 + metaData.putValue(DataConstants.MSG_SOURCE_KEY, DataConstants.EDGE_MSG_SOURCE);
  813 + if (entityData.hasPostAttributesMsg()) {
  814 + metaData.putValue("scope", entityData.getPostAttributeScope());
  815 + result.add(processPostAttributes(entityId, entityData.getPostAttributesMsg(), metaData));
  816 + }
  817 + if (entityData.hasPostTelemetryMsg()) {
  818 + result.add(processPostTelemetry(entityId, entityData.getPostTelemetryMsg(), metaData));
  819 + }
797 } 820 }
798 } 821 }
799 } 822 }
800 823
801 if (uplinkMsg.getDeviceUpdateMsgList() != null && !uplinkMsg.getDeviceUpdateMsgList().isEmpty()) { 824 if (uplinkMsg.getDeviceUpdateMsgList() != null && !uplinkMsg.getDeviceUpdateMsgList().isEmpty()) {
802 for (DeviceUpdateMsg deviceUpdateMsg : uplinkMsg.getDeviceUpdateMsgList()) { 825 for (DeviceUpdateMsg deviceUpdateMsg : uplinkMsg.getDeviceUpdateMsgList()) {
803 - onDeviceUpdate(deviceUpdateMsg); 826 + result.add(onDeviceUpdate(deviceUpdateMsg));
804 } 827 }
805 } 828 }
806 if (uplinkMsg.getDeviceCredentialsUpdateMsgList() != null && !uplinkMsg.getDeviceCredentialsUpdateMsgList().isEmpty()) { 829 if (uplinkMsg.getDeviceCredentialsUpdateMsgList() != null && !uplinkMsg.getDeviceCredentialsUpdateMsgList().isEmpty()) {
807 for (DeviceCredentialsUpdateMsg deviceCredentialsUpdateMsg : uplinkMsg.getDeviceCredentialsUpdateMsgList()) { 830 for (DeviceCredentialsUpdateMsg deviceCredentialsUpdateMsg : uplinkMsg.getDeviceCredentialsUpdateMsgList()) {
808 - onDeviceCredentialsUpdate(deviceCredentialsUpdateMsg); 831 + result.add(onDeviceCredentialsUpdate(deviceCredentialsUpdateMsg));
809 } 832 }
810 } 833 }
811 if (uplinkMsg.getAlarmUpdateMsgList() != null && !uplinkMsg.getAlarmUpdateMsgList().isEmpty()) { 834 if (uplinkMsg.getAlarmUpdateMsgList() != null && !uplinkMsg.getAlarmUpdateMsgList().isEmpty()) {
812 for (AlarmUpdateMsg alarmUpdateMsg : uplinkMsg.getAlarmUpdateMsgList()) { 835 for (AlarmUpdateMsg alarmUpdateMsg : uplinkMsg.getAlarmUpdateMsgList()) {
813 - onAlarmUpdate(alarmUpdateMsg); 836 + result.add(onAlarmUpdate(alarmUpdateMsg));
814 } 837 }
815 } 838 }
816 if (uplinkMsg.getRuleChainMetadataRequestMsgList() != null && !uplinkMsg.getRuleChainMetadataRequestMsgList().isEmpty()) { 839 if (uplinkMsg.getRuleChainMetadataRequestMsgList() != null && !uplinkMsg.getRuleChainMetadataRequestMsgList().isEmpty()) {
817 for (RuleChainMetadataRequestMsg ruleChainMetadataRequestMsg : uplinkMsg.getRuleChainMetadataRequestMsgList()) { 840 for (RuleChainMetadataRequestMsg ruleChainMetadataRequestMsg : uplinkMsg.getRuleChainMetadataRequestMsgList()) {
818 - ctx.getSyncEdgeService().processRuleChainMetadataRequestMsg(edge, ruleChainMetadataRequestMsg); 841 + result.add(ctx.getSyncEdgeService().processRuleChainMetadataRequestMsg(edge, ruleChainMetadataRequestMsg));
819 } 842 }
820 } 843 }
821 if (uplinkMsg.getAttributesRequestMsgList() != null && !uplinkMsg.getAttributesRequestMsgList().isEmpty()) { 844 if (uplinkMsg.getAttributesRequestMsgList() != null && !uplinkMsg.getAttributesRequestMsgList().isEmpty()) {
822 for (AttributesRequestMsg attributesRequestMsg : uplinkMsg.getAttributesRequestMsgList()) { 845 for (AttributesRequestMsg attributesRequestMsg : uplinkMsg.getAttributesRequestMsgList()) {
823 - ctx.getSyncEdgeService().processAttributesRequestMsg(edge, attributesRequestMsg); 846 + result.add(ctx.getSyncEdgeService().processAttributesRequestMsg(edge, attributesRequestMsg));
824 } 847 }
825 } 848 }
826 if (uplinkMsg.getRelationRequestMsgList() != null && !uplinkMsg.getRelationRequestMsgList().isEmpty()) { 849 if (uplinkMsg.getRelationRequestMsgList() != null && !uplinkMsg.getRelationRequestMsgList().isEmpty()) {
827 for (RelationRequestMsg relationRequestMsg : uplinkMsg.getRelationRequestMsgList()) { 850 for (RelationRequestMsg relationRequestMsg : uplinkMsg.getRelationRequestMsgList()) {
828 - ctx.getSyncEdgeService().processRelationRequestMsg(edge, relationRequestMsg); 851 + result.add(ctx.getSyncEdgeService().processRelationRequestMsg(edge, relationRequestMsg));
829 } 852 }
830 } 853 }
831 if (uplinkMsg.getUserCredentialsRequestMsgList() != null && !uplinkMsg.getUserCredentialsRequestMsgList().isEmpty()) { 854 if (uplinkMsg.getUserCredentialsRequestMsgList() != null && !uplinkMsg.getUserCredentialsRequestMsgList().isEmpty()) {
832 for (UserCredentialsRequestMsg userCredentialsRequestMsg : uplinkMsg.getUserCredentialsRequestMsgList()) { 855 for (UserCredentialsRequestMsg userCredentialsRequestMsg : uplinkMsg.getUserCredentialsRequestMsgList()) {
833 - ctx.getSyncEdgeService().processUserCredentialsRequestMsg(edge, userCredentialsRequestMsg); 856 + result.add(ctx.getSyncEdgeService().processUserCredentialsRequestMsg(edge, userCredentialsRequestMsg));
834 } 857 }
835 } 858 }
836 if (uplinkMsg.getDeviceCredentialsRequestMsgList() != null && !uplinkMsg.getDeviceCredentialsRequestMsgList().isEmpty()) { 859 if (uplinkMsg.getDeviceCredentialsRequestMsgList() != null && !uplinkMsg.getDeviceCredentialsRequestMsgList().isEmpty()) {
837 for (DeviceCredentialsRequestMsg deviceCredentialsRequestMsg : uplinkMsg.getDeviceCredentialsRequestMsgList()) { 860 for (DeviceCredentialsRequestMsg deviceCredentialsRequestMsg : uplinkMsg.getDeviceCredentialsRequestMsgList()) {
838 - ctx.getSyncEdgeService().processDeviceCredentialsRequestMsg(edge, deviceCredentialsRequestMsg); 861 + result.add(ctx.getSyncEdgeService().processDeviceCredentialsRequestMsg(edge, deviceCredentialsRequestMsg));
839 } 862 }
840 } 863 }
841 } catch (Exception e) { 864 } catch (Exception e) {
842 - return UplinkResponseMsg.newBuilder().setSuccess(false).setErrorMsg(e.getMessage()).build(); 865 + log.error("Can't process uplink msg [{}]", uplinkMsg, e);
843 } 866 }
844 -  
845 - return UplinkResponseMsg.newBuilder().setSuccess(true).build(); 867 + return Futures.allAsList(result);
846 } 868 }
847 869
848 - private ListenableFuture<TbMsgMetaData> constructBaseMsgMetadata(EntityId entityId) { 870 + private TbMsgMetaData constructBaseMsgMetadata(EntityId entityId) {
  871 + TbMsgMetaData metaData = new TbMsgMetaData();
849 switch (entityId.getEntityType()) { 872 switch (entityId.getEntityType()) {
850 case DEVICE: 873 case DEVICE:
851 - ListenableFuture<Device> deviceFuture = ctx.getDeviceService().findDeviceByIdAsync(edge.getTenantId(), new DeviceId(entityId.getId()));  
852 - return Futures.transform(deviceFuture, device -> {  
853 - TbMsgMetaData metaData = new TbMsgMetaData();  
854 - if (device != null) {  
855 - metaData.putValue("deviceName", device.getName());  
856 - metaData.putValue("deviceType", device.getType());  
857 - }  
858 - return metaData;  
859 - }, ctx.getDbCallbackExecutor()); 874 + Device device = ctx.getDeviceService().findDeviceById(edge.getTenantId(), new DeviceId(entityId.getId()));
  875 + if (device != null) {
  876 + metaData.putValue("deviceName", device.getName());
  877 + metaData.putValue("deviceType", device.getType());
  878 + }
  879 + break;
860 case ASSET: 880 case ASSET:
861 - ListenableFuture<Asset> assetFuture = ctx.getAssetService().findAssetByIdAsync(edge.getTenantId(), new AssetId(entityId.getId()));  
862 - return Futures.transform(assetFuture, asset -> {  
863 - TbMsgMetaData metaData = new TbMsgMetaData();  
864 - if (asset != null) {  
865 - metaData.putValue("assetName", asset.getName());  
866 - metaData.putValue("assetType", asset.getType());  
867 - }  
868 - return metaData;  
869 - }, ctx.getDbCallbackExecutor()); 881 + Asset asset = ctx.getAssetService().findAssetById(edge.getTenantId(), new AssetId(entityId.getId()));
  882 + if (asset != null) {
  883 + metaData.putValue("assetName", asset.getName());
  884 + metaData.putValue("assetType", asset.getType());
  885 + }
  886 + break;
870 case ENTITY_VIEW: 887 case ENTITY_VIEW:
871 - ListenableFuture<EntityView> entityViewFuture = ctx.getEntityViewService().findEntityViewByIdAsync(edge.getTenantId(), new EntityViewId(entityId.getId()));  
872 - return Futures.transform(entityViewFuture, entityView -> {  
873 - TbMsgMetaData metaData = new TbMsgMetaData();  
874 - if (entityView != null) {  
875 - metaData.putValue("entityViewName", entityView.getName());  
876 - metaData.putValue("entityViewType", entityView.getType());  
877 - }  
878 - return metaData;  
879 - }, ctx.getDbCallbackExecutor()); 888 + EntityView entityView = ctx.getEntityViewService().findEntityViewById(edge.getTenantId(), new EntityViewId(entityId.getId()));
  889 + if (entityView != null) {
  890 + metaData.putValue("entityViewName", entityView.getName());
  891 + metaData.putValue("entityViewType", entityView.getType());
  892 + }
  893 + break;
880 default: 894 default:
881 - log.debug("Constructing empty metadata for entityId [{}]", entityId);  
882 - return Futures.immediateFuture(new TbMsgMetaData()); 895 + log.debug("Using empty metadata for entityId [{}]", entityId);
  896 + break;
883 } 897 }
  898 + return metaData;
884 } 899 }
885 900
886 private EntityId constructEntityId(EntityDataProto entityData) { 901 private EntityId constructEntityId(EntityDataProto entityData) {
@@ -904,7 +919,7 @@ public final class EdgeGrpcSession implements Closeable { @@ -904,7 +919,7 @@ public final class EdgeGrpcSession implements Closeable {
904 } 919 }
905 } 920 }
906 921
907 - private void processPostTelemetry(EntityId entityId, TransportProtos.PostTelemetryMsg msg, TbMsgMetaData metaData) { 922 + private ListenableFuture<Void> processPostTelemetry(EntityId entityId, TransportProtos.PostTelemetryMsg msg, TbMsgMetaData metaData) {
908 for (TransportProtos.TsKvListProto tsKv : msg.getTsKvListList()) { 923 for (TransportProtos.TsKvListProto tsKv : msg.getTsKvListList()) {
909 JsonObject json = JsonUtils.getJsonObject(tsKv.getKvList()); 924 JsonObject json = JsonUtils.getJsonObject(tsKv.getKvList());
910 metaData.putValue("ts", tsKv.getTs() + ""); 925 metaData.putValue("ts", tsKv.getTs() + "");
@@ -912,17 +927,18 @@ public final class EdgeGrpcSession implements Closeable { @@ -912,17 +927,18 @@ public final class EdgeGrpcSession implements Closeable {
912 // TODO: voba - verify that null callback is OK 927 // TODO: voba - verify that null callback is OK
913 ctx.getTbClusterService().pushMsgToRuleEngine(edge.getTenantId(), tbMsg.getOriginator(), tbMsg, null); 928 ctx.getTbClusterService().pushMsgToRuleEngine(edge.getTenantId(), tbMsg.getOriginator(), tbMsg, null);
914 } 929 }
  930 + return Futures.immediateFuture(null);
915 } 931 }
916 932
917 - private void processPostAttributes(EntityId entityId, TransportProtos.PostAttributeMsg msg, TbMsgMetaData metaData) { 933 + private ListenableFuture<Void> processPostAttributes(EntityId entityId, TransportProtos.PostAttributeMsg msg, TbMsgMetaData metaData) {
918 JsonObject json = JsonUtils.getJsonObject(msg.getKvList()); 934 JsonObject json = JsonUtils.getJsonObject(msg.getKvList());
919 TbMsg tbMsg = TbMsg.newMsg(SessionMsgType.POST_ATTRIBUTES_REQUEST.name(), entityId, metaData, gson.toJson(json)); 935 TbMsg tbMsg = TbMsg.newMsg(SessionMsgType.POST_ATTRIBUTES_REQUEST.name(), entityId, metaData, gson.toJson(json));
920 // TODO: voba - verify that null callback is OK 936 // TODO: voba - verify that null callback is OK
921 ctx.getTbClusterService().pushMsgToRuleEngine(edge.getTenantId(), tbMsg.getOriginator(), tbMsg, null); 937 ctx.getTbClusterService().pushMsgToRuleEngine(edge.getTenantId(), tbMsg.getOriginator(), tbMsg, null);
  938 + return Futures.immediateFuture(null);
922 } 939 }
923 940
924 - private void onDeviceUpdate(DeviceUpdateMsg deviceUpdateMsg) {  
925 - log.info("onDeviceUpdate {}", deviceUpdateMsg); 941 + private ListenableFuture<Void> onDeviceUpdate(DeviceUpdateMsg deviceUpdateMsg) {
926 DeviceId edgeDeviceId = new DeviceId(new UUID(deviceUpdateMsg.getIdMSB(), deviceUpdateMsg.getIdLSB())); 942 DeviceId edgeDeviceId = new DeviceId(new UUID(deviceUpdateMsg.getIdMSB(), deviceUpdateMsg.getIdLSB()));
927 switch (deviceUpdateMsg.getMsgType()) { 943 switch (deviceUpdateMsg.getMsgType()) {
928 case ENTITY_CREATED_RPC_MESSAGE: 944 case ENTITY_CREATED_RPC_MESSAGE:
@@ -931,11 +947,12 @@ public final class EdgeGrpcSession implements Closeable { @@ -931,11 +947,12 @@ public final class EdgeGrpcSession implements Closeable {
931 if (device != null) { 947 if (device != null) {
932 // device with this name already exists on the cloud - update ID on the edge 948 // device with this name already exists on the cloud - update ID on the edge
933 if (!device.getId().equals(edgeDeviceId)) { 949 if (!device.getId().equals(edgeDeviceId)) {
934 - EntityUpdateMsg entityUpdateMsg = EntityUpdateMsg.newBuilder()  
935 - .setDeviceUpdateMsg(ctx.getDeviceUpdateMsgConstructor().constructDeviceUpdatedMsg(UpdateMsgType.DEVICE_CONFLICT_RPC_MESSAGE, device)) 950 + DeviceUpdateMsg d = ctx.getDeviceUpdateMsgConstructor().constructDeviceUpdatedMsg(UpdateMsgType.DEVICE_CONFLICT_RPC_MESSAGE, device);
  951 + DownlinkMsg downlinkMsg = DownlinkMsg.newBuilder()
  952 + .addAllDeviceUpdateMsg(Collections.singletonList(d))
936 .build(); 953 .build();
937 - outputStream.onNext(ResponseMsg.newBuilder()  
938 - .setEntityUpdateMsg(entityUpdateMsg) 954 + sendResponseMsg(ResponseMsg.newBuilder()
  955 + .setDownlinkMsg(downlinkMsg)
939 .build()); 956 .build());
940 } 957 }
941 } else { 958 } else {
@@ -943,11 +960,12 @@ public final class EdgeGrpcSession implements Closeable { @@ -943,11 +960,12 @@ public final class EdgeGrpcSession implements Closeable {
943 if (deviceById != null) { 960 if (deviceById != null) {
944 // this ID already used by other device - create new device and update ID on the edge 961 // this ID already used by other device - create new device and update ID on the edge
945 device = createDevice(deviceUpdateMsg); 962 device = createDevice(deviceUpdateMsg);
946 - EntityUpdateMsg entityUpdateMsg = EntityUpdateMsg.newBuilder()  
947 - .setDeviceUpdateMsg(ctx.getDeviceUpdateMsgConstructor().constructDeviceUpdatedMsg(UpdateMsgType.DEVICE_CONFLICT_RPC_MESSAGE, device)) 963 + DeviceUpdateMsg d = ctx.getDeviceUpdateMsgConstructor().constructDeviceUpdatedMsg(UpdateMsgType.DEVICE_CONFLICT_RPC_MESSAGE, device);
  964 + DownlinkMsg downlinkMsg = DownlinkMsg.newBuilder()
  965 + .addAllDeviceUpdateMsg(Collections.singletonList(d))
948 .build(); 966 .build();
949 - outputStream.onNext(ResponseMsg.newBuilder()  
950 - .setEntityUpdateMsg(entityUpdateMsg) 967 + sendResponseMsg(ResponseMsg.newBuilder()
  968 + .setDownlinkMsg(downlinkMsg)
951 .build()); 969 .build());
952 } else { 970 } else {
953 device = createDevice(deviceUpdateMsg); 971 device = createDevice(deviceUpdateMsg);
@@ -966,8 +984,10 @@ public final class EdgeGrpcSession implements Closeable { @@ -966,8 +984,10 @@ public final class EdgeGrpcSession implements Closeable {
966 } 984 }
967 break; 985 break;
968 case UNRECOGNIZED: 986 case UNRECOGNIZED:
969 - log.error("Unsupported msg type"); 987 + log.error("Unsupported msg type {}", deviceUpdateMsg.getMsgType());
  988 + return Futures.immediateFailedFuture(new RuntimeException("Unsupported msg type " + deviceUpdateMsg.getMsgType()));
970 } 989 }
  990 + return Futures.immediateFuture(null);
971 } 991 }
972 992
973 private void updateDevice(DeviceUpdateMsg deviceUpdateMsg) { 993 private void updateDevice(DeviceUpdateMsg deviceUpdateMsg) {
@@ -981,33 +1001,26 @@ public final class EdgeGrpcSession implements Closeable { @@ -981,33 +1001,26 @@ public final class EdgeGrpcSession implements Closeable {
981 requestDeviceCredentialsFromEdge(device); 1001 requestDeviceCredentialsFromEdge(device);
982 } 1002 }
983 1003
984 - private void onDeviceCredentialsUpdate(DeviceCredentialsUpdateMsg deviceCredentialsUpdateMsg) { 1004 + private ListenableFuture<Void> onDeviceCredentialsUpdate(DeviceCredentialsUpdateMsg deviceCredentialsUpdateMsg) {
985 log.debug("Executing onDeviceCredentialsUpdate, deviceCredentialsUpdateMsg [{}]", deviceCredentialsUpdateMsg); 1005 log.debug("Executing onDeviceCredentialsUpdate, deviceCredentialsUpdateMsg [{}]", deviceCredentialsUpdateMsg);
986 DeviceId deviceId = new DeviceId(new UUID(deviceCredentialsUpdateMsg.getDeviceIdMSB(), deviceCredentialsUpdateMsg.getDeviceIdLSB())); 1006 DeviceId deviceId = new DeviceId(new UUID(deviceCredentialsUpdateMsg.getDeviceIdMSB(), deviceCredentialsUpdateMsg.getDeviceIdLSB()));
987 ListenableFuture<Device> deviceFuture = ctx.getDeviceService().findDeviceByIdAsync(edge.getTenantId(), deviceId); 1007 ListenableFuture<Device> deviceFuture = ctx.getDeviceService().findDeviceByIdAsync(edge.getTenantId(), deviceId);
988 -  
989 - Futures.addCallback(deviceFuture, new FutureCallback<Device>() {  
990 - @Override  
991 - public void onSuccess(@Nullable Device device) {  
992 - if (device != null) {  
993 - log.debug("Updating device credentials for device [{}]. New device credentials Id [{}], value [{}]",  
994 - device.getName(), deviceCredentialsUpdateMsg.getCredentialsId(), deviceCredentialsUpdateMsg.getCredentialsValue());  
995 - try {  
996 - DeviceCredentials deviceCredentials = ctx.getDeviceCredentialsService().findDeviceCredentialsByDeviceId(edge.getTenantId(), device.getId());  
997 - deviceCredentials.setCredentialsType(DeviceCredentialsType.valueOf(deviceCredentialsUpdateMsg.getCredentialsType()));  
998 - deviceCredentials.setCredentialsId(deviceCredentialsUpdateMsg.getCredentialsId());  
999 - deviceCredentials.setCredentialsValue(deviceCredentialsUpdateMsg.getCredentialsValue());  
1000 - ctx.getDeviceCredentialsService().updateDeviceCredentials(edge.getTenantId(), deviceCredentials);  
1001 - } catch (Exception e) {  
1002 - log.error("Can't update device credentials for device [{}], deviceCredentialsUpdateMsg [{}]", device.getName(), deviceCredentialsUpdateMsg, e);  
1003 - } 1008 + return Futures.transform(deviceFuture, device -> {
  1009 + if (device != null) {
  1010 + log.debug("Updating device credentials for device [{}]. New device credentials Id [{}], value [{}]",
  1011 + device.getName(), deviceCredentialsUpdateMsg.getCredentialsId(), deviceCredentialsUpdateMsg.getCredentialsValue());
  1012 + try {
  1013 + DeviceCredentials deviceCredentials = ctx.getDeviceCredentialsService().findDeviceCredentialsByDeviceId(edge.getTenantId(), device.getId());
  1014 + deviceCredentials.setCredentialsType(DeviceCredentialsType.valueOf(deviceCredentialsUpdateMsg.getCredentialsType()));
  1015 + deviceCredentials.setCredentialsId(deviceCredentialsUpdateMsg.getCredentialsId());
  1016 + deviceCredentials.setCredentialsValue(deviceCredentialsUpdateMsg.getCredentialsValue());
  1017 + ctx.getDeviceCredentialsService().updateDeviceCredentials(edge.getTenantId(), deviceCredentials);
  1018 + } catch (Exception e) {
  1019 + log.error("Can't update device credentials for device [{}], deviceCredentialsUpdateMsg [{}]", device.getName(), deviceCredentialsUpdateMsg, e);
  1020 + throw new RuntimeException(e);
1004 } 1021 }
1005 } 1022 }
1006 -  
1007 - @Override  
1008 - public void onFailure(Throwable t) {  
1009 - log.error("Can't update device credentials for deviceCredentialsUpdateMsg [{}]", deviceCredentialsUpdateMsg, t);  
1010 - } 1023 + return null;
1011 }, ctx.getDbCallbackExecutor()); 1024 }, ctx.getDbCallbackExecutor());
1012 } 1025 }
1013 1026
@@ -1015,7 +1028,7 @@ public final class EdgeGrpcSession implements Closeable { @@ -1015,7 +1028,7 @@ public final class EdgeGrpcSession implements Closeable {
1015 log.debug("Executing requestDeviceCredentialsFromEdge device [{}]", device); 1028 log.debug("Executing requestDeviceCredentialsFromEdge device [{}]", device);
1016 1029
1017 DownlinkMsg downlinkMsg = constructDeviceCredentialsRequestMsg(device.getId()); 1030 DownlinkMsg downlinkMsg = constructDeviceCredentialsRequestMsg(device.getId());
1018 - outputStream.onNext(ResponseMsg.newBuilder() 1031 + sendResponseMsg(ResponseMsg.newBuilder()
1019 .setDownlinkMsg(downlinkMsg) 1032 .setDownlinkMsg(downlinkMsg)
1020 .build()); 1033 .build());
1021 } 1034 }
@@ -1118,49 +1131,52 @@ public final class EdgeGrpcSession implements Closeable { @@ -1118,49 +1131,52 @@ public final class EdgeGrpcSession implements Closeable {
1118 } 1131 }
1119 } 1132 }
1120 1133
1121 - private void onAlarmUpdate(AlarmUpdateMsg alarmUpdateMsg) { 1134 + private ListenableFuture<Void> onAlarmUpdate(AlarmUpdateMsg alarmUpdateMsg) {
1122 EntityId originatorId = getAlarmOriginator(alarmUpdateMsg.getOriginatorName(), org.thingsboard.server.common.data.EntityType.valueOf(alarmUpdateMsg.getOriginatorType())); 1135 EntityId originatorId = getAlarmOriginator(alarmUpdateMsg.getOriginatorName(), org.thingsboard.server.common.data.EntityType.valueOf(alarmUpdateMsg.getOriginatorType()));
1123 - if (originatorId != null) {  
1124 - try {  
1125 - Alarm existentAlarm = ctx.getAlarmService().findLatestByOriginatorAndType(edge.getTenantId(), originatorId, alarmUpdateMsg.getType()).get();  
1126 - switch (alarmUpdateMsg.getMsgType()) {  
1127 - case ENTITY_CREATED_RPC_MESSAGE:  
1128 - case ENTITY_UPDATED_RPC_MESSAGE:  
1129 - if (existentAlarm == null || existentAlarm.getStatus().isCleared()) {  
1130 - existentAlarm = new Alarm();  
1131 - existentAlarm.setTenantId(edge.getTenantId());  
1132 - existentAlarm.setType(alarmUpdateMsg.getName());  
1133 - existentAlarm.setOriginator(originatorId);  
1134 - existentAlarm.setSeverity(AlarmSeverity.valueOf(alarmUpdateMsg.getSeverity()));  
1135 - existentAlarm.setStartTs(alarmUpdateMsg.getStartTs());  
1136 - existentAlarm.setClearTs(alarmUpdateMsg.getClearTs());  
1137 - existentAlarm.setPropagate(alarmUpdateMsg.getPropagate());  
1138 - }  
1139 - existentAlarm.setStatus(AlarmStatus.valueOf(alarmUpdateMsg.getStatus()));  
1140 - existentAlarm.setAckTs(alarmUpdateMsg.getAckTs());  
1141 - existentAlarm.setEndTs(alarmUpdateMsg.getEndTs());  
1142 - existentAlarm.setDetails(mapper.readTree(alarmUpdateMsg.getDetails()));  
1143 - ctx.getAlarmService().createOrUpdateAlarm(existentAlarm);  
1144 - break;  
1145 - case ALARM_ACK_RPC_MESSAGE:  
1146 - if (existentAlarm != null) {  
1147 - ctx.getAlarmService().ackAlarm(edge.getTenantId(), existentAlarm.getId(), alarmUpdateMsg.getAckTs());  
1148 - }  
1149 - break;  
1150 - case ALARM_CLEAR_RPC_MESSAGE:  
1151 - if (existentAlarm != null) {  
1152 - ctx.getAlarmService().clearAlarm(edge.getTenantId(), existentAlarm.getId(), mapper.readTree(alarmUpdateMsg.getDetails()), alarmUpdateMsg.getAckTs());  
1153 - }  
1154 - break;  
1155 - case ENTITY_DELETED_RPC_MESSAGE:  
1156 - if (existentAlarm != null) {  
1157 - ctx.getAlarmService().deleteAlarm(edge.getTenantId(), existentAlarm.getId());  
1158 - }  
1159 - break;  
1160 - }  
1161 - } catch (Exception e) {  
1162 - log.error("Error during finding existent alarm", e); 1136 + if (originatorId == null) {
  1137 + return Futures.immediateFuture(null);
  1138 + }
  1139 + try {
  1140 + Alarm existentAlarm = ctx.getAlarmService().findLatestByOriginatorAndType(edge.getTenantId(), originatorId, alarmUpdateMsg.getType()).get();
  1141 + switch (alarmUpdateMsg.getMsgType()) {
  1142 + case ENTITY_CREATED_RPC_MESSAGE:
  1143 + case ENTITY_UPDATED_RPC_MESSAGE:
  1144 + if (existentAlarm == null || existentAlarm.getStatus().isCleared()) {
  1145 + existentAlarm = new Alarm();
  1146 + existentAlarm.setTenantId(edge.getTenantId());
  1147 + existentAlarm.setType(alarmUpdateMsg.getName());
  1148 + existentAlarm.setOriginator(originatorId);
  1149 + existentAlarm.setSeverity(AlarmSeverity.valueOf(alarmUpdateMsg.getSeverity()));
  1150 + existentAlarm.setStartTs(alarmUpdateMsg.getStartTs());
  1151 + existentAlarm.setClearTs(alarmUpdateMsg.getClearTs());
  1152 + existentAlarm.setPropagate(alarmUpdateMsg.getPropagate());
  1153 + }
  1154 + existentAlarm.setStatus(AlarmStatus.valueOf(alarmUpdateMsg.getStatus()));
  1155 + existentAlarm.setAckTs(alarmUpdateMsg.getAckTs());
  1156 + existentAlarm.setEndTs(alarmUpdateMsg.getEndTs());
  1157 + existentAlarm.setDetails(mapper.readTree(alarmUpdateMsg.getDetails()));
  1158 + ctx.getAlarmService().createOrUpdateAlarm(existentAlarm);
  1159 + break;
  1160 + case ALARM_ACK_RPC_MESSAGE:
  1161 + if (existentAlarm != null) {
  1162 + ctx.getAlarmService().ackAlarm(edge.getTenantId(), existentAlarm.getId(), alarmUpdateMsg.getAckTs());
  1163 + }
  1164 + break;
  1165 + case ALARM_CLEAR_RPC_MESSAGE:
  1166 + if (existentAlarm != null) {
  1167 + ctx.getAlarmService().clearAlarm(edge.getTenantId(), existentAlarm.getId(), mapper.readTree(alarmUpdateMsg.getDetails()), alarmUpdateMsg.getAckTs());
  1168 + }
  1169 + break;
  1170 + case ENTITY_DELETED_RPC_MESSAGE:
  1171 + if (existentAlarm != null) {
  1172 + ctx.getAlarmService().deleteAlarm(edge.getTenantId(), existentAlarm.getId());
  1173 + }
  1174 + break;
1163 } 1175 }
  1176 + return Futures.immediateFuture(null);
  1177 + } catch (Exception e) {
  1178 + log.error("Error during finding existent alarm", e);
  1179 + return Futures.immediateFailedFuture(new RuntimeException("Error during finding existent alarm", e));
1164 } 1180 }
1165 } 1181 }
1166 1182
@@ -316,64 +316,62 @@ public class DefaultSyncEdgeService implements SyncEdgeService { @@ -316,64 +316,62 @@ public class DefaultSyncEdgeService implements SyncEdgeService {
316 } 316 }
317 317
318 @Override 318 @Override
319 - public void processRuleChainMetadataRequestMsg(Edge edge, RuleChainMetadataRequestMsg ruleChainMetadataRequestMsg) { 319 + public ListenableFuture<Void> processRuleChainMetadataRequestMsg(Edge edge, RuleChainMetadataRequestMsg ruleChainMetadataRequestMsg) {
320 if (ruleChainMetadataRequestMsg.getRuleChainIdMSB() != 0 && ruleChainMetadataRequestMsg.getRuleChainIdLSB() != 0) { 320 if (ruleChainMetadataRequestMsg.getRuleChainIdMSB() != 0 && ruleChainMetadataRequestMsg.getRuleChainIdLSB() != 0) {
321 RuleChainId ruleChainId = new RuleChainId(new UUID(ruleChainMetadataRequestMsg.getRuleChainIdMSB(), ruleChainMetadataRequestMsg.getRuleChainIdLSB())); 321 RuleChainId ruleChainId = new RuleChainId(new UUID(ruleChainMetadataRequestMsg.getRuleChainIdMSB(), ruleChainMetadataRequestMsg.getRuleChainIdLSB()));
322 - saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.RULE_CHAIN_METADATA, ActionType.ADDED, ruleChainId, null); 322 + ListenableFuture<EdgeEvent> future = saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.RULE_CHAIN_METADATA, ActionType.ADDED, ruleChainId, null);
  323 + return Futures.transform(future, edgeEvent -> null, dbCallbackExecutorService);
323 } 324 }
  325 + return Futures.immediateFuture(null);
324 } 326 }
325 327
326 @Override 328 @Override
327 - public void processAttributesRequestMsg(Edge edge, AttributesRequestMsg attributesRequestMsg) { 329 + public ListenableFuture<Void> processAttributesRequestMsg(Edge edge, AttributesRequestMsg attributesRequestMsg) {
328 EntityId entityId = EntityIdFactory.getByTypeAndUuid( 330 EntityId entityId = EntityIdFactory.getByTypeAndUuid(
329 EntityType.valueOf(attributesRequestMsg.getEntityType()), 331 EntityType.valueOf(attributesRequestMsg.getEntityType()),
330 new UUID(attributesRequestMsg.getEntityIdMSB(), attributesRequestMsg.getEntityIdLSB())); 332 new UUID(attributesRequestMsg.getEntityIdMSB(), attributesRequestMsg.getEntityIdLSB()));
331 final EdgeEventType edgeEventType = getEdgeQueueTypeByEntityType(entityId.getEntityType()); 333 final EdgeEventType edgeEventType = getEdgeQueueTypeByEntityType(entityId.getEntityType());
332 if (edgeEventType != null) { 334 if (edgeEventType != null) {
333 ListenableFuture<List<AttributeKvEntry>> ssAttrFuture = attributesService.findAll(edge.getTenantId(), entityId, DataConstants.SERVER_SCOPE); 335 ListenableFuture<List<AttributeKvEntry>> ssAttrFuture = attributesService.findAll(edge.getTenantId(), entityId, DataConstants.SERVER_SCOPE);
334 - Futures.addCallback(ssAttrFuture, new FutureCallback<List<AttributeKvEntry>>() {  
335 - @Override  
336 - public void onSuccess(@Nullable List<AttributeKvEntry> ssAttributes) {  
337 - if (ssAttributes != null && !ssAttributes.isEmpty()) {  
338 - try {  
339 - Map<String, Object> entityData = new HashMap<>();  
340 - ObjectNode attributes = mapper.createObjectNode();  
341 - for (AttributeKvEntry attr : ssAttributes) {  
342 - if (attr.getDataType() == DataType.BOOLEAN && attr.getBooleanValue().isPresent()) {  
343 - attributes.put(attr.getKey(), attr.getBooleanValue().get());  
344 - } else if (attr.getDataType() == DataType.DOUBLE && attr.getDoubleValue().isPresent()) {  
345 - attributes.put(attr.getKey(), attr.getDoubleValue().get());  
346 - } else if (attr.getDataType() == DataType.LONG && attr.getLongValue().isPresent()) {  
347 - attributes.put(attr.getKey(), attr.getLongValue().get());  
348 - } else {  
349 - attributes.put(attr.getKey(), attr.getValueAsString());  
350 - } 336 + return Futures.transform(ssAttrFuture, ssAttributes -> {
  337 + if (ssAttributes != null && !ssAttributes.isEmpty()) {
  338 + try {
  339 + Map<String, Object> entityData = new HashMap<>();
  340 + ObjectNode attributes = mapper.createObjectNode();
  341 + for (AttributeKvEntry attr : ssAttributes) {
  342 + if (attr.getDataType() == DataType.BOOLEAN && attr.getBooleanValue().isPresent()) {
  343 + attributes.put(attr.getKey(), attr.getBooleanValue().get());
  344 + } else if (attr.getDataType() == DataType.DOUBLE && attr.getDoubleValue().isPresent()) {
  345 + attributes.put(attr.getKey(), attr.getDoubleValue().get());
  346 + } else if (attr.getDataType() == DataType.LONG && attr.getLongValue().isPresent()) {
  347 + attributes.put(attr.getKey(), attr.getLongValue().get());
  348 + } else {
  349 + attributes.put(attr.getKey(), attr.getValueAsString());
351 } 350 }
352 - entityData.put("kv", attributes);  
353 - entityData.put("scope", DataConstants.SERVER_SCOPE);  
354 - JsonNode entityBody = mapper.valueToTree(entityData);  
355 - log.debug("Sending attributes data msg, entityId [{}], attributes [{}]", entityId, entityBody);  
356 - saveEdgeEvent(edge.getTenantId(),  
357 - edge.getId(),  
358 - edgeEventType,  
359 - ActionType.ATTRIBUTES_UPDATED,  
360 - entityId,  
361 - entityBody);  
362 - } catch (Exception e) {  
363 - log.error("[{}] Failed to send attribute updates to the edge", edge.getName(), e);  
364 } 351 }
  352 + entityData.put("kv", attributes);
  353 + entityData.put("scope", DataConstants.SERVER_SCOPE);
  354 + JsonNode entityBody = mapper.valueToTree(entityData);
  355 + log.debug("Sending attributes data msg, entityId [{}], attributes [{}]", entityId, entityBody);
  356 + saveEdgeEvent(edge.getTenantId(),
  357 + edge.getId(),
  358 + edgeEventType,
  359 + ActionType.ATTRIBUTES_UPDATED,
  360 + entityId,
  361 + entityBody);
  362 + } catch (Exception e) {
  363 + log.error("[{}] Failed to send attribute updates to the edge", edge.getName(), e);
  364 + throw new RuntimeException("[" + edge.getName() + "] Failed to send attribute updates to the edge", e);
365 } 365 }
366 } 366 }
367 -  
368 - @Override  
369 - public void onFailure(Throwable t) {  
370 -  
371 - } 367 + return null;
372 }, dbCallbackExecutorService); 368 }, dbCallbackExecutorService);
373 369
374 // TODO: voba - push shared attributes to edge? 370 // TODO: voba - push shared attributes to edge?
375 - ListenableFuture<List<AttributeKvEntry>> shAttrFuture = attributesService.findAll(edge.getTenantId(), entityId, DataConstants.SHARED_SCOPE);  
376 - ListenableFuture<List<AttributeKvEntry>> clAttrFuture = attributesService.findAll(edge.getTenantId(), entityId, DataConstants.CLIENT_SCOPE); 371 + // ListenableFuture<List<AttributeKvEntry>> shAttrFuture = attributesService.findAll(edge.getTenantId(), entityId, DataConstants.SHARED_SCOPE);
  372 + // ListenableFuture<List<AttributeKvEntry>> clAttrFuture = attributesService.findAll(edge.getTenantId(), entityId, DataConstants.CLIENT_SCOPE);
  373 + } else {
  374 + return Futures.immediateFuture(null);
377 } 375 }
378 } 376 }
379 377
@@ -391,7 +389,7 @@ public class DefaultSyncEdgeService implements SyncEdgeService { @@ -391,7 +389,7 @@ public class DefaultSyncEdgeService implements SyncEdgeService {
391 } 389 }
392 390
393 @Override 391 @Override
394 - public void processRelationRequestMsg(Edge edge, RelationRequestMsg relationRequestMsg) { 392 + public ListenableFuture<Void> processRelationRequestMsg(Edge edge, RelationRequestMsg relationRequestMsg) {
395 EntityId entityId = EntityIdFactory.getByTypeAndUuid( 393 EntityId entityId = EntityIdFactory.getByTypeAndUuid(
396 EntityType.valueOf(relationRequestMsg.getEntityType()), 394 EntityType.valueOf(relationRequestMsg.getEntityType()),
397 new UUID(relationRequestMsg.getEntityIdMSB(), relationRequestMsg.getEntityIdLSB())); 395 new UUID(relationRequestMsg.getEntityIdMSB(), relationRequestMsg.getEntityIdLSB()));
@@ -400,39 +398,33 @@ public class DefaultSyncEdgeService implements SyncEdgeService { @@ -400,39 +398,33 @@ public class DefaultSyncEdgeService implements SyncEdgeService {
400 futures.add(findRelationByQuery(edge, entityId, EntitySearchDirection.FROM)); 398 futures.add(findRelationByQuery(edge, entityId, EntitySearchDirection.FROM));
401 futures.add(findRelationByQuery(edge, entityId, EntitySearchDirection.TO)); 399 futures.add(findRelationByQuery(edge, entityId, EntitySearchDirection.TO));
402 ListenableFuture<List<List<EntityRelation>>> relationsListFuture = Futures.allAsList(futures); 400 ListenableFuture<List<List<EntityRelation>>> relationsListFuture = Futures.allAsList(futures);
403 - Futures.addCallback(relationsListFuture, new FutureCallback<List<List<EntityRelation>>>() {  
404 - @Override  
405 - public void onSuccess(@Nullable List<List<EntityRelation>> relationsList) {  
406 - try {  
407 - if (!relationsList.isEmpty()) {  
408 - for (List<EntityRelation> entityRelations : relationsList) {  
409 - log.trace("[{}] [{}] [{}] relation(s) are going to be pushed to edge.", edge.getId(), entityId, entityRelations.size());  
410 - for (EntityRelation relation : entityRelations) {  
411 - try {  
412 - if (!relation.getFrom().getEntityType().equals(EntityType.EDGE) &&  
413 - !relation.getTo().getEntityType().equals(EntityType.EDGE)) {  
414 - saveEdgeEvent(edge.getTenantId(),  
415 - edge.getId(),  
416 - EdgeEventType.RELATION,  
417 - ActionType.ADDED,  
418 - null,  
419 - mapper.valueToTree(relation));  
420 - }  
421 - } catch (Exception e) {  
422 - log.error("Exception during loading relation [{}] to edge on sync!", relation, e); 401 + return Futures.transform(relationsListFuture, relationsList -> {
  402 + try {
  403 + if (relationsList != null && !relationsList.isEmpty()) {
  404 + for (List<EntityRelation> entityRelations : relationsList) {
  405 + log.trace("[{}] [{}] [{}] relation(s) are going to be pushed to edge.", edge.getId(), entityId, entityRelations.size());
  406 + for (EntityRelation relation : entityRelations) {
  407 + try {
  408 + if (!relation.getFrom().getEntityType().equals(EntityType.EDGE) &&
  409 + !relation.getTo().getEntityType().equals(EntityType.EDGE)) {
  410 + saveEdgeEvent(edge.getTenantId(),
  411 + edge.getId(),
  412 + EdgeEventType.RELATION,
  413 + ActionType.ADDED,
  414 + null,
  415 + mapper.valueToTree(relation));
423 } 416 }
  417 + } catch (Exception e) {
  418 + log.error("Exception during loading relation [{}] to edge on sync!", relation, e);
424 } 419 }
425 } 420 }
426 } 421 }
427 - } catch (Exception e) {  
428 - log.error("Exception during loading relation(s) to edge on sync!", e);  
429 } 422 }
  423 + } catch (Exception e) {
  424 + log.error("Exception during loading relation(s) to edge on sync!", e);
  425 + throw new RuntimeException("Exception during loading relation(s) to edge on sync!", e);
430 } 426 }
431 -  
432 - @Override  
433 - public void onFailure(Throwable t) {  
434 - log.error("Exception during loading relation(s) to edge on sync!", t);  
435 - } 427 + return null;
436 }, dbCallbackExecutorService); 428 }, dbCallbackExecutorService);
437 } 429 }
438 430
@@ -443,22 +435,26 @@ public class DefaultSyncEdgeService implements SyncEdgeService { @@ -443,22 +435,26 @@ public class DefaultSyncEdgeService implements SyncEdgeService {
443 } 435 }
444 436
445 @Override 437 @Override
446 - public void processDeviceCredentialsRequestMsg(Edge edge, DeviceCredentialsRequestMsg deviceCredentialsRequestMsg) { 438 + public ListenableFuture<Void> processDeviceCredentialsRequestMsg(Edge edge, DeviceCredentialsRequestMsg deviceCredentialsRequestMsg) {
447 if (deviceCredentialsRequestMsg.getDeviceIdMSB() != 0 && deviceCredentialsRequestMsg.getDeviceIdLSB() != 0) { 439 if (deviceCredentialsRequestMsg.getDeviceIdMSB() != 0 && deviceCredentialsRequestMsg.getDeviceIdLSB() != 0) {
448 DeviceId deviceId = new DeviceId(new UUID(deviceCredentialsRequestMsg.getDeviceIdMSB(), deviceCredentialsRequestMsg.getDeviceIdLSB())); 440 DeviceId deviceId = new DeviceId(new UUID(deviceCredentialsRequestMsg.getDeviceIdMSB(), deviceCredentialsRequestMsg.getDeviceIdLSB()));
449 - saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.DEVICE, ActionType.CREDENTIALS_UPDATED, deviceId, null); 441 + ListenableFuture<EdgeEvent> future = saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.DEVICE, ActionType.CREDENTIALS_UPDATED, deviceId, null);
  442 + return Futures.transform(future, edgeEvent -> null, dbCallbackExecutorService);
450 } 443 }
  444 + return Futures.immediateFuture(null);
451 } 445 }
452 446
453 @Override 447 @Override
454 - public void processUserCredentialsRequestMsg(Edge edge, UserCredentialsRequestMsg userCredentialsRequestMsg) { 448 + public ListenableFuture<Void> processUserCredentialsRequestMsg(Edge edge, UserCredentialsRequestMsg userCredentialsRequestMsg) {
455 if (userCredentialsRequestMsg.getUserIdMSB() != 0 && userCredentialsRequestMsg.getUserIdLSB() != 0) { 449 if (userCredentialsRequestMsg.getUserIdMSB() != 0 && userCredentialsRequestMsg.getUserIdLSB() != 0) {
456 UserId userId = new UserId(new UUID(userCredentialsRequestMsg.getUserIdMSB(), userCredentialsRequestMsg.getUserIdLSB())); 450 UserId userId = new UserId(new UUID(userCredentialsRequestMsg.getUserIdMSB(), userCredentialsRequestMsg.getUserIdLSB()));
457 - saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.USER, ActionType.CREDENTIALS_UPDATED, userId, null); 451 + ListenableFuture<EdgeEvent> future = saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.USER, ActionType.CREDENTIALS_UPDATED, userId, null);
  452 + return Futures.transform(future, edgeEvent -> null, dbCallbackExecutorService);
458 } 453 }
  454 + return Futures.immediateFuture(null);
459 } 455 }
460 456
461 - private void saveEdgeEvent(TenantId tenantId, 457 + private ListenableFuture<EdgeEvent> saveEdgeEvent(TenantId tenantId,
462 EdgeId edgeId, 458 EdgeId edgeId,
463 EdgeEventType edgeEventType, 459 EdgeEventType edgeEventType,
464 ActionType edgeEventAction, 460 ActionType edgeEventAction,
@@ -476,6 +472,6 @@ public class DefaultSyncEdgeService implements SyncEdgeService { @@ -476,6 +472,6 @@ public class DefaultSyncEdgeService implements SyncEdgeService {
476 edgeEvent.setEntityId(entityId.getId()); 472 edgeEvent.setEntityId(entityId.getId());
477 } 473 }
478 edgeEvent.setEntityBody(entityBody); 474 edgeEvent.setEntityBody(entityBody);
479 - edgeEventService.saveAsync(edgeEvent); 475 + return edgeEventService.saveAsync(edgeEvent);
480 } 476 }
481 } 477 }
@@ -15,6 +15,7 @@ @@ -15,6 +15,7 @@
15 */ 15 */
16 package org.thingsboard.server.service.edge.rpc.init; 16 package org.thingsboard.server.service.edge.rpc.init;
17 17
  18 +import com.google.common.util.concurrent.ListenableFuture;
18 import org.thingsboard.server.common.data.edge.Edge; 19 import org.thingsboard.server.common.data.edge.Edge;
19 import org.thingsboard.server.gen.edge.AttributesRequestMsg; 20 import org.thingsboard.server.gen.edge.AttributesRequestMsg;
20 import org.thingsboard.server.gen.edge.DeviceCredentialsRequestMsg; 21 import org.thingsboard.server.gen.edge.DeviceCredentialsRequestMsg;
@@ -26,13 +27,13 @@ public interface SyncEdgeService { @@ -26,13 +27,13 @@ public interface SyncEdgeService {
26 27
27 void sync(Edge edge); 28 void sync(Edge edge);
28 29
29 - void processRuleChainMetadataRequestMsg(Edge edge, RuleChainMetadataRequestMsg ruleChainMetadataRequestMsg); 30 + ListenableFuture<Void> processRuleChainMetadataRequestMsg(Edge edge, RuleChainMetadataRequestMsg ruleChainMetadataRequestMsg);
30 31
31 - void processAttributesRequestMsg(Edge edge, AttributesRequestMsg attributesRequestMsg); 32 + ListenableFuture<Void> processAttributesRequestMsg(Edge edge, AttributesRequestMsg attributesRequestMsg);
32 33
33 - void processRelationRequestMsg(Edge edge, RelationRequestMsg relationRequestMsg); 34 + ListenableFuture<Void> processRelationRequestMsg(Edge edge, RelationRequestMsg relationRequestMsg);
34 35
35 - void processDeviceCredentialsRequestMsg(Edge edge, DeviceCredentialsRequestMsg deviceCredentialsRequestMsg); 36 + ListenableFuture<Void> processDeviceCredentialsRequestMsg(Edge edge, DeviceCredentialsRequestMsg deviceCredentialsRequestMsg);
36 37
37 - void processUserCredentialsRequestMsg(Edge edge, UserCredentialsRequestMsg userCredentialsRequestMsg); 38 + ListenableFuture<Void> processUserCredentialsRequestMsg(Edge edge, UserCredentialsRequestMsg userCredentialsRequestMsg);
38 } 39 }
@@ -28,9 +28,9 @@ import org.thingsboard.server.gen.edge.ConnectRequestMsg; @@ -28,9 +28,9 @@ import org.thingsboard.server.gen.edge.ConnectRequestMsg;
28 import org.thingsboard.server.gen.edge.ConnectResponseCode; 28 import org.thingsboard.server.gen.edge.ConnectResponseCode;
29 import org.thingsboard.server.gen.edge.ConnectResponseMsg; 29 import org.thingsboard.server.gen.edge.ConnectResponseMsg;
30 import org.thingsboard.server.gen.edge.DownlinkMsg; 30 import org.thingsboard.server.gen.edge.DownlinkMsg;
  31 +import org.thingsboard.server.gen.edge.DownlinkResponseMsg;
31 import org.thingsboard.server.gen.edge.EdgeConfiguration; 32 import org.thingsboard.server.gen.edge.EdgeConfiguration;
32 import org.thingsboard.server.gen.edge.EdgeRpcServiceGrpc; 33 import org.thingsboard.server.gen.edge.EdgeRpcServiceGrpc;
33 -import org.thingsboard.server.gen.edge.EntityUpdateMsg;  
34 import org.thingsboard.server.gen.edge.RequestMsg; 34 import org.thingsboard.server.gen.edge.RequestMsg;
35 import org.thingsboard.server.gen.edge.RequestMsgType; 35 import org.thingsboard.server.gen.edge.RequestMsgType;
36 import org.thingsboard.server.gen.edge.ResponseMsg; 36 import org.thingsboard.server.gen.edge.ResponseMsg;
@@ -41,6 +41,7 @@ import javax.net.ssl.SSLException; @@ -41,6 +41,7 @@ import javax.net.ssl.SSLException;
41 import java.io.File; 41 import java.io.File;
42 import java.net.URISyntaxException; 42 import java.net.URISyntaxException;
43 import java.util.concurrent.TimeUnit; 43 import java.util.concurrent.TimeUnit;
  44 +import java.util.concurrent.locks.ReentrantLock;
44 import java.util.function.Consumer; 45 import java.util.function.Consumer;
45 46
46 @Service 47 @Service
@@ -62,12 +63,13 @@ public class EdgeGrpcClient implements EdgeRpcClient { @@ -62,12 +63,13 @@ public class EdgeGrpcClient implements EdgeRpcClient {
62 63
63 private StreamObserver<RequestMsg> inputStream; 64 private StreamObserver<RequestMsg> inputStream;
64 65
  66 + private static final ReentrantLock uplinkMsgLock = new ReentrantLock();
  67 +
65 @Override 68 @Override
66 public void connect(String edgeKey, 69 public void connect(String edgeKey,
67 String edgeSecret, 70 String edgeSecret,
68 Consumer<UplinkResponseMsg> onUplinkResponse, 71 Consumer<UplinkResponseMsg> onUplinkResponse,
69 Consumer<EdgeConfiguration> onEdgeUpdate, 72 Consumer<EdgeConfiguration> onEdgeUpdate,
70 - Consumer<EntityUpdateMsg> onEntityUpdate,  
71 Consumer<DownlinkMsg> onDownlink, 73 Consumer<DownlinkMsg> onDownlink,
72 Consumer<Exception> onError) { 74 Consumer<Exception> onError) {
73 NettyChannelBuilder builder = NettyChannelBuilder.forAddress(rpcHost, rpcPort).usePlaintext(); 75 NettyChannelBuilder builder = NettyChannelBuilder.forAddress(rpcHost, rpcPort).usePlaintext();
@@ -83,7 +85,7 @@ public class EdgeGrpcClient implements EdgeRpcClient { @@ -83,7 +85,7 @@ public class EdgeGrpcClient implements EdgeRpcClient {
83 channel = builder.build(); 85 channel = builder.build();
84 EdgeRpcServiceGrpc.EdgeRpcServiceStub stub = EdgeRpcServiceGrpc.newStub(channel); 86 EdgeRpcServiceGrpc.EdgeRpcServiceStub stub = EdgeRpcServiceGrpc.newStub(channel);
85 log.info("[{}] Sending a connect request to the TB!", edgeKey); 87 log.info("[{}] Sending a connect request to the TB!", edgeKey);
86 - this.inputStream = stub.handleMsgs(initOutputStream(edgeKey, onUplinkResponse, onEdgeUpdate, onEntityUpdate, onDownlink, onError)); 88 + this.inputStream = stub.handleMsgs(initOutputStream(edgeKey, onUplinkResponse, onEdgeUpdate, onDownlink, onError));
87 this.inputStream.onNext(RequestMsg.newBuilder() 89 this.inputStream.onNext(RequestMsg.newBuilder()
88 .setMsgType(RequestMsgType.CONNECT_RPC_MESSAGE) 90 .setMsgType(RequestMsgType.CONNECT_RPC_MESSAGE)
89 .setConnectRequestMsg(ConnectRequestMsg.newBuilder().setEdgeRoutingKey(edgeKey).setEdgeSecret(edgeSecret).build()) 91 .setConnectRequestMsg(ConnectRequestMsg.newBuilder().setEdgeRoutingKey(edgeKey).setEdgeSecret(edgeSecret).build())
@@ -110,16 +112,33 @@ public class EdgeGrpcClient implements EdgeRpcClient { @@ -110,16 +112,33 @@ public class EdgeGrpcClient implements EdgeRpcClient {
110 112
111 @Override 113 @Override
112 public void sendUplinkMsg(UplinkMsg msg) { 114 public void sendUplinkMsg(UplinkMsg msg) {
113 - this.inputStream.onNext(RequestMsg.newBuilder()  
114 - .setMsgType(RequestMsgType.UPLINK_RPC_MESSAGE)  
115 - .setUplinkMsg(msg)  
116 - .build()); 115 + try {
  116 + uplinkMsgLock.lock();
  117 + this.inputStream.onNext(RequestMsg.newBuilder()
  118 + .setMsgType(RequestMsgType.UPLINK_RPC_MESSAGE)
  119 + .setUplinkMsg(msg)
  120 + .build());
  121 + } finally {
  122 + uplinkMsgLock.unlock();
  123 + }
  124 + }
  125 +
  126 + @Override
  127 + public void sendDownlinkResponseMsg(DownlinkResponseMsg downlinkResponseMsg) {
  128 + try {
  129 + uplinkMsgLock.lock();
  130 + this.inputStream.onNext(RequestMsg.newBuilder()
  131 + .setMsgType(RequestMsgType.UPLINK_RPC_MESSAGE)
  132 + .setDownlinkResponseMsg(downlinkResponseMsg)
  133 + .build());
  134 + } finally {
  135 + uplinkMsgLock.unlock();
  136 + }
117 } 137 }
118 138
119 private StreamObserver<ResponseMsg> initOutputStream(String edgeKey, 139 private StreamObserver<ResponseMsg> initOutputStream(String edgeKey,
120 Consumer<UplinkResponseMsg> onUplinkResponse, 140 Consumer<UplinkResponseMsg> onUplinkResponse,
121 Consumer<EdgeConfiguration> onEdgeUpdate, 141 Consumer<EdgeConfiguration> onEdgeUpdate,
122 - Consumer<EntityUpdateMsg> onEntityUpdate,  
123 Consumer<DownlinkMsg> onDownlink, 142 Consumer<DownlinkMsg> onDownlink,
124 Consumer<Exception> onError) { 143 Consumer<Exception> onError) {
125 return new StreamObserver<ResponseMsg>() { 144 return new StreamObserver<ResponseMsg>() {
@@ -137,9 +156,6 @@ public class EdgeGrpcClient implements EdgeRpcClient { @@ -137,9 +156,6 @@ public class EdgeGrpcClient implements EdgeRpcClient {
137 } else if (responseMsg.hasUplinkResponseMsg()) { 156 } else if (responseMsg.hasUplinkResponseMsg()) {
138 log.debug("[{}] Uplink response message received {}", edgeKey, responseMsg.getUplinkResponseMsg()); 157 log.debug("[{}] Uplink response message received {}", edgeKey, responseMsg.getUplinkResponseMsg());
139 onUplinkResponse.accept(responseMsg.getUplinkResponseMsg()); 158 onUplinkResponse.accept(responseMsg.getUplinkResponseMsg());
140 - } else if (responseMsg.hasEntityUpdateMsg()) {  
141 - log.debug("[{}] Entity update message received {}", edgeKey, responseMsg.getEntityUpdateMsg());  
142 - onEntityUpdate.accept(responseMsg.getEntityUpdateMsg());  
143 } else if (responseMsg.hasDownlinkMsg()) { 159 } else if (responseMsg.hasDownlinkMsg()) {
144 log.debug("[{}] Downlink message received {}", edgeKey, responseMsg.getDownlinkMsg()); 160 log.debug("[{}] Downlink message received {}", edgeKey, responseMsg.getDownlinkMsg());
145 onDownlink.accept(responseMsg.getDownlinkMsg()); 161 onDownlink.accept(responseMsg.getDownlinkMsg());
@@ -16,8 +16,8 @@ @@ -16,8 +16,8 @@
16 package org.thingsboard.edge.rpc; 16 package org.thingsboard.edge.rpc;
17 17
18 import org.thingsboard.server.gen.edge.DownlinkMsg; 18 import org.thingsboard.server.gen.edge.DownlinkMsg;
  19 +import org.thingsboard.server.gen.edge.DownlinkResponseMsg;
19 import org.thingsboard.server.gen.edge.EdgeConfiguration; 20 import org.thingsboard.server.gen.edge.EdgeConfiguration;
20 -import org.thingsboard.server.gen.edge.EntityUpdateMsg;  
21 import org.thingsboard.server.gen.edge.UplinkMsg; 21 import org.thingsboard.server.gen.edge.UplinkMsg;
22 import org.thingsboard.server.gen.edge.UplinkResponseMsg; 22 import org.thingsboard.server.gen.edge.UplinkResponseMsg;
23 23
@@ -29,11 +29,12 @@ public interface EdgeRpcClient { @@ -29,11 +29,12 @@ public interface EdgeRpcClient {
29 String integrationSecret, 29 String integrationSecret,
30 Consumer<UplinkResponseMsg> onUplinkResponse, 30 Consumer<UplinkResponseMsg> onUplinkResponse,
31 Consumer<EdgeConfiguration> onEdgeUpdate, 31 Consumer<EdgeConfiguration> onEdgeUpdate,
32 - Consumer<EntityUpdateMsg> onEntityUpdate,  
33 Consumer<DownlinkMsg> onDownlink, 32 Consumer<DownlinkMsg> onDownlink,
34 Consumer<Exception> onError); 33 Consumer<Exception> onError);
35 34
36 void disconnect() throws InterruptedException; 35 void disconnect() throws InterruptedException;
37 36
38 - void sendUplinkMsg(UplinkMsg uplinkMsg) throws InterruptedException; 37 + void sendUplinkMsg(UplinkMsg uplinkMsg);
  38 +
  39 + void sendDownlinkResponseMsg(DownlinkResponseMsg downlinkResponseMsg);
39 } 40 }
@@ -37,31 +37,13 @@ message RequestMsg { @@ -37,31 +37,13 @@ message RequestMsg {
37 RequestMsgType msgType = 1; 37 RequestMsgType msgType = 1;
38 ConnectRequestMsg connectRequestMsg = 2; 38 ConnectRequestMsg connectRequestMsg = 2;
39 UplinkMsg uplinkMsg = 3; 39 UplinkMsg uplinkMsg = 3;
  40 + DownlinkResponseMsg downlinkResponseMsg = 4;
40 } 41 }
41 42
42 message ResponseMsg { 43 message ResponseMsg {
43 ConnectResponseMsg connectResponseMsg = 1; 44 ConnectResponseMsg connectResponseMsg = 1;
44 UplinkResponseMsg uplinkResponseMsg = 2; 45 UplinkResponseMsg uplinkResponseMsg = 2;
45 - EntityUpdateMsg entityUpdateMsg = 3;  
46 - DownlinkMsg downlinkMsg = 4;  
47 -}  
48 -  
49 -message EntityUpdateMsg {  
50 - DeviceUpdateMsg deviceUpdateMsg = 1;  
51 - DeviceCredentialsUpdateMsg deviceCredentialsUpdateMsg = 2;  
52 - RuleChainUpdateMsg ruleChainUpdateMsg = 3;  
53 - RuleChainMetadataUpdateMsg ruleChainMetadataUpdateMsg = 4;  
54 - DashboardUpdateMsg dashboardUpdateMsg = 5;  
55 - AssetUpdateMsg assetUpdateMsg = 6;  
56 - EntityViewUpdateMsg entityViewUpdateMsg = 7;  
57 - AlarmUpdateMsg alarmUpdateMsg = 8;  
58 - UserUpdateMsg userUpdateMsg = 9;  
59 - UserCredentialsUpdateMsg userCredentialsUpdateMsg = 10;  
60 - CustomerUpdateMsg customerUpdateMsg = 11;  
61 - RelationUpdateMsg relationUpdateMsg = 12;  
62 - WidgetsBundleUpdateMsg widgetsBundleUpdateMsg = 13;  
63 - WidgetTypeUpdateMsg widgetTypeUpdateMsg = 14;  
64 - AdminSettingsUpdateMsg adminSettingsUpdateMsg = 15; 46 + DownlinkMsg downlinkMsg = 3;
65 } 47 }
66 48
67 enum RequestMsgType { 49 enum RequestMsgType {
@@ -360,9 +342,30 @@ message UplinkResponseMsg { @@ -360,9 +342,30 @@ message UplinkResponseMsg {
360 string errorMsg = 2; 342 string errorMsg = 2;
361 } 343 }
362 344
  345 +message DownlinkResponseMsg {
  346 + bool success = 1;
  347 + string errorMsg = 2;
  348 +}
  349 +
363 message DownlinkMsg { 350 message DownlinkMsg {
364 int32 downlinkMsgId = 1; 351 int32 downlinkMsgId = 1;
365 repeated EntityDataProto entityData = 2; 352 repeated EntityDataProto entityData = 2;
366 repeated DeviceCredentialsRequestMsg deviceCredentialsRequestMsg = 3; 353 repeated DeviceCredentialsRequestMsg deviceCredentialsRequestMsg = 3;
  354 + repeated DeviceUpdateMsg deviceUpdateMsg = 4;
  355 + repeated DeviceCredentialsUpdateMsg deviceCredentialsUpdateMsg = 5;
  356 + repeated RuleChainUpdateMsg ruleChainUpdateMsg = 6;
  357 + repeated RuleChainMetadataUpdateMsg ruleChainMetadataUpdateMsg = 7;
  358 + repeated DashboardUpdateMsg dashboardUpdateMsg = 8;
  359 + repeated AssetUpdateMsg assetUpdateMsg = 9;
  360 + repeated EntityViewUpdateMsg entityViewUpdateMsg = 10;
  361 + repeated AlarmUpdateMsg alarmUpdateMsg = 11;
  362 + repeated UserUpdateMsg userUpdateMsg = 12;
  363 + repeated UserCredentialsUpdateMsg userCredentialsUpdateMsg = 13;
  364 + repeated CustomerUpdateMsg customerUpdateMsg = 14;
  365 + repeated RelationUpdateMsg relationUpdateMsg = 15;
  366 + repeated WidgetsBundleUpdateMsg widgetsBundleUpdateMsg = 16;
  367 + repeated WidgetTypeUpdateMsg widgetTypeUpdateMsg = 17;
  368 + repeated AdminSettingsUpdateMsg adminSettingsUpdateMsg = 18;
  369 +
367 } 370 }
368 371