Merge branch 'master' into develop/3.0
This commit is contained in:
commit
7e8c90ec6d
@ -120,7 +120,9 @@ public class AlarmController extends BaseController {
|
||||
try {
|
||||
AlarmId alarmId = new AlarmId(toUUID(strAlarmId));
|
||||
Alarm alarm = checkAlarmId(alarmId, Operation.WRITE);
|
||||
alarmService.ackAlarm(getCurrentUser().getTenantId(), alarmId, System.currentTimeMillis()).get();
|
||||
long ackTs = System.currentTimeMillis();
|
||||
alarmService.ackAlarm(getCurrentUser().getTenantId(), alarmId, ackTs).get();
|
||||
alarm.setAckTs(ackTs);
|
||||
logEntityAction(alarmId, alarm, getCurrentUser().getCustomerId(), ActionType.ALARM_ACK, null);
|
||||
} catch (Exception e) {
|
||||
throw handleException(e);
|
||||
@ -135,7 +137,9 @@ public class AlarmController extends BaseController {
|
||||
try {
|
||||
AlarmId alarmId = new AlarmId(toUUID(strAlarmId));
|
||||
Alarm alarm = checkAlarmId(alarmId, Operation.WRITE);
|
||||
alarmService.clearAlarm(getCurrentUser().getTenantId(), alarmId, null, System.currentTimeMillis()).get();
|
||||
long clearTs = System.currentTimeMillis();
|
||||
alarmService.clearAlarm(getCurrentUser().getTenantId(), alarmId, null, clearTs).get();
|
||||
alarm.setClearTs(clearTs);
|
||||
logEntityAction(alarmId, alarm, getCurrentUser().getCustomerId(), ActionType.ALARM_CLEAR, null);
|
||||
} catch (Exception e) {
|
||||
throw handleException(e);
|
||||
|
||||
@ -24,13 +24,11 @@ import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.thingsboard.server.common.data.alarm.Alarm;
|
||||
import org.thingsboard.server.common.data.audit.ActionType;
|
||||
import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
|
||||
import org.thingsboard.server.common.data.exception.ThingsboardException;
|
||||
import org.thingsboard.server.common.data.id.EntityId;
|
||||
import org.thingsboard.server.common.data.id.EntityIdFactory;
|
||||
import org.thingsboard.server.common.data.id.UUIDBased;
|
||||
import org.thingsboard.server.common.data.relation.EntityRelation;
|
||||
import org.thingsboard.server.common.data.relation.EntityRelationInfo;
|
||||
import org.thingsboard.server.common.data.relation.EntityRelationsQuery;
|
||||
@ -38,6 +36,7 @@ import org.thingsboard.server.common.data.relation.RelationTypeGroup;
|
||||
import org.thingsboard.server.service.security.permission.Operation;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
@RestController
|
||||
@ -167,7 +166,7 @@ public class EntityRelationController extends BaseController {
|
||||
checkEntityId(entityId, Operation.READ);
|
||||
RelationTypeGroup typeGroup = parseRelationTypeGroup(strRelationTypeGroup, RelationTypeGroup.COMMON);
|
||||
try {
|
||||
return checkNotNull(relationService.findByFrom(getTenantId(), entityId, typeGroup));
|
||||
return checkNotNull(filterRelationsByReadPermission(relationService.findByFrom(getTenantId(), entityId, typeGroup)));
|
||||
} catch (Exception e) {
|
||||
throw handleException(e);
|
||||
}
|
||||
@ -185,7 +184,7 @@ public class EntityRelationController extends BaseController {
|
||||
checkEntityId(entityId, Operation.READ);
|
||||
RelationTypeGroup typeGroup = parseRelationTypeGroup(strRelationTypeGroup, RelationTypeGroup.COMMON);
|
||||
try {
|
||||
return checkNotNull(relationService.findInfoByFrom(getTenantId(), entityId, typeGroup).get());
|
||||
return checkNotNull(filterRelationsByReadPermission(relationService.findInfoByFrom(getTenantId(), entityId, typeGroup).get()));
|
||||
} catch (Exception e) {
|
||||
throw handleException(e);
|
||||
}
|
||||
@ -205,7 +204,7 @@ public class EntityRelationController extends BaseController {
|
||||
checkEntityId(entityId, Operation.READ);
|
||||
RelationTypeGroup typeGroup = parseRelationTypeGroup(strRelationTypeGroup, RelationTypeGroup.COMMON);
|
||||
try {
|
||||
return checkNotNull(relationService.findByFromAndType(getTenantId(), entityId, strRelationType, typeGroup));
|
||||
return checkNotNull(filterRelationsByReadPermission(relationService.findByFromAndType(getTenantId(), entityId, strRelationType, typeGroup)));
|
||||
} catch (Exception e) {
|
||||
throw handleException(e);
|
||||
}
|
||||
@ -223,7 +222,7 @@ public class EntityRelationController extends BaseController {
|
||||
checkEntityId(entityId, Operation.READ);
|
||||
RelationTypeGroup typeGroup = parseRelationTypeGroup(strRelationTypeGroup, RelationTypeGroup.COMMON);
|
||||
try {
|
||||
return checkNotNull(relationService.findByTo(getTenantId(), entityId, typeGroup));
|
||||
return checkNotNull(filterRelationsByReadPermission(relationService.findByTo(getTenantId(), entityId, typeGroup)));
|
||||
} catch (Exception e) {
|
||||
throw handleException(e);
|
||||
}
|
||||
@ -241,7 +240,7 @@ public class EntityRelationController extends BaseController {
|
||||
checkEntityId(entityId, Operation.READ);
|
||||
RelationTypeGroup typeGroup = parseRelationTypeGroup(strRelationTypeGroup, RelationTypeGroup.COMMON);
|
||||
try {
|
||||
return checkNotNull(relationService.findInfoByTo(getTenantId(), entityId, typeGroup).get());
|
||||
return checkNotNull(filterRelationsByReadPermission(relationService.findInfoByTo(getTenantId(), entityId, typeGroup).get()));
|
||||
} catch (Exception e) {
|
||||
throw handleException(e);
|
||||
}
|
||||
@ -261,7 +260,7 @@ public class EntityRelationController extends BaseController {
|
||||
checkEntityId(entityId, Operation.READ);
|
||||
RelationTypeGroup typeGroup = parseRelationTypeGroup(strRelationTypeGroup, RelationTypeGroup.COMMON);
|
||||
try {
|
||||
return checkNotNull(relationService.findByToAndType(getTenantId(), entityId, strRelationType, typeGroup));
|
||||
return checkNotNull(filterRelationsByReadPermission(relationService.findByToAndType(getTenantId(), entityId, strRelationType, typeGroup)));
|
||||
} catch (Exception e) {
|
||||
throw handleException(e);
|
||||
}
|
||||
@ -276,7 +275,7 @@ public class EntityRelationController extends BaseController {
|
||||
checkNotNull(query.getFilters());
|
||||
checkEntityId(query.getParameters().getEntityId(), Operation.READ);
|
||||
try {
|
||||
return checkNotNull(relationService.findByQuery(getTenantId(), query).get());
|
||||
return checkNotNull(filterRelationsByReadPermission(relationService.findByQuery(getTenantId(), query).get()));
|
||||
} catch (Exception e) {
|
||||
throw handleException(e);
|
||||
}
|
||||
@ -291,12 +290,28 @@ public class EntityRelationController extends BaseController {
|
||||
checkNotNull(query.getFilters());
|
||||
checkEntityId(query.getParameters().getEntityId(), Operation.READ);
|
||||
try {
|
||||
return checkNotNull(relationService.findInfoByQuery(getTenantId(), query).get());
|
||||
return checkNotNull(filterRelationsByReadPermission(relationService.findInfoByQuery(getTenantId(), query).get()));
|
||||
} catch (Exception e) {
|
||||
throw handleException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private <T extends EntityRelation> List<T> filterRelationsByReadPermission(List<T> relationsByQuery) {
|
||||
return relationsByQuery.stream().filter(relationByQuery -> {
|
||||
try {
|
||||
checkEntityId(relationByQuery.getTo(), Operation.READ);
|
||||
} catch (ThingsboardException e) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
checkEntityId(relationByQuery.getFrom(), Operation.READ);
|
||||
} catch (ThingsboardException e) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private RelationTypeGroup parseRelationTypeGroup(String strRelationTypeGroup, RelationTypeGroup defaultValue) {
|
||||
RelationTypeGroup result = defaultValue;
|
||||
if (strRelationTypeGroup != null && strRelationTypeGroup.trim().length() > 0) {
|
||||
|
||||
@ -39,7 +39,7 @@ public interface AlarmService {
|
||||
|
||||
ListenableFuture<Boolean> ackAlarm(TenantId tenantId, AlarmId alarmId, long ackTs);
|
||||
|
||||
ListenableFuture<Boolean> clearAlarm(TenantId tenantId, AlarmId alarmId, JsonNode details, long ackTs);
|
||||
ListenableFuture<Boolean> clearAlarm(TenantId tenantId, AlarmId alarmId, JsonNode details, long clearTs);
|
||||
|
||||
ListenableFuture<Alarm> findAlarmByIdAsync(TenantId tenantId, AlarmId alarmId);
|
||||
|
||||
|
||||
@ -407,8 +407,12 @@ final class MqttClientImpl implements MqttClient {
|
||||
}
|
||||
|
||||
private MqttMessageIdVariableHeader getNewMessageId() {
|
||||
this.nextMessageId.compareAndSet(0xffff, 1);
|
||||
return MqttMessageIdVariableHeader.from(this.nextMessageId.getAndIncrement());
|
||||
int messageId;
|
||||
synchronized (this.nextMessageId) {
|
||||
this.nextMessageId.compareAndSet(0xffff, 1);
|
||||
messageId = this.nextMessageId.getAndIncrement();
|
||||
}
|
||||
return MqttMessageIdVariableHeader.from(messageId);
|
||||
}
|
||||
|
||||
private Future<Void> createSubscription(String topic, MqttHandler handler, boolean once, MqttQoS qos) {
|
||||
|
||||
@ -55,7 +55,7 @@ while :
|
||||
echo "Done"
|
||||
exit 0
|
||||
;;
|
||||
[yY]|[yY][eE]|[yY][eE]|[sS]|[yY]|"")
|
||||
[yY]|[yY][eE]|[yY][eE][sS]|"")
|
||||
echo "Cleaning up files"
|
||||
rm -rf $CLIENT_FILE_PREFIX.jks
|
||||
rm -rf $CLIENT_FILE_PREFIX.pub.pem
|
||||
|
||||
@ -71,7 +71,7 @@ while :
|
||||
echo "Done"
|
||||
exit 0
|
||||
;;
|
||||
[yY]|[yY][eE]|[yY][eE]|[sS]|[yY]|"")
|
||||
[yY]|[yY][eE]|[yY][eE][sS]|"")
|
||||
echo "Cleaning up files"
|
||||
rm -rf $SERVER_FILE_PREFIX.jks
|
||||
rm -rf $SERVER_FILE_PREFIX.pub.pem
|
||||
@ -129,7 +129,7 @@ if [[ $COPY = true ]]; then
|
||||
[nN]|[nN][oO])
|
||||
break
|
||||
;;
|
||||
[yY]|[yY][eE]|[yY][eE]|[sS]|[yY]|"")
|
||||
[yY]|[yY][eE]|[yY][eE][sS]|"")
|
||||
read -p "(Default: $SERVER_KEYSTORE_DIR): " dir
|
||||
if [[ ! -z $dir ]]; then
|
||||
DESTINATION=$dir;
|
||||
|
||||
@ -616,7 +616,7 @@ export default class TbMapWidgetV2 {
|
||||
locationChanged = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
} else if (latData.length > 0 && lngData.length > 0) {
|
||||
// Create or update marker
|
||||
lat = latData[latData.length - 1][1];
|
||||
lng = lngData[lngData.length - 1][1];
|
||||
|
||||
@ -31,10 +31,6 @@ tb-timeseries-table-widget {
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
md-table-container {
|
||||
overflow-x: visible;
|
||||
}
|
||||
|
||||
md-tabs:not(.md-no-tab-content):not(.md-dynamic-height) {
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
@ -38,56 +38,58 @@
|
||||
</div>
|
||||
</md-toolbar>
|
||||
|
||||
<md-tabs flex md-selected="vm.sourceIndex" ng-class="{'tb-headless': vm.sources.length === 1}"
|
||||
<md-tabs md-selected="vm.sourceIndex" ng-class="{'tb-headless': vm.sources.length === 1}"
|
||||
id="tabs" md-border-bottom flex>
|
||||
<md-tab ng-repeat="source in vm.sources" label="{{ source.datasource.name }}">
|
||||
<md-table-container class="flex">
|
||||
<table md-table>
|
||||
<thead fix-head md-head md-order="source.query.order" md-on-reorder="vm.onReorder(source)">
|
||||
<tr md-row>
|
||||
<th ng-show="vm.showTimestamp"
|
||||
md-column md-order-by="0"
|
||||
>
|
||||
<span>Timestamp</span>
|
||||
</th>
|
||||
<th md-column
|
||||
md-order-by="{{ h.index }}"
|
||||
ng-repeat="h in source.ts.header"
|
||||
>
|
||||
<span>{{ h.dataKey.label }}</span>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<div class="tb-absolute-fill" layout="column">
|
||||
<md-table-container flex>
|
||||
<table md-table>
|
||||
<thead fix-head md-head md-order="source.query.order" md-on-reorder="vm.onReorder(source)">
|
||||
<tr md-row>
|
||||
<th ng-show="vm.showTimestamp"
|
||||
md-column md-order-by="0"
|
||||
>
|
||||
<span>Timestamp</span>
|
||||
</th>
|
||||
<th md-column
|
||||
md-order-by="{{ h.index }}"
|
||||
ng-repeat="h in source.ts.header"
|
||||
>
|
||||
<span>{{ h.dataKey.label }}</span>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody md-body>
|
||||
<tr md-row ng-repeat="row in source.ts.data track by $index" ng-click="vm.onRowClick($event, row)">
|
||||
<td ng-show="$index > 0 || ($index === 0 && vm.showTimestamp)"
|
||||
md-cell
|
||||
ng-repeat="d in row track by $index"
|
||||
ng-style="vm.cellStyle(source, $index, d)"
|
||||
ng-bind-html="vm.cellContent(source, $index, row, d)"
|
||||
></td>
|
||||
<td md-cell class="tb-action-cell"
|
||||
ng-style="{minWidth: vm.actionCellDescriptors.length*36+'px',
|
||||
maxWidth: vm.actionCellDescriptors.length*36+'px',
|
||||
width: vm.actionCellDescriptors.length*36+'px'}">
|
||||
<md-button class="md-icon-button" ng-repeat="actionDescriptor in vm.actionCellDescriptors"
|
||||
aria-label="{{ actionDescriptor.displayName }}"
|
||||
ng-click="vm.onActionButtonClick($event, row, actionDescriptor)" ng-disabled="$root.loading">
|
||||
<md-icon aria-label="{{ actionDescriptor.displayName }}" class="material-icons">{{actionDescriptor.icon}}</md-icon>
|
||||
<md-tooltip md-direction="top">
|
||||
{{ actionDescriptor.displayName }}
|
||||
</md-tooltip>
|
||||
</md-button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<md-divider></md-divider>
|
||||
<span ng-show="!vm.sources[vm.sourceIndex].data.length"
|
||||
layout-align="center center"
|
||||
class="no-data-found" translate>widget.no-data-found</span>
|
||||
</md-table-container>
|
||||
<tbody md-body>
|
||||
<tr md-row ng-repeat="row in source.ts.data track by $index" ng-click="vm.onRowClick($event, row)">
|
||||
<td ng-show="$index > 0 || ($index === 0 && vm.showTimestamp)"
|
||||
md-cell
|
||||
ng-repeat="d in row track by $index"
|
||||
ng-style="vm.cellStyle(source, $index, d)"
|
||||
ng-bind-html="vm.cellContent(source, $index, row, d)"
|
||||
></td>
|
||||
<td md-cell class="tb-action-cell"
|
||||
ng-style="{minWidth: vm.actionCellDescriptors.length*36+'px',
|
||||
maxWidth: vm.actionCellDescriptors.length*36+'px',
|
||||
width: vm.actionCellDescriptors.length*36+'px'}">
|
||||
<md-button class="md-icon-button" ng-repeat="actionDescriptor in vm.actionCellDescriptors"
|
||||
aria-label="{{ actionDescriptor.displayName }}"
|
||||
ng-click="vm.onActionButtonClick($event, row, actionDescriptor)" ng-disabled="$root.loading">
|
||||
<md-icon aria-label="{{ actionDescriptor.displayName }}" class="material-icons">{{actionDescriptor.icon}}</md-icon>
|
||||
<md-tooltip md-direction="top">
|
||||
{{ actionDescriptor.displayName }}
|
||||
</md-tooltip>
|
||||
</md-button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<md-divider></md-divider>
|
||||
<span ng-show="!vm.sources[vm.sourceIndex].data.length"
|
||||
layout-align="center center"
|
||||
class="no-data-found" translate>widget.no-data-found</span>
|
||||
</md-table-container>
|
||||
</div>
|
||||
</md-tab>
|
||||
</md-tabs>
|
||||
<md-table-pagination ng-if="vm.displayPagination"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user