Browse Source

Merge remote-tracking branch 'upstream/feature/edge' into feature/widgets_bundle_fetch

pull/2436/head
Bohdan Smetaniuk 6 years ago
parent
commit
b5659fd32d
  1. 16
      application/src/main/java/org/thingsboard/server/actors/ActorSystemContext.java
  2. 17
      application/src/main/java/org/thingsboard/server/actors/tenant/TenantActor.java
  3. 9
      application/src/main/java/org/thingsboard/server/controller/EdgeController.java
  4. 2
      application/src/main/java/org/thingsboard/server/controller/EdgeEventController.java
  5. 2
      application/src/main/java/org/thingsboard/server/service/edge/DefaultEdgeNotificationService.java
  6. 20
      application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java
  7. 14
      application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java
  8. 26
      application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeRpcService.java
  9. 5
      common/dao-api/src/main/java/org/thingsboard/server/dao/edge/EdgeEventService.java
  10. 6
      dao/src/main/java/org/thingsboard/server/dao/edge/BaseEdgeEventService.java
  11. 2
      dao/src/main/java/org/thingsboard/server/dao/edge/CassandraEdgeEventDao.java
  12. 2
      dao/src/main/java/org/thingsboard/server/dao/edge/EdgeEventDao.java
  13. 11
      dao/src/main/java/org/thingsboard/server/dao/sql/edge/JpaBaseEdgeEventDao.java
  14. 25
      dao/src/test/java/org/thingsboard/server/dao/service/BaseEdgeEventServiceTest.java
  15. 2
      ui/src/app/api/edge.service.js
  16. 19
      ui/src/app/common/types.constant.js
  17. 15
      ui/src/app/edge/edge-fieldset.tpl.html
  18. 5
      ui/src/app/edge/edge.controller.js
  19. 5
      ui/src/app/edge/edge.directive.js
  20. 5
      ui/src/app/edge/edges.tpl.html
  21. 7
      ui/src/app/event/event-header-edge-event.tpl.html
  22. 12
      ui/src/app/event/event-row-edge-event.tpl.html
  23. 56
      ui/src/app/event/event-row.directive.js
  24. 63
      ui/src/app/event/event-table.directive.js
  25. 7
      ui/src/app/locale/locale.constant-en_US.json

16
application/src/main/java/org/thingsboard/server/actors/ActorSystemContext.java

@ -66,6 +66,7 @@ import org.thingsboard.server.dao.user.UserService;
import org.thingsboard.server.queue.discovery.PartitionService;
import org.thingsboard.server.queue.discovery.TbServiceInfoProvider;
import org.thingsboard.server.service.component.ComponentDiscoveryService;
import org.thingsboard.server.service.edge.rpc.EdgeRpcService;
import org.thingsboard.server.service.encoding.DataDecodingEncodingService;
import org.thingsboard.server.service.executors.DbCallbackExecutorService;
import org.thingsboard.server.service.executors.ExternalCallExecutorService;
@ -254,15 +255,14 @@ public class ActorSystemContext {
@Getter
private TbCoreDeviceRpcService tbCoreDeviceRpcService;
@Lazy
@Autowired
@Getter
private EdgeService edgeService;
@Autowired(required = false)
@Getter private EdgeService edgeService;
@Lazy
@Autowired
@Getter
private EdgeEventService edgeEventService;
@Autowired(required = false)
@Getter private EdgeEventService edgeEventService;
@Autowired(required = false)
@Getter private EdgeRpcService edgeRpcService;
@Value("${actors.session.max_concurrent_sessions_per_device:1}")
@Getter

17
application/src/main/java/org/thingsboard/server/actors/tenant/TenantActor.java

@ -31,10 +31,13 @@ import org.thingsboard.server.actors.service.ContextBasedCreator;
import org.thingsboard.server.actors.service.DefaultActorService;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.edge.Edge;
import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.EdgeId;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.RuleChainId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent;
import org.thingsboard.server.common.data.rule.RuleChain;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.MsgType;
@ -47,6 +50,7 @@ import org.thingsboard.server.common.msg.queue.PartitionChangeMsg;
import org.thingsboard.server.common.msg.queue.QueueToRuleEngineMsg;
import org.thingsboard.server.common.msg.queue.RuleEngineException;
import org.thingsboard.server.common.msg.queue.ServiceType;
import org.thingsboard.server.service.edge.rpc.EdgeRpcService;
import java.util.List;
import java.util.Optional;
@ -202,7 +206,18 @@ public class TenantActor extends RuleChainManagerActor {
}
private void onComponentLifecycleMsg(ComponentLifecycleMsg msg) {
if (isRuleEngineForCurrentTenant) {
if (msg.getEntityId().getEntityType() == EntityType.EDGE) {
EdgeId edgeId = new EdgeId(msg.getEntityId().getId());
EdgeRpcService edgeRpcService = systemContext.getEdgeRpcService();
if (msg.getEvent() == ComponentLifecycleEvent.DELETED) {
edgeRpcService.deleteEdge(edgeId);
} else {
Edge edge = systemContext.getEdgeService().findEdgeById(tenantId, edgeId);
if (msg.getEvent() == ComponentLifecycleEvent.UPDATED) {
edgeRpcService.updateEdge(edge);
}
}
} else if (isRuleEngineForCurrentTenant) {
TbActorRef target = getEntityActorRef(msg.getEntityId());
if (target != null) {
if (msg.getEntityId().getEntityType() == EntityType.RULE_CHAIN) {

9
application/src/main/java/org/thingsboard/server/controller/EdgeController.java

@ -40,6 +40,7 @@ import org.thingsboard.server.common.data.id.RuleChainId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.TextPageData;
import org.thingsboard.server.common.data.page.TextPageLink;
import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent;
import org.thingsboard.server.common.data.rule.RuleChain;
import org.thingsboard.server.dao.exception.DataValidationException;
import org.thingsboard.server.dao.exception.IncorrectParameterException;
@ -101,6 +102,9 @@ public class EdgeController extends BaseController {
edgeService.assignDefaultRuleChainsToEdge(tenantId, savedEdge.getId());
}
tbClusterService.onEntityStateChange(savedEdge.getTenantId(), savedEdge.getId(),
created ? ComponentLifecycleEvent.CREATED : ComponentLifecycleEvent.UPDATED);
logEntityAction(savedEdge.getId(), savedEdge, null, created ? ActionType.ADDED : ActionType.UPDATED, null);
return savedEdge;
} catch (Exception e) {
@ -120,6 +124,9 @@ public class EdgeController extends BaseController {
Edge edge = checkEdgeId(edgeId, Operation.DELETE);
edgeService.deleteEdge(getTenantId(), edgeId);
tbClusterService.onEntityStateChange(getTenantId(), edgeId,
ComponentLifecycleEvent.DELETED);
logEntityAction(edgeId, edge,
null,
ActionType.DELETED, null, strEdgeId);
@ -284,6 +291,8 @@ public class EdgeController extends BaseController {
Edge updatedEdge = edgeNotificationService.setEdgeRootRuleChain(getTenantId(), edge, ruleChainId);
tbClusterService.onEntityStateChange(updatedEdge.getTenantId(), updatedEdge.getId(), ComponentLifecycleEvent.UPDATED);
logEntityAction(updatedEdge.getId(), updatedEdge, null, ActionType.UPDATED, null);
return updatedEdge;

2
application/src/main/java/org/thingsboard/server/controller/EdgeEventController.java

@ -61,7 +61,7 @@ public class EdgeEventController extends BaseController {
EdgeId edgeId = new EdgeId(toUUID(strEdgeId));
checkEdgeId(edgeId, Operation.READ);
TimePageLink pageLink = createPageLink(limit, startTime, endTime, ascOrder, offset);
return checkNotNull(edgeEventService.findEdgeEvents(tenantId, edgeId, pageLink));
return checkNotNull(edgeEventService.findEdgeEvents(tenantId, edgeId, pageLink, false));
} catch (Exception e) {
throw handleException(e);
}

2
application/src/main/java/org/thingsboard/server/service/edge/DefaultEdgeNotificationService.java

@ -111,7 +111,7 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService {
@Override
public TimePageData<EdgeEvent> findEdgeEvents(TenantId tenantId, EdgeId edgeId, TimePageLink pageLink) {
return edgeEventService.findEdgeEvents(tenantId, edgeId, pageLink);
return edgeEventService.findEdgeEvents(tenantId, edgeId, pageLink, true);
}
@Override

20
application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java

@ -27,6 +27,7 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import org.thingsboard.server.common.data.DataConstants;
import org.thingsboard.server.common.data.edge.Edge;
import org.thingsboard.server.common.data.id.EdgeId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.kv.BasicTsKvEntry;
@ -52,7 +53,7 @@ import java.util.concurrent.Executors;
@Service
@Slf4j
@ConditionalOnProperty(prefix = "edges.rpc", value = "enabled", havingValue = "true")
public class EdgeGrpcService extends EdgeRpcServiceGrpc.EdgeRpcServiceImplBase {
public class EdgeGrpcService extends EdgeRpcServiceGrpc.EdgeRpcServiceImplBase implements EdgeRpcService {
private final Map<EdgeId, EdgeGrpcSession> sessions = new ConcurrentHashMap<>();
private static final ObjectMapper mapper = new ObjectMapper();
@ -117,6 +118,23 @@ public class EdgeGrpcService extends EdgeRpcServiceGrpc.EdgeRpcServiceImplBase {
return new EdgeGrpcSession(ctx, outputStream, this::onEdgeConnect, this::onEdgeDisconnect, mapper).getInputStream();
}
@Override
public void updateEdge(Edge edge) {
EdgeGrpcSession session = sessions.get(edge.getId());
if (session != null && session.isConnected()) {
session.onConfigurationUpdate(edge);
}
}
@Override
public void deleteEdge(EdgeId edgeId) {
EdgeGrpcSession session = sessions.get(edgeId);
if (session != null && session.isConnected()) {
session.close();
sessions.remove(edgeId);
}
}
private void onEdgeConnect(EdgeId edgeId, EdgeGrpcSession edgeGrpcSession) {
sessions.put(edgeId, edgeGrpcSession);
save(edgeId, DefaultDeviceStateService.ACTIVITY_STATE, true);

14
application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java

@ -198,6 +198,20 @@ public final class EdgeGrpcSession implements Closeable {
};
}
void onConfigurationUpdate(Edge edge) {
try {
this.edge = edge;
// TODO: voba - push edge configuration update to edge
// outputStream.onNext(org.thingsboard.server.gen.integration.ResponseMsg.newBuilder()
// .setIntegrationUpdateMsg(IntegrationUpdateMsg.newBuilder()
// .setConfiguration(constructIntegrationConfigProto(configuration, defaultConverterProto, downLinkConverterProto))
// .build())
// .build());
} catch (Exception e) {
log.error("Failed to construct proto objects!", e);
}
}
void processHandleMessages() throws ExecutionException, InterruptedException {
Long queueStartTs = getQueueStartTs().get();
TimePageLink pageLink = new TimePageLink(ctx.getEdgeEventStorageSettings().getMaxReadRecordsCount(), queueStartTs, null, true);

26
application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeRpcService.java

@ -0,0 +1,26 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.service.edge.rpc;
import org.thingsboard.server.common.data.edge.Edge;
import org.thingsboard.server.common.data.id.EdgeId;
public interface EdgeRpcService {
void updateEdge(Edge edge);
void deleteEdge(EdgeId edgeId);
}

5
common/dao-api/src/main/java/org/thingsboard/server/dao/edge/EdgeEventService.java

@ -16,9 +16,7 @@
package org.thingsboard.server.dao.edge;
import com.google.common.util.concurrent.ListenableFuture;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.edge.EdgeEvent;
import org.thingsboard.server.common.data.edge.EdgeEventType;
import org.thingsboard.server.common.data.id.EdgeId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.TimePageData;
@ -28,6 +26,5 @@ public interface EdgeEventService {
ListenableFuture<EdgeEvent> saveAsync(EdgeEvent edgeEvent);
TimePageData<EdgeEvent> findEdgeEvents(TenantId tenantId, EdgeId edgeId, TimePageLink pageLink);
TimePageData<EdgeEvent> findEdgeEvents(TenantId tenantId, EdgeId edgeId, TimePageLink pageLink, boolean withTsUpdate);
}

6
dao/src/main/java/org/thingsboard/server/dao/edge/BaseEdgeEventService.java

@ -35,7 +35,7 @@ import java.util.List;
public class BaseEdgeEventService implements EdgeEventService {
@Autowired
public EdgeEventDao edgeEventDao;
private EdgeEventDao edgeEventDao;
@Override
public ListenableFuture<EdgeEvent> saveAsync(EdgeEvent edgeEvent) {
@ -44,8 +44,8 @@ public class BaseEdgeEventService implements EdgeEventService {
}
@Override
public TimePageData<EdgeEvent> findEdgeEvents(TenantId tenantId, EdgeId edgeId, TimePageLink pageLink) {
List<EdgeEvent> events = edgeEventDao.findEdgeEvents(tenantId.getId(), edgeId, pageLink);
public TimePageData<EdgeEvent> findEdgeEvents(TenantId tenantId, EdgeId edgeId, TimePageLink pageLink, boolean withTsUpdate) {
List<EdgeEvent> events = edgeEventDao.findEdgeEvents(tenantId.getId(), edgeId, pageLink, withTsUpdate);
return new TimePageData<>(events, pageLink);
}

2
dao/src/main/java/org/thingsboard/server/dao/edge/CassandraEdgeEventDao.java

@ -53,7 +53,7 @@ public class CassandraEdgeEventDao extends CassandraAbstractSearchTimeDao<EdgeEv
}
@Override
public List<EdgeEvent> findEdgeEvents(UUID tenantId, EdgeId edgeId, TimePageLink pageLink) {
public List<EdgeEvent> findEdgeEvents(UUID tenantId, EdgeId edgeId, TimePageLink pageLink, boolean withTsUpdate) {
return null;
}
}

2
dao/src/main/java/org/thingsboard/server/dao/edge/EdgeEventDao.java

@ -46,6 +46,6 @@ public interface EdgeEventDao extends Dao<EdgeEvent> {
* @param pageLink the pageLink
* @return the event list
*/
List<EdgeEvent> findEdgeEvents(UUID tenantId, EdgeId edgeId, TimePageLink pageLink);
List<EdgeEvent> findEdgeEvents(UUID tenantId, EdgeId edgeId, TimePageLink pageLink, boolean withTsUpdate);
}

11
dao/src/main/java/org/thingsboard/server/dao/sql/edge/JpaBaseEdgeEventDao.java

@ -26,6 +26,7 @@ import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Component;
import org.thingsboard.server.common.data.UUIDConverter;
import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.edge.EdgeEvent;
import org.thingsboard.server.common.data.id.EdgeEventId;
import org.thingsboard.server.common.data.id.EdgeId;
@ -75,9 +76,9 @@ public class JpaBaseEdgeEventDao extends JpaAbstractSearchTimeDao<EdgeEventEntit
}
@Override
public List<EdgeEvent> findEdgeEvents(UUID tenantId, EdgeId edgeId, TimePageLink pageLink) {
public List<EdgeEvent> findEdgeEvents(UUID tenantId, EdgeId edgeId, TimePageLink pageLink, boolean withTsUpdate) {
Specification<EdgeEventEntity> timeSearchSpec = JpaAbstractSearchTimeDao.getTimeSearchPageSpec(pageLink, "id");
Specification<EdgeEventEntity> fieldsSpec = getEntityFieldsSpec(tenantId, edgeId);
Specification<EdgeEventEntity> fieldsSpec = getEntityFieldsSpec(tenantId, edgeId, withTsUpdate);
Sort.Direction sortDirection = pageLink.isAscOrder() ? Sort.Direction.ASC : Sort.Direction.DESC;
Pageable pageable = PageRequest.of(0, pageLink.getLimit(), sortDirection, ID_PROPERTY);
return DaoUtil.convertDataList(edgeEventRepository.findAll(Specification.where(timeSearchSpec).and(fieldsSpec), pageable).getContent());
@ -95,7 +96,7 @@ public class JpaBaseEdgeEventDao extends JpaAbstractSearchTimeDao<EdgeEventEntit
return Optional.of(DaoUtil.getData(edgeEventRepository.save(entity)));
}
private Specification<EdgeEventEntity> getEntityFieldsSpec(UUID tenantId, EdgeId edgeId) {
private Specification<EdgeEventEntity> getEntityFieldsSpec(UUID tenantId, EdgeId edgeId, boolean withTsUpdate) {
return (root, criteriaQuery, criteriaBuilder) -> {
List<Predicate> predicates = new ArrayList<>();
if (tenantId != null) {
@ -106,6 +107,10 @@ public class JpaBaseEdgeEventDao extends JpaAbstractSearchTimeDao<EdgeEventEntit
Predicate entityIdPredicate = criteriaBuilder.equal(root.get("edgeId"), UUIDConverter.fromTimeUUID(edgeId.getId()));
predicates.add(entityIdPredicate);
}
if (!withTsUpdate) {
Predicate edgeEventActionPredicate = criteriaBuilder.notEqual(root.get("edgeEventAction"), ActionType.TIMESERIES_UPDATED.name());
predicates.add(edgeEventActionPredicate);
}
return criteriaBuilder.and(predicates.toArray(new Predicate[]{}));
};
}

25
dao/src/test/java/org/thingsboard/server/dao/service/BaseEdgeEventServiceTest.java

@ -19,6 +19,7 @@ import com.datastax.driver.core.utils.UUIDs;
import org.junit.Assert;
import org.junit.Test;
import org.thingsboard.server.common.data.DataConstants;
import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.edge.EdgeEvent;
import org.thingsboard.server.common.data.edge.EdgeEventType;
import org.thingsboard.server.common.data.id.DeviceId;
@ -82,7 +83,7 @@ public abstract class BaseEdgeEventServiceTest extends AbstractServiceTest {
EdgeEvent savedEdgeEvent3 = saveEdgeEventWithProvidedTime(eventTime + 2, edgeId, deviceId, tenantId);
saveEdgeEventWithProvidedTime(timeAfterEndTime, edgeId, deviceId, tenantId);
TimePageData<EdgeEvent> edgeEvents = edgeEventService.findEdgeEvents(tenantId, edgeId, new TimePageLink(2, startTime, endTime, false));
TimePageData<EdgeEvent> edgeEvents = edgeEventService.findEdgeEvents(tenantId, edgeId, new TimePageLink(2, startTime, endTime, false), true);
Assert.assertNotNull(edgeEvents.getData());
Assert.assertTrue(edgeEvents.getData().size() == 2);
@ -91,7 +92,7 @@ public abstract class BaseEdgeEventServiceTest extends AbstractServiceTest {
Assert.assertTrue(edgeEvents.hasNext());
Assert.assertNotNull(edgeEvents.getNextPageLink());
edgeEvents = edgeEventService.findEdgeEvents(tenantId, edgeId, edgeEvents.getNextPageLink());
edgeEvents = edgeEventService.findEdgeEvents(tenantId, edgeId, edgeEvents.getNextPageLink(), true);
Assert.assertNotNull(edgeEvents.getData());
Assert.assertTrue(edgeEvents.getData().size() == 1);
@ -100,6 +101,26 @@ public abstract class BaseEdgeEventServiceTest extends AbstractServiceTest {
Assert.assertNull(edgeEvents.getNextPageLink());
}
@Test
public void findEdgeEventsWithTsUpdateAndWithout() throws Exception {
EdgeId edgeId = new EdgeId(UUIDs.timeBased());
DeviceId deviceId = new DeviceId(UUIDs.timeBased());
TenantId tenantId = new TenantId(UUIDs.timeBased());
TimePageLink pageLink = new TimePageLink(1);
EdgeEvent edgeEventWithTsUpdate = generateEdgeEvent(tenantId, edgeId, deviceId, ActionType.TIMESERIES_UPDATED.name());
edgeEventService.saveAsync(edgeEventWithTsUpdate);
TimePageData<EdgeEvent> allEdgeEvents = edgeEventService.findEdgeEvents(tenantId, edgeId, pageLink, true);
TimePageData<EdgeEvent> edgeEventsWithoutTsUpdate = edgeEventService.findEdgeEvents(tenantId, edgeId, pageLink, false);
Assert.assertNotNull(allEdgeEvents.getData());
Assert.assertNotNull(edgeEventsWithoutTsUpdate.getData());
Assert.assertEquals(1, allEdgeEvents.getData().size());
Assert.assertEquals(allEdgeEvents.getData().get(0).getUuidId(), edgeEventWithTsUpdate.getUuidId());
Assert.assertTrue(edgeEventsWithoutTsUpdate.getData().isEmpty());
}
private EdgeEvent saveEdgeEventWithProvidedTime(long time, EdgeId edgeId, EntityId entityId, TenantId tenantId) throws Exception {
EdgeEvent edgeEvent = generateEdgeEvent(tenantId, edgeId, entityId, DataConstants.ENTITY_CREATED);
edgeEvent.setId(new EdgeEventId(UUIDs.startOf(time)));

2
ui/src/app/api/edge.service.js

@ -56,7 +56,7 @@ function EdgeService($http, $q, customerService) {
deferred.reject();
});
return deferred.promise;
} // TODO: deaflynx: check usage in UI
}
function getEdgesByIds(edgeIds, config) {
var deferred = $q.defer();

19
ui/src/app/common/types.constant.js

@ -389,6 +389,25 @@ export default angular.module('thingsboard.types', [])
customer: "CUSTOMER",
relation: "RELATION"
},
edgeEventAction: {
updated: "UPDATED",
added: "ADDED",
assignedToEdge: "ASSIGNED_TO_EDGE",
deleted: "DELETED",
unassignedFromEdge: "UNASSIGNED_FROM_EDGE",
alarmAck: "ALARM_ACK",
alarmClear: "ALARM_CLEAR",
credentialsUpdated: "CREDENTIALS_UPDATED",
attributesUpdated: "ATTRIBUTES_UPDATED",
attributesDeleted: "ATTRIBUTES_DELETED",
timeseriesUpdated: "TIMESERIES_UPDATED"
},
edgeAttributeKeys: {
active: "active",
lastConnectTime: "lastConnectTime",
lastDisconnectTime: "lastDisconnectTime",
queueStartTs: "queueStartTs"
},
importEntityColumnType: {
name: {
name: 'import.column-type.name',

15
ui/src/app/edge/edge-fieldset.tpl.html

@ -21,6 +21,21 @@
<md-button ng-click="onUnassignFromCustomer({event: $event, isPublic: isPublic})"
ng-show="!isEdit && (edgeScope === 'customer' || edgeScope === 'tenant') && isAssignedToCustomer"
class="md-raised md-primary">{{ isPublic ? 'edge.make-private' : 'edge.unassign-from-customer' | translate }}</md-button>
<md-button ng-click="onManageEdgeAssets({event: $event})"
ng-show="!isEdit && edgeScope === 'tenant'"
class="md-raised md-primary">{{ 'edge.manage-edge-assets' | translate }}</md-button>
<md-button ng-click="onManageEdgeDevices({event: $event})"
ng-show="!isEdit && edgeScope === 'tenant'"
class="md-raised md-primary">{{ 'edge.manage-edge-devices' | translate }}</md-button>
<md-button ng-click="onManageEdgeEntityViews({event: $event})"
ng-show="!isEdit && edgeScope === 'tenant'"
class="md-raised md-primary">{{ 'edge.manage-edge-entity-views' | translate }}</md-button>
<md-button ng-click="onManageEdgeDashboards({event: $event})"
ng-show="!isEdit && edgeScope === 'tenant'"
class="md-raised md-primary">{{ 'edge.manage-edge-dashboards' | translate }}</md-button>
<md-button ng-click="onManageEdgeRuleChains({event: $event})"
ng-show="!isEdit && edgeScope === 'tenant'"
class="md-raised md-primary">{{ 'edge.manage-edge-rulechains' | translate }}</md-button>
<md-button ng-click="onDeleteEdge({event: $event})"
ng-show="!isEdit && edgeScope === 'tenant'"
class="md-raised md-primary">{{ 'edge.delete' | translate }}</md-button>

5
ui/src/app/edge/edge.controller.js

@ -129,6 +129,11 @@ export function EdgeController($rootScope, userService, edgeService, customerSer
vm.assignToCustomer = assignToCustomer;
vm.makePublic = makePublic;
vm.unassignFromCustomer = unassignFromCustomer;
vm.openEdgeAssets = openEdgeAssets;
vm.openEdgeDevices = openEdgeDevices;
vm.openEdgeEntityViews = openEdgeEntityViews;
vm.openEdgeDashboards = openEdgeDashboards;
vm.openEdgeRuleChains = openEdgeRuleChains;
initController();

5
ui/src/app/edge/edge.directive.js

@ -96,6 +96,11 @@ export default function EdgeDirective($compile, $templateCache, $translate, $mdD
onAssignToCustomer: '&',
onMakePublic: '&',
onUnassignFromCustomer: '&',
onManageEdgeAssets: '&',
onManageEdgeDevices: '&',
onManageEdgeEntityViews: '&',
onManageEdgeDashboards: '&',
onManageEdgeRuleChains: '&',
onDeleteEdge: '&'
}
};

5
ui/src/app/edge/edges.tpl.html

@ -29,6 +29,11 @@
on-assign-to-customer="vm.assignToCustomer(event, [ vm.grid.detailsConfig.currentItem.id.id ])"
on-make-public="vm.makePublic(event, vm.grid.detailsConfig.currentItem)"
on-unassign-from-customer="vm.unassignFromCustomer(event, vm.grid.detailsConfig.currentItem, isPublic)"
on-manage-edge-assets="vm.openEdgeAssets(event, vm.grid.detailsConfig.currentItem)"
on-manage-edge-devices="vm.openEdgeDevices(event, vm.grid.detailsConfig.currentItem)"
on-manage-edge-entity-views="vm.openEdgeEntityViews(event, vm.grid.detailsConfig.currentItem)"
on-manage-edge-dashboards="vm.openEdgeDashboards(event, vm.grid.detailsConfig.currentItem)"
on-manage-edge-rule-chains="vm.openEdgeRuleChains(event, vm.grid.detailsConfig.currentItem)"
on-delete-edge="vm.grid.deleteItem(event, vm.grid.detailsConfig.currentItem)"></tb-edge>
</md-tab>
<md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" md-on-select="vm.grid.triggerResize()" label="{{ 'attribute.attributes' | translate }}">

7
ui/src/app/event/event-header-edge-event.tpl.html

@ -17,6 +17,7 @@
-->
<div translate class="tb-cell" flex="20">event.event-time</div>
<div translate class="tb-cell" flex="20">event.event-type</div>
<div translate class="tb-cell" flex="20">edge.event-action</div>
<div translate class="tb-cell" flex="30">edge.entity-id</div>
<div translate class="tb-cell" flex="20">edge.entity-info</div>
<div translate class="tb-cell" flex="40">edge.event-action</div>
<div translate class="tb-cell" flex="20">edge.entity-id</div>
<div translate class="tb-cell" flex="15">edge.status</div>
<div translate class="tb-cell" flex="10">edge.entity-info</div>

12
ui/src/app/event/event-row-edge-event.tpl.html

@ -15,11 +15,12 @@
limitations under the License.
-->
<div class="tb-cell" flex="20">{{event.createdTime | date : 'yyyy-MM-dd HH:mm:ss'}}</div>
<div class="tb-cell" flex="20">{{event.edgeEventType}}</div>
<div class="tb-cell" flex="20">{{event.edgeEventAction}}</div>
<div class="tb-cell" flex="30">{{event.entityId}}</div>
<div class="tb-cell" flex="20">
<div class="tb-cell" flex="20">{{ event.createdTime | date : 'yyyy-MM-dd HH:mm:ss' }}</div>
<div class="tb-cell" flex="20">{{ event.edgeEventType }}</div>
<div class="tb-cell" flex="40">{{ event.edgeEventAction }}</div>
<div class="tb-cell" flex="20">{{ event.entityId }}</div>
<div class="tb-cell" flex="15" ng-style="isPending ? {'color': 'rgba(0, 0, 0, .38)'} : {'color': '#000'}">{{ updateStatus(event.createdTime) | translate }}</div>
<div class="tb-cell" flex="10">
<md-button class="md-icon-button md-primary"
ng-click="showEdgeEntityContent($event, 'edge.entity-info', 'JSON')"
aria-label="{{ 'action.view' | translate }}">
@ -33,3 +34,4 @@
</md-button>
</div>

56
ui/src/app/event/event-row.directive.js

@ -102,37 +102,45 @@ export default function EventRowDirective($compile, $templateCache, $mdDialog, $
switch(scope.event.edgeEventType) {
case types.edgeEventType.relation:
content = angular.toJson(scope.event.entityBody);
showDialog();
break;
case types.edgeEventType.ruleChainMetaData:
content = ruleChainService.getRuleChainMetaData(scope.event.entityId, {}).then(
content = ruleChainService.getRuleChainMetaData(scope.event.entityId, {ignoreErrors: true}).then(
function success(info) {
showDialog();
return angular.toJson(info);
}, function fail() {
toast.showError($translate.instant('edge.load-entity-error'));
showError();
});
break;
default:
content = entityService.getEntity(scope.event.edgeEventType, scope.event.entityId, {}).then(
content = entityService.getEntity(scope.event.edgeEventType, scope.event.entityId, {ignoreErrors: true}).then(
function success(info) {
showDialog();
return angular.toJson(info);
}, function fail() {
toast.showError($translate.instant('edge.load-entity-error'));
showError();
});
break;
}
$mdDialog.show({
controller: 'EventContentDialogController',
controllerAs: 'vm',
templateUrl: eventErrorDialogTemplate,
locals: {content: content, title: title, contentType: contentType, showingCallback: onShowingCallback},
parent: angular.element($document[0].body),
fullscreen: true,
targetEvent: $event,
multiple: true,
onShowing: function(scope, element) {
onShowingCallback.onShowing(scope, element);
}
});
function showDialog() {
$mdDialog.show({
controller: 'EventContentDialogController',
controllerAs: 'vm',
templateUrl: eventErrorDialogTemplate,
locals: {content: content, title: title, contentType: contentType, showingCallback: onShowingCallback},
parent: angular.element($document[0].body),
fullscreen: true,
targetEvent: $event,
multiple: true,
onShowing: function(scope, element) {
onShowingCallback.onShowing(scope, element);
}
});
}
function showError() {
toast.showError($translate.instant('edge.load-entity-error'));
}
}
scope.checkTooltip = function($event) {
@ -144,6 +152,20 @@ export default function EventRowDirective($compile, $templateCache, $mdDialog, $
}
$compile(element.contents())(scope);
scope.updateStatus = function(eventCreatedTime) {
if (scope.queueStartTs) {
var status;
if (eventCreatedTime < scope.queueStartTs) {
status = $translate.instant('edge.success');
scope.isPending = false;
} else {
status = $translate.instant('edge.failed');
scope.isPending = true;
}
return status;
}
}
}
return {

63
ui/src/app/event/event-table.directive.js

@ -22,7 +22,8 @@ import eventTableTemplate from './event-table.tpl.html';
/* eslint-enable import/no-unresolved, import/default */
/*@ngInject*/
export default function EventTableDirective($compile, $templateCache, $rootScope, types, eventService, edgeService) {
export default function EventTableDirective($compile, $templateCache, $rootScope, types,
eventService, edgeService, attributeService) {
var linker = function (scope, element, attrs) {
@ -30,11 +31,16 @@ export default function EventTableDirective($compile, $templateCache, $rootScope
element.html(template);
scope.eventTypeScope = angular.copy(types.eventType);
if (scope.entityType !== types.entityType.edge) {
delete scope.eventTypeScope.edgeEvent;
}
if (attrs.disabledEventTypes) {
var disabledEventTypes = attrs.disabledEventTypes.split(',');
scope.eventTypes = {};
for (var type in types.eventType) {
var eventType = types.eventType[type];
for (var type in scope.eventTypeScope) {
var eventType = scope.eventTypeScope[type];
var enabled = true;
for (var i=0;i<disabledEventTypes.length;i++) {
if (eventType.value === disabledEventTypes[i]) {
@ -47,7 +53,7 @@ export default function EventTableDirective($compile, $templateCache, $rootScope
}
}
} else {
scope.eventTypes = angular.copy(types.eventType);
scope.eventTypes = angular.copy(scope.eventTypeScope);
}
if (attrs.debugEventTypes) {
@ -106,6 +112,7 @@ export default function EventTableDirective($compile, $templateCache, $rootScope
scope.eventType, scope.tenantId, scope.events.nextPageLink);
} else {
promise = edgeService.getEdgeEvents(scope.entityId, scope.events.nextPageLink);
scope.loadEdgeInfo();
}
if (promise) {
scope.events.pending = true;
@ -135,6 +142,7 @@ export default function EventTableDirective($compile, $templateCache, $rootScope
scope.$watch("entityId", function(newVal, prevVal) {
if (newVal && !angular.equals(newVal, prevVal)) {
scope.loadEdgeInfo();
scope.resetFilter();
scope.reload();
}
@ -212,6 +220,53 @@ export default function EventTableDirective($compile, $templateCache, $rootScope
return false;
}
scope.subscriptionId = null;
scope.queueStartTs;
scope.loadEdgeInfo = function() {
attributeService.getEntityAttributesValues(scope.entityType, scope.entityId, types.attributesScope.server.value,
types.edgeAttributeKeys.queueStartTs, {})
.then(function success(attributes) {
scope.onUpdate(attributes);
});
scope.checkSubscription();
attributeService.getEntityAttributes(scope.entityType, scope.entityId, types.attributesScope.server.value, {order: '', limit: 1, page: 1, search: ''},
function (attributes) {
if (attributes && attributes.data) {
scope.onUpdate(attributes.data);
}
});
}
scope.onUpdate = function(attributes) {
let edge = attributes.reduce(function (map, attribute) {
map[attribute.key] = attribute;
return map;
}, {});
if (edge.queueStartTs) {
scope.queueStartTs = edge.queueStartTs.lastUpdateTs;
}
}
scope.checkSubscription = function() {
var newSubscriptionId = null;
if (scope.entityId && scope.entityType && types.attributesScope.server.value) {
newSubscriptionId = attributeService.subscribeForEntityAttributes(scope.entityType, scope.entityId, types.attributesScope.server.value);
}
if (scope.subscriptionId && scope.subscriptionId != newSubscriptionId) {
attributeService.unsubscribeForEntityAttributes(scope.subscriptionId);
}
scope.subscriptionId = newSubscriptionId;
}
scope.$on('$destroy', function () {
if (scope.subscriptionId) {
attributeService.unsubscribeForEntityAttributes(scope.subscriptionId);
}
});
scope.reload();
$compile(element.contents())(scope);

7
ui/src/app/locale/locale.constant-en_US.json

@ -821,7 +821,7 @@
"make-private-edge-text": "After the confirmation the edge and all its data will be made private and won't be accessible by others.",
"import": "Import edge",
"label": "Label",
"load-entity-error": "Could not load entity info",
"load-entity-error": "Entity not found. Failed to load info",
"assign-new-edge": "Assign new edge",
"manage-edge-dashboards": "Manage edge dashboards",
"unassign-from-edge": "Unassign from edge",
@ -843,7 +843,10 @@
"entity-views": "Edge entity views",
"set-root-rule-chain-text": "Please select root rule chain for edge(s)",
"set-root-rule-chain-to-edges": "Set root rule chain for Edge(s)",
"set-root-rule-chain-to-edges-text": "Set root rule chain for { count, plural, 1 {1 edge} other {# edges} }"
"set-root-rule-chain-to-edges-text": "Set root rule chain for { count, plural, 1 {1 edge} other {# edges} }",
"status": "Received by edge",
"success": "Deployed",
"failed": "Pending"
},
"error": {
"unable-to-connect": "Unable to connect to the server! Please check your internet connection.",

Loading…
Cancel
Save