Commit e0881cfc44a857518d6ea58a73c05a8959e1b854
1 parent
5e46f3e7
Added Rule Chain Metadata Update Msg. Added assigned edges text to rule chain
Showing
17 changed files
with
314 additions
and
42 deletions
... | ... | @@ -41,7 +41,11 @@ import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry; |
41 | 41 | import org.thingsboard.server.common.data.kv.LongDataEntry; |
42 | 42 | import org.thingsboard.server.common.data.page.TimePageData; |
43 | 43 | import org.thingsboard.server.common.data.page.TimePageLink; |
44 | +import org.thingsboard.server.common.data.rule.NodeConnectionInfo; | |
44 | 45 | import org.thingsboard.server.common.data.rule.RuleChain; |
46 | +import org.thingsboard.server.common.data.rule.RuleChainConnectionInfo; | |
47 | +import org.thingsboard.server.common.data.rule.RuleChainMetaData; | |
48 | +import org.thingsboard.server.common.data.rule.RuleNode; | |
45 | 49 | import org.thingsboard.server.dao.asset.AssetService; |
46 | 50 | import org.thingsboard.server.dao.attributes.AttributesService; |
47 | 51 | import org.thingsboard.server.dao.device.DeviceService; |
... | ... | @@ -55,16 +59,20 @@ import org.thingsboard.server.gen.edge.DashboardUpdateMsg; |
55 | 59 | import org.thingsboard.server.gen.edge.DeviceUpdateMsg; |
56 | 60 | import org.thingsboard.server.gen.edge.EdgeConfiguration; |
57 | 61 | import org.thingsboard.server.gen.edge.EntityViewUpdateMsg; |
62 | +import org.thingsboard.server.gen.edge.NodeConnectionInfoProto; | |
58 | 63 | import org.thingsboard.server.gen.edge.RequestMsg; |
59 | 64 | import org.thingsboard.server.gen.edge.RequestMsgType; |
60 | 65 | import org.thingsboard.server.gen.edge.ResponseMsg; |
66 | +import org.thingsboard.server.gen.edge.RuleChainConnectionInfoProto; | |
67 | +import org.thingsboard.server.gen.edge.RuleChainMetadataUpdateMsg; | |
61 | 68 | import org.thingsboard.server.gen.edge.RuleChainUpdateMsg; |
69 | +import org.thingsboard.server.gen.edge.RuleNodeProto; | |
62 | 70 | import org.thingsboard.server.gen.edge.UpdateMsgType; |
63 | 71 | import org.thingsboard.server.gen.edge.UplinkMsg; |
64 | 72 | import org.thingsboard.server.gen.edge.UplinkResponseMsg; |
65 | 73 | import org.thingsboard.server.service.edge.EdgeContextComponent; |
66 | 74 | |
67 | -import java.util.Arrays; | |
75 | +import java.util.ArrayList; | |
68 | 76 | import java.util.Collections; |
69 | 77 | import java.util.List; |
70 | 78 | import java.util.Optional; |
... | ... | @@ -146,7 +154,7 @@ public final class EdgeGrpcSession implements Cloneable { |
146 | 154 | |
147 | 155 | void processHandleMessages() throws ExecutionException, InterruptedException { |
148 | 156 | Long queueStartTs = getQueueStartTs().get(); |
149 | - // TODO: this 100 value must be chagned properly | |
157 | + // TODO: this 100 value must be changed properly | |
150 | 158 | TimePageLink pageLink = new TimePageLink(30, queueStartTs + 1000); |
151 | 159 | TimePageData<Event> pageData; |
152 | 160 | UUID ifOffset = null; |
... | ... | @@ -179,6 +187,10 @@ public final class EdgeGrpcSession implements Cloneable { |
179 | 187 | RuleChain ruleChain = objectMapper.readValue(entry.getData(), RuleChain.class); |
180 | 188 | onRuleChainUpdated(msgType, ruleChain); |
181 | 189 | break; |
190 | + case RULE_CHAIN_METADATA: | |
191 | + RuleChainMetaData ruleChainMetaData = objectMapper.readValue(entry.getData(), RuleChainMetaData.class); | |
192 | + onRuleChainMetadataUpdated(msgType, ruleChainMetaData); | |
193 | + break; | |
182 | 194 | } |
183 | 195 | } catch (Exception e) { |
184 | 196 | log.error("Exception during processing records from queue", e); |
... | ... | @@ -244,6 +256,15 @@ public final class EdgeGrpcSession implements Cloneable { |
244 | 256 | .build()); |
245 | 257 | } |
246 | 258 | |
259 | + private void onRuleChainMetadataUpdated(UpdateMsgType msgType, RuleChainMetaData ruleChainMetaData) { | |
260 | + RuleChainMetadataUpdateMsg ruleChainMetadataUpdateMsg = constructRuleChainMetadataUpdatedMsg(msgType, ruleChainMetaData); | |
261 | + if (ruleChainMetadataUpdateMsg != null) { | |
262 | + outputStream.onNext(ResponseMsg.newBuilder() | |
263 | + .setRuleChainMetadataUpdateMsg(ruleChainMetadataUpdateMsg) | |
264 | + .build()); | |
265 | + } | |
266 | + } | |
267 | + | |
247 | 268 | private void onDashboardUpdated(UpdateMsgType msgType, Dashboard dashboard) { |
248 | 269 | outputStream.onNext(ResponseMsg.newBuilder() |
249 | 270 | .setDashboardUpdateMsg(constructDashboardUpdatedMsg(msgType, dashboard)) |
... | ... | @@ -281,6 +302,83 @@ public final class EdgeGrpcSession implements Cloneable { |
281 | 302 | return builder.build(); |
282 | 303 | } |
283 | 304 | |
305 | + private RuleChainMetadataUpdateMsg constructRuleChainMetadataUpdatedMsg(UpdateMsgType msgType, RuleChainMetaData ruleChainMetaData) { | |
306 | + try { | |
307 | + RuleChainMetadataUpdateMsg.Builder builder = RuleChainMetadataUpdateMsg.newBuilder() | |
308 | + .setRuleChainIdMSB(ruleChainMetaData.getRuleChainId().getId().getMostSignificantBits()) | |
309 | + .setRuleChainIdLSB(ruleChainMetaData.getRuleChainId().getId().getLeastSignificantBits()) | |
310 | + .addAllNodes(constructNodes(ruleChainMetaData.getNodes())) | |
311 | + .addAllConnections(constructConnections(ruleChainMetaData.getConnections())) | |
312 | + .addAllRuleChainConnections(constructRuleChainConnections(ruleChainMetaData.getRuleChainConnections())); | |
313 | + if (ruleChainMetaData.getFirstNodeIndex() != null) { | |
314 | + builder.setFirstNodeIndex(ruleChainMetaData.getFirstNodeIndex()); | |
315 | + } | |
316 | + builder.setMsgType(msgType); | |
317 | + return builder.build(); | |
318 | + } catch (JsonProcessingException ex) { | |
319 | + log.error("Can't construct RuleChainMetadataUpdateMsg", ex); | |
320 | + } | |
321 | + return null; | |
322 | + } | |
323 | + | |
324 | + private List<RuleChainConnectionInfoProto> constructRuleChainConnections(List<RuleChainConnectionInfo> ruleChainConnections) throws JsonProcessingException { | |
325 | + List<RuleChainConnectionInfoProto> result = new ArrayList<>(); | |
326 | + if (ruleChainConnections != null && !ruleChainConnections.isEmpty()) { | |
327 | + for (RuleChainConnectionInfo ruleChainConnectionInfo : ruleChainConnections) { | |
328 | + result.add(constructRuleChainConnection(ruleChainConnectionInfo)); | |
329 | + } | |
330 | + } | |
331 | + return result; | |
332 | + } | |
333 | + | |
334 | + private RuleChainConnectionInfoProto constructRuleChainConnection(RuleChainConnectionInfo ruleChainConnectionInfo) throws JsonProcessingException { | |
335 | + return RuleChainConnectionInfoProto.newBuilder() | |
336 | + .setFromIndex(ruleChainConnectionInfo.getFromIndex()) | |
337 | + .setTargetRuleChainIdMSB(ruleChainConnectionInfo.getTargetRuleChainId().getId().getMostSignificantBits()) | |
338 | + .setTargetRuleChainIdLSB(ruleChainConnectionInfo.getTargetRuleChainId().getId().getLeastSignificantBits()) | |
339 | + .setType(ruleChainConnectionInfo.getType()) | |
340 | + .setAdditionalInfo(objectMapper.writeValueAsString(ruleChainConnectionInfo.getAdditionalInfo())) | |
341 | + .build(); | |
342 | + } | |
343 | + | |
344 | + private List<NodeConnectionInfoProto> constructConnections(List<NodeConnectionInfo> connections) { | |
345 | + List<NodeConnectionInfoProto> result = new ArrayList<>(); | |
346 | + if (connections != null && !connections.isEmpty()) { | |
347 | + for (NodeConnectionInfo connection : connections) { | |
348 | + result.add(constructConnection(connection)); | |
349 | + } | |
350 | + } | |
351 | + return result; | |
352 | + } | |
353 | + | |
354 | + private NodeConnectionInfoProto constructConnection(NodeConnectionInfo connection) { | |
355 | + return NodeConnectionInfoProto.newBuilder() | |
356 | + .setFromIndex(connection.getFromIndex()) | |
357 | + .setToIndex(connection.getToIndex()) | |
358 | + .setType(connection.getType()) | |
359 | + .build(); | |
360 | + } | |
361 | + | |
362 | + private List<RuleNodeProto> constructNodes(List<RuleNode> nodes) throws JsonProcessingException { | |
363 | + List<RuleNodeProto> result = new ArrayList<>(); | |
364 | + if (nodes != null && !nodes.isEmpty()) { | |
365 | + for (RuleNode node : nodes) { | |
366 | + result.add(constructNode(node)); | |
367 | + } | |
368 | + } | |
369 | + return result; | |
370 | + } | |
371 | + | |
372 | + private RuleNodeProto constructNode(RuleNode node) throws JsonProcessingException { | |
373 | + return RuleNodeProto.newBuilder() | |
374 | + .setType(node.getType()) | |
375 | + .setName(node.getName()) | |
376 | + .setDebugMode(node.isDebugMode()) | |
377 | + .setConfiguration(objectMapper.writeValueAsString(node.getConfiguration())) | |
378 | + .setAdditionalInfo(objectMapper.writeValueAsString(node.getAdditionalInfo())) | |
379 | + .build(); | |
380 | + } | |
381 | + | |
284 | 382 | private DashboardUpdateMsg constructDashboardUpdatedMsg(UpdateMsgType msgType, Dashboard dashboard) { |
285 | 383 | DashboardUpdateMsg.Builder builder = DashboardUpdateMsg.newBuilder() |
286 | 384 | .setMsgType(msgType) | ... | ... |
... | ... | @@ -15,16 +15,13 @@ |
15 | 15 | */ |
16 | 16 | package org.thingsboard.server.dao.edge; |
17 | 17 | |
18 | -import com.fasterxml.jackson.databind.JsonNode; | |
19 | 18 | import com.google.common.util.concurrent.ListenableFuture; |
20 | 19 | import org.thingsboard.server.common.data.EntitySubtype; |
21 | 20 | import org.thingsboard.server.common.data.Event; |
22 | -import org.thingsboard.server.common.data.Tenant; | |
23 | 21 | import org.thingsboard.server.common.data.edge.Edge; |
24 | 22 | import org.thingsboard.server.common.data.edge.EdgeSearchQuery; |
25 | 23 | import org.thingsboard.server.common.data.id.CustomerId; |
26 | 24 | import org.thingsboard.server.common.data.id.EdgeId; |
27 | -import org.thingsboard.server.common.data.id.EntityId; | |
28 | 25 | import org.thingsboard.server.common.data.id.TenantId; |
29 | 26 | import org.thingsboard.server.common.data.page.TextPageData; |
30 | 27 | import org.thingsboard.server.common.data.page.TextPageLink; | ... | ... |
common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeQueueEntityType.java
0 → 100644
1 | +/** | |
2 | + * Copyright © 2016-2019 The Thingsboard Authors | |
3 | + * | |
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | |
5 | + * you may not use this file except in compliance with the License. | |
6 | + * You may obtain a copy of the License at | |
7 | + * | |
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | |
9 | + * | |
10 | + * Unless required by applicable law or agreed to in writing, software | |
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | |
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 | + * See the License for the specific language governing permissions and | |
14 | + * limitations under the License. | |
15 | + */ | |
16 | +package org.thingsboard.server.common.data.edge; | |
17 | + | |
18 | +public enum EdgeQueueEntityType { | |
19 | + DASHBOARD, ASSET, DEVICE, ENTITY_VIEW, ALARM, RULE_CHAIN, RULE_CHAIN_METADATA | |
20 | +} | ... | ... |
... | ... | @@ -16,11 +16,10 @@ |
16 | 16 | package org.thingsboard.server.common.data.edge; |
17 | 17 | |
18 | 18 | import lombok.Data; |
19 | -import org.thingsboard.server.common.data.EntityType; | |
20 | 19 | |
21 | 20 | @Data |
22 | 21 | public class EdgeQueueEntry { |
23 | 22 | private String type; |
24 | - private EntityType entityType; | |
23 | + private EdgeQueueEntityType entityType; | |
25 | 24 | private String data; |
26 | 25 | } | ... | ... |
... | ... | @@ -37,6 +37,7 @@ import org.thingsboard.server.gen.edge.EntityViewUpdateMsg; |
37 | 37 | import org.thingsboard.server.gen.edge.RequestMsg; |
38 | 38 | import org.thingsboard.server.gen.edge.RequestMsgType; |
39 | 39 | import org.thingsboard.server.gen.edge.ResponseMsg; |
40 | +import org.thingsboard.server.gen.edge.RuleChainMetadataUpdateMsg; | |
40 | 41 | import org.thingsboard.server.gen.edge.RuleChainUpdateMsg; |
41 | 42 | import org.thingsboard.server.gen.edge.UplinkMsg; |
42 | 43 | import org.thingsboard.server.gen.edge.UplinkResponseMsg; |
... | ... | @@ -75,6 +76,7 @@ public class EdgeGrpcClient implements EdgeRpcClient { |
75 | 76 | Consumer<AssetUpdateMsg> onAssetUpdate, |
76 | 77 | Consumer<EntityViewUpdateMsg> onEntityViewUpdate, |
77 | 78 | Consumer<RuleChainUpdateMsg> onRuleChainUpdate, |
79 | + Consumer<RuleChainMetadataUpdateMsg> onRuleChainMetadataUpdate, | |
78 | 80 | Consumer<DashboardUpdateMsg> onDashboardUpdate, |
79 | 81 | Consumer<DownlinkMsg> onDownlink, |
80 | 82 | Consumer<Exception> onError) { |
... | ... | @@ -90,7 +92,7 @@ public class EdgeGrpcClient implements EdgeRpcClient { |
90 | 92 | channel = builder.build(); |
91 | 93 | EdgeRpcServiceGrpc.EdgeRpcServiceStub stub = EdgeRpcServiceGrpc.newStub(channel); |
92 | 94 | log.info("[{}] Sending a connect request to the TB!", edgeKey); |
93 | - this.inputStream = stub.handleMsgs(initOutputStream(edgeKey, onUplinkResponse, onEdgeUpdate, onDeviceUpdate, onAssetUpdate, onEntityViewUpdate, onRuleChainUpdate, onDashboardUpdate, onDownlink, onError)); | |
95 | + this.inputStream = stub.handleMsgs(initOutputStream(edgeKey, onUplinkResponse, onEdgeUpdate, onDeviceUpdate, onAssetUpdate, onEntityViewUpdate, onRuleChainUpdate, onRuleChainMetadataUpdate, onDashboardUpdate, onDownlink, onError)); | |
94 | 96 | this.inputStream.onNext(RequestMsg.newBuilder() |
95 | 97 | .setMsgType(RequestMsgType.CONNECT_RPC_MESSAGE) |
96 | 98 | .setConnectRequestMsg(ConnectRequestMsg.newBuilder().setEdgeRoutingKey(edgeKey).setEdgeSecret(edgeSecret).build()) |
... | ... | @@ -120,6 +122,7 @@ public class EdgeGrpcClient implements EdgeRpcClient { |
120 | 122 | Consumer<AssetUpdateMsg> onAssetUpdate, |
121 | 123 | Consumer<EntityViewUpdateMsg> onEntityViewUpdate, |
122 | 124 | Consumer<RuleChainUpdateMsg> onRuleChainUpdate, |
125 | + Consumer<RuleChainMetadataUpdateMsg> onRuleChainMetadataUpdate, | |
123 | 126 | Consumer<DashboardUpdateMsg> onDashboardUpdate, |
124 | 127 | Consumer<DownlinkMsg> onDownlink, |
125 | 128 | Consumer<Exception> onError) { |
... | ... | @@ -150,6 +153,9 @@ public class EdgeGrpcClient implements EdgeRpcClient { |
150 | 153 | } else if (responseMsg.hasRuleChainUpdateMsg()) { |
151 | 154 | log.debug("[{}] Rule Chain udpate message received {}", edgeKey, responseMsg.getRuleChainUpdateMsg()); |
152 | 155 | onRuleChainUpdate.accept(responseMsg.getRuleChainUpdateMsg()); |
156 | + } else if (responseMsg.hasRuleChainMetadataUpdateMsg()) { | |
157 | + log.debug("[{}] Rule Chain Metadata udpate message received {}", edgeKey, responseMsg.getRuleChainMetadataUpdateMsg()); | |
158 | + onRuleChainMetadataUpdate.accept(responseMsg.getRuleChainMetadataUpdateMsg()); | |
153 | 159 | } else if (responseMsg.hasDashboardUpdateMsg()) { |
154 | 160 | log.debug("[{}] Dashboard message received {}", edgeKey, responseMsg.getDashboardUpdateMsg()); |
155 | 161 | onDashboardUpdate.accept(responseMsg.getDashboardUpdateMsg()); | ... | ... |
... | ... | @@ -21,6 +21,7 @@ import org.thingsboard.server.gen.edge.DeviceUpdateMsg; |
21 | 21 | import org.thingsboard.server.gen.edge.DownlinkMsg; |
22 | 22 | import org.thingsboard.server.gen.edge.EdgeConfiguration; |
23 | 23 | import org.thingsboard.server.gen.edge.EntityViewUpdateMsg; |
24 | +import org.thingsboard.server.gen.edge.RuleChainMetadataUpdateMsg; | |
24 | 25 | import org.thingsboard.server.gen.edge.RuleChainUpdateMsg; |
25 | 26 | import org.thingsboard.server.gen.edge.UplinkMsg; |
26 | 27 | import org.thingsboard.server.gen.edge.UplinkResponseMsg; |
... | ... | @@ -37,6 +38,7 @@ public interface EdgeRpcClient { |
37 | 38 | Consumer<AssetUpdateMsg> onAssetUpdate, |
38 | 39 | Consumer<EntityViewUpdateMsg> onEntityViewUpdate, |
39 | 40 | Consumer<RuleChainUpdateMsg> onRuleChainUpdate, |
41 | + Consumer<RuleChainMetadataUpdateMsg> onRuleChainMetadataUpdate, | |
40 | 42 | Consumer<DashboardUpdateMsg> onDashboardUpdate, |
41 | 43 | Consumer<DownlinkMsg> onDownlink, |
42 | 44 | Consumer<Exception> onError); | ... | ... |
... | ... | @@ -43,10 +43,11 @@ message ResponseMsg { |
43 | 43 | UplinkResponseMsg uplinkResponseMsg = 2; |
44 | 44 | DeviceUpdateMsg deviceUpdateMsg = 3; |
45 | 45 | RuleChainUpdateMsg ruleChainUpdateMsg = 4; |
46 | - DashboardUpdateMsg dashboardUpdateMsg = 5; | |
47 | - AssetUpdateMsg assetUpdateMsg = 6; | |
48 | - EntityViewUpdateMsg entityViewUpdateMsg = 7; | |
49 | - DownlinkMsg downlinkMsg = 8; | |
46 | + RuleChainMetadataUpdateMsg ruleChainMetadataUpdateMsg = 5; | |
47 | + DashboardUpdateMsg dashboardUpdateMsg = 6; | |
48 | + AssetUpdateMsg assetUpdateMsg = 7; | |
49 | + EntityViewUpdateMsg entityViewUpdateMsg = 8; | |
50 | + DownlinkMsg downlinkMsg = 9; | |
50 | 51 | } |
51 | 52 | |
52 | 53 | enum RequestMsgType { |
... | ... | @@ -127,6 +128,38 @@ message RuleChainUpdateMsg { |
127 | 128 | string configuration = 9; |
128 | 129 | } |
129 | 130 | |
131 | +message RuleChainMetadataUpdateMsg { | |
132 | + UpdateMsgType msgType = 1; | |
133 | + int64 ruleChainIdMSB = 2; | |
134 | + int64 ruleChainIdLSB = 3; | |
135 | + int32 firstNodeIndex = 4; | |
136 | + repeated RuleNodeProto nodes = 5; | |
137 | + repeated NodeConnectionInfoProto connections = 6; | |
138 | + repeated RuleChainConnectionInfoProto ruleChainConnections = 7; | |
139 | +} | |
140 | + | |
141 | +message RuleNodeProto { | |
142 | + string type = 1; | |
143 | + string name = 2; | |
144 | + bool debugMode = 3; | |
145 | + string configuration = 4; | |
146 | + string additionalInfo = 5; | |
147 | +} | |
148 | + | |
149 | +message NodeConnectionInfoProto { | |
150 | + int32 fromIndex = 1; | |
151 | + int32 toIndex = 2; | |
152 | + string type = 3; | |
153 | +} | |
154 | + | |
155 | +message RuleChainConnectionInfoProto { | |
156 | + int32 fromIndex = 1; | |
157 | + int64 targetRuleChainIdMSB = 2; | |
158 | + int64 targetRuleChainIdLSB = 3; | |
159 | + string type = 4; | |
160 | + string additionalInfo = 5; | |
161 | +} | |
162 | + | |
130 | 163 | message DashboardUpdateMsg { |
131 | 164 | UpdateMsgType msgType = 1; |
132 | 165 | int64 idMSB = 2; | ... | ... |
... | ... | @@ -15,12 +15,10 @@ |
15 | 15 | */ |
16 | 16 | package org.thingsboard.server.dao.edge; |
17 | 17 | |
18 | -import com.fasterxml.jackson.databind.JsonNode; | |
19 | 18 | import com.fasterxml.jackson.databind.ObjectMapper; |
20 | 19 | import com.google.common.base.Function; |
21 | 20 | import com.google.common.util.concurrent.Futures; |
22 | 21 | import com.google.common.util.concurrent.ListenableFuture; |
23 | -import lombok.Data; | |
24 | 22 | import lombok.extern.slf4j.Slf4j; |
25 | 23 | import org.springframework.beans.factory.annotation.Autowired; |
26 | 24 | import org.springframework.cache.Cache; |
... | ... | @@ -31,12 +29,16 @@ import org.springframework.stereotype.Service; |
31 | 29 | import org.springframework.util.StringUtils; |
32 | 30 | import org.thingsboard.server.common.data.Customer; |
33 | 31 | import org.thingsboard.server.common.data.DataConstants; |
32 | +import org.thingsboard.server.common.data.Device; | |
34 | 33 | import org.thingsboard.server.common.data.EntitySubtype; |
35 | 34 | import org.thingsboard.server.common.data.EntityType; |
35 | +import org.thingsboard.server.common.data.EntityView; | |
36 | 36 | import org.thingsboard.server.common.data.Event; |
37 | 37 | import org.thingsboard.server.common.data.ShortEdgeInfo; |
38 | 38 | import org.thingsboard.server.common.data.Tenant; |
39 | +import org.thingsboard.server.common.data.asset.Asset; | |
39 | 40 | import org.thingsboard.server.common.data.edge.Edge; |
41 | +import org.thingsboard.server.common.data.edge.EdgeQueueEntityType; | |
40 | 42 | import org.thingsboard.server.common.data.edge.EdgeQueueEntry; |
41 | 43 | import org.thingsboard.server.common.data.edge.EdgeSearchQuery; |
42 | 44 | import org.thingsboard.server.common.data.id.CustomerId; |
... | ... | @@ -50,6 +52,7 @@ import org.thingsboard.server.common.data.page.TimePageLink; |
50 | 52 | import org.thingsboard.server.common.data.relation.EntityRelation; |
51 | 53 | import org.thingsboard.server.common.data.relation.EntitySearchDirection; |
52 | 54 | import org.thingsboard.server.common.data.rule.RuleChain; |
55 | +import org.thingsboard.server.common.data.rule.RuleChainMetaData; | |
53 | 56 | import org.thingsboard.server.common.msg.TbMsg; |
54 | 57 | import org.thingsboard.server.dao.customer.CustomerDao; |
55 | 58 | import org.thingsboard.server.dao.dashboard.DashboardService; |
... | ... | @@ -328,62 +331,118 @@ public class BaseEdgeService extends AbstractEntityService implements EdgeServic |
328 | 331 | |
329 | 332 | } |
330 | 333 | |
331 | - private void processDevice(TenantId tenantId, TbMsg tbMsg) { | |
332 | - // TODO | |
333 | - } | |
334 | - | |
335 | - private void processDashboard(TenantId tenantId, TbMsg tbMsg) { | |
336 | - processAssignedEntity(tenantId, tbMsg, EntityType.DASHBOARD); | |
337 | - } | |
338 | - | |
339 | - private void processEntityView(TenantId tenantId, TbMsg tbMsg) { | |
340 | - // TODO | |
334 | + private void processDevice(TenantId tenantId, TbMsg tbMsg) throws IOException { | |
335 | + switch (tbMsg.getType()) { | |
336 | + case DataConstants.ENTITY_ASSIGNED_TO_EDGE: | |
337 | + case DataConstants.ENTITY_UNASSIGNED_FROM_EDGE: | |
338 | + processAssignedEntity(tenantId, tbMsg, EdgeQueueEntityType.DEVICE); | |
339 | + break; | |
340 | + case DataConstants.ENTITY_DELETED: | |
341 | + case DataConstants.ENTITY_CREATED: | |
342 | + case DataConstants.ENTITY_UPDATED: | |
343 | + Device device = mapper.readValue(tbMsg.getData(), Device.class); | |
344 | + if (device.getEdgeId() != null) { | |
345 | + pushEventsToEdge(tenantId, device.getEdgeId(), EdgeQueueEntityType.DEVICE, tbMsg); | |
346 | + } | |
347 | + break; | |
348 | + default: | |
349 | + log.warn("Unsupported msgType [{}], tbMsg [{}]", tbMsg.getType(), tbMsg); | |
350 | + } | |
341 | 351 | } |
342 | 352 | |
343 | - private void processAsset(TenantId tenantId, TbMsg tbMsg) { | |
344 | - // TODO | |
353 | + private void processAsset(TenantId tenantId, TbMsg tbMsg) throws IOException { | |
354 | + switch (tbMsg.getType()) { | |
355 | + case DataConstants.ENTITY_ASSIGNED_TO_EDGE: | |
356 | + case DataConstants.ENTITY_UNASSIGNED_FROM_EDGE: | |
357 | + processAssignedEntity(tenantId, tbMsg, EdgeQueueEntityType.ASSET); | |
358 | + break; | |
359 | + case DataConstants.ENTITY_DELETED: | |
360 | + case DataConstants.ENTITY_CREATED: | |
361 | + case DataConstants.ENTITY_UPDATED: | |
362 | + Asset asset = mapper.readValue(tbMsg.getData(), Asset.class); | |
363 | + if (asset.getEdgeId() != null) { | |
364 | + pushEventsToEdge(tenantId, asset.getEdgeId(), EdgeQueueEntityType.ASSET, tbMsg); | |
365 | + } | |
366 | + break; | |
367 | + default: | |
368 | + log.warn("Unsupported msgType [{}], tbMsg [{}]", tbMsg.getType(), tbMsg); | |
369 | + } | |
345 | 370 | } |
346 | 371 | |
347 | - private void processAssignedEntity(TenantId tenantId, TbMsg tbMsg, EntityType entityType) { | |
348 | - EdgeId edgeId; | |
372 | + private void processEntityView(TenantId tenantId, TbMsg tbMsg) throws IOException { | |
349 | 373 | switch (tbMsg.getType()) { |
350 | 374 | case DataConstants.ENTITY_ASSIGNED_TO_EDGE: |
351 | - edgeId = new EdgeId(UUID.fromString(tbMsg.getMetaData().getValue("assignedEdgeId"))); | |
352 | - pushEventToEdge(tenantId, edgeId, tbMsg.getType(), entityType, tbMsg.getData()); | |
353 | - break; | |
354 | 375 | case DataConstants.ENTITY_UNASSIGNED_FROM_EDGE: |
355 | - edgeId = new EdgeId(UUID.fromString(tbMsg.getMetaData().getValue("unassignedEdgeId"))); | |
356 | - pushEventToEdge(tenantId, edgeId, tbMsg.getType(), entityType, tbMsg.getData()); | |
376 | + processAssignedEntity(tenantId, tbMsg, EdgeQueueEntityType.ENTITY_VIEW); | |
357 | 377 | break; |
378 | + case DataConstants.ENTITY_DELETED: | |
379 | + case DataConstants.ENTITY_CREATED: | |
380 | + case DataConstants.ENTITY_UPDATED: | |
381 | + EntityView entityView = mapper.readValue(tbMsg.getData(), EntityView.class); | |
382 | + if (entityView.getEdgeId() != null) { | |
383 | + pushEventsToEdge(tenantId, entityView.getEdgeId(), EdgeQueueEntityType.ENTITY_VIEW, tbMsg); | |
384 | + } | |
385 | + break; | |
386 | + default: | |
387 | + log.warn("Unsupported msgType [{}], tbMsg [{}]", tbMsg.getType(), tbMsg); | |
358 | 388 | } |
359 | 389 | } |
360 | 390 | |
391 | + private void processDashboard(TenantId tenantId, TbMsg tbMsg) throws IOException { | |
392 | + processAssignedEntity(tenantId, tbMsg, EdgeQueueEntityType.DASHBOARD); | |
393 | + } | |
394 | + | |
361 | 395 | private void processRuleChain(TenantId tenantId, TbMsg tbMsg) throws IOException { |
362 | 396 | switch (tbMsg.getType()) { |
363 | 397 | case DataConstants.ENTITY_ASSIGNED_TO_EDGE: |
364 | 398 | case DataConstants.ENTITY_UNASSIGNED_FROM_EDGE: |
365 | - processAssignedEntity(tenantId, tbMsg, EntityType.RULE_CHAIN); | |
399 | + processAssignedEntity(tenantId, tbMsg, EdgeQueueEntityType.RULE_CHAIN); | |
366 | 400 | break; |
367 | 401 | case DataConstants.ENTITY_DELETED: |
368 | 402 | case DataConstants.ENTITY_CREATED: |
369 | 403 | case DataConstants.ENTITY_UPDATED: |
370 | 404 | RuleChain ruleChain = mapper.readValue(tbMsg.getData(), RuleChain.class); |
371 | - for (ShortEdgeInfo assignedEdge : ruleChain.getAssignedEdges()) { | |
372 | - pushEventToEdge(tenantId, assignedEdge.getEdgeId(), tbMsg.getType(), EntityType.RULE_CHAIN, tbMsg.getData()); | |
405 | + if (ruleChain.getAssignedEdges() != null && !ruleChain.getAssignedEdges().isEmpty()) { | |
406 | + for (ShortEdgeInfo assignedEdge : ruleChain.getAssignedEdges()) { | |
407 | + pushEventsToEdge(tenantId, assignedEdge.getEdgeId(), EdgeQueueEntityType.RULE_CHAIN, tbMsg); | |
408 | + } | |
373 | 409 | } |
374 | 410 | break; |
375 | 411 | default: |
376 | - log.warn("Unsupported message type " + tbMsg.getType()); | |
412 | + log.warn("Unsupported msgType [{}], tbMsg [{}]", tbMsg.getType(), tbMsg); | |
413 | + } | |
414 | + } | |
415 | + | |
416 | + private void processAssignedEntity(TenantId tenantId, TbMsg tbMsg, EdgeQueueEntityType entityType) throws IOException { | |
417 | + EdgeId edgeId; | |
418 | + switch (tbMsg.getType()) { | |
419 | + case DataConstants.ENTITY_ASSIGNED_TO_EDGE: | |
420 | + edgeId = new EdgeId(UUID.fromString(tbMsg.getMetaData().getValue("assignedEdgeId"))); | |
421 | + pushEventsToEdge(tenantId, edgeId, entityType, tbMsg); | |
422 | + break; | |
423 | + case DataConstants.ENTITY_UNASSIGNED_FROM_EDGE: | |
424 | + edgeId = new EdgeId(UUID.fromString(tbMsg.getMetaData().getValue("unassignedEdgeId"))); | |
425 | + pushEventsToEdge(tenantId, edgeId, entityType, tbMsg); | |
426 | + break; | |
377 | 427 | } |
428 | + } | |
429 | + | |
430 | + private void pushEventsToEdge(TenantId tenantId, EdgeId edgeId, EdgeQueueEntityType entityType, TbMsg tbMsg) throws IOException { | |
431 | + log.debug("Pushing event(s) to edge queue. tenantId [{}], edgeId [{}], entityType [{}], tbMsg [{}]", tenantId, edgeId, entityType, tbMsg); | |
432 | + | |
433 | + pushEventsToEdge(tenantId, edgeId, entityType, tbMsg.getType(), tbMsg.getData()); | |
378 | 434 | |
435 | + if (entityType.equals(EdgeQueueEntityType.RULE_CHAIN)) { | |
436 | + pushRuleChainMetadataToEdge(tenantId, edgeId, tbMsg); | |
437 | + } | |
379 | 438 | } |
380 | 439 | |
381 | - private void pushEventToEdge(TenantId tenantId, EdgeId edgeId, String type, EntityType entityType, String data) { | |
382 | - log.debug("Pushing event to edge queue. tenantId [{}], edgeId [{}], type [{}], data [{}]", tenantId, edgeId, type, data); | |
440 | + private void pushEventsToEdge(TenantId tenantId, EdgeId edgeId, EdgeQueueEntityType entityType, String type, String data) throws IOException { | |
441 | + log.debug("Pushing single event to edge queue. tenantId [{}], edgeId [{}], entityType [{}], type[{}], data [{}]", tenantId, edgeId, entityType, type, data); | |
383 | 442 | |
384 | 443 | EdgeQueueEntry queueEntry = new EdgeQueueEntry(); |
385 | - queueEntry.setType(type); | |
386 | 444 | queueEntry.setEntityType(entityType); |
445 | + queueEntry.setType(type); | |
387 | 446 | queueEntry.setData(data); |
388 | 447 | |
389 | 448 | Event event = new Event(); |
... | ... | @@ -394,6 +453,20 @@ public class BaseEdgeService extends AbstractEntityService implements EdgeServic |
394 | 453 | eventService.saveAsync(event); |
395 | 454 | } |
396 | 455 | |
456 | + private void pushRuleChainMetadataToEdge(TenantId tenantId, EdgeId edgeId, TbMsg tbMsg) throws IOException { | |
457 | + RuleChain ruleChain = mapper.readValue(tbMsg.getData(), RuleChain.class); | |
458 | + switch (tbMsg.getType()) { | |
459 | + case DataConstants.ENTITY_ASSIGNED_TO_EDGE: | |
460 | + case DataConstants.ENTITY_UNASSIGNED_FROM_EDGE: | |
461 | + case DataConstants.ENTITY_UPDATED: | |
462 | + RuleChainMetaData ruleChainMetaData = ruleChainService.loadRuleChainMetaData(tenantId, ruleChain.getId()); | |
463 | + pushEventsToEdge(tenantId, edgeId, EdgeQueueEntityType.RULE_CHAIN_METADATA, tbMsg.getType(), mapper.writeValueAsString(ruleChainMetaData)); | |
464 | + break; | |
465 | + default: | |
466 | + log.warn("Unsupported msgType [{}], tbMsg [{}]", tbMsg.getType(), tbMsg); | |
467 | + } | |
468 | + } | |
469 | + | |
397 | 470 | @Override |
398 | 471 | public TimePageData<Event> findQueueEvents(TenantId tenantId, EdgeId edgeId, TimePageLink pageLink) { |
399 | 472 | return eventService.findEvents(tenantId, edgeId, DataConstants.EDGE_QUEUE_EVENT_TYPE, pageLink); | ... | ... |
... | ... | @@ -388,17 +388,24 @@ function RuleChainService($http, $q, $filter, $ocLazyLoad, $translate, types, co |
388 | 388 | } |
389 | 389 | |
390 | 390 | function prepareRuleChain(ruleChain) { |
391 | + ruleChain.assignedEdgesText = ""; | |
391 | 392 | ruleChain.assignedEdgesIds = []; |
393 | + | |
392 | 394 | if (ruleChain.assignedEdges && ruleChain.assignedEdges.length) { |
395 | + var assignedEdgesTitles = []; | |
393 | 396 | for (var j = 0; j < ruleChain.assignedEdges.length; j++) { |
394 | 397 | var assignedEdge = ruleChain.assignedEdges[j]; |
395 | 398 | ruleChain.assignedEdgesIds.push(assignedEdge.edgeId.id); |
399 | + assignedEdgesTitles.push(assignedEdge.title); | |
396 | 400 | } |
401 | + ruleChain.assignedEdgesText = assignedEdgesTitles.join(', '); | |
397 | 402 | } |
403 | + | |
398 | 404 | return ruleChain; |
399 | 405 | } |
400 | 406 | |
401 | 407 | function cleanRuleChain(ruleChain) { |
408 | + delete ruleChain.assignedEdgesText; | |
402 | 409 | delete ruleChain.assignedEdgesIds; |
403 | 410 | return ruleChain; |
404 | 411 | } | ... | ... |
... | ... | @@ -1436,7 +1436,8 @@ |
1436 | 1436 | "assign-to-edges": "Assign Rule Chain(s) To Edges", |
1437 | 1437 | "assign-to-edges-text": "Please select the edges to assign the rulechain(s)", |
1438 | 1438 | "unassign-from-edges": "Unassign Rule Chain(s) From Edges", |
1439 | - "unassign-from-edges-text": "Please select the edges to unassign from the rulechain(s)" | |
1439 | + "unassign-from-edges-text": "Please select the edges to unassign from the rulechain(s)", | |
1440 | + "assigned-to-edges": "Assigned to edges" | |
1440 | 1441 | }, |
1441 | 1442 | "rulenode": { |
1442 | 1443 | "details": "Details", | ... | ... |
ui/src/app/rulechain/rulechain-card.scss
0 → 100644
1 | +/** | |
2 | + * Copyright © 2016-2019 The Thingsboard Authors | |
3 | + * | |
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | |
5 | + * you may not use this file except in compliance with the License. | |
6 | + * You may obtain a copy of the License at | |
7 | + * | |
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | |
9 | + * | |
10 | + * Unless required by applicable law or agreed to in writing, software | |
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | |
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 | + * See the License for the specific language governing permissions and | |
14 | + * limitations under the License. | |
15 | + */ | |
16 | +.tb-rule-chain-assigned-edges { | |
17 | + display: block; | |
18 | + display: -webkit-box; /* stylelint-disable-line value-no-vendor-prefix */ | |
19 | + height: 34px; | |
20 | + margin-bottom: 4px; | |
21 | + overflow: hidden; | |
22 | + text-overflow: ellipsis; | |
23 | + -webkit-line-clamp: 2; | |
24 | + -webkit-box-orient: vertical; /* stylelint-disable-line property-no-vendor-prefix */ | |
25 | +} | ... | ... |
... | ... | @@ -15,4 +15,5 @@ |
15 | 15 | limitations under the License. |
16 | 16 | |
17 | 17 | --> |
18 | +<div class="tb-small tb-rule-chain-assigned-edges" ng-show="vm.parentCtl.ruleChainsScope === 'tenant' && vm.item.assignedEdgesText">{{'rulechain.assigned-to-edges' | translate}}: '{{vm.item.assignedEdgesText}}'</div> | |
18 | 19 | <div ng-if="item && item.root" translate>rulechain.root</div> | ... | ... |
... | ... | @@ -36,6 +36,11 @@ |
36 | 36 | </div> |
37 | 37 | |
38 | 38 | <md-content class="md-padding tb-rulechain-fieldset" layout="column"> |
39 | + <md-input-container class="md-block" | |
40 | + ng-show="!isEdit && ruleChain.assignedEdgesText && ruleChainScope === 'tenant'"> | |
41 | + <label translate>rulechain.assigned-to-edges</label> | |
42 | + <input ng-model="ruleChain.assignedEdgesText" disabled> | |
43 | + </md-input-container> | |
39 | 44 | <fieldset ng-disabled="$root.loading || !isEdit || isReadOnly"> |
40 | 45 | <md-input-container class="md-block"> |
41 | 46 | <label translate>rulechain.name</label> | ... | ... |
... | ... | @@ -37,11 +37,12 @@ export default function RuleChainDirective($compile, $templateCache, $mdDialog, |
37 | 37 | scope: { |
38 | 38 | ruleChain: '=', |
39 | 39 | isEdit: '=', |
40 | + ruleChainScope: '=', | |
40 | 41 | isReadOnly: '=', |
41 | 42 | theForm: '=', |
42 | 43 | onSetRootRuleChain: '&', |
43 | 44 | onExportRuleChain: '&', |
44 | - onDeleteRuleChain: '&' | |
45 | + onDeleteRuleChain: '&', | |
45 | 46 | } |
46 | 47 | }; |
47 | 48 | } | ... | ... |
... | ... | @@ -22,6 +22,8 @@ import addRuleChainsToEdgeTemplate from "./add-rulechains-to-edge.tpl.html"; |
22 | 22 | |
23 | 23 | /* eslint-enable import/no-unresolved, import/default */ |
24 | 24 | |
25 | +import './rulechain-card.scss'; | |
26 | + | |
25 | 27 | /*@ngInject*/ |
26 | 28 | export default function RuleChainsController(ruleChainService, userService, importExport, $state, |
27 | 29 | $stateParams, $filter, $translate, $mdDialog, $document, $q, types) { | ... | ... |
... | ... | @@ -24,6 +24,7 @@ |
24 | 24 | <md-tab label="{{ 'rulechain.details' | translate }}"> |
25 | 25 | <tb-rule-chain rule-chain="vm.grid.operatingItem()" |
26 | 26 | is-edit="vm.grid.detailsConfig.isDetailsEditMode" |
27 | + rule-chain-scope="vm.ruleChainsScope" | |
27 | 28 | is-read-only="vm.grid.isDetailsReadOnly(vm.grid.operatingItem())" |
28 | 29 | the-form="vm.grid.detailsForm" |
29 | 30 | on-set-root-rule-chain="vm.setRootRuleChain(event, vm.grid.detailsConfig.currentItem)" | ... | ... |