Fix: don't fetch name of deleted alarm originator. Add ability to create dynamic subscriptions for alarms.
This commit is contained in:
		
							parent
							
								
									25af06f25d
								
							
						
					
					
						commit
						849f53ca4c
					
				@ -44,7 +44,7 @@ import java.util.stream.Collectors;
 | 
			
		||||
@RequestMapping("/api")
 | 
			
		||||
public class AlarmController extends BaseController {
 | 
			
		||||
 | 
			
		||||
    @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
 | 
			
		||||
    @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
 | 
			
		||||
    @RequestMapping(value = "/alarm/{alarmId}", method = RequestMethod.GET)
 | 
			
		||||
    @ResponseBody
 | 
			
		||||
    public Alarm getAlarmById(@PathVariable("alarmId") String strAlarmId) throws ThingsboardException {
 | 
			
		||||
@ -57,7 +57,7 @@ public class AlarmController extends BaseController {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
 | 
			
		||||
    @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
 | 
			
		||||
    @RequestMapping(value = "/alarm/info/{alarmId}", method = RequestMethod.GET)
 | 
			
		||||
    @ResponseBody
 | 
			
		||||
    public AlarmInfo getAlarmInfoById(@PathVariable("alarmId") String strAlarmId) throws ThingsboardException {
 | 
			
		||||
@ -70,7 +70,7 @@ public class AlarmController extends BaseController {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
 | 
			
		||||
    @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
 | 
			
		||||
    @RequestMapping(value = "/alarm", method = RequestMethod.POST)
 | 
			
		||||
    @ResponseBody
 | 
			
		||||
    public Alarm saveAlarm(@RequestBody Alarm alarm) throws ThingsboardException {
 | 
			
		||||
@ -82,7 +82,7 @@ public class AlarmController extends BaseController {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
 | 
			
		||||
    @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
 | 
			
		||||
    @RequestMapping(value = "/alarm/{alarmId}/ack", method = RequestMethod.POST)
 | 
			
		||||
    @ResponseStatus(value = HttpStatus.OK)
 | 
			
		||||
    public void ackAlarm(@PathVariable("alarmId") String strAlarmId) throws ThingsboardException {
 | 
			
		||||
@ -96,7 +96,7 @@ public class AlarmController extends BaseController {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
 | 
			
		||||
    @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
 | 
			
		||||
    @RequestMapping(value = "/alarm/{alarmId}/clear", method = RequestMethod.POST)
 | 
			
		||||
    @ResponseStatus(value = HttpStatus.OK)
 | 
			
		||||
    public void clearAlarm(@PathVariable("alarmId") String strAlarmId) throws ThingsboardException {
 | 
			
		||||
@ -110,7 +110,7 @@ public class AlarmController extends BaseController {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
 | 
			
		||||
    @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
 | 
			
		||||
    @RequestMapping(value = "/alarm/{entityType}/{entityId}", method = RequestMethod.GET)
 | 
			
		||||
    @ResponseBody
 | 
			
		||||
    public TimePageData<AlarmInfo> getAlarms(
 | 
			
		||||
@ -143,7 +143,7 @@ public class AlarmController extends BaseController {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
 | 
			
		||||
    @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
 | 
			
		||||
    @RequestMapping(value = "/alarm/highestSeverity/{entityType}/{entityId}", method = RequestMethod.GET)
 | 
			
		||||
    @ResponseBody
 | 
			
		||||
    public AlarmSeverity getHighestAlarmSeverity(
 | 
			
		||||
 | 
			
		||||
@ -227,6 +227,9 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
 | 
			
		||||
                    alarmFutures.add(Futures.transform(
 | 
			
		||||
                            entityService.fetchEntityNameAsync(alarmInfo.getOriginator()), (Function<String, AlarmInfo>)
 | 
			
		||||
                                    originatorName -> {
 | 
			
		||||
                                        if (originatorName == null) {
 | 
			
		||||
                                            originatorName = "Deleted";
 | 
			
		||||
                                        }
 | 
			
		||||
                                        alarmInfo.setOriginatorName(originatorName);
 | 
			
		||||
                                        return alarmInfo;
 | 
			
		||||
                                    }
 | 
			
		||||
 | 
			
		||||
@ -109,7 +109,7 @@ public class BaseEntityService extends AbstractEntityService implements EntitySe
 | 
			
		||||
            default:
 | 
			
		||||
                throw new IllegalStateException("Not Implemented!");
 | 
			
		||||
        }
 | 
			
		||||
        entityName = Futures.transform(hasName, (Function<HasName, String>) hasName1 -> hasName1.getName() );
 | 
			
		||||
        entityName = Futures.transform(hasName, (Function<HasName, String>) hasName1 -> hasName1 != null ? hasName1.getName() : null );
 | 
			
		||||
        return entityName;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -84,7 +84,6 @@ public class BaseRelationService implements RelationService {
 | 
			
		||||
        for (RelationTypeGroup typeGroup : RelationTypeGroup.values()) {
 | 
			
		||||
            inboundRelationsList.add(relationDao.findAllByTo(entity, typeGroup));
 | 
			
		||||
        }
 | 
			
		||||
        Futures.allAsList(inboundRelationsList);
 | 
			
		||||
        ListenableFuture<List<List<EntityRelation>>> inboundRelations = Futures.allAsList(inboundRelationsList);
 | 
			
		||||
        ListenableFuture<List<Boolean>> inboundDeletions = Futures.transform(inboundRelations, new AsyncFunction<List<List<EntityRelation>>, List<Boolean>>() {
 | 
			
		||||
            @Override
 | 
			
		||||
 | 
			
		||||
@ -35,6 +35,7 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device
 | 
			
		||||
        prepareAllowedEntityTypesList: prepareAllowedEntityTypesList,
 | 
			
		||||
        getEntityKeys: getEntityKeys,
 | 
			
		||||
        createDatasourcesFromSubscriptionsInfo: createDatasourcesFromSubscriptionsInfo,
 | 
			
		||||
        createAlarmSourceFromSubscriptionInfo: createAlarmSourceFromSubscriptionInfo,
 | 
			
		||||
        getRelatedEntities: getRelatedEntities,
 | 
			
		||||
        saveRelatedEntity: saveRelatedEntity,
 | 
			
		||||
        getRelatedEntity: getRelatedEntity,
 | 
			
		||||
@ -757,6 +758,26 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device
 | 
			
		||||
        return deferred.promise;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function createAlarmSourceFromSubscriptionInfo(subscriptionInfo) {
 | 
			
		||||
        var deferred = $q.defer();
 | 
			
		||||
        var datasources = [];
 | 
			
		||||
        if (subscriptionInfo.entityId && subscriptionInfo.entityType) {
 | 
			
		||||
            getEntity(subscriptionInfo.entityType, subscriptionInfo.entityId, {ignoreLoading: true}).then(
 | 
			
		||||
                function success(entity) {
 | 
			
		||||
                    createDatasourceFromSubscription(subscriptionInfo, datasources, entity);
 | 
			
		||||
                    var alarmSource = datasources[0];
 | 
			
		||||
                    deferred.resolve(alarmSource);
 | 
			
		||||
                },
 | 
			
		||||
                function fail() {
 | 
			
		||||
                    deferred.reject();
 | 
			
		||||
                }
 | 
			
		||||
            );
 | 
			
		||||
        } else {
 | 
			
		||||
            deferred.reject();
 | 
			
		||||
        }
 | 
			
		||||
        return deferred.promise;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function processSubscriptionsInfo(index, subscriptionsInfo, datasources, deferred) {
 | 
			
		||||
        if (index < subscriptionsInfo.length) {
 | 
			
		||||
            var subscriptionInfo = validateSubscriptionInfo(subscriptionsInfo[index]);
 | 
			
		||||
@ -858,6 +879,9 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device
 | 
			
		||||
        if (subscriptionInfo.functions) {
 | 
			
		||||
            createDatasourceKeys(subscriptionInfo.functions, types.dataKeyType.function, datasource, datasources);
 | 
			
		||||
        }
 | 
			
		||||
        if (subscriptionInfo.alarmFields) {
 | 
			
		||||
            createDatasourceKeys(subscriptionInfo.alarmFields, types.dataKeyType.alarm, datasource, datasources);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function createDatasourceKeys(keyInfos, type, datasource, datasources) {
 | 
			
		||||
 | 
			
		||||
@ -61,47 +61,57 @@ export default angular.module('thingsboard.types', [])
 | 
			
		||||
            },
 | 
			
		||||
            alarmFields: {
 | 
			
		||||
                createdTime: {
 | 
			
		||||
                    keyName: 'createdTime',
 | 
			
		||||
                    value: "createdTime",
 | 
			
		||||
                    name: "alarm.created-time",
 | 
			
		||||
                    time: true
 | 
			
		||||
                },
 | 
			
		||||
                startTime: {
 | 
			
		||||
                    keyName: 'startTime',
 | 
			
		||||
                    value: "startTs",
 | 
			
		||||
                    name: "alarm.start-time",
 | 
			
		||||
                    time: true
 | 
			
		||||
                },
 | 
			
		||||
                endTime: {
 | 
			
		||||
                    keyName: 'endTime',
 | 
			
		||||
                    value: "endTs",
 | 
			
		||||
                    name: "alarm.end-time",
 | 
			
		||||
                    time: true
 | 
			
		||||
                },
 | 
			
		||||
                ackTime: {
 | 
			
		||||
                    keyName: 'ackTime',
 | 
			
		||||
                    value: "ackTs",
 | 
			
		||||
                    name: "alarm.ack-time",
 | 
			
		||||
                    time: true
 | 
			
		||||
                },
 | 
			
		||||
                clearTime: {
 | 
			
		||||
                    keyName: 'clearTime',
 | 
			
		||||
                    value: "clearTs",
 | 
			
		||||
                    name: "alarm.clear-time",
 | 
			
		||||
                    time: true
 | 
			
		||||
                },
 | 
			
		||||
                originator: {
 | 
			
		||||
                    keyName: 'originator',
 | 
			
		||||
                    value: "originatorName",
 | 
			
		||||
                    name: "alarm.originator"
 | 
			
		||||
                },
 | 
			
		||||
                originatorType: {
 | 
			
		||||
                    keyName: 'originatorType',
 | 
			
		||||
                    value: "originator.entityType",
 | 
			
		||||
                    name: "alarm.originator-type"
 | 
			
		||||
                },
 | 
			
		||||
                type: {
 | 
			
		||||
                    keyName: 'type',
 | 
			
		||||
                    value: "type",
 | 
			
		||||
                    name: "alarm.type"
 | 
			
		||||
                },
 | 
			
		||||
                severity: {
 | 
			
		||||
                    keyName: 'severity',
 | 
			
		||||
                    value: "severity",
 | 
			
		||||
                    name: "alarm.severity"
 | 
			
		||||
                },
 | 
			
		||||
                status: {
 | 
			
		||||
                    keyName: 'status',
 | 
			
		||||
                    value: "status",
 | 
			
		||||
                    name: "alarm.status"
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
@ -96,11 +96,11 @@ function Utils($mdColorPalette, $rootScope, $window, $translate, types) {
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    var defaultAlarmFields = [
 | 
			
		||||
        'createdTime',
 | 
			
		||||
        'originator',
 | 
			
		||||
        'type',
 | 
			
		||||
        'severity',
 | 
			
		||||
        'status'
 | 
			
		||||
        types.alarmFields.createdTime.keyName,
 | 
			
		||||
        types.alarmFields.originator.keyName,
 | 
			
		||||
        types.alarmFields.type.keyName,
 | 
			
		||||
        types.alarmFields.severity.keyName,
 | 
			
		||||
        types.alarmFields.status.keyName
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    var defaultAlarmDataKeys = [];
 | 
			
		||||
@ -376,10 +376,20 @@ function Utils($mdColorPalette, $rootScope, $window, $translate, types) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function createKey(keyInfo, type, datasources) {
 | 
			
		||||
        var label;
 | 
			
		||||
        if (type === types.dataKeyType.alarm && !keyInfo.label) {
 | 
			
		||||
            var alarmField = types.alarmFields[keyInfo.name];
 | 
			
		||||
            if (alarmField) {
 | 
			
		||||
                label = $translate.instant(alarmField.name)+'';
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (!label) {
 | 
			
		||||
            label = keyInfo.label || keyInfo.name;
 | 
			
		||||
        }
 | 
			
		||||
        var dataKey = {
 | 
			
		||||
            name: keyInfo.name,
 | 
			
		||||
            type: type,
 | 
			
		||||
            label: keyInfo.label || keyInfo.name,
 | 
			
		||||
            label: label,
 | 
			
		||||
            color: genNextColor(datasources),
 | 
			
		||||
            funcBody: keyInfo.funcBody,
 | 
			
		||||
            settings: {},
 | 
			
		||||
 | 
			
		||||
@ -36,6 +36,8 @@ export default function WidgetController($scope, $timeout, $window, $element, $q
 | 
			
		||||
    $scope.rpcEnabled = false;
 | 
			
		||||
    $scope.executingRpcRequest = false;
 | 
			
		||||
 | 
			
		||||
    vm.dashboardTimewindow = dashboardTimewindow;
 | 
			
		||||
 | 
			
		||||
    var gridsterItemInited = false;
 | 
			
		||||
    var subscriptionInited = false;
 | 
			
		||||
    var widgetSizeDetected = false;
 | 
			
		||||
@ -192,9 +194,20 @@ export default function WidgetController($scope, $timeout, $window, $element, $q
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        entityService.createDatasourcesFromSubscriptionsInfo(subscriptionsInfo).then(
 | 
			
		||||
            function (datasources) {
 | 
			
		||||
                options.datasources = datasources;
 | 
			
		||||
        var createDatasourcesPromise;
 | 
			
		||||
        if (options.type == types.widgetType.alarm.value) {
 | 
			
		||||
            createDatasourcesPromise = entityService.createAlarmSourceFromSubscriptionInfo(subscriptionsInfo);
 | 
			
		||||
        } else {
 | 
			
		||||
            createDatasourcesPromise = entityService.createDatasourcesFromSubscriptionsInfo(subscriptionsInfo);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        createDatasourcesPromise.then(
 | 
			
		||||
            function (result) {
 | 
			
		||||
                if (options.type == types.widgetType.alarm.value) {
 | 
			
		||||
                    options.alarmSource = result;
 | 
			
		||||
                } else {
 | 
			
		||||
                    options.datasources = result;
 | 
			
		||||
                }
 | 
			
		||||
                createSubscription(options, subscribe).then(
 | 
			
		||||
                    function success(subscription) {
 | 
			
		||||
                        if (useDefaultComponents) {
 | 
			
		||||
@ -213,7 +226,7 @@ export default function WidgetController($scope, $timeout, $window, $element, $q
 | 
			
		||||
 | 
			
		||||
    function createSubscription(options, subscribe) {
 | 
			
		||||
        var deferred = $q.defer();
 | 
			
		||||
        options.dashboardTimewindow = dashboardTimewindow;
 | 
			
		||||
        options.dashboardTimewindow = vm.dashboardTimewindow;
 | 
			
		||||
        new Subscription(subscriptionContext, options).then(
 | 
			
		||||
            function success(subscription) {
 | 
			
		||||
                widgetContext.subscriptions[subscription.id] = subscription;
 | 
			
		||||
@ -234,7 +247,7 @@ export default function WidgetController($scope, $timeout, $window, $element, $q
 | 
			
		||||
        options.useDashboardTimewindow = angular.isDefined(widget.config.useDashboardTimewindow)
 | 
			
		||||
            ? widget.config.useDashboardTimewindow : true;
 | 
			
		||||
 | 
			
		||||
        options.timeWindowConfig = options.useDashboardTimewindow ? dashboardTimewindow : widget.config.timewindow;
 | 
			
		||||
        options.timeWindowConfig = options.useDashboardTimewindow ? vm.dashboardTimewindow : widget.config.timewindow;
 | 
			
		||||
        options.legendConfig = null;
 | 
			
		||||
 | 
			
		||||
        if ($scope.displayLegend) {
 | 
			
		||||
@ -504,6 +517,10 @@ export default function WidgetController($scope, $timeout, $window, $element, $q
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        $scope.$on('dashboardTimewindowChanged', function (event, newDashboardTimewindow) {
 | 
			
		||||
            vm.dashboardTimewindow = newDashboardTimewindow;
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        $scope.$on("$destroy", function () {
 | 
			
		||||
            onDestroy();
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user