Commit b5659fd32d06cd090f25c9eefce8898aac1c2e48
Merge remote-tracking branch 'upstream/feature/edge' into feature/widgets_bundle_fetch
Showing
25 changed files
with
295 additions
and
58 deletions
@@ -66,6 +66,7 @@ import org.thingsboard.server.dao.user.UserService; | @@ -66,6 +66,7 @@ import org.thingsboard.server.dao.user.UserService; | ||
66 | import org.thingsboard.server.queue.discovery.PartitionService; | 66 | import org.thingsboard.server.queue.discovery.PartitionService; |
67 | import org.thingsboard.server.queue.discovery.TbServiceInfoProvider; | 67 | import org.thingsboard.server.queue.discovery.TbServiceInfoProvider; |
68 | import org.thingsboard.server.service.component.ComponentDiscoveryService; | 68 | import org.thingsboard.server.service.component.ComponentDiscoveryService; |
69 | +import org.thingsboard.server.service.edge.rpc.EdgeRpcService; | ||
69 | import org.thingsboard.server.service.encoding.DataDecodingEncodingService; | 70 | import org.thingsboard.server.service.encoding.DataDecodingEncodingService; |
70 | import org.thingsboard.server.service.executors.DbCallbackExecutorService; | 71 | import org.thingsboard.server.service.executors.DbCallbackExecutorService; |
71 | import org.thingsboard.server.service.executors.ExternalCallExecutorService; | 72 | import org.thingsboard.server.service.executors.ExternalCallExecutorService; |
@@ -254,15 +255,14 @@ public class ActorSystemContext { | @@ -254,15 +255,14 @@ public class ActorSystemContext { | ||
254 | @Getter | 255 | @Getter |
255 | private TbCoreDeviceRpcService tbCoreDeviceRpcService; | 256 | private TbCoreDeviceRpcService tbCoreDeviceRpcService; |
256 | 257 | ||
257 | - @Lazy | ||
258 | - @Autowired | ||
259 | - @Getter | ||
260 | - private EdgeService edgeService; | 258 | + @Autowired(required = false) |
259 | + @Getter private EdgeService edgeService; | ||
261 | 260 | ||
262 | - @Lazy | ||
263 | - @Autowired | ||
264 | - @Getter | ||
265 | - private EdgeEventService edgeEventService; | 261 | + @Autowired(required = false) |
262 | + @Getter private EdgeEventService edgeEventService; | ||
263 | + | ||
264 | + @Autowired(required = false) | ||
265 | + @Getter private EdgeRpcService edgeRpcService; | ||
266 | 266 | ||
267 | @Value("${actors.session.max_concurrent_sessions_per_device:1}") | 267 | @Value("${actors.session.max_concurrent_sessions_per_device:1}") |
268 | @Getter | 268 | @Getter |
@@ -31,10 +31,13 @@ import org.thingsboard.server.actors.service.ContextBasedCreator; | @@ -31,10 +31,13 @@ import org.thingsboard.server.actors.service.ContextBasedCreator; | ||
31 | import org.thingsboard.server.actors.service.DefaultActorService; | 31 | import org.thingsboard.server.actors.service.DefaultActorService; |
32 | import org.thingsboard.server.common.data.EntityType; | 32 | import org.thingsboard.server.common.data.EntityType; |
33 | import org.thingsboard.server.common.data.Tenant; | 33 | import org.thingsboard.server.common.data.Tenant; |
34 | +import org.thingsboard.server.common.data.edge.Edge; | ||
34 | import org.thingsboard.server.common.data.id.DeviceId; | 35 | import org.thingsboard.server.common.data.id.DeviceId; |
36 | +import org.thingsboard.server.common.data.id.EdgeId; | ||
35 | import org.thingsboard.server.common.data.id.EntityId; | 37 | import org.thingsboard.server.common.data.id.EntityId; |
36 | import org.thingsboard.server.common.data.id.RuleChainId; | 38 | import org.thingsboard.server.common.data.id.RuleChainId; |
37 | import org.thingsboard.server.common.data.id.TenantId; | 39 | import org.thingsboard.server.common.data.id.TenantId; |
40 | +import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; | ||
38 | import org.thingsboard.server.common.data.rule.RuleChain; | 41 | import org.thingsboard.server.common.data.rule.RuleChain; |
39 | import org.thingsboard.server.common.data.rule.RuleChainType; | 42 | import org.thingsboard.server.common.data.rule.RuleChainType; |
40 | import org.thingsboard.server.common.msg.MsgType; | 43 | import org.thingsboard.server.common.msg.MsgType; |
@@ -47,6 +50,7 @@ import org.thingsboard.server.common.msg.queue.PartitionChangeMsg; | @@ -47,6 +50,7 @@ import org.thingsboard.server.common.msg.queue.PartitionChangeMsg; | ||
47 | import org.thingsboard.server.common.msg.queue.QueueToRuleEngineMsg; | 50 | import org.thingsboard.server.common.msg.queue.QueueToRuleEngineMsg; |
48 | import org.thingsboard.server.common.msg.queue.RuleEngineException; | 51 | import org.thingsboard.server.common.msg.queue.RuleEngineException; |
49 | import org.thingsboard.server.common.msg.queue.ServiceType; | 52 | import org.thingsboard.server.common.msg.queue.ServiceType; |
53 | +import org.thingsboard.server.service.edge.rpc.EdgeRpcService; | ||
50 | 54 | ||
51 | import java.util.List; | 55 | import java.util.List; |
52 | import java.util.Optional; | 56 | import java.util.Optional; |
@@ -202,7 +206,18 @@ public class TenantActor extends RuleChainManagerActor { | @@ -202,7 +206,18 @@ public class TenantActor extends RuleChainManagerActor { | ||
202 | } | 206 | } |
203 | 207 | ||
204 | private void onComponentLifecycleMsg(ComponentLifecycleMsg msg) { | 208 | private void onComponentLifecycleMsg(ComponentLifecycleMsg msg) { |
205 | - if (isRuleEngineForCurrentTenant) { | 209 | + if (msg.getEntityId().getEntityType() == EntityType.EDGE) { |
210 | + EdgeId edgeId = new EdgeId(msg.getEntityId().getId()); | ||
211 | + EdgeRpcService edgeRpcService = systemContext.getEdgeRpcService(); | ||
212 | + if (msg.getEvent() == ComponentLifecycleEvent.DELETED) { | ||
213 | + edgeRpcService.deleteEdge(edgeId); | ||
214 | + } else { | ||
215 | + Edge edge = systemContext.getEdgeService().findEdgeById(tenantId, edgeId); | ||
216 | + if (msg.getEvent() == ComponentLifecycleEvent.UPDATED) { | ||
217 | + edgeRpcService.updateEdge(edge); | ||
218 | + } | ||
219 | + } | ||
220 | + } else if (isRuleEngineForCurrentTenant) { | ||
206 | TbActorRef target = getEntityActorRef(msg.getEntityId()); | 221 | TbActorRef target = getEntityActorRef(msg.getEntityId()); |
207 | if (target != null) { | 222 | if (target != null) { |
208 | if (msg.getEntityId().getEntityType() == EntityType.RULE_CHAIN) { | 223 | if (msg.getEntityId().getEntityType() == EntityType.RULE_CHAIN) { |
@@ -40,6 +40,7 @@ import org.thingsboard.server.common.data.id.RuleChainId; | @@ -40,6 +40,7 @@ import org.thingsboard.server.common.data.id.RuleChainId; | ||
40 | import org.thingsboard.server.common.data.id.TenantId; | 40 | import org.thingsboard.server.common.data.id.TenantId; |
41 | import org.thingsboard.server.common.data.page.TextPageData; | 41 | import org.thingsboard.server.common.data.page.TextPageData; |
42 | import org.thingsboard.server.common.data.page.TextPageLink; | 42 | import org.thingsboard.server.common.data.page.TextPageLink; |
43 | +import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; | ||
43 | import org.thingsboard.server.common.data.rule.RuleChain; | 44 | import org.thingsboard.server.common.data.rule.RuleChain; |
44 | import org.thingsboard.server.dao.exception.DataValidationException; | 45 | import org.thingsboard.server.dao.exception.DataValidationException; |
45 | import org.thingsboard.server.dao.exception.IncorrectParameterException; | 46 | import org.thingsboard.server.dao.exception.IncorrectParameterException; |
@@ -101,6 +102,9 @@ public class EdgeController extends BaseController { | @@ -101,6 +102,9 @@ public class EdgeController extends BaseController { | ||
101 | edgeService.assignDefaultRuleChainsToEdge(tenantId, savedEdge.getId()); | 102 | edgeService.assignDefaultRuleChainsToEdge(tenantId, savedEdge.getId()); |
102 | } | 103 | } |
103 | 104 | ||
105 | + tbClusterService.onEntityStateChange(savedEdge.getTenantId(), savedEdge.getId(), | ||
106 | + created ? ComponentLifecycleEvent.CREATED : ComponentLifecycleEvent.UPDATED); | ||
107 | + | ||
104 | logEntityAction(savedEdge.getId(), savedEdge, null, created ? ActionType.ADDED : ActionType.UPDATED, null); | 108 | logEntityAction(savedEdge.getId(), savedEdge, null, created ? ActionType.ADDED : ActionType.UPDATED, null); |
105 | return savedEdge; | 109 | return savedEdge; |
106 | } catch (Exception e) { | 110 | } catch (Exception e) { |
@@ -120,6 +124,9 @@ public class EdgeController extends BaseController { | @@ -120,6 +124,9 @@ public class EdgeController extends BaseController { | ||
120 | Edge edge = checkEdgeId(edgeId, Operation.DELETE); | 124 | Edge edge = checkEdgeId(edgeId, Operation.DELETE); |
121 | edgeService.deleteEdge(getTenantId(), edgeId); | 125 | edgeService.deleteEdge(getTenantId(), edgeId); |
122 | 126 | ||
127 | + tbClusterService.onEntityStateChange(getTenantId(), edgeId, | ||
128 | + ComponentLifecycleEvent.DELETED); | ||
129 | + | ||
123 | logEntityAction(edgeId, edge, | 130 | logEntityAction(edgeId, edge, |
124 | null, | 131 | null, |
125 | ActionType.DELETED, null, strEdgeId); | 132 | ActionType.DELETED, null, strEdgeId); |
@@ -284,6 +291,8 @@ public class EdgeController extends BaseController { | @@ -284,6 +291,8 @@ public class EdgeController extends BaseController { | ||
284 | 291 | ||
285 | Edge updatedEdge = edgeNotificationService.setEdgeRootRuleChain(getTenantId(), edge, ruleChainId); | 292 | Edge updatedEdge = edgeNotificationService.setEdgeRootRuleChain(getTenantId(), edge, ruleChainId); |
286 | 293 | ||
294 | + tbClusterService.onEntityStateChange(updatedEdge.getTenantId(), updatedEdge.getId(), ComponentLifecycleEvent.UPDATED); | ||
295 | + | ||
287 | logEntityAction(updatedEdge.getId(), updatedEdge, null, ActionType.UPDATED, null); | 296 | logEntityAction(updatedEdge.getId(), updatedEdge, null, ActionType.UPDATED, null); |
288 | 297 | ||
289 | return updatedEdge; | 298 | return updatedEdge; |
@@ -61,7 +61,7 @@ public class EdgeEventController extends BaseController { | @@ -61,7 +61,7 @@ public class EdgeEventController extends BaseController { | ||
61 | EdgeId edgeId = new EdgeId(toUUID(strEdgeId)); | 61 | EdgeId edgeId = new EdgeId(toUUID(strEdgeId)); |
62 | checkEdgeId(edgeId, Operation.READ); | 62 | checkEdgeId(edgeId, Operation.READ); |
63 | TimePageLink pageLink = createPageLink(limit, startTime, endTime, ascOrder, offset); | 63 | TimePageLink pageLink = createPageLink(limit, startTime, endTime, ascOrder, offset); |
64 | - return checkNotNull(edgeEventService.findEdgeEvents(tenantId, edgeId, pageLink)); | 64 | + return checkNotNull(edgeEventService.findEdgeEvents(tenantId, edgeId, pageLink, false)); |
65 | } catch (Exception e) { | 65 | } catch (Exception e) { |
66 | throw handleException(e); | 66 | throw handleException(e); |
67 | } | 67 | } |
@@ -111,7 +111,7 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService { | @@ -111,7 +111,7 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService { | ||
111 | 111 | ||
112 | @Override | 112 | @Override |
113 | public TimePageData<EdgeEvent> findEdgeEvents(TenantId tenantId, EdgeId edgeId, TimePageLink pageLink) { | 113 | public TimePageData<EdgeEvent> findEdgeEvents(TenantId tenantId, EdgeId edgeId, TimePageLink pageLink) { |
114 | - return edgeEventService.findEdgeEvents(tenantId, edgeId, pageLink); | 114 | + return edgeEventService.findEdgeEvents(tenantId, edgeId, pageLink, true); |
115 | } | 115 | } |
116 | 116 | ||
117 | @Override | 117 | @Override |
@@ -27,6 +27,7 @@ import org.springframework.beans.factory.annotation.Value; | @@ -27,6 +27,7 @@ import org.springframework.beans.factory.annotation.Value; | ||
27 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; | 27 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; |
28 | import org.springframework.stereotype.Service; | 28 | import org.springframework.stereotype.Service; |
29 | import org.thingsboard.server.common.data.DataConstants; | 29 | import org.thingsboard.server.common.data.DataConstants; |
30 | +import org.thingsboard.server.common.data.edge.Edge; | ||
30 | import org.thingsboard.server.common.data.id.EdgeId; | 31 | import org.thingsboard.server.common.data.id.EdgeId; |
31 | import org.thingsboard.server.common.data.id.TenantId; | 32 | import org.thingsboard.server.common.data.id.TenantId; |
32 | import org.thingsboard.server.common.data.kv.BasicTsKvEntry; | 33 | import org.thingsboard.server.common.data.kv.BasicTsKvEntry; |
@@ -52,7 +53,7 @@ import java.util.concurrent.Executors; | @@ -52,7 +53,7 @@ import java.util.concurrent.Executors; | ||
52 | @Service | 53 | @Service |
53 | @Slf4j | 54 | @Slf4j |
54 | @ConditionalOnProperty(prefix = "edges.rpc", value = "enabled", havingValue = "true") | 55 | @ConditionalOnProperty(prefix = "edges.rpc", value = "enabled", havingValue = "true") |
55 | -public class EdgeGrpcService extends EdgeRpcServiceGrpc.EdgeRpcServiceImplBase { | 56 | +public class EdgeGrpcService extends EdgeRpcServiceGrpc.EdgeRpcServiceImplBase implements EdgeRpcService { |
56 | 57 | ||
57 | private final Map<EdgeId, EdgeGrpcSession> sessions = new ConcurrentHashMap<>(); | 58 | private final Map<EdgeId, EdgeGrpcSession> sessions = new ConcurrentHashMap<>(); |
58 | private static final ObjectMapper mapper = new ObjectMapper(); | 59 | private static final ObjectMapper mapper = new ObjectMapper(); |
@@ -117,6 +118,23 @@ public class EdgeGrpcService extends EdgeRpcServiceGrpc.EdgeRpcServiceImplBase { | @@ -117,6 +118,23 @@ public class EdgeGrpcService extends EdgeRpcServiceGrpc.EdgeRpcServiceImplBase { | ||
117 | return new EdgeGrpcSession(ctx, outputStream, this::onEdgeConnect, this::onEdgeDisconnect, mapper).getInputStream(); | 118 | return new EdgeGrpcSession(ctx, outputStream, this::onEdgeConnect, this::onEdgeDisconnect, mapper).getInputStream(); |
118 | } | 119 | } |
119 | 120 | ||
121 | + @Override | ||
122 | + public void updateEdge(Edge edge) { | ||
123 | + EdgeGrpcSession session = sessions.get(edge.getId()); | ||
124 | + if (session != null && session.isConnected()) { | ||
125 | + session.onConfigurationUpdate(edge); | ||
126 | + } | ||
127 | + } | ||
128 | + | ||
129 | + @Override | ||
130 | + public void deleteEdge(EdgeId edgeId) { | ||
131 | + EdgeGrpcSession session = sessions.get(edgeId); | ||
132 | + if (session != null && session.isConnected()) { | ||
133 | + session.close(); | ||
134 | + sessions.remove(edgeId); | ||
135 | + } | ||
136 | + } | ||
137 | + | ||
120 | private void onEdgeConnect(EdgeId edgeId, EdgeGrpcSession edgeGrpcSession) { | 138 | private void onEdgeConnect(EdgeId edgeId, EdgeGrpcSession edgeGrpcSession) { |
121 | sessions.put(edgeId, edgeGrpcSession); | 139 | sessions.put(edgeId, edgeGrpcSession); |
122 | save(edgeId, DefaultDeviceStateService.ACTIVITY_STATE, true); | 140 | save(edgeId, DefaultDeviceStateService.ACTIVITY_STATE, true); |
@@ -198,6 +198,20 @@ public final class EdgeGrpcSession implements Closeable { | @@ -198,6 +198,20 @@ public final class EdgeGrpcSession implements Closeable { | ||
198 | }; | 198 | }; |
199 | } | 199 | } |
200 | 200 | ||
201 | + void onConfigurationUpdate(Edge edge) { | ||
202 | + try { | ||
203 | + this.edge = edge; | ||
204 | + // TODO: voba - push edge configuration update to edge | ||
205 | +// outputStream.onNext(org.thingsboard.server.gen.integration.ResponseMsg.newBuilder() | ||
206 | +// .setIntegrationUpdateMsg(IntegrationUpdateMsg.newBuilder() | ||
207 | +// .setConfiguration(constructIntegrationConfigProto(configuration, defaultConverterProto, downLinkConverterProto)) | ||
208 | +// .build()) | ||
209 | +// .build()); | ||
210 | + } catch (Exception e) { | ||
211 | + log.error("Failed to construct proto objects!", e); | ||
212 | + } | ||
213 | + } | ||
214 | + | ||
201 | void processHandleMessages() throws ExecutionException, InterruptedException { | 215 | void processHandleMessages() throws ExecutionException, InterruptedException { |
202 | Long queueStartTs = getQueueStartTs().get(); | 216 | Long queueStartTs = getQueueStartTs().get(); |
203 | TimePageLink pageLink = new TimePageLink(ctx.getEdgeEventStorageSettings().getMaxReadRecordsCount(), queueStartTs, null, true); | 217 | TimePageLink pageLink = new TimePageLink(ctx.getEdgeEventStorageSettings().getMaxReadRecordsCount(), queueStartTs, null, true); |
1 | +/** | ||
2 | + * Copyright © 2016-2020 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.service.edge.rpc; | ||
17 | + | ||
18 | +import org.thingsboard.server.common.data.edge.Edge; | ||
19 | +import org.thingsboard.server.common.data.id.EdgeId; | ||
20 | + | ||
21 | +public interface EdgeRpcService { | ||
22 | + | ||
23 | + void updateEdge(Edge edge); | ||
24 | + | ||
25 | + void deleteEdge(EdgeId edgeId); | ||
26 | +} |
@@ -16,9 +16,7 @@ | @@ -16,9 +16,7 @@ | ||
16 | package org.thingsboard.server.dao.edge; | 16 | package org.thingsboard.server.dao.edge; |
17 | 17 | ||
18 | import com.google.common.util.concurrent.ListenableFuture; | 18 | import com.google.common.util.concurrent.ListenableFuture; |
19 | -import org.thingsboard.server.common.data.EntityType; | ||
20 | import org.thingsboard.server.common.data.edge.EdgeEvent; | 19 | import org.thingsboard.server.common.data.edge.EdgeEvent; |
21 | -import org.thingsboard.server.common.data.edge.EdgeEventType; | ||
22 | import org.thingsboard.server.common.data.id.EdgeId; | 20 | import org.thingsboard.server.common.data.id.EdgeId; |
23 | import org.thingsboard.server.common.data.id.TenantId; | 21 | import org.thingsboard.server.common.data.id.TenantId; |
24 | import org.thingsboard.server.common.data.page.TimePageData; | 22 | import org.thingsboard.server.common.data.page.TimePageData; |
@@ -28,6 +26,5 @@ public interface EdgeEventService { | @@ -28,6 +26,5 @@ public interface EdgeEventService { | ||
28 | 26 | ||
29 | ListenableFuture<EdgeEvent> saveAsync(EdgeEvent edgeEvent); | 27 | ListenableFuture<EdgeEvent> saveAsync(EdgeEvent edgeEvent); |
30 | 28 | ||
31 | - TimePageData<EdgeEvent> findEdgeEvents(TenantId tenantId, EdgeId edgeId, TimePageLink pageLink); | ||
32 | - | 29 | + TimePageData<EdgeEvent> findEdgeEvents(TenantId tenantId, EdgeId edgeId, TimePageLink pageLink, boolean withTsUpdate); |
33 | } | 30 | } |
@@ -35,7 +35,7 @@ import java.util.List; | @@ -35,7 +35,7 @@ import java.util.List; | ||
35 | public class BaseEdgeEventService implements EdgeEventService { | 35 | public class BaseEdgeEventService implements EdgeEventService { |
36 | 36 | ||
37 | @Autowired | 37 | @Autowired |
38 | - public EdgeEventDao edgeEventDao; | 38 | + private EdgeEventDao edgeEventDao; |
39 | 39 | ||
40 | @Override | 40 | @Override |
41 | public ListenableFuture<EdgeEvent> saveAsync(EdgeEvent edgeEvent) { | 41 | public ListenableFuture<EdgeEvent> saveAsync(EdgeEvent edgeEvent) { |
@@ -44,8 +44,8 @@ public class BaseEdgeEventService implements EdgeEventService { | @@ -44,8 +44,8 @@ public class BaseEdgeEventService implements EdgeEventService { | ||
44 | } | 44 | } |
45 | 45 | ||
46 | @Override | 46 | @Override |
47 | - public TimePageData<EdgeEvent> findEdgeEvents(TenantId tenantId, EdgeId edgeId, TimePageLink pageLink) { | ||
48 | - List<EdgeEvent> events = edgeEventDao.findEdgeEvents(tenantId.getId(), edgeId, pageLink); | 47 | + public TimePageData<EdgeEvent> findEdgeEvents(TenantId tenantId, EdgeId edgeId, TimePageLink pageLink, boolean withTsUpdate) { |
48 | + List<EdgeEvent> events = edgeEventDao.findEdgeEvents(tenantId.getId(), edgeId, pageLink, withTsUpdate); | ||
49 | return new TimePageData<>(events, pageLink); | 49 | return new TimePageData<>(events, pageLink); |
50 | } | 50 | } |
51 | 51 |
@@ -53,7 +53,7 @@ public class CassandraEdgeEventDao extends CassandraAbstractSearchTimeDao<EdgeEv | @@ -53,7 +53,7 @@ public class CassandraEdgeEventDao extends CassandraAbstractSearchTimeDao<EdgeEv | ||
53 | } | 53 | } |
54 | 54 | ||
55 | @Override | 55 | @Override |
56 | - public List<EdgeEvent> findEdgeEvents(UUID tenantId, EdgeId edgeId, TimePageLink pageLink) { | 56 | + public List<EdgeEvent> findEdgeEvents(UUID tenantId, EdgeId edgeId, TimePageLink pageLink, boolean withTsUpdate) { |
57 | return null; | 57 | return null; |
58 | } | 58 | } |
59 | } | 59 | } |
@@ -46,6 +46,6 @@ public interface EdgeEventDao extends Dao<EdgeEvent> { | @@ -46,6 +46,6 @@ public interface EdgeEventDao extends Dao<EdgeEvent> { | ||
46 | * @param pageLink the pageLink | 46 | * @param pageLink the pageLink |
47 | * @return the event list | 47 | * @return the event list |
48 | */ | 48 | */ |
49 | - List<EdgeEvent> findEdgeEvents(UUID tenantId, EdgeId edgeId, TimePageLink pageLink); | 49 | + List<EdgeEvent> findEdgeEvents(UUID tenantId, EdgeId edgeId, TimePageLink pageLink, boolean withTsUpdate); |
50 | 50 | ||
51 | } | 51 | } |
@@ -26,6 +26,7 @@ import org.springframework.data.jpa.domain.Specification; | @@ -26,6 +26,7 @@ import org.springframework.data.jpa.domain.Specification; | ||
26 | import org.springframework.data.repository.CrudRepository; | 26 | import org.springframework.data.repository.CrudRepository; |
27 | import org.springframework.stereotype.Component; | 27 | import org.springframework.stereotype.Component; |
28 | import org.thingsboard.server.common.data.UUIDConverter; | 28 | import org.thingsboard.server.common.data.UUIDConverter; |
29 | +import org.thingsboard.server.common.data.audit.ActionType; | ||
29 | import org.thingsboard.server.common.data.edge.EdgeEvent; | 30 | import org.thingsboard.server.common.data.edge.EdgeEvent; |
30 | import org.thingsboard.server.common.data.id.EdgeEventId; | 31 | import org.thingsboard.server.common.data.id.EdgeEventId; |
31 | import org.thingsboard.server.common.data.id.EdgeId; | 32 | import org.thingsboard.server.common.data.id.EdgeId; |
@@ -75,9 +76,9 @@ public class JpaBaseEdgeEventDao extends JpaAbstractSearchTimeDao<EdgeEventEntit | @@ -75,9 +76,9 @@ public class JpaBaseEdgeEventDao extends JpaAbstractSearchTimeDao<EdgeEventEntit | ||
75 | } | 76 | } |
76 | 77 | ||
77 | @Override | 78 | @Override |
78 | - public List<EdgeEvent> findEdgeEvents(UUID tenantId, EdgeId edgeId, TimePageLink pageLink) { | 79 | + public List<EdgeEvent> findEdgeEvents(UUID tenantId, EdgeId edgeId, TimePageLink pageLink, boolean withTsUpdate) { |
79 | Specification<EdgeEventEntity> timeSearchSpec = JpaAbstractSearchTimeDao.getTimeSearchPageSpec(pageLink, "id"); | 80 | Specification<EdgeEventEntity> timeSearchSpec = JpaAbstractSearchTimeDao.getTimeSearchPageSpec(pageLink, "id"); |
80 | - Specification<EdgeEventEntity> fieldsSpec = getEntityFieldsSpec(tenantId, edgeId); | 81 | + Specification<EdgeEventEntity> fieldsSpec = getEntityFieldsSpec(tenantId, edgeId, withTsUpdate); |
81 | Sort.Direction sortDirection = pageLink.isAscOrder() ? Sort.Direction.ASC : Sort.Direction.DESC; | 82 | Sort.Direction sortDirection = pageLink.isAscOrder() ? Sort.Direction.ASC : Sort.Direction.DESC; |
82 | Pageable pageable = PageRequest.of(0, pageLink.getLimit(), sortDirection, ID_PROPERTY); | 83 | Pageable pageable = PageRequest.of(0, pageLink.getLimit(), sortDirection, ID_PROPERTY); |
83 | return DaoUtil.convertDataList(edgeEventRepository.findAll(Specification.where(timeSearchSpec).and(fieldsSpec), pageable).getContent()); | 84 | return DaoUtil.convertDataList(edgeEventRepository.findAll(Specification.where(timeSearchSpec).and(fieldsSpec), pageable).getContent()); |
@@ -95,7 +96,7 @@ public class JpaBaseEdgeEventDao extends JpaAbstractSearchTimeDao<EdgeEventEntit | @@ -95,7 +96,7 @@ public class JpaBaseEdgeEventDao extends JpaAbstractSearchTimeDao<EdgeEventEntit | ||
95 | return Optional.of(DaoUtil.getData(edgeEventRepository.save(entity))); | 96 | return Optional.of(DaoUtil.getData(edgeEventRepository.save(entity))); |
96 | } | 97 | } |
97 | 98 | ||
98 | - private Specification<EdgeEventEntity> getEntityFieldsSpec(UUID tenantId, EdgeId edgeId) { | 99 | + private Specification<EdgeEventEntity> getEntityFieldsSpec(UUID tenantId, EdgeId edgeId, boolean withTsUpdate) { |
99 | return (root, criteriaQuery, criteriaBuilder) -> { | 100 | return (root, criteriaQuery, criteriaBuilder) -> { |
100 | List<Predicate> predicates = new ArrayList<>(); | 101 | List<Predicate> predicates = new ArrayList<>(); |
101 | if (tenantId != null) { | 102 | if (tenantId != null) { |
@@ -106,6 +107,10 @@ public class JpaBaseEdgeEventDao extends JpaAbstractSearchTimeDao<EdgeEventEntit | @@ -106,6 +107,10 @@ public class JpaBaseEdgeEventDao extends JpaAbstractSearchTimeDao<EdgeEventEntit | ||
106 | Predicate entityIdPredicate = criteriaBuilder.equal(root.get("edgeId"), UUIDConverter.fromTimeUUID(edgeId.getId())); | 107 | Predicate entityIdPredicate = criteriaBuilder.equal(root.get("edgeId"), UUIDConverter.fromTimeUUID(edgeId.getId())); |
107 | predicates.add(entityIdPredicate); | 108 | predicates.add(entityIdPredicate); |
108 | } | 109 | } |
110 | + if (!withTsUpdate) { | ||
111 | + Predicate edgeEventActionPredicate = criteriaBuilder.notEqual(root.get("edgeEventAction"), ActionType.TIMESERIES_UPDATED.name()); | ||
112 | + predicates.add(edgeEventActionPredicate); | ||
113 | + } | ||
109 | return criteriaBuilder.and(predicates.toArray(new Predicate[]{})); | 114 | return criteriaBuilder.and(predicates.toArray(new Predicate[]{})); |
110 | }; | 115 | }; |
111 | } | 116 | } |
@@ -19,6 +19,7 @@ import com.datastax.driver.core.utils.UUIDs; | @@ -19,6 +19,7 @@ import com.datastax.driver.core.utils.UUIDs; | ||
19 | import org.junit.Assert; | 19 | import org.junit.Assert; |
20 | import org.junit.Test; | 20 | import org.junit.Test; |
21 | import org.thingsboard.server.common.data.DataConstants; | 21 | import org.thingsboard.server.common.data.DataConstants; |
22 | +import org.thingsboard.server.common.data.audit.ActionType; | ||
22 | import org.thingsboard.server.common.data.edge.EdgeEvent; | 23 | import org.thingsboard.server.common.data.edge.EdgeEvent; |
23 | import org.thingsboard.server.common.data.edge.EdgeEventType; | 24 | import org.thingsboard.server.common.data.edge.EdgeEventType; |
24 | import org.thingsboard.server.common.data.id.DeviceId; | 25 | import org.thingsboard.server.common.data.id.DeviceId; |
@@ -82,7 +83,7 @@ public abstract class BaseEdgeEventServiceTest extends AbstractServiceTest { | @@ -82,7 +83,7 @@ public abstract class BaseEdgeEventServiceTest extends AbstractServiceTest { | ||
82 | EdgeEvent savedEdgeEvent3 = saveEdgeEventWithProvidedTime(eventTime + 2, edgeId, deviceId, tenantId); | 83 | EdgeEvent savedEdgeEvent3 = saveEdgeEventWithProvidedTime(eventTime + 2, edgeId, deviceId, tenantId); |
83 | saveEdgeEventWithProvidedTime(timeAfterEndTime, edgeId, deviceId, tenantId); | 84 | saveEdgeEventWithProvidedTime(timeAfterEndTime, edgeId, deviceId, tenantId); |
84 | 85 | ||
85 | - TimePageData<EdgeEvent> edgeEvents = edgeEventService.findEdgeEvents(tenantId, edgeId, new TimePageLink(2, startTime, endTime, false)); | 86 | + TimePageData<EdgeEvent> edgeEvents = edgeEventService.findEdgeEvents(tenantId, edgeId, new TimePageLink(2, startTime, endTime, false), true); |
86 | 87 | ||
87 | Assert.assertNotNull(edgeEvents.getData()); | 88 | Assert.assertNotNull(edgeEvents.getData()); |
88 | Assert.assertTrue(edgeEvents.getData().size() == 2); | 89 | Assert.assertTrue(edgeEvents.getData().size() == 2); |
@@ -91,7 +92,7 @@ public abstract class BaseEdgeEventServiceTest extends AbstractServiceTest { | @@ -91,7 +92,7 @@ public abstract class BaseEdgeEventServiceTest extends AbstractServiceTest { | ||
91 | Assert.assertTrue(edgeEvents.hasNext()); | 92 | Assert.assertTrue(edgeEvents.hasNext()); |
92 | Assert.assertNotNull(edgeEvents.getNextPageLink()); | 93 | Assert.assertNotNull(edgeEvents.getNextPageLink()); |
93 | 94 | ||
94 | - edgeEvents = edgeEventService.findEdgeEvents(tenantId, edgeId, edgeEvents.getNextPageLink()); | 95 | + edgeEvents = edgeEventService.findEdgeEvents(tenantId, edgeId, edgeEvents.getNextPageLink(), true); |
95 | 96 | ||
96 | Assert.assertNotNull(edgeEvents.getData()); | 97 | Assert.assertNotNull(edgeEvents.getData()); |
97 | Assert.assertTrue(edgeEvents.getData().size() == 1); | 98 | Assert.assertTrue(edgeEvents.getData().size() == 1); |
@@ -100,6 +101,26 @@ public abstract class BaseEdgeEventServiceTest extends AbstractServiceTest { | @@ -100,6 +101,26 @@ public abstract class BaseEdgeEventServiceTest extends AbstractServiceTest { | ||
100 | Assert.assertNull(edgeEvents.getNextPageLink()); | 101 | Assert.assertNull(edgeEvents.getNextPageLink()); |
101 | } | 102 | } |
102 | 103 | ||
104 | + @Test | ||
105 | + public void findEdgeEventsWithTsUpdateAndWithout() throws Exception { | ||
106 | + EdgeId edgeId = new EdgeId(UUIDs.timeBased()); | ||
107 | + DeviceId deviceId = new DeviceId(UUIDs.timeBased()); | ||
108 | + TenantId tenantId = new TenantId(UUIDs.timeBased()); | ||
109 | + TimePageLink pageLink = new TimePageLink(1); | ||
110 | + | ||
111 | + EdgeEvent edgeEventWithTsUpdate = generateEdgeEvent(tenantId, edgeId, deviceId, ActionType.TIMESERIES_UPDATED.name()); | ||
112 | + edgeEventService.saveAsync(edgeEventWithTsUpdate); | ||
113 | + | ||
114 | + TimePageData<EdgeEvent> allEdgeEvents = edgeEventService.findEdgeEvents(tenantId, edgeId, pageLink, true); | ||
115 | + TimePageData<EdgeEvent> edgeEventsWithoutTsUpdate = edgeEventService.findEdgeEvents(tenantId, edgeId, pageLink, false); | ||
116 | + | ||
117 | + Assert.assertNotNull(allEdgeEvents.getData()); | ||
118 | + Assert.assertNotNull(edgeEventsWithoutTsUpdate.getData()); | ||
119 | + Assert.assertEquals(1, allEdgeEvents.getData().size()); | ||
120 | + Assert.assertEquals(allEdgeEvents.getData().get(0).getUuidId(), edgeEventWithTsUpdate.getUuidId()); | ||
121 | + Assert.assertTrue(edgeEventsWithoutTsUpdate.getData().isEmpty()); | ||
122 | + } | ||
123 | + | ||
103 | private EdgeEvent saveEdgeEventWithProvidedTime(long time, EdgeId edgeId, EntityId entityId, TenantId tenantId) throws Exception { | 124 | private EdgeEvent saveEdgeEventWithProvidedTime(long time, EdgeId edgeId, EntityId entityId, TenantId tenantId) throws Exception { |
104 | EdgeEvent edgeEvent = generateEdgeEvent(tenantId, edgeId, entityId, DataConstants.ENTITY_CREATED); | 125 | EdgeEvent edgeEvent = generateEdgeEvent(tenantId, edgeId, entityId, DataConstants.ENTITY_CREATED); |
105 | edgeEvent.setId(new EdgeEventId(UUIDs.startOf(time))); | 126 | edgeEvent.setId(new EdgeEventId(UUIDs.startOf(time))); |
@@ -56,7 +56,7 @@ function EdgeService($http, $q, customerService) { | @@ -56,7 +56,7 @@ function EdgeService($http, $q, customerService) { | ||
56 | deferred.reject(); | 56 | deferred.reject(); |
57 | }); | 57 | }); |
58 | return deferred.promise; | 58 | return deferred.promise; |
59 | - } // TODO: deaflynx: check usage in UI | 59 | + } |
60 | 60 | ||
61 | function getEdgesByIds(edgeIds, config) { | 61 | function getEdgesByIds(edgeIds, config) { |
62 | var deferred = $q.defer(); | 62 | var deferred = $q.defer(); |
@@ -389,6 +389,25 @@ export default angular.module('thingsboard.types', []) | @@ -389,6 +389,25 @@ export default angular.module('thingsboard.types', []) | ||
389 | customer: "CUSTOMER", | 389 | customer: "CUSTOMER", |
390 | relation: "RELATION" | 390 | relation: "RELATION" |
391 | }, | 391 | }, |
392 | + edgeEventAction: { | ||
393 | + updated: "UPDATED", | ||
394 | + added: "ADDED", | ||
395 | + assignedToEdge: "ASSIGNED_TO_EDGE", | ||
396 | + deleted: "DELETED", | ||
397 | + unassignedFromEdge: "UNASSIGNED_FROM_EDGE", | ||
398 | + alarmAck: "ALARM_ACK", | ||
399 | + alarmClear: "ALARM_CLEAR", | ||
400 | + credentialsUpdated: "CREDENTIALS_UPDATED", | ||
401 | + attributesUpdated: "ATTRIBUTES_UPDATED", | ||
402 | + attributesDeleted: "ATTRIBUTES_DELETED", | ||
403 | + timeseriesUpdated: "TIMESERIES_UPDATED" | ||
404 | + }, | ||
405 | + edgeAttributeKeys: { | ||
406 | + active: "active", | ||
407 | + lastConnectTime: "lastConnectTime", | ||
408 | + lastDisconnectTime: "lastDisconnectTime", | ||
409 | + queueStartTs: "queueStartTs" | ||
410 | + }, | ||
392 | importEntityColumnType: { | 411 | importEntityColumnType: { |
393 | name: { | 412 | name: { |
394 | name: 'import.column-type.name', | 413 | name: 'import.column-type.name', |
@@ -21,6 +21,21 @@ | @@ -21,6 +21,21 @@ | ||
21 | <md-button ng-click="onUnassignFromCustomer({event: $event, isPublic: isPublic})" | 21 | <md-button ng-click="onUnassignFromCustomer({event: $event, isPublic: isPublic})" |
22 | ng-show="!isEdit && (edgeScope === 'customer' || edgeScope === 'tenant') && isAssignedToCustomer" | 22 | ng-show="!isEdit && (edgeScope === 'customer' || edgeScope === 'tenant') && isAssignedToCustomer" |
23 | class="md-raised md-primary">{{ isPublic ? 'edge.make-private' : 'edge.unassign-from-customer' | translate }}</md-button> | 23 | class="md-raised md-primary">{{ isPublic ? 'edge.make-private' : 'edge.unassign-from-customer' | translate }}</md-button> |
24 | +<md-button ng-click="onManageEdgeAssets({event: $event})" | ||
25 | + ng-show="!isEdit && edgeScope === 'tenant'" | ||
26 | + class="md-raised md-primary">{{ 'edge.manage-edge-assets' | translate }}</md-button> | ||
27 | +<md-button ng-click="onManageEdgeDevices({event: $event})" | ||
28 | + ng-show="!isEdit && edgeScope === 'tenant'" | ||
29 | + class="md-raised md-primary">{{ 'edge.manage-edge-devices' | translate }}</md-button> | ||
30 | +<md-button ng-click="onManageEdgeEntityViews({event: $event})" | ||
31 | + ng-show="!isEdit && edgeScope === 'tenant'" | ||
32 | + class="md-raised md-primary">{{ 'edge.manage-edge-entity-views' | translate }}</md-button> | ||
33 | +<md-button ng-click="onManageEdgeDashboards({event: $event})" | ||
34 | + ng-show="!isEdit && edgeScope === 'tenant'" | ||
35 | + class="md-raised md-primary">{{ 'edge.manage-edge-dashboards' | translate }}</md-button> | ||
36 | +<md-button ng-click="onManageEdgeRuleChains({event: $event})" | ||
37 | + ng-show="!isEdit && edgeScope === 'tenant'" | ||
38 | + class="md-raised md-primary">{{ 'edge.manage-edge-rulechains' | translate }}</md-button> | ||
24 | <md-button ng-click="onDeleteEdge({event: $event})" | 39 | <md-button ng-click="onDeleteEdge({event: $event})" |
25 | ng-show="!isEdit && edgeScope === 'tenant'" | 40 | ng-show="!isEdit && edgeScope === 'tenant'" |
26 | class="md-raised md-primary">{{ 'edge.delete' | translate }}</md-button> | 41 | class="md-raised md-primary">{{ 'edge.delete' | translate }}</md-button> |
@@ -129,6 +129,11 @@ export function EdgeController($rootScope, userService, edgeService, customerSer | @@ -129,6 +129,11 @@ export function EdgeController($rootScope, userService, edgeService, customerSer | ||
129 | vm.assignToCustomer = assignToCustomer; | 129 | vm.assignToCustomer = assignToCustomer; |
130 | vm.makePublic = makePublic; | 130 | vm.makePublic = makePublic; |
131 | vm.unassignFromCustomer = unassignFromCustomer; | 131 | vm.unassignFromCustomer = unassignFromCustomer; |
132 | + vm.openEdgeAssets = openEdgeAssets; | ||
133 | + vm.openEdgeDevices = openEdgeDevices; | ||
134 | + vm.openEdgeEntityViews = openEdgeEntityViews; | ||
135 | + vm.openEdgeDashboards = openEdgeDashboards; | ||
136 | + vm.openEdgeRuleChains = openEdgeRuleChains; | ||
132 | 137 | ||
133 | initController(); | 138 | initController(); |
134 | 139 |
@@ -96,6 +96,11 @@ export default function EdgeDirective($compile, $templateCache, $translate, $mdD | @@ -96,6 +96,11 @@ export default function EdgeDirective($compile, $templateCache, $translate, $mdD | ||
96 | onAssignToCustomer: '&', | 96 | onAssignToCustomer: '&', |
97 | onMakePublic: '&', | 97 | onMakePublic: '&', |
98 | onUnassignFromCustomer: '&', | 98 | onUnassignFromCustomer: '&', |
99 | + onManageEdgeAssets: '&', | ||
100 | + onManageEdgeDevices: '&', | ||
101 | + onManageEdgeEntityViews: '&', | ||
102 | + onManageEdgeDashboards: '&', | ||
103 | + onManageEdgeRuleChains: '&', | ||
99 | onDeleteEdge: '&' | 104 | onDeleteEdge: '&' |
100 | } | 105 | } |
101 | }; | 106 | }; |
@@ -29,6 +29,11 @@ | @@ -29,6 +29,11 @@ | ||
29 | on-assign-to-customer="vm.assignToCustomer(event, [ vm.grid.detailsConfig.currentItem.id.id ])" | 29 | on-assign-to-customer="vm.assignToCustomer(event, [ vm.grid.detailsConfig.currentItem.id.id ])" |
30 | on-make-public="vm.makePublic(event, vm.grid.detailsConfig.currentItem)" | 30 | on-make-public="vm.makePublic(event, vm.grid.detailsConfig.currentItem)" |
31 | on-unassign-from-customer="vm.unassignFromCustomer(event, vm.grid.detailsConfig.currentItem, isPublic)" | 31 | on-unassign-from-customer="vm.unassignFromCustomer(event, vm.grid.detailsConfig.currentItem, isPublic)" |
32 | + on-manage-edge-assets="vm.openEdgeAssets(event, vm.grid.detailsConfig.currentItem)" | ||
33 | + on-manage-edge-devices="vm.openEdgeDevices(event, vm.grid.detailsConfig.currentItem)" | ||
34 | + on-manage-edge-entity-views="vm.openEdgeEntityViews(event, vm.grid.detailsConfig.currentItem)" | ||
35 | + on-manage-edge-dashboards="vm.openEdgeDashboards(event, vm.grid.detailsConfig.currentItem)" | ||
36 | + on-manage-edge-rule-chains="vm.openEdgeRuleChains(event, vm.grid.detailsConfig.currentItem)" | ||
32 | on-delete-edge="vm.grid.deleteItem(event, vm.grid.detailsConfig.currentItem)"></tb-edge> | 37 | on-delete-edge="vm.grid.deleteItem(event, vm.grid.detailsConfig.currentItem)"></tb-edge> |
33 | </md-tab> | 38 | </md-tab> |
34 | <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" md-on-select="vm.grid.triggerResize()" label="{{ 'attribute.attributes' | translate }}"> | 39 | <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" md-on-select="vm.grid.triggerResize()" label="{{ 'attribute.attributes' | translate }}"> |
@@ -17,6 +17,7 @@ | @@ -17,6 +17,7 @@ | ||
17 | --> | 17 | --> |
18 | <div translate class="tb-cell" flex="20">event.event-time</div> | 18 | <div translate class="tb-cell" flex="20">event.event-time</div> |
19 | <div translate class="tb-cell" flex="20">event.event-type</div> | 19 | <div translate class="tb-cell" flex="20">event.event-type</div> |
20 | -<div translate class="tb-cell" flex="20">edge.event-action</div> | ||
21 | -<div translate class="tb-cell" flex="30">edge.entity-id</div> | ||
22 | -<div translate class="tb-cell" flex="20">edge.entity-info</div> | 20 | +<div translate class="tb-cell" flex="40">edge.event-action</div> |
21 | +<div translate class="tb-cell" flex="20">edge.entity-id</div> | ||
22 | +<div translate class="tb-cell" flex="15">edge.status</div> | ||
23 | +<div translate class="tb-cell" flex="10">edge.entity-info</div> |
@@ -15,11 +15,12 @@ | @@ -15,11 +15,12 @@ | ||
15 | limitations under the License. | 15 | limitations under the License. |
16 | 16 | ||
17 | --> | 17 | --> |
18 | -<div class="tb-cell" flex="20">{{event.createdTime | date : 'yyyy-MM-dd HH:mm:ss'}}</div> | ||
19 | -<div class="tb-cell" flex="20">{{event.edgeEventType}}</div> | ||
20 | -<div class="tb-cell" flex="20">{{event.edgeEventAction}}</div> | ||
21 | -<div class="tb-cell" flex="30">{{event.entityId}}</div> | ||
22 | -<div class="tb-cell" flex="20"> | 18 | +<div class="tb-cell" flex="20">{{ event.createdTime | date : 'yyyy-MM-dd HH:mm:ss' }}</div> |
19 | +<div class="tb-cell" flex="20">{{ event.edgeEventType }}</div> | ||
20 | +<div class="tb-cell" flex="40">{{ event.edgeEventAction }}</div> | ||
21 | +<div class="tb-cell" flex="20">{{ event.entityId }}</div> | ||
22 | +<div class="tb-cell" flex="15" ng-style="isPending ? {'color': 'rgba(0, 0, 0, .38)'} : {'color': '#000'}">{{ updateStatus(event.createdTime) | translate }}</div> | ||
23 | +<div class="tb-cell" flex="10"> | ||
23 | <md-button class="md-icon-button md-primary" | 24 | <md-button class="md-icon-button md-primary" |
24 | ng-click="showEdgeEntityContent($event, 'edge.entity-info', 'JSON')" | 25 | ng-click="showEdgeEntityContent($event, 'edge.entity-info', 'JSON')" |
25 | aria-label="{{ 'action.view' | translate }}"> | 26 | aria-label="{{ 'action.view' | translate }}"> |
@@ -33,3 +34,4 @@ | @@ -33,3 +34,4 @@ | ||
33 | </md-button> | 34 | </md-button> |
34 | </div> | 35 | </div> |
35 | 36 | ||
37 | + |
@@ -102,37 +102,45 @@ export default function EventRowDirective($compile, $templateCache, $mdDialog, $ | @@ -102,37 +102,45 @@ export default function EventRowDirective($compile, $templateCache, $mdDialog, $ | ||
102 | switch(scope.event.edgeEventType) { | 102 | switch(scope.event.edgeEventType) { |
103 | case types.edgeEventType.relation: | 103 | case types.edgeEventType.relation: |
104 | content = angular.toJson(scope.event.entityBody); | 104 | content = angular.toJson(scope.event.entityBody); |
105 | + showDialog(); | ||
105 | break; | 106 | break; |
106 | case types.edgeEventType.ruleChainMetaData: | 107 | case types.edgeEventType.ruleChainMetaData: |
107 | - content = ruleChainService.getRuleChainMetaData(scope.event.entityId, {}).then( | 108 | + content = ruleChainService.getRuleChainMetaData(scope.event.entityId, {ignoreErrors: true}).then( |
108 | function success(info) { | 109 | function success(info) { |
110 | + showDialog(); | ||
109 | return angular.toJson(info); | 111 | return angular.toJson(info); |
110 | }, function fail() { | 112 | }, function fail() { |
111 | - toast.showError($translate.instant('edge.load-entity-error')); | 113 | + showError(); |
112 | }); | 114 | }); |
113 | break; | 115 | break; |
114 | default: | 116 | default: |
115 | - content = entityService.getEntity(scope.event.edgeEventType, scope.event.entityId, {}).then( | 117 | + content = entityService.getEntity(scope.event.edgeEventType, scope.event.entityId, {ignoreErrors: true}).then( |
116 | function success(info) { | 118 | function success(info) { |
119 | + showDialog(); | ||
117 | return angular.toJson(info); | 120 | return angular.toJson(info); |
118 | }, function fail() { | 121 | }, function fail() { |
119 | - toast.showError($translate.instant('edge.load-entity-error')); | 122 | + showError(); |
120 | }); | 123 | }); |
121 | break; | 124 | break; |
122 | } | 125 | } |
123 | - $mdDialog.show({ | ||
124 | - controller: 'EventContentDialogController', | ||
125 | - controllerAs: 'vm', | ||
126 | - templateUrl: eventErrorDialogTemplate, | ||
127 | - locals: {content: content, title: title, contentType: contentType, showingCallback: onShowingCallback}, | ||
128 | - parent: angular.element($document[0].body), | ||
129 | - fullscreen: true, | ||
130 | - targetEvent: $event, | ||
131 | - multiple: true, | ||
132 | - onShowing: function(scope, element) { | ||
133 | - onShowingCallback.onShowing(scope, element); | ||
134 | - } | ||
135 | - }); | 126 | + function showDialog() { |
127 | + $mdDialog.show({ | ||
128 | + controller: 'EventContentDialogController', | ||
129 | + controllerAs: 'vm', | ||
130 | + templateUrl: eventErrorDialogTemplate, | ||
131 | + locals: {content: content, title: title, contentType: contentType, showingCallback: onShowingCallback}, | ||
132 | + parent: angular.element($document[0].body), | ||
133 | + fullscreen: true, | ||
134 | + targetEvent: $event, | ||
135 | + multiple: true, | ||
136 | + onShowing: function(scope, element) { | ||
137 | + onShowingCallback.onShowing(scope, element); | ||
138 | + } | ||
139 | + }); | ||
140 | + } | ||
141 | + function showError() { | ||
142 | + toast.showError($translate.instant('edge.load-entity-error')); | ||
143 | + } | ||
136 | } | 144 | } |
137 | 145 | ||
138 | scope.checkTooltip = function($event) { | 146 | scope.checkTooltip = function($event) { |
@@ -144,6 +152,20 @@ export default function EventRowDirective($compile, $templateCache, $mdDialog, $ | @@ -144,6 +152,20 @@ export default function EventRowDirective($compile, $templateCache, $mdDialog, $ | ||
144 | } | 152 | } |
145 | 153 | ||
146 | $compile(element.contents())(scope); | 154 | $compile(element.contents())(scope); |
155 | + | ||
156 | + scope.updateStatus = function(eventCreatedTime) { | ||
157 | + if (scope.queueStartTs) { | ||
158 | + var status; | ||
159 | + if (eventCreatedTime < scope.queueStartTs) { | ||
160 | + status = $translate.instant('edge.success'); | ||
161 | + scope.isPending = false; | ||
162 | + } else { | ||
163 | + status = $translate.instant('edge.failed'); | ||
164 | + scope.isPending = true; | ||
165 | + } | ||
166 | + return status; | ||
167 | + } | ||
168 | + } | ||
147 | } | 169 | } |
148 | 170 | ||
149 | return { | 171 | return { |
@@ -22,7 +22,8 @@ import eventTableTemplate from './event-table.tpl.html'; | @@ -22,7 +22,8 @@ import eventTableTemplate from './event-table.tpl.html'; | ||
22 | /* eslint-enable import/no-unresolved, import/default */ | 22 | /* eslint-enable import/no-unresolved, import/default */ |
23 | 23 | ||
24 | /*@ngInject*/ | 24 | /*@ngInject*/ |
25 | -export default function EventTableDirective($compile, $templateCache, $rootScope, types, eventService, edgeService) { | 25 | +export default function EventTableDirective($compile, $templateCache, $rootScope, types, |
26 | + eventService, edgeService, attributeService) { | ||
26 | 27 | ||
27 | var linker = function (scope, element, attrs) { | 28 | var linker = function (scope, element, attrs) { |
28 | 29 | ||
@@ -30,11 +31,16 @@ export default function EventTableDirective($compile, $templateCache, $rootScope | @@ -30,11 +31,16 @@ export default function EventTableDirective($compile, $templateCache, $rootScope | ||
30 | 31 | ||
31 | element.html(template); | 32 | element.html(template); |
32 | 33 | ||
34 | + scope.eventTypeScope = angular.copy(types.eventType); | ||
35 | + if (scope.entityType !== types.entityType.edge) { | ||
36 | + delete scope.eventTypeScope.edgeEvent; | ||
37 | + } | ||
38 | + | ||
33 | if (attrs.disabledEventTypes) { | 39 | if (attrs.disabledEventTypes) { |
34 | var disabledEventTypes = attrs.disabledEventTypes.split(','); | 40 | var disabledEventTypes = attrs.disabledEventTypes.split(','); |
35 | scope.eventTypes = {}; | 41 | scope.eventTypes = {}; |
36 | - for (var type in types.eventType) { | ||
37 | - var eventType = types.eventType[type]; | 42 | + for (var type in scope.eventTypeScope) { |
43 | + var eventType = scope.eventTypeScope[type]; | ||
38 | var enabled = true; | 44 | var enabled = true; |
39 | for (var i=0;i<disabledEventTypes.length;i++) { | 45 | for (var i=0;i<disabledEventTypes.length;i++) { |
40 | if (eventType.value === disabledEventTypes[i]) { | 46 | if (eventType.value === disabledEventTypes[i]) { |
@@ -47,7 +53,7 @@ export default function EventTableDirective($compile, $templateCache, $rootScope | @@ -47,7 +53,7 @@ export default function EventTableDirective($compile, $templateCache, $rootScope | ||
47 | } | 53 | } |
48 | } | 54 | } |
49 | } else { | 55 | } else { |
50 | - scope.eventTypes = angular.copy(types.eventType); | 56 | + scope.eventTypes = angular.copy(scope.eventTypeScope); |
51 | } | 57 | } |
52 | 58 | ||
53 | if (attrs.debugEventTypes) { | 59 | if (attrs.debugEventTypes) { |
@@ -106,6 +112,7 @@ export default function EventTableDirective($compile, $templateCache, $rootScope | @@ -106,6 +112,7 @@ export default function EventTableDirective($compile, $templateCache, $rootScope | ||
106 | scope.eventType, scope.tenantId, scope.events.nextPageLink); | 112 | scope.eventType, scope.tenantId, scope.events.nextPageLink); |
107 | } else { | 113 | } else { |
108 | promise = edgeService.getEdgeEvents(scope.entityId, scope.events.nextPageLink); | 114 | promise = edgeService.getEdgeEvents(scope.entityId, scope.events.nextPageLink); |
115 | + scope.loadEdgeInfo(); | ||
109 | } | 116 | } |
110 | if (promise) { | 117 | if (promise) { |
111 | scope.events.pending = true; | 118 | scope.events.pending = true; |
@@ -135,6 +142,7 @@ export default function EventTableDirective($compile, $templateCache, $rootScope | @@ -135,6 +142,7 @@ export default function EventTableDirective($compile, $templateCache, $rootScope | ||
135 | 142 | ||
136 | scope.$watch("entityId", function(newVal, prevVal) { | 143 | scope.$watch("entityId", function(newVal, prevVal) { |
137 | if (newVal && !angular.equals(newVal, prevVal)) { | 144 | if (newVal && !angular.equals(newVal, prevVal)) { |
145 | + scope.loadEdgeInfo(); | ||
138 | scope.resetFilter(); | 146 | scope.resetFilter(); |
139 | scope.reload(); | 147 | scope.reload(); |
140 | } | 148 | } |
@@ -212,6 +220,53 @@ export default function EventTableDirective($compile, $templateCache, $rootScope | @@ -212,6 +220,53 @@ export default function EventTableDirective($compile, $templateCache, $rootScope | ||
212 | return false; | 220 | return false; |
213 | } | 221 | } |
214 | 222 | ||
223 | + scope.subscriptionId = null; | ||
224 | + scope.queueStartTs; | ||
225 | + | ||
226 | + scope.loadEdgeInfo = function() { | ||
227 | + attributeService.getEntityAttributesValues(scope.entityType, scope.entityId, types.attributesScope.server.value, | ||
228 | + types.edgeAttributeKeys.queueStartTs, {}) | ||
229 | + .then(function success(attributes) { | ||
230 | + scope.onUpdate(attributes); | ||
231 | + }); | ||
232 | + | ||
233 | + scope.checkSubscription(); | ||
234 | + | ||
235 | + attributeService.getEntityAttributes(scope.entityType, scope.entityId, types.attributesScope.server.value, {order: '', limit: 1, page: 1, search: ''}, | ||
236 | + function (attributes) { | ||
237 | + if (attributes && attributes.data) { | ||
238 | + scope.onUpdate(attributes.data); | ||
239 | + } | ||
240 | + }); | ||
241 | + } | ||
242 | + | ||
243 | + scope.onUpdate = function(attributes) { | ||
244 | + let edge = attributes.reduce(function (map, attribute) { | ||
245 | + map[attribute.key] = attribute; | ||
246 | + return map; | ||
247 | + }, {}); | ||
248 | + if (edge.queueStartTs) { | ||
249 | + scope.queueStartTs = edge.queueStartTs.lastUpdateTs; | ||
250 | + } | ||
251 | + } | ||
252 | + | ||
253 | + scope.checkSubscription = function() { | ||
254 | + var newSubscriptionId = null; | ||
255 | + if (scope.entityId && scope.entityType && types.attributesScope.server.value) { | ||
256 | + newSubscriptionId = attributeService.subscribeForEntityAttributes(scope.entityType, scope.entityId, types.attributesScope.server.value); | ||
257 | + } | ||
258 | + if (scope.subscriptionId && scope.subscriptionId != newSubscriptionId) { | ||
259 | + attributeService.unsubscribeForEntityAttributes(scope.subscriptionId); | ||
260 | + } | ||
261 | + scope.subscriptionId = newSubscriptionId; | ||
262 | + } | ||
263 | + | ||
264 | + scope.$on('$destroy', function () { | ||
265 | + if (scope.subscriptionId) { | ||
266 | + attributeService.unsubscribeForEntityAttributes(scope.subscriptionId); | ||
267 | + } | ||
268 | + }); | ||
269 | + | ||
215 | scope.reload(); | 270 | scope.reload(); |
216 | 271 | ||
217 | $compile(element.contents())(scope); | 272 | $compile(element.contents())(scope); |
@@ -821,7 +821,7 @@ | @@ -821,7 +821,7 @@ | ||
821 | "make-private-edge-text": "After the confirmation the edge and all its data will be made private and won't be accessible by others.", | 821 | "make-private-edge-text": "After the confirmation the edge and all its data will be made private and won't be accessible by others.", |
822 | "import": "Import edge", | 822 | "import": "Import edge", |
823 | "label": "Label", | 823 | "label": "Label", |
824 | - "load-entity-error": "Could not load entity info", | 824 | + "load-entity-error": "Entity not found. Failed to load info", |
825 | "assign-new-edge": "Assign new edge", | 825 | "assign-new-edge": "Assign new edge", |
826 | "manage-edge-dashboards": "Manage edge dashboards", | 826 | "manage-edge-dashboards": "Manage edge dashboards", |
827 | "unassign-from-edge": "Unassign from edge", | 827 | "unassign-from-edge": "Unassign from edge", |
@@ -843,7 +843,10 @@ | @@ -843,7 +843,10 @@ | ||
843 | "entity-views": "Edge entity views", | 843 | "entity-views": "Edge entity views", |
844 | "set-root-rule-chain-text": "Please select root rule chain for edge(s)", | 844 | "set-root-rule-chain-text": "Please select root rule chain for edge(s)", |
845 | "set-root-rule-chain-to-edges": "Set root rule chain for Edge(s)", | 845 | "set-root-rule-chain-to-edges": "Set root rule chain for Edge(s)", |
846 | - "set-root-rule-chain-to-edges-text": "Set root rule chain for { count, plural, 1 {1 edge} other {# edges} }" | 846 | + "set-root-rule-chain-to-edges-text": "Set root rule chain for { count, plural, 1 {1 edge} other {# edges} }", |
847 | + "status": "Received by edge", | ||
848 | + "success": "Deployed", | ||
849 | + "failed": "Pending" | ||
847 | }, | 850 | }, |
848 | "error": { | 851 | "error": { |
849 | "unable-to-connect": "Unable to connect to the server! Please check your internet connection.", | 852 | "unable-to-connect": "Unable to connect to the server! Please check your internet connection.", |