@ -51,7 +51,7 @@ import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.common.util.ThingsBoardThreadFactory ;
import org.thingsboard.rule.engine.api.msg.DeviceAttributesEventNotificationMsg ;
import org.thingsboard.server.common.adaptor.JsonConverter ;
import org.thingsboard.server.common.data.DataConstants ;
import org.thingsboard.server.common.data.AttributeScope ;
import org.thingsboard.server.common.data.EntityType ;
import org.thingsboard.server.common.data.StringUtils ;
import org.thingsboard.server.common.data.TenantProfile ;
@ -198,7 +198,7 @@ public class TelemetryController extends BaseController {
public DeferredResult < ResponseEntity > getAttributeKeysByScope (
@Parameter ( description = ENTITY_TYPE_PARAM_DESCRIPTION , required = true , schema = @Schema ( defaultValue = "DEVICE" ) ) @PathVariable ( "entityType" ) String entityType ,
@Parameter ( description = ENTITY_ID_PARAM_DESCRIPTION , required = true ) @PathVariable ( "entityId" ) String entityIdStr ,
@Parameter ( description = ATTRIBUTES_SCOPE_DESCRIPTION , required = true , schema = @Schema ( allowableValues = { "SERVER_SCOPE" , "SHARED_SCOPE" , "CLIENT_SCOPE" } ) ) @PathVariable ( "scope" ) String scope ) throws ThingsboardException {
@Parameter ( description = ATTRIBUTES_SCOPE_DESCRIPTION , required = true , schema = @Schema ( allowableValues = { "SERVER_SCOPE" , "SHARED_SCOPE" , "CLIENT_SCOPE" } ) ) @PathVariable ( "scope" ) AttributeScope scope ) throws ThingsboardException {
return accessValidator . validateEntityAndCallback ( getCurrentUser ( ) , Operation . READ_ATTRIBUTES , entityType , entityIdStr ,
( result , tenantId , entityId ) - > getAttributeKeysCallback ( result , tenantId , entityId , scope ) ) ;
}
@ -240,7 +240,7 @@ public class TelemetryController extends BaseController {
public DeferredResult < ResponseEntity > getAttributesByScope (
@Parameter ( description = ENTITY_TYPE_PARAM_DESCRIPTION , required = true , schema = @Schema ( defaultValue = "DEVICE" ) ) @PathVariable ( "entityType" ) String entityType ,
@Parameter ( description = ENTITY_ID_PARAM_DESCRIPTION , required = true ) @PathVariable ( "entityId" ) String entityIdStr ,
@Parameter ( description = ATTRIBUTES_SCOPE_DESCRIPTION , schema = @Schema ( allowableValues = { "SERVER_SCOPE" , "SHARED_SCOPE" , "CLIENT_SCOPE" } , required = true ) ) @PathVariable ( "scope" ) String scope ,
@Parameter ( description = ATTRIBUTES_SCOPE_DESCRIPTION , schema = @Schema ( allowableValues = { "SERVER_SCOPE" , "SHARED_SCOPE" , "CLIENT_SCOPE" } , required = true ) ) @PathVariable ( "scope" ) AttributeScope scope ,
@Parameter ( description = ATTRIBUTES_KEYS_DESCRIPTION ) @RequestParam ( name = "keys" , required = false ) String keysStr ) throws ThingsboardException {
SecurityUser user = getCurrentUser ( ) ;
return accessValidator . validateEntityAndCallback ( getCurrentUser ( ) , Operation . READ_ATTRIBUTES , entityType , entityIdStr ,
@ -352,7 +352,7 @@ public class TelemetryController extends BaseController {
@ResponseBody
public DeferredResult < ResponseEntity > saveDeviceAttributes (
@Parameter ( description = DEVICE_ID_PARAM_DESCRIPTION , required = true ) @PathVariable ( "deviceId" ) String deviceIdStr ,
@Parameter ( description = ATTRIBUTES_SCOPE_DESCRIPTION , schema = @Schema ( allowableValues = { "SERVER_SCOPE" , "SHARED_SCOPE" } , required = true ) ) @PathVariable ( "scope" ) String scope ,
@Parameter ( description = ATTRIBUTES_SCOPE_DESCRIPTION , schema = @Schema ( allowableValues = { "SERVER_SCOPE" , "SHARED_SCOPE" } , required = true ) ) @PathVariable ( "scope" ) AttributeScope scope ,
@Parameter ( description = ATTRIBUTES_JSON_REQUEST_DESCRIPTION , required = true ) @RequestBody JsonNode request ) throws ThingsboardException {
EntityId entityId = EntityIdFactory . getByTypeAndUuid ( EntityType . DEVICE , deviceIdStr ) ;
return saveAttributes ( getTenantId ( ) , entityId , scope , request ) ;
@ -376,7 +376,7 @@ public class TelemetryController extends BaseController {
public DeferredResult < ResponseEntity > saveEntityAttributesV1 (
@Parameter ( description = ENTITY_TYPE_PARAM_DESCRIPTION , required = true , schema = @Schema ( defaultValue = "DEVICE" ) ) @PathVariable ( "entityType" ) String entityType ,
@Parameter ( description = ENTITY_ID_PARAM_DESCRIPTION , required = true ) @PathVariable ( "entityId" ) String entityIdStr ,
@Parameter ( description = ATTRIBUTES_SCOPE_DESCRIPTION , schema = @Schema ( allowableValues = { "SERVER_SCOPE" , "SHARED_SCOPE" } ) ) @PathVariable ( "scope" ) String scope ,
@Parameter ( description = ATTRIBUTES_SCOPE_DESCRIPTION , schema = @Schema ( allowableValues = { "SERVER_SCOPE" , "SHARED_SCOPE" } ) ) @PathVariable ( "scope" ) AttributeScope scope ,
@Parameter ( description = ATTRIBUTES_JSON_REQUEST_DESCRIPTION , required = true ) @RequestBody JsonNode request ) throws ThingsboardException {
EntityId entityId = EntityIdFactory . getByTypeAndId ( entityType , entityIdStr ) ;
return saveAttributes ( getTenantId ( ) , entityId , scope , request ) ;
@ -400,7 +400,7 @@ public class TelemetryController extends BaseController {
public DeferredResult < ResponseEntity > saveEntityAttributesV2 (
@Parameter ( description = ENTITY_TYPE_PARAM_DESCRIPTION , required = true , schema = @Schema ( defaultValue = "DEVICE" ) ) @PathVariable ( "entityType" ) String entityType ,
@Parameter ( description = ENTITY_ID_PARAM_DESCRIPTION , required = true ) @PathVariable ( "entityId" ) String entityIdStr ,
@Parameter ( description = ATTRIBUTES_SCOPE_DESCRIPTION , schema = @Schema ( allowableValues = { "SERVER_SCOPE" , "SHARED_SCOPE" } , required = true ) ) @PathVariable ( "scope" ) String scope ,
@Parameter ( description = ATTRIBUTES_SCOPE_DESCRIPTION , schema = @Schema ( allowableValues = { "SERVER_SCOPE" , "SHARED_SCOPE" } , required = true ) ) @PathVariable ( "scope" ) AttributeScope scope ,
@Parameter ( description = ATTRIBUTES_JSON_REQUEST_DESCRIPTION , required = true ) @RequestBody JsonNode request ) throws ThingsboardException {
EntityId entityId = EntityIdFactory . getByTypeAndId ( entityType , entityIdStr ) ;
return saveAttributes ( getTenantId ( ) , entityId , scope , request ) ;
@ -425,7 +425,7 @@ public class TelemetryController extends BaseController {
public DeferredResult < ResponseEntity > saveEntityTelemetry (
@Parameter ( description = ENTITY_TYPE_PARAM_DESCRIPTION , required = true , schema = @Schema ( defaultValue = "DEVICE" ) ) @PathVariable ( "entityType" ) String entityType ,
@Parameter ( description = ENTITY_ID_PARAM_DESCRIPTION , required = true ) @PathVariable ( "entityId" ) String entityIdStr ,
@Parameter ( description = TELEMETRY_SCOPE_DESCRIPTION , required = true , schema = @Schema ( allowableValues = "ANY" ) ) @PathVariable ( "scope" ) String scope ,
@Parameter ( description = TELEMETRY_SCOPE_DESCRIPTION , required = true , schema = @Schema ( allowableValues = "ANY" ) ) @PathVariable ( "scope" ) AttributeScope scope ,
@Parameter ( description = TELEMETRY_JSON_REQUEST_DESCRIPTION , required = true ) @RequestBody String requestBody ) throws ThingsboardException {
EntityId entityId = EntityIdFactory . getByTypeAndId ( entityType , entityIdStr ) ;
return saveTelemetry ( getTenantId ( ) , entityId , requestBody , 0L ) ;
@ -450,7 +450,7 @@ public class TelemetryController extends BaseController {
public DeferredResult < ResponseEntity > saveEntityTelemetryWithTTL (
@Parameter ( description = ENTITY_TYPE_PARAM_DESCRIPTION , required = true , schema = @Schema ( defaultValue = "DEVICE" ) ) @PathVariable ( "entityType" ) String entityType ,
@Parameter ( description = ENTITY_ID_PARAM_DESCRIPTION , required = true ) @PathVariable ( "entityId" ) String entityIdStr ,
@Parameter ( description = TELEMETRY_SCOPE_DESCRIPTION , required = true , schema = @Schema ( allowableValues = "ANY" ) ) @PathVariable ( "scope" ) String scope ,
@Parameter ( description = TELEMETRY_SCOPE_DESCRIPTION , required = true , schema = @Schema ( allowableValues = "ANY" ) ) @PathVariable ( "scope" ) AttributeScope scope ,
@Parameter ( description = "A long value representing TTL (Time to Live) parameter." , required = true ) @PathVariable ( "ttl" ) Long ttl ,
@Parameter ( description = TELEMETRY_JSON_REQUEST_DESCRIPTION , required = true ) @RequestBody String requestBody ) throws ThingsboardException {
EntityId entityId = EntityIdFactory . getByTypeAndId ( entityType , entityIdStr ) ;
@ -555,7 +555,7 @@ public class TelemetryController extends BaseController {
@ResponseBody
public DeferredResult < ResponseEntity > deleteDeviceAttributes (
@Parameter ( description = DEVICE_ID_PARAM_DESCRIPTION , required = true ) @PathVariable ( DEVICE_ID ) String deviceIdStr ,
@Parameter ( description = ATTRIBUTES_SCOPE_DESCRIPTION , schema = @Schema ( allowableValues = { "SERVER_SCOPE" , "SHARED_SCOPE" , "CLIENT_SCOPE" } , required = true ) ) @PathVariable ( "scope" ) String scope ,
@Parameter ( description = ATTRIBUTES_SCOPE_DESCRIPTION , schema = @Schema ( allowableValues = { "SERVER_SCOPE" , "SHARED_SCOPE" , "CLIENT_SCOPE" } , required = true ) ) @PathVariable ( "scope" ) AttributeScope scope ,
@Parameter ( description = ATTRIBUTES_KEYS_DESCRIPTION , required = true ) @RequestParam ( name = "keys" ) String keysStr ) throws ThingsboardException {
EntityId entityId = EntityIdFactory . getByTypeAndUuid ( EntityType . DEVICE , deviceIdStr ) ;
return deleteAttributes ( entityId , scope , keysStr ) ;
@ -579,49 +579,43 @@ public class TelemetryController extends BaseController {
public DeferredResult < ResponseEntity > deleteEntityAttributes (
@Parameter ( description = ENTITY_TYPE_PARAM_DESCRIPTION , required = true , schema = @Schema ( defaultValue = "DEVICE" ) ) @PathVariable ( "entityType" ) String entityType ,
@Parameter ( description = ENTITY_ID_PARAM_DESCRIPTION , required = true ) @PathVariable ( "entityId" ) String entityIdStr ,
@Parameter ( description = ATTRIBUTES_SCOPE_DESCRIPTION , required = true , schema = @Schema ( allowableValues = { "SERVER_SCOPE" , "SHARED_SCOPE" , "CLIENT_SCOPE" } ) ) @PathVariable ( "scope" ) String scope ,
@Parameter ( description = ATTRIBUTES_SCOPE_DESCRIPTION , required = true , schema = @Schema ( allowableValues = { "SERVER_SCOPE" , "SHARED_SCOPE" , "CLIENT_SCOPE" } ) ) @PathVariable ( "scope" ) AttributeScope scope ,
@Parameter ( description = ATTRIBUTES_KEYS_DESCRIPTION , required = true ) @RequestParam ( name = "keys" ) String keysStr ) throws ThingsboardException {
EntityId entityId = EntityIdFactory . getByTypeAndId ( entityType , entityIdStr ) ;
return deleteAttributes ( entityId , scope , keysStr ) ;
}
private DeferredResult < ResponseEntity > deleteAttributes ( EntityId entityIdSrc , String scope , String keysStr ) throws ThingsboardException {
private DeferredResult < ResponseEntity > deleteAttributes ( EntityId entityIdSrc , AttributeScope scope , String keysStr ) throws ThingsboardException {
List < String > keys = toKeysList ( keysStr ) ;
if ( keys . isEmpty ( ) ) {
return getImmediateDeferredResult ( "Empty keys: " + keysStr , HttpStatus . BAD_REQUEST ) ;
}
SecurityUser user = getCurrentUser ( ) ;
if ( DataConstants . SERVER_SCOPE . equals ( scope ) | |
DataConstants . SHARED_SCOPE . equals ( scope ) | |
DataConstants . CLIENT_SCOPE . equals ( scope ) ) {
return accessValidator . validateEntityAndCallback ( getCurrentUser ( ) , Operation . WRITE_ATTRIBUTES , entityIdSrc , ( result , tenantId , entityId ) - > {
tsSubService . deleteAndNotify ( tenantId , entityId , scope , keys , new FutureCallback < Void > ( ) {
@Override
public void onSuccess ( @Nullable Void tmp ) {
logAttributesDeleted ( user , entityId , scope , keys , null ) ;
if ( entityIdSrc . getEntityType ( ) . equals ( EntityType . DEVICE ) ) {
DeviceId deviceId = new DeviceId ( entityId . getId ( ) ) ;
tbClusterService . pushMsgToCore ( DeviceAttributesEventNotificationMsg . onDelete (
user . getTenantId ( ) , deviceId , scope , keys ) , null ) ;
}
result . setResult ( new ResponseEntity < > ( HttpStatus . OK ) ) ;
return accessValidator . validateEntityAndCallback ( getCurrentUser ( ) , Operation . WRITE_ATTRIBUTES , entityIdSrc , ( result , tenantId , entityId ) - > {
tsSubService . deleteAndNotify ( tenantId , entityId , scope . name ( ) , keys , new FutureCallback < Void > ( ) {
@Override
public void onSuccess ( @Nullable Void tmp ) {
logAttributesDeleted ( user , entityId , scope , keys , null ) ;
if ( entityIdSrc . getEntityType ( ) . equals ( EntityType . DEVICE ) ) {
DeviceId deviceId = new DeviceId ( entityId . getId ( ) ) ;
tbClusterService . pushMsgToCore ( DeviceAttributesEventNotificationMsg . onDelete (
user . getTenantId ( ) , deviceId , scope . name ( ) , keys ) , null ) ;
}
result . setResult ( new ResponseEntity < > ( HttpStatus . OK ) ) ;
}
@Override
public void onFailure ( Throwable t ) {
logAttributesDeleted ( user , entityId , scope , keys , t ) ;
result . setResult ( new ResponseEntity < > ( HttpStatus . INTERNAL_SERVER_ERROR ) ) ;
}
} ) ;
@Override
public void onFailure ( Throwable t ) {
logAttributesDeleted ( user , entityId , scope , keys , t ) ;
result . setResult ( new ResponseEntity < > ( HttpStatus . INTERNAL_SERVER_ERROR ) ) ;
}
} ) ;
} else {
return getImmediateDeferredResult ( "Invalid attribute scope: " + scope , HttpStatus . BAD_REQUEST ) ;
}
} ) ;
}
private DeferredResult < ResponseEntity > saveAttributes ( TenantId srcTenantId , EntityId entityIdSrc , String scope , JsonNode json ) throws ThingsboardException {
if ( ! DataConstants . SERVER_SCOPE . equals ( scope ) & & ! DataConstants . SHARED_SCOPE . equals ( scope ) ) {
private DeferredResult < ResponseEntity > saveAttributes ( TenantId srcTenantId , EntityId entityIdSrc , AttributeScope scope , JsonNode json ) throws ThingsboardException {
if ( AttributeScope . SERVER_SCOPE ! = scope & & AttributeScope . SHARED_SCOPE ! = scope ) {
return getImmediateDeferredResult ( "Invalid scope: " + scope , HttpStatus . BAD_REQUEST ) ;
}
if ( json . isObject ( ) ) {
@ -636,7 +630,7 @@ public class TelemetryController extends BaseController {
}
SecurityUser user = getCurrentUser ( ) ;
return accessValidator . validateEntityAndCallback ( getCurrentUser ( ) , Operation . WRITE_ATTRIBUTES , entityIdSrc , ( result , tenantId , entityId ) - > {
tsSubService . saveAndNotify ( tenantId , entityId , scope , attributes , new FutureCallback < Void > ( ) {
tsSubService . saveAndNotify ( tenantId , entityId , scope . name ( ) , attributes , new FutureCallback < Void > ( ) {
@Override
public void onSuccess ( @Nullable Void tmp ) {
logAttributesUpdated ( user , entityId , scope , attributes , null ) ;
@ -710,10 +704,10 @@ public class TelemetryController extends BaseController {
Futures . addCallback ( future , getTsKvListCallback ( result , useStrictDataTypes ) , MoreExecutors . directExecutor ( ) ) ;
}
private void getAttributeValuesCallback ( @Nullable DeferredResult < ResponseEntity > result , SecurityUser user , EntityId entityId , String scope , String keys ) {
private void getAttributeValuesCallback ( @Nullable DeferredResult < ResponseEntity > result , SecurityUser user , EntityId entityId , AttributeScope scope , String keys ) {
List < String > keyList = toKeysList ( keys ) ;
FutureCallback < List < AttributeKvEntry > > callback = getAttributeValuesToResponseCallback ( result , user , scope , entityId , keyList ) ;
if ( ! StringUtils . isEmpty ( scope ) ) {
if ( scope ! = null ) {
if ( keyList ! = null & & ! keyList . isEmpty ( ) ) {
Futures . addCallback ( attributesService . find ( user . getTenantId ( ) , entityId , scope , keyList ) , callback , MoreExecutors . directExecutor ( ) ) ;
} else {
@ -721,7 +715,7 @@ public class TelemetryController extends BaseController {
}
} else {
List < ListenableFuture < List < AttributeKvEntry > > > futures = new ArrayList < > ( ) ;
for ( String tmpScope : DataConstants . allScop es( ) ) {
for ( AttributeScope tmpScope : AttributeScope . valu es( ) ) {
if ( keyList ! = null & & ! keyList . isEmpty ( ) ) {
futures . add ( attributesService . find ( user . getTenantId ( ) , entityId , tmpScope , keyList ) ) ;
} else {
@ -735,13 +729,13 @@ public class TelemetryController extends BaseController {
}
}
private void getAttributeKeysCallback ( @Nullable DeferredResult < ResponseEntity > result , TenantId tenantId , EntityId entityId , String scope ) {
private void getAttributeKeysCallback ( @Nullable DeferredResult < ResponseEntity > result , TenantId tenantId , EntityId entityId , AttributeScope scope ) {
Futures . addCallback ( attributesService . findAll ( tenantId , entityId , scope ) , getAttributeKeysToResponseCallback ( result ) , MoreExecutors . directExecutor ( ) ) ;
}
private void getAttributeKeysCallback ( @Nullable DeferredResult < ResponseEntity > result , TenantId tenantId , EntityId entityId ) {
List < ListenableFuture < List < AttributeKvEntry > > > futures = new ArrayList < > ( ) ;
for ( String scope : DataConstants . allScop es( ) ) {
for ( AttributeScope scope : AttributeScope . valu es( ) ) {
futures . add ( attributesService . findAll ( tenantId , entityId , scope ) ) ;
}
@ -784,7 +778,7 @@ public class TelemetryController extends BaseController {
}
private FutureCallback < List < AttributeKvEntry > > getAttributeValuesToResponseCallback ( final DeferredResult < ResponseEntity > response ,
final SecurityUser user , final String scope ,
final SecurityUser user , final AttributeScope scope ,
final EntityId entityId , final List < String > keyList ) {
return new FutureCallback < > ( ) {
@Override
@ -835,18 +829,18 @@ public class TelemetryController extends BaseController {
toException ( e ) , telemetry ) ;
}
private void logAttributesDeleted ( SecurityUser user , EntityId entityId , String scope , List < String > keys , Throwable e ) {
private void logAttributesDeleted ( SecurityUser user , EntityId entityId , AttributeScope scope , List < String > keys , Throwable e ) {
notificationEntityService . logEntityAction ( user . getTenantId ( ) , ( UUIDBased & EntityId ) entityId ,
ActionType . ATTRIBUTES_DELETED , user , toException ( e ) , scope , keys ) ;
}
private void logAttributesUpdated ( SecurityUser user , EntityId entityId , String scope , List < AttributeKvEntry > attributes , Throwable e ) {
private void logAttributesUpdated ( SecurityUser user , EntityId entityId , AttributeScope scope , List < AttributeKvEntry > attributes , Throwable e ) {
notificationEntityService . logEntityAction ( user . getTenantId ( ) , entityId , ActionType . ATTRIBUTES_UPDATED , user ,
toException ( e ) , scope , attributes ) ;
}
private void logAttributesRead ( SecurityUser user , EntityId entityId , String scope , List < String > keys , Throwable e ) {
private void logAttributesRead ( SecurityUser user , EntityId entityId , AttributeScope scope , List < String > keys , Throwable e ) {
notificationEntityService . logEntityAction ( user . getTenantId ( ) , entityId , ActionType . ATTRIBUTES_READ , user ,
toException ( e ) , scope , keys ) ;
}