@ -76,6 +76,7 @@ import org.thingsboard.server.common.data.kv.StringDataEntry;
import org.thingsboard.server.common.data.kv.TsKvEntry ;
import org.thingsboard.server.common.data.tenant.profile.DefaultTenantProfileConfiguration ;
import org.thingsboard.server.common.transport.adaptor.JsonConverter ;
import org.thingsboard.server.dao.service.ConstraintValidator ;
import org.thingsboard.server.dao.timeseries.TimeseriesService ;
import org.thingsboard.server.queue.util.TbCoreComponent ;
import org.thingsboard.server.service.security.AccessValidator ;
@ -184,7 +185,11 @@ public class TelemetryController extends BaseController {
public DeferredResult < ResponseEntity > getAttributeKeys (
@ApiParam ( value = ENTITY_TYPE_PARAM_DESCRIPTION , required = true , defaultValue = "DEVICE" ) @PathVariable ( "entityType" ) String entityType ,
@ApiParam ( value = ENTITY_ID_PARAM_DESCRIPTION , required = true ) @PathVariable ( "entityId" ) String entityIdStr ) throws ThingsboardException {
return accessValidator . validateEntityAndCallback ( getCurrentUser ( ) , Operation . READ_ATTRIBUTES , entityType , entityIdStr , this : : getAttributeKeysCallback ) ;
try {
return accessValidator . validateEntityAndCallback ( getCurrentUser ( ) , Operation . READ_ATTRIBUTES , entityType , entityIdStr , this : : getAttributeKeysCallback ) ;
} catch ( Exception e ) {
throw handleException ( e ) ;
}
}
@ApiOperation ( value = "Get all attribute keys by scope (getAttributeKeysByScope)" ,
@ -201,8 +206,12 @@ public class TelemetryController extends BaseController {
@ApiParam ( value = ENTITY_TYPE_PARAM_DESCRIPTION , required = true , defaultValue = "DEVICE" ) @PathVariable ( "entityType" ) String entityType ,
@ApiParam ( value = ENTITY_ID_PARAM_DESCRIPTION , required = true ) @PathVariable ( "entityId" ) String entityIdStr ,
@ApiParam ( value = ATTRIBUTES_SCOPE_DESCRIPTION , required = true , allowableValues = ATTRIBUTES_SCOPE_ALLOWED_VALUES ) @PathVariable ( "scope" ) String scope ) throws ThingsboardException {
return accessValidator . validateEntityAndCallback ( getCurrentUser ( ) , Operation . READ_ATTRIBUTES , entityType , entityIdStr ,
( result , tenantId , entityId ) - > getAttributeKeysCallback ( result , tenantId , entityId , scope ) ) ;
try {
return accessValidator . validateEntityAndCallback ( getCurrentUser ( ) , Operation . READ_ATTRIBUTES , entityType , entityIdStr ,
( result , tenantId , entityId ) - > getAttributeKeysCallback ( result , tenantId , entityId , scope ) ) ;
} catch ( Exception e ) {
throw handleException ( e ) ;
}
}
@ApiOperation ( value = "Get attributes (getAttributes)" ,
@ -220,9 +229,13 @@ public class TelemetryController extends BaseController {
@ApiParam ( value = ENTITY_TYPE_PARAM_DESCRIPTION , required = true , defaultValue = "DEVICE" ) @PathVariable ( "entityType" ) String entityType ,
@ApiParam ( value = ENTITY_ID_PARAM_DESCRIPTION , required = true ) @PathVariable ( "entityId" ) String entityIdStr ,
@ApiParam ( value = ATTRIBUTES_KEYS_DESCRIPTION ) @RequestParam ( name = "keys" , required = false ) String keysStr ) throws ThingsboardException {
SecurityUser user = getCurrentUser ( ) ;
return accessValidator . validateEntityAndCallback ( getCurrentUser ( ) , Operation . READ_ATTRIBUTES , entityType , entityIdStr ,
( result , tenantId , entityId ) - > getAttributeValuesCallback ( result , user , entityId , null , keysStr ) ) ;
try {
SecurityUser user = getCurrentUser ( ) ;
return accessValidator . validateEntityAndCallback ( getCurrentUser ( ) , Operation . READ_ATTRIBUTES , entityType , entityIdStr ,
( result , tenantId , entityId ) - > getAttributeValuesCallback ( result , user , entityId , null , keysStr ) ) ;
} catch ( Exception e ) {
throw handleException ( e ) ;
}
}
@ -244,9 +257,13 @@ public class TelemetryController extends BaseController {
@ApiParam ( value = ENTITY_ID_PARAM_DESCRIPTION , required = true ) @PathVariable ( "entityId" ) String entityIdStr ,
@ApiParam ( value = ATTRIBUTES_SCOPE_DESCRIPTION , allowableValues = ATTRIBUTES_SCOPE_ALLOWED_VALUES , required = true ) @PathVariable ( "scope" ) String scope ,
@ApiParam ( value = ATTRIBUTES_KEYS_DESCRIPTION ) @RequestParam ( name = "keys" , required = false ) String keysStr ) throws ThingsboardException {
SecurityUser user = getCurrentUser ( ) ;
return accessValidator . validateEntityAndCallback ( getCurrentUser ( ) , Operation . READ_ATTRIBUTES , entityType , entityIdStr ,
( result , tenantId , entityId ) - > getAttributeValuesCallback ( result , user , entityId , scope , keysStr ) ) ;
try {
SecurityUser user = getCurrentUser ( ) ;
return accessValidator . validateEntityAndCallback ( getCurrentUser ( ) , Operation . READ_ATTRIBUTES , entityType , entityIdStr ,
( result , tenantId , entityId ) - > getAttributeValuesCallback ( result , user , entityId , scope , keysStr ) ) ;
} catch ( Exception e ) {
throw handleException ( e ) ;
}
}
@ApiOperation ( value = "Get time-series keys (getTimeseriesKeys)" ,
@ -259,8 +276,12 @@ public class TelemetryController extends BaseController {
public DeferredResult < ResponseEntity > getTimeseriesKeys (
@ApiParam ( value = ENTITY_TYPE_PARAM_DESCRIPTION , required = true , defaultValue = "DEVICE" ) @PathVariable ( "entityType" ) String entityType ,
@ApiParam ( value = ENTITY_ID_PARAM_DESCRIPTION , required = true ) @PathVariable ( "entityId" ) String entityIdStr ) throws ThingsboardException {
return accessValidator . validateEntityAndCallback ( getCurrentUser ( ) , Operation . READ_TELEMETRY , entityType , entityIdStr ,
( result , tenantId , entityId ) - > Futures . addCallback ( tsService . findAllLatest ( tenantId , entityId ) , getTsKeysToResponseCallback ( result ) , MoreExecutors . directExecutor ( ) ) ) ;
try {
return accessValidator . validateEntityAndCallback ( getCurrentUser ( ) , Operation . READ_TELEMETRY , entityType , entityIdStr ,
( result , tenantId , entityId ) - > Futures . addCallback ( tsService . findAllLatest ( tenantId , entityId ) , getTsKeysToResponseCallback ( result ) , MoreExecutors . directExecutor ( ) ) ) ;
} catch ( Exception e ) {
throw handleException ( e ) ;
}
}
@ApiOperation ( value = "Get latest time-series value (getLatestTimeseries)" ,
@ -285,9 +306,13 @@ public class TelemetryController extends BaseController {
@ApiParam ( value = TELEMETRY_KEYS_DESCRIPTION ) @RequestParam ( name = "keys" , required = false ) String keysStr ,
@ApiParam ( value = STRICT_DATA_TYPES_DESCRIPTION )
@RequestParam ( name = "useStrictDataTypes" , required = false , defaultValue = "false" ) Boolean useStrictDataTypes ) throws ThingsboardException {
SecurityUser user = getCurrentUser ( ) ;
return accessValidator . validateEntityAndCallback ( getCurrentUser ( ) , Operation . READ_TELEMETRY , entityType , entityIdStr ,
( result , tenantId , entityId ) - > getLatestTimeseriesValuesCallback ( result , user , entityId , keysStr , useStrictDataTypes ) ) ;
try {
SecurityUser user = getCurrentUser ( ) ;
return accessValidator . validateEntityAndCallback ( getCurrentUser ( ) , Operation . READ_TELEMETRY , entityType , entityIdStr ,
( result , tenantId , entityId ) - > getLatestTimeseriesValuesCallback ( result , user , entityId , keysStr , useStrictDataTypes ) ) ;
} catch ( Exception e ) {
throw handleException ( e ) ;
}
}
@ApiOperation ( value = "Get time-series data (getTimeseries)" ,
@ -324,15 +349,19 @@ public class TelemetryController extends BaseController {
@RequestParam ( name = "orderBy" , defaultValue = "DESC" ) String orderBy ,
@ApiParam ( value = STRICT_DATA_TYPES_DESCRIPTION )
@RequestParam ( name = "useStrictDataTypes" , required = false , defaultValue = "false" ) Boolean useStrictDataTypes ) throws ThingsboardException {
return accessValidator . validateEntityAndCallback ( getCurrentUser ( ) , Operation . READ_TELEMETRY , entityType , entityIdStr ,
( result , tenantId , entityId ) - > {
// If interval is 0, convert this to a NONE aggregation, which is probably what the user really wanted
Aggregation agg = interval = = 0L ? Aggregation . valueOf ( Aggregation . NONE . name ( ) ) : Aggregation . valueOf ( aggStr ) ;
List < ReadTsKvQuery > queries = toKeysList ( keys ) . stream ( ) . map ( key - > new BaseReadTsKvQuery ( key , startTs , endTs , interval , limit , agg , orderBy ) )
. collect ( Collectors . toList ( ) ) ;
Futures . addCallback ( tsService . findAll ( tenantId , entityId , queries ) , getTsKvListCallback ( result , useStrictDataTypes ) , MoreExecutors . directExecutor ( ) ) ;
} ) ;
try {
return accessValidator . validateEntityAndCallback ( getCurrentUser ( ) , Operation . READ_TELEMETRY , entityType , entityIdStr ,
( result , tenantId , entityId ) - > {
// If interval is 0, convert this to a NONE aggregation, which is probably what the user really wanted
Aggregation agg = interval = = 0L ? Aggregation . valueOf ( Aggregation . NONE . name ( ) ) : Aggregation . valueOf ( aggStr ) ;
List < ReadTsKvQuery > queries = toKeysList ( keys ) . stream ( ) . map ( key - > new BaseReadTsKvQuery ( key , startTs , endTs , interval , limit , agg , orderBy ) )
. collect ( Collectors . toList ( ) ) ;
Futures . addCallback ( tsService . findAll ( tenantId , entityId , queries ) , getTsKvListCallback ( result , useStrictDataTypes ) , MoreExecutors . directExecutor ( ) ) ;
} ) ;
} catch ( Exception e ) {
throw handleException ( e ) ;
}
}
@ApiOperation ( value = "Save device attributes (saveDeviceAttributes)" ,
@ -356,8 +385,12 @@ public class TelemetryController extends BaseController {
@ApiParam ( value = DEVICE_ID_PARAM_DESCRIPTION , required = true ) @PathVariable ( "deviceId" ) String deviceIdStr ,
@ApiParam ( value = ATTRIBUTES_SCOPE_DESCRIPTION , allowableValues = ATTRIBUTES_SCOPE_ALLOWED_VALUES , required = true ) @PathVariable ( "scope" ) String scope ,
@ApiParam ( value = ATTRIBUTES_JSON_REQUEST_DESCRIPTION , required = true ) @RequestBody JsonNode request ) throws ThingsboardException {
EntityId entityId = EntityIdFactory . getByTypeAndUuid ( EntityType . DEVICE , deviceIdStr ) ;
return saveAttributes ( getTenantId ( ) , entityId , scope , request ) ;
try {
EntityId entityId = EntityIdFactory . getByTypeAndUuid ( EntityType . DEVICE , deviceIdStr ) ;
return saveAttributes ( getTenantId ( ) , entityId , scope , request ) ;
} catch ( Exception e ) {
throw handleException ( e ) ;
}
}
@ApiOperation ( value = "Save entity attributes (saveEntityAttributesV1)" ,
@ -380,8 +413,12 @@ public class TelemetryController extends BaseController {
@ApiParam ( value = ENTITY_ID_PARAM_DESCRIPTION , required = true ) @PathVariable ( "entityId" ) String entityIdStr ,
@ApiParam ( value = ATTRIBUTES_SCOPE_DESCRIPTION , allowableValues = ATTRIBUTES_SCOPE_ALLOWED_VALUES ) @PathVariable ( "scope" ) String scope ,
@ApiParam ( value = ATTRIBUTES_JSON_REQUEST_DESCRIPTION , required = true ) @RequestBody JsonNode request ) throws ThingsboardException {
EntityId entityId = EntityIdFactory . getByTypeAndId ( entityType , entityIdStr ) ;
return saveAttributes ( getTenantId ( ) , entityId , scope , request ) ;
try {
EntityId entityId = EntityIdFactory . getByTypeAndId ( entityType , entityIdStr ) ;
return saveAttributes ( getTenantId ( ) , entityId , scope , request ) ;
} catch ( Exception e ) {
throw handleException ( e ) ;
}
}
@ApiOperation ( value = "Save entity attributes (saveEntityAttributesV2)" ,
@ -404,8 +441,12 @@ public class TelemetryController extends BaseController {
@ApiParam ( value = ENTITY_ID_PARAM_DESCRIPTION , required = true ) @PathVariable ( "entityId" ) String entityIdStr ,
@ApiParam ( value = ATTRIBUTES_SCOPE_DESCRIPTION , allowableValues = ATTRIBUTES_SCOPE_ALLOWED_VALUES , required = true ) @PathVariable ( "scope" ) String scope ,
@ApiParam ( value = ATTRIBUTES_JSON_REQUEST_DESCRIPTION , required = true ) @RequestBody JsonNode request ) throws ThingsboardException {
EntityId entityId = EntityIdFactory . getByTypeAndId ( entityType , entityIdStr ) ;
return saveAttributes ( getTenantId ( ) , entityId , scope , request ) ;
try {
EntityId entityId = EntityIdFactory . getByTypeAndId ( entityType , entityIdStr ) ;
return saveAttributes ( getTenantId ( ) , entityId , scope , request ) ;
} catch ( Exception e ) {
throw handleException ( e ) ;
}
}
@ -429,8 +470,12 @@ public class TelemetryController extends BaseController {
@ApiParam ( value = ENTITY_ID_PARAM_DESCRIPTION , required = true ) @PathVariable ( "entityId" ) String entityIdStr ,
@ApiParam ( value = TELEMETRY_SCOPE_DESCRIPTION , required = true , allowableValues = "ANY" ) @PathVariable ( "scope" ) String scope ,
@ApiParam ( value = TELEMETRY_JSON_REQUEST_DESCRIPTION , required = true ) @RequestBody String requestBody ) throws ThingsboardException {
EntityId entityId = EntityIdFactory . getByTypeAndId ( entityType , entityIdStr ) ;
return saveTelemetry ( getTenantId ( ) , entityId , requestBody , 0L ) ;
try {
EntityId entityId = EntityIdFactory . getByTypeAndId ( entityType , entityIdStr ) ;
return saveTelemetry ( getTenantId ( ) , entityId , requestBody , 0L ) ;
} catch ( Exception e ) {
throw handleException ( e ) ;
}
}
@ApiOperation ( value = "Save or update time-series data with TTL (saveEntityTelemetryWithTTL)" ,
@ -455,8 +500,12 @@ public class TelemetryController extends BaseController {
@ApiParam ( value = TELEMETRY_SCOPE_DESCRIPTION , required = true , allowableValues = "ANY" ) @PathVariable ( "scope" ) String scope ,
@ApiParam ( value = "A long value representing TTL (Time to Live) parameter." , required = true ) @PathVariable ( "ttl" ) Long ttl ,
@ApiParam ( value = TELEMETRY_JSON_REQUEST_DESCRIPTION , required = true ) @RequestBody String requestBody ) throws ThingsboardException {
EntityId entityId = EntityIdFactory . getByTypeAndId ( entityType , entityIdStr ) ;
return saveTelemetry ( getTenantId ( ) , entityId , requestBody , ttl ) ;
try {
EntityId entityId = EntityIdFactory . getByTypeAndId ( entityType , entityIdStr ) ;
return saveTelemetry ( getTenantId ( ) , entityId , requestBody , ttl ) ;
} catch ( Exception e ) {
throw handleException ( e ) ;
}
}
@ApiOperation ( value = "Delete entity time-series data (deleteEntityTimeseries)" ,
@ -489,8 +538,12 @@ public class TelemetryController extends BaseController {
@RequestParam ( name = "endTs" , required = false ) Long endTs ,
@ApiParam ( value = "If the parameter is set to true, the latest telemetry will be rewritten in case that current latest value was removed, otherwise, in case that parameter is set to false the new latest value will not set." )
@RequestParam ( name = "rewriteLatestIfDeleted" , defaultValue = "false" ) boolean rewriteLatestIfDeleted ) throws ThingsboardException {
EntityId entityId = EntityIdFactory . getByTypeAndId ( entityType , entityIdStr ) ;
return deleteTimeseries ( entityId , keysStr , deleteAllDataForKeys , startTs , endTs , rewriteLatestIfDeleted ) ;
try {
EntityId entityId = EntityIdFactory . getByTypeAndId ( entityType , entityIdStr ) ;
return deleteTimeseries ( entityId , keysStr , deleteAllDataForKeys , startTs , endTs , rewriteLatestIfDeleted ) ;
} catch ( Exception e ) {
throw handleException ( e ) ;
}
}
private DeferredResult < ResponseEntity > deleteTimeseries ( EntityId entityIdStr , String keysStr , boolean deleteAllDataForKeys ,
@ -556,8 +609,12 @@ public class TelemetryController extends BaseController {
@ApiParam ( value = DEVICE_ID_PARAM_DESCRIPTION , required = true ) @PathVariable ( DEVICE_ID ) String deviceIdStr ,
@ApiParam ( value = ATTRIBUTES_SCOPE_DESCRIPTION , allowableValues = ATTRIBUTES_SCOPE_ALLOWED_VALUES , required = true ) @PathVariable ( "scope" ) String scope ,
@ApiParam ( value = ATTRIBUTES_KEYS_DESCRIPTION , required = true ) @RequestParam ( name = "keys" ) String keysStr ) throws ThingsboardException {
EntityId entityId = EntityIdFactory . getByTypeAndUuid ( EntityType . DEVICE , deviceIdStr ) ;
return deleteAttributes ( entityId , scope , keysStr ) ;
try {
EntityId entityId = EntityIdFactory . getByTypeAndUuid ( EntityType . DEVICE , deviceIdStr ) ;
return deleteAttributes ( entityId , scope , keysStr ) ;
} catch ( Exception e ) {
throw handleException ( e ) ;
}
}
@ApiOperation ( value = "Delete entity attributes (deleteEntityAttributes)" ,
@ -580,8 +637,12 @@ public class TelemetryController extends BaseController {
@ApiParam ( value = ENTITY_ID_PARAM_DESCRIPTION , required = true ) @PathVariable ( "entityId" ) String entityIdStr ,
@ApiParam ( value = ATTRIBUTES_SCOPE_DESCRIPTION , required = true , allowableValues = ATTRIBUTES_SCOPE_ALLOWED_VALUES ) @PathVariable ( "scope" ) String scope ,
@ApiParam ( value = ATTRIBUTES_KEYS_DESCRIPTION , required = true ) @RequestParam ( name = "keys" ) String keysStr ) throws ThingsboardException {
EntityId entityId = EntityIdFactory . getByTypeAndId ( entityType , entityIdStr ) ;
return deleteAttributes ( entityId , scope , keysStr ) ;
try {
EntityId entityId = EntityIdFactory . getByTypeAndId ( entityType , entityIdStr ) ;
return deleteAttributes ( entityId , scope , keysStr ) ;
} catch ( Exception e ) {
throw handleException ( e ) ;
}
}
private DeferredResult < ResponseEntity > deleteAttributes ( EntityId entityIdSrc , String scope , String keysStr ) throws ThingsboardException {
@ -627,6 +688,7 @@ public class TelemetryController extends BaseController {
}
if ( json . isObject ( ) ) {
List < AttributeKvEntry > attributes = extractRequestAttributes ( json ) ;
attributes . forEach ( ConstraintValidator : : validateFields ) ;
if ( attributes . isEmpty ( ) ) {
return getImmediateDeferredResult ( "No attributes data found in request body!" , HttpStatus . BAD_REQUEST ) ;
}