Commit 91d614bab3a8529128d9ac9fd9cd1795a5a07fa3

Authored by Mariia Synelnyk
Committed by GitHub
1 parent 991ef278

[3.2.2] Feature/swagger telemetry controller (#5374)

* add more notes to TelemetryController

* add detailed notes to Telemetryontroller and try to fix Inline Model

* remove responsecontainer from @ApiOperaion

* description updated for Telemetry Controller API calls

Co-authored-by: ShvaykaD <dshvaika@thingsboard.io>
... ... @@ -28,10 +28,13 @@ import com.google.gson.JsonParseException;
28 28 import com.google.gson.JsonParser;
29 29 import io.swagger.annotations.ApiOperation;
30 30 import io.swagger.annotations.ApiParam;
  31 +import io.swagger.annotations.ApiResponse;
  32 +import io.swagger.annotations.ApiResponses;
31 33 import lombok.extern.slf4j.Slf4j;
32 34 import org.springframework.beans.factory.annotation.Autowired;
33 35 import org.springframework.beans.factory.annotation.Value;
34 36 import org.springframework.http.HttpStatus;
  37 +import org.springframework.http.MediaType;
35 38 import org.springframework.http.ResponseEntity;
36 39 import org.springframework.security.access.prepost.PreAuthorize;
37 40 import org.springframework.util.StringUtils;
... ... @@ -113,12 +116,43 @@ public class TelemetryController extends BaseController {
113 116 private static final String ATTRIBUTES_KEYS_DESCRIPTION = "A string value representing the comma-separated list of attributes keys. For example, 'active,inactivityAlarmTime'.";
114 117 private static final String ATTRIBUTES_SCOPE_ALLOWED_VALUES = "SERVER_SCOPE, CLIENT_SCOPE, SHARED_SCOPE";
115 118 private static final String ATTRIBUTES_JSON_REQUEST_DESCRIPTION = "A string value representing the json object. For example, '{\"key\":\"value\"}'";
116   -
117   - private static final String TELEMETRY_KEYS_DESCRIPTION = "A string value representing the comma-separated list of timeseries keys. If keys are not selected, the result will return all latest timeseries. For example, 'temp,humidity'.";
118   - private static final String TELEMETRY_SCOPE_DESCRIPTION = "Value is not used in the API call implementation";
119   - private static final String TELEMETRY_JSON_REQUEST_DESCRIPTION = "A string value representing the json object. For example, '{\"key\":\"value\"}' or '{\"ts\":1527863043000,\"values\":{\"key1\":\"value1\",\"key2\":\"value2\"}}'";
120   -
121   - private static final String STRICT_DATA_TYPES_DESCRIPTION = "A boolean value to specify if values of selected timeseries keys will representing a string (by default) or use strict data type.";
  119 + private static final String ATTRIBUTE_DATA_CLASS_DESCRIPTION = "AttributeData class represents information regarding a particular attribute and includes the next parameters: 'lastUpdatesTs' - a long value representing the timestamp of the last attribute modification in milliseconds. 'key' - attribute key name, and 'value' - attribute value.";
  120 + private static final String GET_ALL_ATTRIBUTES_BASE_DESCRIPTION = "Returns a JSON structure that represents a list of AttributeData class objects for the selected entity based on the specified comma-separated list of attribute key names. " + ATTRIBUTE_DATA_CLASS_DESCRIPTION;
  121 + private static final String GET_ALL_ATTRIBUTES_BY_SCOPE_BASE_DESCRIPTION = "Returns a JSON structure that represents a list of AttributeData class objects for the selected entity based on the attributes scope selected and a comma-separated list of attribute key names. " + ATTRIBUTE_DATA_CLASS_DESCRIPTION;
  122 +
  123 + private static final String TS_DATA_CLASS_DESCRIPTION = "TsData class is a timeseries data point for specific telemetry key that includes 'value' - object value, and 'ts' - a long value representing timestamp in milliseconds for this value. ";
  124 +
  125 + private static final String TELEMETRY_KEYS_BASE_DESCRIPTION = "A string value representing the comma-separated list of telemetry keys.";
  126 + private static final String TELEMETRY_KEYS_DESCRIPTION = TELEMETRY_KEYS_BASE_DESCRIPTION + " If keys are not selected, the result will return all latest timeseries. For example, 'temp,humidity'.";
  127 + private static final String TELEMETRY_SCOPE_DESCRIPTION = "Value is not used in the API call implementation. However, you need to specify whatever value cause scope is a path variable.";
  128 + private static final String TELEMETRY_JSON_REQUEST_DESCRIPTION = "A string value representing the json object. For example, '{\"key\":\"value\"}' or '{\"ts\":1527863043000,\"values\":{\"key1\":\"value1\",\"key2\":\"value2\"}}' or [{\"ts\":1527863043000,\"values\":{\"key1\":\"value1\",\"key2\":\"value2\"}}, {\"ts\":1527863053000,\"values\":{\"key1\":\"value3\",\"key2\":\"value4\"}}]";
  129 +
  130 +
  131 + private static final String STRICT_DATA_TYPES_DESCRIPTION = "A boolean value to specify if values of selected telemetry keys will represent string values(by default) or use strict data type.";
  132 + private static final String INVALID_ENTITY_ID_OR_ENTITY_TYPE_DESCRIPTION = "Referencing a non-existing entity Id or invalid entity type will cause an error. ";
  133 +
  134 + private static final String SAVE_ENTITY_ATTRIBUTES_DESCRIPTION = "Creates or updates the entity attributes based on entity id, entity type, specified attributes scope " +
  135 + "and request payload that represents a JSON object with key-value format of attributes to create or update. " +
  136 + "For example, '{\"temperature\": 26}'. Key is a unique parameter and cannot be overwritten. Only value can be overwritten for the key. ";
  137 + private static final String SAVE_ATTIRIBUTES_STATUS_OK = "Attribute from the request was created or updated. ";
  138 + private static final String INVALID_STRUCTURE_OF_THE_REQUEST = "Invalid structure of the request";
  139 + private static final String SAVE_ATTIRIBUTES_STATUS_BAD_REQUEST = INVALID_STRUCTURE_OF_THE_REQUEST + " or invalid attributes scope provided.";
  140 + private static final String SAVE_ENTITY_ATTRIBUTES_STATUS_OK = "Platform creates an audit log event about entity attributes updates with action type 'ATTRIBUTES_UPDATED', " +
  141 + "and also sends event msg to the rule engine with msg type 'ATTRIBUTES_UPDATED'.";
  142 + private static final String SAVE_ENTITY_ATTRIBUTES_STATUS_UNAUTHORIZED = "User is not authorized to save entity attributes for selected entity. Most likely, User belongs to different Customer or Tenant.";
  143 + private static final String SAVE_ENTITY_ATTRIBUTES_STATUS_INTERNAL_SERVER_ERROR = "The exception was thrown during processing the request. " +
  144 + "Platform creates an audit log event about entity attributes updates with action type 'ATTRIBUTES_UPDATED' that includes an error stacktrace.";
  145 + private static final String SAVE_ENTITY_TIMESERIES_DESCRIPTION = "Creates or updates the entity timeseries based on entity id, entity type " +
  146 + "and request payload that represents a JSON object with key-value or ts-values format. " +
  147 + "For example, '{\"temperature\": 26}' or '{\"ts\":1634712287000,\"values\":{\"temperature\":26, \"humidity\":87}}', " +
  148 + "or JSON array with inner objects inside of ts-values format. " +
  149 + "For example, '[{\"ts\":1634712287000,\"values\":{\"temperature\":26, \"humidity\":87}}, {\"ts\":1634712588000,\"values\":{\"temperature\":25, \"humidity\":88}}]'. " +
  150 + "The scope parameter is not used in the API call implementation but should be specified whatever value because it is used as a path variable. ";
  151 + private static final String SAVE_ENTITY_TIMESERIES_STATUS_OK = "Timeseries from the request was created or updated. " +
  152 + "Platform creates an audit log event about entity timeseries updates with action type 'TIMESERIES_UPDATED'.";
  153 + private static final String SAVE_ENTITY_TIMESERIES_STATUS_UNAUTHORIZED = "User is not authorized to save entity timeseries for selected entity. Most likely, User belongs to different Customer or Tenant.";
  154 + private static final String SAVE_ENTITY_TIMESERIES_STATUS_INTERNAL_SERVER_ERROR = "The exception was thrown during processing the request. " +
  155 + "Platform creates an audit log event about entity timeseries updates with action type 'TIMESERIES_UPDATED' that includes an error stacktrace.";
122 156
123 157 @Autowired
124 158 private TimeseriesService tsService;
... ... @@ -146,7 +180,10 @@ public class TelemetryController extends BaseController {
146 180 }
147 181
148 182 @ApiOperation(value = "Get all attribute keys (getAttributeKeys)",
149   - notes = "Returns key names for the selected entity.")
  183 + notes = "Returns a list of all attribute key names for the selected entity. " +
  184 + "In the case of device entity specified, a response will include merged attribute key names list from each scope: " +
  185 + "SERVER_SCOPE, CLIENT_SCOPE, SHARED_SCOPE. " + INVALID_ENTITY_ID_OR_ENTITY_TYPE_DESCRIPTION,
  186 + produces = MediaType.APPLICATION_JSON_VALUE)
150 187 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
151 188 @RequestMapping(value = "/{entityType}/{entityId}/keys/attributes", method = RequestMethod.GET)
152 189 @ResponseBody
... ... @@ -156,8 +193,10 @@ public class TelemetryController extends BaseController {
156 193 return accessValidator.validateEntityAndCallback(getCurrentUser(), Operation.READ_ATTRIBUTES, entityType, entityIdStr, this::getAttributeKeysCallback);
157 194 }
158 195
159   - @ApiOperation(value = "Get all attributes by scope (getAttributeKeysByScope)",
160   - notes = "Returns key names of specified scope for the selected entity.")
  196 + @ApiOperation(value = "Get all attributes keys by scope (getAttributeKeysByScope)",
  197 + notes = "Returns a list of attribute key names from the specified attributes scope for the selected entity. " +
  198 + "If scope parameter is omitted, Get all attribute keys(getAttributeKeys) API will be called. " + INVALID_ENTITY_ID_OR_ENTITY_TYPE_DESCRIPTION,
  199 + produces = MediaType.APPLICATION_JSON_VALUE)
161 200 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
162 201 @RequestMapping(value = "/{entityType}/{entityId}/keys/attributes/{scope}", method = RequestMethod.GET)
163 202 @ResponseBody
... ... @@ -170,7 +209,9 @@ public class TelemetryController extends BaseController {
170 209 }
171 210
172 211 @ApiOperation(value = "Get attributes (getAttributes)",
173   - notes = "Returns JSON array of AttributeData objects for the selected entity.")
  212 + notes = GET_ALL_ATTRIBUTES_BASE_DESCRIPTION + " If 'keys' parameter is omitted, AttributeData class objects will be added to the response for all existing keys of the selected entity. " +
  213 + INVALID_ENTITY_ID_OR_ENTITY_TYPE_DESCRIPTION,
  214 + produces = MediaType.APPLICATION_JSON_VALUE)
174 215 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
175 216 @RequestMapping(value = "/{entityType}/{entityId}/values/attributes", method = RequestMethod.GET)
176 217 @ResponseBody
... ... @@ -184,7 +225,11 @@ public class TelemetryController extends BaseController {
184 225 }
185 226
186 227 @ApiOperation(value = "Get attributes by scope (getAttributesByScope)",
187   - notes = "Returns JSON array of AttributeData objects for the selected entity.")
  228 + notes = GET_ALL_ATTRIBUTES_BY_SCOPE_BASE_DESCRIPTION + " In case that 'keys' parameter is not selected, " +
  229 + "AttributeData class objects will be added to the response for all existing attribute keys from the " +
  230 + "specified attributes scope of the selected entity. If 'scope' parameter is omitted, " +
  231 + "Get attributes (getAttributes) API will be called. " + INVALID_ENTITY_ID_OR_ENTITY_TYPE_DESCRIPTION,
  232 + produces = MediaType.APPLICATION_JSON_VALUE)
188 233 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
189 234 @RequestMapping(value = "/{entityType}/{entityId}/values/attributes/{scope}", method = RequestMethod.GET)
190 235 @ResponseBody
... ... @@ -199,7 +244,9 @@ public class TelemetryController extends BaseController {
199 244 }
200 245
201 246 @ApiOperation(value = "Get timeseries keys (getTimeseriesKeys)",
202   - notes = "Returns latest timeseries keys for selected entity.")
  247 + notes = "Returns a list of all telemetry key names for the selected entity based on entity id and entity type specified. " +
  248 + INVALID_ENTITY_ID_OR_ENTITY_TYPE_DESCRIPTION,
  249 + produces = MediaType.APPLICATION_JSON_VALUE)
203 250 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
204 251 @RequestMapping(value = "/{entityType}/{entityId}/keys/timeseries", method = RequestMethod.GET)
205 252 @ResponseBody
... ... @@ -211,7 +258,9 @@ public class TelemetryController extends BaseController {
211 258 }
212 259
213 260 @ApiOperation(value = "Get latest timeseries (getLatestTimeseries)",
214   - notes = "Returns JSON object with mapping latest timeseries keys to JSON arrays of TsData objects for the selected entity.")
  261 + notes = "Returns a JSON structure that represents a Map, where the map key is a telemetry key name " +
  262 + "and map value - is a singleton list of TsData class objects. " + TS_DATA_CLASS_DESCRIPTION + INVALID_ENTITY_ID_OR_ENTITY_TYPE_DESCRIPTION,
  263 + produces = MediaType.APPLICATION_JSON_VALUE)
215 264 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
216 265 @RequestMapping(value = "/{entityType}/{entityId}/values/timeseries", method = RequestMethod.GET)
217 266 @ResponseBody
... ... @@ -222,30 +271,35 @@ public class TelemetryController extends BaseController {
222 271 @ApiParam(value = STRICT_DATA_TYPES_DESCRIPTION)
223 272 @RequestParam(name = "useStrictDataTypes", required = false, defaultValue = "false") Boolean useStrictDataTypes) throws ThingsboardException {
224 273 SecurityUser user = getCurrentUser();
225   -
226 274 return accessValidator.validateEntityAndCallback(getCurrentUser(), Operation.READ_TELEMETRY, entityType, entityIdStr,
227 275 (result, tenantId, entityId) -> getLatestTimeseriesValuesCallback(result, user, entityId, keysStr, useStrictDataTypes));
228 276 }
229 277
230 278 @ApiOperation(value = "Get timeseries (getTimeseries)",
231   - notes = "Returns JSON object with mapping timeseries keys to JSON arrays of TsData objects based on specified filters for the selected entity.")
  279 + notes = "Returns a JSON structure that represents a Map, where the map key is a telemetry key name " +
  280 + "and map value - is a list of TsData class objects. " + TS_DATA_CLASS_DESCRIPTION +
  281 + "This method allows us to group original data into intervals and aggregate it using one of the aggregation methods or just limit the number of TsData objects to fetch for each key specified. " +
  282 + "See the desription of the request parameters for more details. " +
  283 + "The result can also be sorted in ascending or descending order. " + INVALID_ENTITY_ID_OR_ENTITY_TYPE_DESCRIPTION,
  284 + produces = MediaType.APPLICATION_JSON_VALUE)
232 285 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
233 286 @RequestMapping(value = "/{entityType}/{entityId}/values/timeseries", method = RequestMethod.GET, params = {"keys", "startTs", "endTs"})
234 287 @ResponseBody
235 288 public DeferredResult<ResponseEntity> getTimeseries(
236 289 @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION) @PathVariable("entityType") String entityType,
237 290 @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION) @PathVariable("entityId") String entityIdStr,
238   - @ApiParam(value = TELEMETRY_KEYS_DESCRIPTION) @RequestParam(name = "keys") String keys,
239   - @ApiParam(value = "A long value representing the start timestamp(milliseconds) of search time range.")
  291 + @ApiParam(value = TELEMETRY_KEYS_BASE_DESCRIPTION) @RequestParam(name = "keys") String keys,
  292 + @ApiParam(value = "A long value representing the start timestamp of search time range in milliseconds.")
240 293 @RequestParam(name = "startTs") Long startTs,
241   - @ApiParam(value = "A long value representing the end timestamp(milliseconds) of search time range.")
  294 + @ApiParam(value = "A long value representing the end timestamp of search time range in milliseconds.")
242 295 @RequestParam(name = "endTs") Long endTs,
243   - @ApiParam(value = "A long value representing the aggregation interval(milliseconds) range.")
  296 + @ApiParam(value = "A long value representing the aggregation interval range in milliseconds.")
244 297 @RequestParam(name = "interval", defaultValue = "0") Long interval,
245   - @ApiParam(value = "An integer value representing max number of selected data points.", defaultValue = "100")
  298 + @ApiParam(value = "An integer value that represents a max number of timeseries data points to fetch." +
  299 + " This parameter is used only in the case if 'agg' parameter is set to 'NONE'.", defaultValue = "100")
246 300 @RequestParam(name = "limit", defaultValue = "100") Integer limit,
247 301 @ApiParam(value = "A string value representing the aggregation function. " +
248   - "If the interval is not specified, 'agg' parameter will be converted to 'NONE' value.",
  302 + "If the interval is not specified, 'agg' parameter will use 'NONE' value.",
249 303 allowableValues = "MIN, MAX, AVG, SUM, COUNT, NONE")
250 304 @RequestParam(name = "agg", defaultValue = "NONE") String aggStr,
251 305 @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES)
... ... @@ -263,7 +317,21 @@ public class TelemetryController extends BaseController {
263 317 });
264 318 }
265 319
266   - @ApiOperation(value = "Save or update device attributes (saveDeviceAttributes)")
  320 + @ApiOperation(value = "Save or update device attributes (saveDeviceAttributes)",
  321 + notes = "Creates or updates the device attributes based on device id, specified attribute scope, " +
  322 + "and request payload that represents a JSON object with key-value format of attributes to create or update. " +
  323 + "For example, '{\"temperature\": 26}'. Key is a unique parameter and cannot be overwritten. Only value can " +
  324 + "be overwritten for the key. ",
  325 + produces = MediaType.APPLICATION_JSON_VALUE)
  326 + @ApiResponses(value = {
  327 + @ApiResponse(code = 200, message = SAVE_ATTIRIBUTES_STATUS_OK +
  328 + "Platform creates an audit log event about device attributes updates with action type 'ATTRIBUTES_UPDATED', " +
  329 + "and also sends event msg to the rule engine with msg type 'ATTRIBUTES_UPDATED'."),
  330 + @ApiResponse(code = 400, message = SAVE_ATTIRIBUTES_STATUS_BAD_REQUEST),
  331 + @ApiResponse(code = 401, message = "User is not authorized to save device attributes for selected device. Most likely, User belongs to different Customer or Tenant."),
  332 + @ApiResponse(code = 500, message = "The exception was thrown during processing the request. " +
  333 + "Platform creates an audit log event about device attributes updates with action type 'ATTRIBUTES_UPDATED' that includes an error stacktrace."),
  334 + })
267 335 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
268 336 @RequestMapping(value = "/{deviceId}/{scope}", method = RequestMethod.POST)
269 337 @ResponseBody
... ... @@ -275,7 +343,15 @@ public class TelemetryController extends BaseController {
275 343 return saveAttributes(getTenantId(), entityId, scope, request);
276 344 }
277 345
278   - @ApiOperation(value = "Save or update attributes (saveEntityAttributesV1)")
  346 + @ApiOperation(value = "Save or update attributes (saveEntityAttributesV1)",
  347 + notes = SAVE_ENTITY_ATTRIBUTES_DESCRIPTION + INVALID_ENTITY_ID_OR_ENTITY_TYPE_DESCRIPTION,
  348 + produces = MediaType.APPLICATION_JSON_VALUE)
  349 + @ApiResponses(value = {
  350 + @ApiResponse(code = 200, message = SAVE_ATTIRIBUTES_STATUS_OK + SAVE_ENTITY_ATTRIBUTES_STATUS_OK),
  351 + @ApiResponse(code = 400, message = SAVE_ATTIRIBUTES_STATUS_BAD_REQUEST),
  352 + @ApiResponse(code = 401, message = SAVE_ENTITY_ATTRIBUTES_STATUS_UNAUTHORIZED),
  353 + @ApiResponse(code = 500, message = SAVE_ENTITY_ATTRIBUTES_STATUS_INTERNAL_SERVER_ERROR),
  354 + })
279 355 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
280 356 @RequestMapping(value = "/{entityType}/{entityId}/{scope}", method = RequestMethod.POST)
281 357 @ResponseBody
... ... @@ -288,7 +364,15 @@ public class TelemetryController extends BaseController {
288 364 return saveAttributes(getTenantId(), entityId, scope, request);
289 365 }
290 366
291   - @ApiOperation(value = "Save or update attributes (saveEntityAttributesV2)")
  367 + @ApiOperation(value = "Save or update attributes (saveEntityAttributesV2)",
  368 + notes = SAVE_ENTITY_ATTRIBUTES_DESCRIPTION + INVALID_ENTITY_ID_OR_ENTITY_TYPE_DESCRIPTION,
  369 + produces = MediaType.APPLICATION_JSON_VALUE)
  370 + @ApiResponses(value = {
  371 + @ApiResponse(code = 200, message = SAVE_ATTIRIBUTES_STATUS_OK + SAVE_ENTITY_ATTRIBUTES_STATUS_OK),
  372 + @ApiResponse(code = 400, message = SAVE_ATTIRIBUTES_STATUS_BAD_REQUEST),
  373 + @ApiResponse(code = 401, message = SAVE_ENTITY_ATTRIBUTES_STATUS_UNAUTHORIZED),
  374 + @ApiResponse(code = 500, message = SAVE_ENTITY_ATTRIBUTES_STATUS_INTERNAL_SERVER_ERROR),
  375 + })
292 376 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
293 377 @RequestMapping(value = "/{entityType}/{entityId}/attributes/{scope}", method = RequestMethod.POST)
294 378 @ResponseBody
... ... @@ -301,7 +385,15 @@ public class TelemetryController extends BaseController {
301 385 return saveAttributes(getTenantId(), entityId, scope, request);
302 386 }
303 387
304   - @ApiOperation(value = "Save or update telemetry (saveEntityTelemetry)")
  388 + @ApiOperation(value = "Save or update telemetry (saveEntityTelemetry)",
  389 + notes = SAVE_ENTITY_TIMESERIES_DESCRIPTION + INVALID_ENTITY_ID_OR_ENTITY_TYPE_DESCRIPTION,
  390 + produces = MediaType.APPLICATION_JSON_VALUE)
  391 + @ApiResponses(value = {
  392 + @ApiResponse(code = 200, message = SAVE_ENTITY_TIMESERIES_STATUS_OK),
  393 + @ApiResponse(code = 400, message = INVALID_STRUCTURE_OF_THE_REQUEST),
  394 + @ApiResponse(code = 401, message = SAVE_ENTITY_TIMESERIES_STATUS_UNAUTHORIZED),
  395 + @ApiResponse(code = 500, message = SAVE_ENTITY_TIMESERIES_STATUS_INTERNAL_SERVER_ERROR),
  396 + })
305 397 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
306 398 @RequestMapping(value = "/{entityType}/{entityId}/timeseries/{scope}", method = RequestMethod.POST)
307 399 @ResponseBody
... ... @@ -315,7 +407,14 @@ public class TelemetryController extends BaseController {
315 407 }
316 408
317 409 @ApiOperation(value = "Save or update telemetry with TTL (saveEntityTelemetryWithTTL)",
318   - notes = "The TTL parameter is used to extract the number of days to store the data.")
  410 + notes = SAVE_ENTITY_TIMESERIES_DESCRIPTION + "The ttl parameter used only in case of Cassandra DB use for timeseries data storage. " + INVALID_ENTITY_ID_OR_ENTITY_TYPE_DESCRIPTION,
  411 + produces = MediaType.APPLICATION_JSON_VALUE)
  412 + @ApiResponses(value = {
  413 + @ApiResponse(code = 200, message = SAVE_ENTITY_TIMESERIES_STATUS_OK),
  414 + @ApiResponse(code = 400, message = INVALID_STRUCTURE_OF_THE_REQUEST),
  415 + @ApiResponse(code = 401, message = SAVE_ENTITY_TIMESERIES_STATUS_UNAUTHORIZED),
  416 + @ApiResponse(code = 500, message = SAVE_ENTITY_TIMESERIES_STATUS_INTERNAL_SERVER_ERROR),
  417 + })
319 418 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
320 419 @RequestMapping(value = "/{entityType}/{entityId}/timeseries/{scope}/{ttl}", method = RequestMethod.POST)
321 420 @ResponseBody
... ... @@ -323,14 +422,25 @@ public class TelemetryController extends BaseController {
323 422 @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION) @PathVariable("entityType") String entityType,
324 423 @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION) @PathVariable("entityId") String entityIdStr,
325 424 @ApiParam(value = TELEMETRY_SCOPE_DESCRIPTION) @PathVariable("scope") String scope,
326   - @ApiParam(value = "A long value representing TTL(Time to Live) parameter.") @PathVariable("ttl") Long ttl,
  425 + @ApiParam(value = "A long value representing TTL (Time to Live) parameter.") @PathVariable("ttl") Long ttl,
327 426 @ApiParam(value = TELEMETRY_JSON_REQUEST_DESCRIPTION) @RequestBody String requestBody) throws ThingsboardException {
328 427 EntityId entityId = EntityIdFactory.getByTypeAndId(entityType, entityIdStr);
329 428 return saveTelemetry(getTenantId(), entityId, requestBody, ttl);
330 429 }
331 430
332 431 @ApiOperation(value = "Delete entity timeseries (deleteEntityTimeseries)",
333   - notes = "Delete timeseries in the specified time range for selected entity.")
  432 + notes = "Delete timeseries for selected entity based on entity id, entity type, keys " +
  433 + "and removal time range. To delete all data for keys parameter 'deleteAllDataForKeys' should be set to true, " +
  434 + "otherwise, will be deleted data that is in range of the selected time interval. ",
  435 + produces = MediaType.APPLICATION_JSON_VALUE)
  436 + @ApiResponses(value = {
  437 + @ApiResponse(code = 200, message = "Timeseries for the selected keys in the request was removed. " +
  438 + "Platform creates an audit log event about entity timeseries removal with action type 'TIMESERIES_DELETED'."),
  439 + @ApiResponse(code = 400, message = "Platform returns a bad request in case if keys list is empty or start and end timestamp values is empty when deleteAllDataForKeys is set to false."),
  440 + @ApiResponse(code = 401, message = "User is not authorized to delete entity timeseries for selected entity. Most likely, User belongs to different Customer or Tenant."),
  441 + @ApiResponse(code = 500, message = "The exception was thrown during processing the request. " +
  442 + "Platform creates an audit log event about entity timeseries removal with action type 'TIMESERIES_DELETED' that includes an error stacktrace."),
  443 + })
334 444 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
335 445 @RequestMapping(value = "/{entityType}/{entityId}/timeseries/delete", method = RequestMethod.DELETE)
336 446 @ResponseBody
... ... @@ -340,11 +450,11 @@ public class TelemetryController extends BaseController {
340 450 @ApiParam(value = TELEMETRY_KEYS_DESCRIPTION) @RequestParam(name = "keys") String keysStr,
341 451 @ApiParam(value = "A boolean value to specify if should be deleted all data for selected keys or only data that are in the selected time range.")
342 452 @RequestParam(name = "deleteAllDataForKeys", defaultValue = "false") boolean deleteAllDataForKeys,
343   - @ApiParam(value = "A long value representing the start timestamp(milliseconds) of removal time range.")
  453 + @ApiParam(value = "A long value representing the start timestamp of removal time range in milliseconds.")
344 454 @RequestParam(name = "startTs", required = false) Long startTs,
345   - @ApiParam(value = "A long value representing the end timestamp(milliseconds) of removal time range.")
  455 + @ApiParam(value = "A long value representing the end timestamp of removal time range in milliseconds.")
346 456 @RequestParam(name = "endTs", required = false) Long endTs,
347   - @ApiParam(value = "If the parameter is set to true, the latest telemetry will be rewritten if the current latest value was removed, otherwise, the new latest value will not set.")
  457 + @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.")
348 458 @RequestParam(name = "rewriteLatestIfDeleted", defaultValue = "false") boolean rewriteLatestIfDeleted) throws ThingsboardException {
349 459 EntityId entityId = EntityIdFactory.getByTypeAndId(entityType, entityIdStr);
350 460 return deleteTimeseries(entityId, keysStr, deleteAllDataForKeys, startTs, endTs, rewriteLatestIfDeleted);
... ... @@ -395,7 +505,17 @@ public class TelemetryController extends BaseController {
395 505 }
396 506
397 507 @ApiOperation(value = "Delete device attributes (deleteEntityAttributes)",
398   - notes = "Delete attributes of specified scope for selected device.")
  508 + notes = "Delete device attributes from the specified attributes scope based on device id and a list of keys to delete. " +
  509 + "Selected keys will be deleted only if there are exist in the specified attribute scope. Referencing a non-existing device Id will cause an error",
  510 + produces = MediaType.APPLICATION_JSON_VALUE)
  511 + @ApiResponses(value = {
  512 + @ApiResponse(code = 200, message = "Device attributes was removed for the selected keys in the request. " +
  513 + "Platform creates an audit log event about device attributes removal with action type 'ATTRIBUTES_DELETED'."),
  514 + @ApiResponse(code = 400, message = "Platform returns a bad request in case if keys or scope are not specified."),
  515 + @ApiResponse(code = 401, message = "User is not authorized to delete device attributes for selected entity. Most likely, User belongs to different Customer or Tenant."),
  516 + @ApiResponse(code = 500, message = "The exception was thrown during processing the request. " +
  517 + "Platform creates an audit log event about device attributes removal with action type 'ATTRIBUTES_DELETED' that includes an error stacktrace."),
  518 + })
399 519 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
400 520 @RequestMapping(value = "/{deviceId}/{scope}", method = RequestMethod.DELETE)
401 521 @ResponseBody
... ... @@ -408,7 +528,17 @@ public class TelemetryController extends BaseController {
408 528 }
409 529
410 530 @ApiOperation(value = "Delete entity attributes (deleteEntityAttributes)",
411   - notes = "Delete attributes of specified scope for selected entity.")
  531 + notes = "Delete entity attributes from the specified attributes scope based on entity id, entity type and a list of keys to delete. " +
  532 + "Selected keys will be deleted only if there are exist in the specified attribute scope." + INVALID_ENTITY_ID_OR_ENTITY_TYPE_DESCRIPTION,
  533 + produces = MediaType.APPLICATION_JSON_VALUE)
  534 + @ApiResponses(value = {
  535 + @ApiResponse(code = 200, message = "Entity attributes was removed for the selected keys in the request. " +
  536 + "Platform creates an audit log event about entity attributes removal with action type 'ATTRIBUTES_DELETED'."),
  537 + @ApiResponse(code = 400, message = "Platform returns a bad request in case if keys or scope are not specified."),
  538 + @ApiResponse(code = 401, message = "User is not authorized to delete entity attributes for selected entity. Most likely, User belongs to different Customer or Tenant."),
  539 + @ApiResponse(code = 500, message = "The exception was thrown during processing the request. " +
  540 + "Platform creates an audit log event about entity attributes removal with action type 'ATTRIBUTES_DELETED' that includes an error stacktrace."),
  541 + })
412 542 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
413 543 @RequestMapping(value = "/{entityType}/{entityId}/{scope}", method = RequestMethod.DELETE)
414 544 @ResponseBody
... ...
... ... @@ -15,6 +15,10 @@
15 15 */
16 16 package org.thingsboard.server.service.telemetry;
17 17
  18 +import io.swagger.annotations.ApiModel;
  19 +import io.swagger.annotations.ApiModelProperty;
  20 +
  21 +@ApiModel
18 22 public class AttributeData implements Comparable<AttributeData>{
19 23
20 24 private final long lastUpdateTs;
... ... @@ -28,14 +32,17 @@ public class AttributeData implements Comparable<AttributeData>{
28 32 this.value = value;
29 33 }
30 34
  35 + @ApiModelProperty(position = 1, value = "Timestamp last updated attribute, in milliseconds", example = "1609459200000", readOnly = true)
31 36 public long getLastUpdateTs() {
32 37 return lastUpdateTs;
33 38 }
34 39
  40 + @ApiModelProperty(position = 2, value = "String representing attribute key", example = "active", readOnly = true)
35 41 public String getKey() {
36 42 return key;
37 43 }
38 44
  45 + @ApiModelProperty(position = 3, value = "Object representing value of attribute key", example = "false", readOnly = true)
39 46 public Object getValue() {
40 47 return value;
41 48 }
... ...
... ... @@ -15,6 +15,10 @@
15 15 */
16 16 package org.thingsboard.server.service.telemetry;
17 17
  18 +import io.swagger.annotations.ApiModel;
  19 +import io.swagger.annotations.ApiModelProperty;
  20 +
  21 +@ApiModel
18 22 public class TsData implements Comparable<TsData>{
19 23
20 24 private final long ts;
... ... @@ -26,10 +30,12 @@ public class TsData implements Comparable<TsData>{
26 30 this.value = value;
27 31 }
28 32
  33 + @ApiModelProperty(position = 1, value = "Timestamp last updated timeseries, in milliseconds", example = "1609459200000", readOnly = true)
29 34 public long getTs() {
30 35 return ts;
31 36 }
32 37
  38 + @ApiModelProperty(position = 2, value = "Object representing value of timeseries key", example = "20", readOnly = true)
33 39 public Object getValue() {
34 40 return value;
35 41 }
... ...