Merge remote-tracking branch 'upstream/master' into dao-refactoring-vs

This commit is contained in:
Volodymyr Babak 2017-06-07 19:42:57 +03:00
commit 776737519d
13 changed files with 284 additions and 26 deletions

View File

@ -72,7 +72,7 @@ public class AlarmController extends BaseController {
} }
} }
@PreAuthorize("hasAuthority('TENANT_ADMIN')") @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
@RequestMapping(value = "/alarm/{alarmId}/ack", method = RequestMethod.POST) @RequestMapping(value = "/alarm/{alarmId}/ack", method = RequestMethod.POST)
@ResponseStatus(value = HttpStatus.OK) @ResponseStatus(value = HttpStatus.OK)
public void ackAlarm(@PathVariable("alarmId") String strAlarmId) throws ThingsboardException { public void ackAlarm(@PathVariable("alarmId") String strAlarmId) throws ThingsboardException {
@ -86,7 +86,7 @@ public class AlarmController extends BaseController {
} }
} }
@PreAuthorize("hasAuthority('TENANT_ADMIN')") @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
@RequestMapping(value = "/alarm/{alarmId}/clear", method = RequestMethod.POST) @RequestMapping(value = "/alarm/{alarmId}/clear", method = RequestMethod.POST)
@ResponseStatus(value = HttpStatus.OK) @ResponseStatus(value = HttpStatus.OK)
public void clearAlarm(@PathVariable("alarmId") String strAlarmId) throws ThingsboardException { public void clearAlarm(@PathVariable("alarmId") String strAlarmId) throws ThingsboardException {

View File

@ -91,4 +91,13 @@ public class DeviceAttributes {
} }
return map; return map;
} }
@Override
public String toString() {
return "DeviceAttributes{" +
"clientSideAttributesMap=" + clientSideAttributesMap +
", serverPrivateAttributesMap=" + serverPrivateAttributesMap +
", serverPublicAttributesMap=" + serverPublicAttributesMap +
'}';
}
} }

View File

@ -15,6 +15,7 @@
*/ */
package org.thingsboard.server.extensions.core.action.template; package org.thingsboard.server.extensions.core.action.template;
import lombok.extern.slf4j.Slf4j;
import org.apache.velocity.Template; import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext; import org.apache.velocity.VelocityContext;
import org.apache.velocity.runtime.parser.ParseException; import org.apache.velocity.runtime.parser.ParseException;
@ -35,6 +36,7 @@ import java.util.Optional;
/** /**
* @author Andrew Shvayka * @author Andrew Shvayka
*/ */
@Slf4j
public abstract class AbstractTemplatePluginAction<T extends TemplateActionConfiguration> extends SimpleRuleLifecycleComponent implements PluginAction<T> { public abstract class AbstractTemplatePluginAction<T extends TemplateActionConfiguration> extends SimpleRuleLifecycleComponent implements PluginAction<T> {
protected T configuration; protected T configuration;
protected Template template; protected Template template;
@ -69,6 +71,7 @@ public abstract class AbstractTemplatePluginAction<T extends TemplateActionConfi
} }
protected String getMsgBody(RuleContext ctx, ToDeviceActorMsg msg) { protected String getMsgBody(RuleContext ctx, ToDeviceActorMsg msg) {
log.trace("Creating context for: {} and payload {}", ctx.getDeviceAttributes(), msg.getPayload());
VelocityContext context = VelocityUtils.createContext(ctx.getDeviceAttributes(), msg.getPayload()); VelocityContext context = VelocityUtils.createContext(ctx.getDeviceAttributes(), msg.getPayload());
return VelocityUtils.merge(template, context); return VelocityUtils.merge(template, context);
} }

View File

@ -16,6 +16,7 @@
package org.thingsboard.server.extensions.kafka.plugin; package org.thingsboard.server.extensions.kafka.plugin;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.kafka.clients.producer.Producer; import org.apache.kafka.clients.producer.Producer;
import org.apache.kafka.clients.producer.ProducerRecord; import org.apache.kafka.clients.producer.ProducerRecord;
import org.thingsboard.server.common.data.id.RuleId; import org.thingsboard.server.common.data.id.RuleId;
@ -30,6 +31,7 @@ import org.thingsboard.server.extensions.kafka.action.KafkaActionMsg;
import org.thingsboard.server.extensions.kafka.action.KafkaActionPayload; import org.thingsboard.server.extensions.kafka.action.KafkaActionPayload;
@RequiredArgsConstructor @RequiredArgsConstructor
@Slf4j
public class KafkaMsgHandler implements RuleMsgHandler { public class KafkaMsgHandler implements RuleMsgHandler {
private final Producer<?, String> producer; private final Producer<?, String> producer;
@ -40,7 +42,7 @@ public class KafkaMsgHandler implements RuleMsgHandler {
throw new RuleException("Unsupported message type " + msg.getClass().getName() + "!"); throw new RuleException("Unsupported message type " + msg.getClass().getName() + "!");
} }
KafkaActionPayload payload = ((KafkaActionMsg) msg).getPayload(); KafkaActionPayload payload = ((KafkaActionMsg) msg).getPayload();
log.debug("Processing kafka payload: {}", payload);
try { try {
producer.send(new ProducerRecord<>(payload.getTopic(), payload.getMsgBody()), producer.send(new ProducerRecord<>(payload.getTopic(), payload.getMsgBody()),
(metadata, e) -> { (metadata, e) -> {

View File

@ -78,6 +78,7 @@ public class GatewaySessionCtx {
Device newDevice = new Device(); Device newDevice = new Device();
newDevice.setTenantId(gateway.getTenantId()); newDevice.setTenantId(gateway.getTenantId());
newDevice.setName(deviceName); newDevice.setName(deviceName);
newDevice.setType("default");
return deviceService.saveDevice(newDevice); return deviceService.saveDevice(newDevice);
}); });
GatewayDeviceSessionCtx ctx = new GatewayDeviceSessionCtx(this, device); GatewayDeviceSessionCtx ctx = new GatewayDeviceSessionCtx(this, device);

View File

@ -0,0 +1,189 @@
/*
* Copyright © 2016-2017 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.
*/
export default angular.module('thingsboard.api.alarm', [])
.factory('alarmService', AlarmService)
.name;
/*@ngInject*/
function AlarmService($http, $q, $interval, $filter) {
var service = {
getAlarm: getAlarm,
saveAlarm: saveAlarm,
ackAlarm: ackAlarm,
clearAlarm: clearAlarm,
getAlarms: getAlarms,
pollAlarms: pollAlarms,
cancelPollAlarms: cancelPollAlarms
}
return service;
function getAlarm(alarmId, ignoreErrors, config) {
var deferred = $q.defer();
var url = '/api/alarm/' + alarmId;
if (!config) {
config = {};
}
config = Object.assign(config, { ignoreErrors: ignoreErrors });
$http.get(url, config).then(function success(response) {
deferred.resolve(response.data);
}, function fail() {
deferred.reject();
});
return deferred.promise;
}
function saveAlarm(alarm, ignoreErrors, config) {
var deferred = $q.defer();
var url = '/api/alarm';
if (!config) {
config = {};
}
config = Object.assign(config, { ignoreErrors: ignoreErrors });
$http.post(url, alarm, config).then(function success(response) {
deferred.resolve(response.data);
}, function fail() {
deferred.reject();
});
return deferred.promise;
}
function ackAlarm(alarmId, ignoreErrors, config) {
var deferred = $q.defer();
var url = '/api/alarm/' + alarmId + '/ack';
if (!config) {
config = {};
}
config = Object.assign(config, { ignoreErrors: ignoreErrors });
$http.post(url, null, config).then(function success(response) {
deferred.resolve(response.data);
}, function fail() {
deferred.reject();
});
return deferred.promise;
}
function clearAlarm(alarmId, ignoreErrors, config) {
var deferred = $q.defer();
var url = '/api/alarm/' + alarmId + '/clear';
if (!config) {
config = {};
}
config = Object.assign(config, { ignoreErrors: ignoreErrors });
$http.post(url, null, config).then(function success(response) {
deferred.resolve(response.data);
}, function fail() {
deferred.reject();
});
return deferred.promise;
}
function getAlarms(entityType, entityId, pageLink, alarmStatus, ascOrder, config) {
var deferred = $q.defer();
var url = '/api/alarm/' + entityType + '/' + entityId + '?limit=' + pageLink.limit;
if (angular.isDefined(pageLink.startTime)) {
url += '&startTime=' + pageLink.startTime;
}
if (angular.isDefined(pageLink.endTime)) {
url += '&endTime=' + pageLink.endTime;
}
if (angular.isDefined(pageLink.idOffset)) {
url += '&offset=' + pageLink.idOffset;
}
if (alarmStatus) {
url += '&status=' + alarmStatus;
}
if (angular.isDefined(ascOrder) && ascOrder != null) {
url += '&ascOrder=' + (ascOrder ? 'true' : 'false');
}
$http.get(url, config).then(function success(response) {
deferred.resolve(response.data);
}, function fail() {
deferred.reject();
});
return deferred.promise;
}
function fetchAlarms(alarmsQuery, pageLink, deferred, alarmsList) {
getAlarms(alarmsQuery.entityType, alarmsQuery.entityId,
pageLink, alarmsQuery.alarmStatus, false, {ignoreLoading: true}).then(
function success(alarms) {
if (!alarmsList) {
alarmsList = [];
}
alarmsList = alarmsList.concat(alarms.data);
if (alarms.hasNext && !alarmsQuery.limit) {
fetchAlarms(alarmsQuery, alarms.nextPageLink, deferred, alarmsList);
} else {
alarmsList = $filter('orderBy')(alarmsList, ['-createdTime']);
deferred.resolve(alarmsList);
}
},
function fail() {
deferred.reject();
}
);
}
function getAlarmsByQuery(alarmsQuery) {
var deferred = $q.defer();
var time = Date.now();
var pageLink;
if (alarmsQuery.limit) {
pageLink = {
limit: alarmsQuery.limit
};
} else {
pageLink = {
limit: 100,
startTime: time - alarmsQuery.interval
};
}
fetchAlarms(alarmsQuery, pageLink, deferred);
return deferred.promise;
}
function onPollAlarms(alarmsQuery) {
getAlarmsByQuery(alarmsQuery).then(
function success(alarms) {
alarmsQuery.onAlarms(alarms);
},
function fail() {}
);
}
function pollAlarms(entityType, entityId, alarmStatus, interval, limit, pollingInterval, onAlarms) {
var alarmsQuery = {
entityType: entityType,
entityId: entityId,
alarmStatus: alarmStatus,
interval: interval,
limit: limit,
onAlarms: onAlarms
};
onPollAlarms(alarmsQuery);
return $interval(onPollAlarms, pollingInterval, 0, false, alarmsQuery);
}
function cancelPollAlarms(pollPromise) {
if (angular.isDefined(pollPromise)) {
$interval.cancel(pollPromise);
}
}
}

View File

@ -595,8 +595,8 @@ function DatasourceSubscription(datasourceSubscription, telemetryWebsocketServic
} }
series = [time, value]; series = [time, value];
data.push(series); data.push(series);
update = true;
} }
update = true;
} }
if (update) { if (update) {
datasourceData[datasourceKey].data = data; datasourceData[datasourceKey].data = data;

View File

@ -67,6 +67,7 @@ import thingsboardApiEntityRelation from './api/entity-relation.service';
import thingsboardApiAsset from './api/asset.service'; import thingsboardApiAsset from './api/asset.service';
import thingsboardApiAttribute from './api/attribute.service'; import thingsboardApiAttribute from './api/attribute.service';
import thingsboardApiEntity from './api/entity.service'; import thingsboardApiEntity from './api/entity.service';
import thingsboardApiAlarm from './api/alarm.service';
import 'typeface-roboto'; import 'typeface-roboto';
import 'font-awesome/css/font-awesome.min.css'; import 'font-awesome/css/font-awesome.min.css';
@ -124,6 +125,7 @@ angular.module('thingsboard', [
thingsboardApiAsset, thingsboardApiAsset,
thingsboardApiAttribute, thingsboardApiAttribute,
thingsboardApiEntity, thingsboardApiEntity,
thingsboardApiAlarm,
uiRouter]) uiRouter])
.config(AppConfig) .config(AppConfig)
.factory('globalInterceptor', GlobalInterceptor) .factory('globalInterceptor', GlobalInterceptor)

View File

@ -59,6 +59,12 @@ export default angular.module('thingsboard.types', [])
name: "aggregation.none" name: "aggregation.none"
} }
}, },
alarmStatus: {
activeUnack: "ACTIVE_UNACK",
activeAck: "ACTIVE_ACK",
clearedUnack: "CLEARED_UNACK",
clearedAck: "CLEARED_ACK"
},
position: { position: {
top: { top: {
value: "top", value: "top",

View File

@ -138,10 +138,10 @@ export default function DashboardController(types, dashboardUtils, widgetService
} }
vm.mainLayoutHeight = function() { vm.mainLayoutHeight = function() {
if (vm.isEditingWidget && vm.editingLayoutCtx.id === 'main') { if (!vm.isEditingWidget || vm.editingLayoutCtx.id === 'main') {
return '100%'; return '100%';
} else { } else {
return 'auto'; return '0px';
} }
} }
@ -154,10 +154,10 @@ export default function DashboardController(types, dashboardUtils, widgetService
} }
vm.rightLayoutHeight = function() { vm.rightLayoutHeight = function() {
if (vm.isEditingWidget && vm.editingLayoutCtx.id === 'right') { if (!vm.isEditingWidget || vm.editingLayoutCtx.id === 'right') {
return '100%'; return '100%';
} else { } else {
return 'auto'; return '0px';
} }
} }
@ -369,7 +369,7 @@ export default function DashboardController(types, dashboardUtils, widgetService
} }
} }
function openDashboardState(state) { function openDashboardState(state, openRightLayout) {
var layoutsData = dashboardUtils.getStateLayoutsData(vm.dashboard, state); var layoutsData = dashboardUtils.getStateLayoutsData(vm.dashboard, state);
if (layoutsData) { if (layoutsData) {
vm.dashboardCtx.state = state; vm.dashboardCtx.state = state;
@ -387,7 +387,7 @@ export default function DashboardController(types, dashboardUtils, widgetService
layoutVisibilityChanged = !vm.isMobile; layoutVisibilityChanged = !vm.isMobile;
} }
} }
vm.isRightLayoutOpened = false; vm.isRightLayoutOpened = openRightLayout ? true : false;
updateLayouts(layoutVisibilityChanged); updateLayouts(layoutVisibilityChanged);
} }

View File

@ -26,12 +26,13 @@ export default function DefaultStateController($scope, $location, $state, $state
vm.navigatePrevState = navigatePrevState; vm.navigatePrevState = navigatePrevState;
vm.getStateId = getStateId; vm.getStateId = getStateId;
vm.getStateParams = getStateParams; vm.getStateParams = getStateParams;
vm.getStateParamsByStateId = getStateParamsByStateId;
vm.getStateName = getStateName; vm.getStateName = getStateName;
vm.displayStateSelection = displayStateSelection; vm.displayStateSelection = displayStateSelection;
function openState(id, params) { function openState(id, params, openRightLayout) {
if (vm.states && vm.states[id]) { if (vm.states && vm.states[id]) {
if (!params) { if (!params) {
params = {}; params = {};
@ -42,11 +43,11 @@ export default function DefaultStateController($scope, $location, $state, $state
} }
//append new state //append new state
vm.stateObject[0] = newState; vm.stateObject[0] = newState;
gotoState(vm.stateObject[0].id, true); gotoState(vm.stateObject[0].id, true, openRightLayout);
} }
} }
function updateState(id, params) { function updateState(id, params, openRightLayout) {
if (vm.states && vm.states[id]) { if (vm.states && vm.states[id]) {
if (!params) { if (!params) {
params = {}; params = {};
@ -57,7 +58,7 @@ export default function DefaultStateController($scope, $location, $state, $state
} }
//replace with new state //replace with new state
vm.stateObject[0] = newState; vm.stateObject[0] = newState;
gotoState(vm.stateObject[0].id, true); gotoState(vm.stateObject[0].id, true, openRightLayout);
} }
} }
@ -76,6 +77,24 @@ export default function DefaultStateController($scope, $location, $state, $state
return vm.stateObject[vm.stateObject.length-1].params; return vm.stateObject[vm.stateObject.length-1].params;
} }
function getStateParamsByStateId(stateId) {
var stateObj = getStateObjById(stateId);
if (stateObj) {
return stateObj.params;
} else {
return null;
}
}
function getStateObjById(id) {
for (var i=0; i < vm.stateObject.length; i++) {
if (vm.stateObject[i].id === id) {
return vm.stateObject[i];
}
}
return null;
}
function getStateName(id, state) { function getStateName(id, state) {
var result = ''; var result = '';
var translationId = types.translate.dashboardStatePrefix + id; var translationId = types.translate.dashboardStatePrefix + id;
@ -161,9 +180,9 @@ export default function DefaultStateController($scope, $location, $state, $state
}, true); }, true);
} }
function gotoState(stateId, update) { function gotoState(stateId, update, openRightLayout) {
if (vm.dashboardCtrl.dashboardCtx.state != stateId) { if (vm.dashboardCtrl.dashboardCtx.state != stateId) {
vm.dashboardCtrl.openDashboardState(stateId); vm.dashboardCtrl.openDashboardState(stateId, openRightLayout);
if (update) { if (update) {
updateLocation(); updateLocation();
} }

View File

@ -28,12 +28,13 @@ export default function EntityStateController($scope, $location, $state, $stateP
vm.navigatePrevState = navigatePrevState; vm.navigatePrevState = navigatePrevState;
vm.getStateId = getStateId; vm.getStateId = getStateId;
vm.getStateParams = getStateParams; vm.getStateParams = getStateParams;
vm.getStateParamsByStateId = getStateParamsByStateId;
vm.getStateName = getStateName; vm.getStateName = getStateName;
vm.selectedStateIndex = -1; vm.selectedStateIndex = -1;
function openState(id, params) { function openState(id, params, openRightLayout) {
if (vm.states && vm.states[id]) { if (vm.states && vm.states[id]) {
resolveEntity(params).then( resolveEntity(params).then(
function success(entityName) { function success(entityName) {
@ -45,13 +46,13 @@ export default function EntityStateController($scope, $location, $state, $stateP
//append new state //append new state
vm.stateObject.push(newState); vm.stateObject.push(newState);
vm.selectedStateIndex = vm.stateObject.length-1; vm.selectedStateIndex = vm.stateObject.length-1;
gotoState(vm.stateObject[vm.stateObject.length-1].id, true); gotoState(vm.stateObject[vm.stateObject.length-1].id, true, openRightLayout);
} }
); );
} }
} }
function updateState(id, params) { function updateState(id, params, openRightLayout) {
if (vm.states && vm.states[id]) { if (vm.states && vm.states[id]) {
resolveEntity(params).then( resolveEntity(params).then(
function success(entityName) { function success(entityName) {
@ -62,7 +63,7 @@ export default function EntityStateController($scope, $location, $state, $stateP
} }
//replace with new state //replace with new state
vm.stateObject[vm.stateObject.length - 1] = newState; vm.stateObject[vm.stateObject.length - 1] = newState;
gotoState(vm.stateObject[vm.stateObject.length - 1].id, true); gotoState(vm.stateObject[vm.stateObject.length - 1].id, true, openRightLayout);
} }
); );
} }
@ -84,6 +85,24 @@ export default function EntityStateController($scope, $location, $state, $stateP
return vm.stateObject[vm.stateObject.length-1].params; return vm.stateObject[vm.stateObject.length-1].params;
} }
function getStateParamsByStateId(stateId) {
var stateObj = getStateObjById(stateId);
if (stateObj) {
return stateObj.params;
} else {
return null;
}
}
function getStateObjById(id) {
for (var i=0; i < vm.stateObject.length; i++) {
if (vm.stateObject[i].id === id) {
return vm.stateObject[i];
}
}
return null;
}
function getStateName(index) { function getStateName(index) {
var result = ''; var result = '';
if (vm.stateObject[index]) { if (vm.stateObject[index]) {
@ -223,9 +242,9 @@ export default function EntityStateController($scope, $location, $state, $stateP
}); });
} }
function gotoState(stateId, update) { function gotoState(stateId, update, openRightLayout) {
if (vm.dashboardCtrl.dashboardCtx.state != stateId) { if (vm.dashboardCtrl.dashboardCtx.state != stateId) {
vm.dashboardCtrl.openDashboardState(stateId); vm.dashboardCtrl.openDashboardState(stateId, openRightLayout);
if (update) { if (update) {
updateLocation(); updateLocation();
} }

View File

@ -29,15 +29,15 @@ export default function StatesComponent($compile, $templateCache, $controller, s
var stateController = scope.dashboardCtrl.dashboardCtx.stateController; var stateController = scope.dashboardCtrl.dashboardCtx.stateController;
stateController.openState = function(id, params) { stateController.openState = function(id, params, openRightLayout) {
if (scope.statesController) { if (scope.statesController) {
scope.statesController.openState(id, params); scope.statesController.openState(id, params, openRightLayout);
} }
} }
stateController.updateState = function(id, params) { stateController.updateState = function(id, params, openRightLayout) {
if (scope.statesController) { if (scope.statesController) {
scope.statesController.updateState(id, params); scope.statesController.updateState(id, params, openRightLayout);
} }
} }
@ -62,6 +62,14 @@ export default function StatesComponent($compile, $templateCache, $controller, s
return {}; return {};
} }
} }
stateController.getStateParamsByStateId = function(id) {
if (scope.statesController) {
return scope.statesController.getStateParamsByStateId(id);
} else {
return null;
}
}
} }
scope.$on('$destroy', function callOnDestroyHook() { scope.$on('$destroy', function callOnDestroyHook() {