Fix: don't fetch name of deleted alarm originator. Add ability to create dynamic subscriptions for alarms.

This commit is contained in:
Igor Kulikov 2017-06-21 19:21:51 +03:00
parent 25af06f25d
commit 849f53ca4c
8 changed files with 83 additions and 20 deletions

View File

@ -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(

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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

View File

@ -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) {

View File

@ -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"
}

View File

@ -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: {},

View File

@ -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();
});