Commit 8cb0622dac8f0111e02c00203bcec8ba50b7ea00

Authored by Andrii Shvaika
2 parents c50dd443 4510a3b3

Merge asset docs

... ... @@ -16,9 +16,12 @@
16 16 package org.thingsboard.server.controller;
17 17
18 18 import com.google.common.util.concurrent.ListenableFuture;
  19 +import io.swagger.annotations.ApiOperation;
  20 +import io.swagger.annotations.ApiParam;
19 21 import lombok.RequiredArgsConstructor;
20 22 import lombok.extern.slf4j.Slf4j;
21 23 import org.springframework.http.HttpStatus;
  24 +import org.springframework.http.MediaType;
22 25 import org.springframework.security.access.prepost.PreAuthorize;
23 26 import org.springframework.web.bind.annotation.PathVariable;
24 27 import org.springframework.web.bind.annotation.PostMapping;
... ... @@ -37,8 +40,8 @@ import org.thingsboard.server.common.data.asset.AssetInfo;
37 40 import org.thingsboard.server.common.data.asset.AssetSearchQuery;
38 41 import org.thingsboard.server.common.data.audit.ActionType;
39 42 import org.thingsboard.server.common.data.edge.Edge;
40   -import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
41 43 import org.thingsboard.server.common.data.edge.EdgeEventActionType;
  44 +import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
42 45 import org.thingsboard.server.common.data.exception.ThingsboardException;
43 46 import org.thingsboard.server.common.data.id.AssetId;
44 47 import org.thingsboard.server.common.data.id.CustomerId;
... ... @@ -61,9 +64,8 @@ import java.util.ArrayList;
61 64 import java.util.List;
62 65 import java.util.stream.Collectors;
63 66
64   -import static org.thingsboard.server.dao.asset.BaseAssetService.TB_SERVICE_QUEUE;
65   -
66 67 import static org.thingsboard.server.controller.EdgeController.EDGE_ID;
  68 +import static org.thingsboard.server.dao.asset.BaseAssetService.TB_SERVICE_QUEUE;
67 69
68 70 @RestController
69 71 @TbCoreComponent
... ... @@ -75,10 +77,15 @@ public class AssetController extends BaseController {
75 77
76 78 public static final String ASSET_ID = "assetId";
77 79
  80 + @ApiOperation(value = "Get Asset (getAssetById)",
  81 + notes = "Fetch the Asset object based on the provided Asset Id. " +
  82 + "If the user has the authority of 'Tenant Administrator', the server checks that the asset is owned by the same tenant. " +
  83 + "If the user has the authority of 'Customer User', the server checks that the asset is assigned to the same customer.", produces = MediaType.APPLICATION_JSON_VALUE)
78 84 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
79 85 @RequestMapping(value = "/asset/{assetId}", method = RequestMethod.GET)
80 86 @ResponseBody
81   - public Asset getAssetById(@PathVariable(ASSET_ID) String strAssetId) throws ThingsboardException {
  87 + public Asset getAssetById(@ApiParam(value = ASSET_ID_PARAM_DESCRIPTION)
  88 + @PathVariable(ASSET_ID) String strAssetId) throws ThingsboardException {
82 89 checkParameter(ASSET_ID, strAssetId);
83 90 try {
84 91 AssetId assetId = new AssetId(toUUID(strAssetId));
... ... @@ -88,10 +95,15 @@ public class AssetController extends BaseController {
88 95 }
89 96 }
90 97
  98 + @ApiOperation(value = "Get Asset Info (getAssetInfoById)",
  99 + notes = "Fetch the Asset Info object based on the provided Asset Id. " +
  100 + "If the user has the authority of 'Tenant Administrator', the server checks that the asset is owned by the same tenant. " +
  101 + "If the user has the authority of 'Customer User', the server checks that the asset is assigned to the same customer. " + ASSET_INFO_DESCRIPTION, produces = MediaType.APPLICATION_JSON_VALUE)
91 102 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
92 103 @RequestMapping(value = "/asset/info/{assetId}", method = RequestMethod.GET)
93 104 @ResponseBody
94   - public AssetInfo getAssetInfoById(@PathVariable(ASSET_ID) String strAssetId) throws ThingsboardException {
  105 + public AssetInfo getAssetInfoById(@ApiParam(value = ASSET_ID_PARAM_DESCRIPTION)
  106 + @PathVariable(ASSET_ID) String strAssetId) throws ThingsboardException {
95 107 checkParameter(ASSET_ID, strAssetId);
96 108 try {
97 109 AssetId assetId = new AssetId(toUUID(strAssetId));
... ... @@ -101,10 +113,15 @@ public class AssetController extends BaseController {
101 113 }
102 114 }
103 115
  116 + @ApiOperation(value = "Create Or Update Asset (saveAsset)",
  117 + notes = "Creates or Updates the Asset. When creating asset, platform generates Asset Id as [time-based UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_1_(date-time_and_MAC_address) " +
  118 + "The newly created Asset id will be present in the response. " +
  119 + "Specify existing Asset id to update the asset. " +
  120 + "Referencing non-existing Asset Id will cause 'Not Found' error.", produces = MediaType.APPLICATION_JSON_VALUE)
104 121 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
105 122 @RequestMapping(value = "/asset", method = RequestMethod.POST)
106 123 @ResponseBody
107   - public Asset saveAsset(@RequestBody Asset asset) throws ThingsboardException {
  124 + public Asset saveAsset(@ApiParam(value = "A JSON value representing the asset.") @RequestBody Asset asset) throws ThingsboardException {
108 125 try {
109 126 if (TB_SERVICE_QUEUE.equals(asset.getType())) {
110 127 throw new ThingsboardException("Unable to save asset with type " + TB_SERVICE_QUEUE, ThingsboardErrorCode.BAD_REQUEST_PARAMS);
... ... @@ -140,10 +157,12 @@ public class AssetController extends BaseController {
140 157 }
141 158 }
142 159
  160 + @ApiOperation(value = "Delete asset (deleteAsset)",
  161 + notes = "Deletes the asset and all the relations (from and to the asset). Referencing non-existing asset Id will cause an error.")
143 162 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
144 163 @RequestMapping(value = "/asset/{assetId}", method = RequestMethod.DELETE)
145 164 @ResponseStatus(value = HttpStatus.OK)
146   - public void deleteAsset(@PathVariable(ASSET_ID) String strAssetId) throws ThingsboardException {
  165 + public void deleteAsset(@ApiParam(value = ASSET_ID_PARAM_DESCRIPTION) @PathVariable(ASSET_ID) String strAssetId) throws ThingsboardException {
147 166 checkParameter(ASSET_ID, strAssetId);
148 167 try {
149 168 AssetId assetId = new AssetId(toUUID(strAssetId));
... ... @@ -167,11 +186,13 @@ public class AssetController extends BaseController {
167 186 }
168 187 }
169 188
  189 + @ApiOperation(value = "Assign asset to customer (assignAssetToCustomer)",
  190 + notes = "Creates assignment of the asset to customer. Customer will be able to query asset afterwards.", produces = MediaType.APPLICATION_JSON_VALUE)
170 191 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
171 192 @RequestMapping(value = "/customer/{customerId}/asset/{assetId}", method = RequestMethod.POST)
172 193 @ResponseBody
173   - public Asset assignAssetToCustomer(@PathVariable("customerId") String strCustomerId,
174   - @PathVariable(ASSET_ID) String strAssetId) throws ThingsboardException {
  194 + public Asset assignAssetToCustomer(@ApiParam(value = CUSTOMER_ID_PARAM_DESCRIPTION) @PathVariable("customerId") String strCustomerId,
  195 + @ApiParam(value = ASSET_ID_PARAM_DESCRIPTION) @PathVariable(ASSET_ID) String strAssetId) throws ThingsboardException {
175 196 checkParameter("customerId", strCustomerId);
176 197 checkParameter(ASSET_ID, strAssetId);
177 198 try {
... ... @@ -201,10 +222,12 @@ public class AssetController extends BaseController {
201 222 }
202 223 }
203 224
  225 + @ApiOperation(value = "Unassign asset from customer (unassignAssetFromCustomer)",
  226 + notes = "Clears assignment of the asset to customer. Customer will not be able to query asset afterwards.", produces = MediaType.APPLICATION_JSON_VALUE)
204 227 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
205 228 @RequestMapping(value = "/customer/asset/{assetId}", method = RequestMethod.DELETE)
206 229 @ResponseBody
207   - public Asset unassignAssetFromCustomer(@PathVariable(ASSET_ID) String strAssetId) throws ThingsboardException {
  230 + public Asset unassignAssetFromCustomer(@ApiParam(value = ASSET_ID_PARAM_DESCRIPTION) @PathVariable(ASSET_ID) String strAssetId) throws ThingsboardException {
208 231 checkParameter(ASSET_ID, strAssetId);
209 232 try {
210 233 AssetId assetId = new AssetId(toUUID(strAssetId));
... ... @@ -235,10 +258,14 @@ public class AssetController extends BaseController {
235 258 }
236 259 }
237 260
  261 + @ApiOperation(value = "Make asset publicly available (assignAssetToPublicCustomer)",
  262 + notes = "Asset will be available for non-authorized (not logged-in) users. " +
  263 + "This is useful to create dashboards that you plan to share/embed on a publicly available website. " +
  264 + "However, users that are logged-in and belong to different tenant will not be able to access the asset.", produces = MediaType.APPLICATION_JSON_VALUE)
238 265 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
239 266 @RequestMapping(value = "/customer/public/asset/{assetId}", method = RequestMethod.POST)
240 267 @ResponseBody
241   - public Asset assignAssetToPublicCustomer(@PathVariable(ASSET_ID) String strAssetId) throws ThingsboardException {
  268 + public Asset assignAssetToPublicCustomer(@ApiParam(value = ASSET_ID_PARAM_DESCRIPTION) @PathVariable(ASSET_ID) String strAssetId) throws ThingsboardException {
242 269 checkParameter(ASSET_ID, strAssetId);
243 270 try {
244 271 AssetId assetId = new AssetId(toUUID(strAssetId));
... ... @@ -261,15 +288,24 @@ public class AssetController extends BaseController {
261 288 }
262 289 }
263 290
  291 + @ApiOperation(value = "Get Tenant Assets (getTenantAssets)",
  292 + notes = "Returns a page of assets owned by tenant. " +
  293 + PAGE_DATA_PARAMETERS, produces = MediaType.APPLICATION_JSON_VALUE)
264 294 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
265 295 @RequestMapping(value = "/tenant/assets", params = {"pageSize", "page"}, method = RequestMethod.GET)
266 296 @ResponseBody
267 297 public PageData<Asset> getTenantAssets(
  298 + @ApiParam(value = PAGE_SIZE_DESCRIPTION)
268 299 @RequestParam int pageSize,
  300 + @ApiParam(value = PAGE_NUMBER_DESCRIPTION)
269 301 @RequestParam int page,
  302 + @ApiParam(value = ASSET_TYPE_DESCRIPTION)
270 303 @RequestParam(required = false) String type,
  304 + @ApiParam(value = ASSET_TEXT_SEARCH_DESCRIPTION)
271 305 @RequestParam(required = false) String textSearch,
  306 + @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = ASSET_SORT_PROPERTY_ALLOWABLE_VALUES)
272 307 @RequestParam(required = false) String sortProperty,
  308 + @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES)
273 309 @RequestParam(required = false) String sortOrder) throws ThingsboardException {
274 310 try {
275 311 TenantId tenantId = getCurrentUser().getTenantId();
... ... @@ -284,15 +320,24 @@ public class AssetController extends BaseController {
284 320 }
285 321 }
286 322
  323 + @ApiOperation(value = "Get Tenant Asset Infos (getTenantAssetInfos)",
  324 + notes = "Returns a page of assets info objects owned by tenant. " +
  325 + PAGE_DATA_PARAMETERS + ASSET_INFO_DESCRIPTION, produces = MediaType.APPLICATION_JSON_VALUE)
287 326 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
288 327 @RequestMapping(value = "/tenant/assetInfos", params = {"pageSize", "page"}, method = RequestMethod.GET)
289 328 @ResponseBody
290 329 public PageData<AssetInfo> getTenantAssetInfos(
  330 + @ApiParam(value = PAGE_SIZE_DESCRIPTION)
291 331 @RequestParam int pageSize,
  332 + @ApiParam(value = PAGE_NUMBER_DESCRIPTION)
292 333 @RequestParam int page,
  334 + @ApiParam(value = ASSET_TYPE_DESCRIPTION)
293 335 @RequestParam(required = false) String type,
  336 + @ApiParam(value = ASSET_TEXT_SEARCH_DESCRIPTION)
294 337 @RequestParam(required = false) String textSearch,
  338 + @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = ASSET_SORT_PROPERTY_ALLOWABLE_VALUES)
295 339 @RequestParam(required = false) String sortProperty,
  340 + @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES)
296 341 @RequestParam(required = false) String sortOrder) throws ThingsboardException {
297 342 try {
298 343 TenantId tenantId = getCurrentUser().getTenantId();
... ... @@ -307,10 +352,14 @@ public class AssetController extends BaseController {
307 352 }
308 353 }
309 354
  355 + @ApiOperation(value = "Get Tenant Asset (getTenantAsset)",
  356 + notes = "Requested asset must be owned by tenant that the user belongs to. " +
  357 + "Asset name is an unique property of asset. So it can be used to identify the asset.", produces = MediaType.APPLICATION_JSON_VALUE)
310 358 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
311 359 @RequestMapping(value = "/tenant/assets", params = {"assetName"}, method = RequestMethod.GET)
312 360 @ResponseBody
313 361 public Asset getTenantAsset(
  362 + @ApiParam(value = ASSET_NAME_DESCRIPTION)
314 363 @RequestParam String assetName) throws ThingsboardException {
315 364 try {
316 365 TenantId tenantId = getCurrentUser().getTenantId();
... ... @@ -320,16 +369,26 @@ public class AssetController extends BaseController {
320 369 }
321 370 }
322 371
  372 + @ApiOperation(value = "Get Customer Assets (getCustomerAssets)",
  373 + notes = "Returns a page of assets objects assigned to customer. " +
  374 + PAGE_DATA_PARAMETERS, produces = MediaType.APPLICATION_JSON_VALUE)
323 375 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
324 376 @RequestMapping(value = "/customer/{customerId}/assets", params = {"pageSize", "page"}, method = RequestMethod.GET)
325 377 @ResponseBody
326 378 public PageData<Asset> getCustomerAssets(
  379 + @ApiParam(value = CUSTOMER_ID_PARAM_DESCRIPTION)
327 380 @PathVariable("customerId") String strCustomerId,
  381 + @ApiParam(value = PAGE_SIZE_DESCRIPTION)
328 382 @RequestParam int pageSize,
  383 + @ApiParam(value = PAGE_NUMBER_DESCRIPTION)
329 384 @RequestParam int page,
  385 + @ApiParam(value = ASSET_TYPE_DESCRIPTION)
330 386 @RequestParam(required = false) String type,
  387 + @ApiParam(value = ASSET_TEXT_SEARCH_DESCRIPTION)
331 388 @RequestParam(required = false) String textSearch,
  389 + @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = ASSET_SORT_PROPERTY_ALLOWABLE_VALUES)
332 390 @RequestParam(required = false) String sortProperty,
  391 + @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES)
333 392 @RequestParam(required = false) String sortOrder) throws ThingsboardException {
334 393 checkParameter("customerId", strCustomerId);
335 394 try {
... ... @@ -347,16 +406,26 @@ public class AssetController extends BaseController {
347 406 }
348 407 }
349 408
  409 + @ApiOperation(value = "Get Customer Asset Infos (getCustomerAssetInfos)",
  410 + notes = "Returns a page of assets info objects assigned to customer. " +
  411 + PAGE_DATA_PARAMETERS + ASSET_INFO_DESCRIPTION, produces = MediaType.APPLICATION_JSON_VALUE)
350 412 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
351 413 @RequestMapping(value = "/customer/{customerId}/assetInfos", params = {"pageSize", "page"}, method = RequestMethod.GET)
352 414 @ResponseBody
353 415 public PageData<AssetInfo> getCustomerAssetInfos(
  416 + @ApiParam(value = CUSTOMER_ID_PARAM_DESCRIPTION)
354 417 @PathVariable("customerId") String strCustomerId,
  418 + @ApiParam(value = PAGE_SIZE_DESCRIPTION)
355 419 @RequestParam int pageSize,
  420 + @ApiParam(value = PAGE_NUMBER_DESCRIPTION)
356 421 @RequestParam int page,
  422 + @ApiParam(value = ASSET_TYPE_DESCRIPTION)
357 423 @RequestParam(required = false) String type,
  424 + @ApiParam(value = ASSET_TEXT_SEARCH_DESCRIPTION)
358 425 @RequestParam(required = false) String textSearch,
  426 + @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = ASSET_SORT_PROPERTY_ALLOWABLE_VALUES)
359 427 @RequestParam(required = false) String sortProperty,
  428 + @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES)
360 429 @RequestParam(required = false) String sortOrder) throws ThingsboardException {
361 430 checkParameter("customerId", strCustomerId);
362 431 try {
... ... @@ -374,10 +443,13 @@ public class AssetController extends BaseController {
374 443 }
375 444 }
376 445
  446 + @ApiOperation(value = "Get Assets By Ids (getAssetsByIds)",
  447 + notes = "Requested assets must be owned by tenant or assigned to customer which user is performing the request. ", produces = MediaType.APPLICATION_JSON_VALUE)
377 448 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
378 449 @RequestMapping(value = "/assets", params = {"assetIds"}, method = RequestMethod.GET)
379 450 @ResponseBody
380 451 public List<Asset> getAssetsByIds(
  452 + @ApiParam(value = "A list of assets ids, separated by comma ','")
381 453 @RequestParam("assetIds") String[] strAssetIds) throws ThingsboardException {
382 454 checkArrayParameter("assetIds", strAssetIds);
383 455 try {
... ... @@ -400,6 +472,10 @@ public class AssetController extends BaseController {
400 472 }
401 473 }
402 474
  475 + @ApiOperation(value = "Find related assets (findByQuery)",
  476 + notes = "Returns all assets that are related to the specific entity. " +
  477 + "The entity id, relation type, asset types, depth of the search, and other query parameters defined using complex 'AssetSearchQuery' object. " +
  478 + "See 'Model' tab of the Parameters for more info.", produces = MediaType.APPLICATION_JSON_VALUE)
403 479 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
404 480 @RequestMapping(value = "/assets", method = RequestMethod.POST)
405 481 @ResponseBody
... ... @@ -424,6 +500,8 @@ public class AssetController extends BaseController {
424 500 }
425 501 }
426 502
  503 + @ApiOperation(value = "Get Asset Types (getAssetTypes)",
  504 + notes = "Returns a set of unique asset types based on assets that are either owned by the tenant or assigned to the customer which user is performing the request.", produces = MediaType.APPLICATION_JSON_VALUE)
427 505 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
428 506 @RequestMapping(value = "/asset/types", method = RequestMethod.GET)
429 507 @ResponseBody
... ... @@ -438,11 +516,15 @@ public class AssetController extends BaseController {
438 516 }
439 517 }
440 518
  519 + @ApiOperation(value = "Assign asset to edge (assignAssetToEdge)",
  520 + notes = "Creates assignment of an existing asset to an instance of The Edge. " +
  521 + "The Edge is a software product for edge computing. " +
  522 + "It allows bringing data analysis and management to the edge, while seamlessly synchronizing with the platform server (cloud). ", produces = MediaType.APPLICATION_JSON_VALUE)
441 523 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
442 524 @RequestMapping(value = "/edge/{edgeId}/asset/{assetId}", method = RequestMethod.POST)
443 525 @ResponseBody
444   - public Asset assignAssetToEdge(@PathVariable(EDGE_ID) String strEdgeId,
445   - @PathVariable(ASSET_ID) String strAssetId) throws ThingsboardException {
  526 + public Asset assignAssetToEdge(@ApiParam(value = EDGE_ID_PARAM_DESCRIPTION) @PathVariable(EDGE_ID) String strEdgeId,
  527 + @ApiParam(value = ASSET_ID_PARAM_DESCRIPTION) @PathVariable(ASSET_ID) String strAssetId) throws ThingsboardException {
446 528 checkParameter(EDGE_ID, strEdgeId);
447 529 checkParameter(ASSET_ID, strAssetId);
448 530 try {
... ... @@ -471,11 +553,13 @@ public class AssetController extends BaseController {
471 553 }
472 554 }
473 555
  556 + @ApiOperation(value = "Unassign asset from edge (unassignAssetFromEdge)",
  557 + notes = "Clears assignment of the asset to the edge", produces = MediaType.APPLICATION_JSON_VALUE)
474 558 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
475 559 @RequestMapping(value = "/edge/{edgeId}/asset/{assetId}", method = RequestMethod.DELETE)
476 560 @ResponseBody
477   - public Asset unassignAssetFromEdge(@PathVariable(EDGE_ID) String strEdgeId,
478   - @PathVariable(ASSET_ID) String strAssetId) throws ThingsboardException {
  561 + public Asset unassignAssetFromEdge(@ApiParam(value = EDGE_ID_PARAM_DESCRIPTION) @PathVariable(EDGE_ID) String strEdgeId,
  562 + @ApiParam(value = ASSET_ID_PARAM_DESCRIPTION) @PathVariable(ASSET_ID) String strAssetId) throws ThingsboardException {
479 563 checkParameter(EDGE_ID, strEdgeId);
480 564 checkParameter(ASSET_ID, strAssetId);
481 565 try {
... ... @@ -504,18 +588,30 @@ public class AssetController extends BaseController {
504 588 }
505 589 }
506 590
  591 + @ApiOperation(value = "Get assets assigned to edge (getEdgeAssets)",
  592 + notes = "Returns a page of assets assigned to edge. " +
  593 + PAGE_DATA_PARAMETERS, produces = MediaType.APPLICATION_JSON_VALUE)
507 594 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
508 595 @RequestMapping(value = "/edge/{edgeId}/assets", params = {"pageSize", "page"}, method = RequestMethod.GET)
509 596 @ResponseBody
510 597 public PageData<Asset> getEdgeAssets(
  598 + @ApiParam(value = EDGE_ID_PARAM_DESCRIPTION)
511 599 @PathVariable(EDGE_ID) String strEdgeId,
  600 + @ApiParam(value = PAGE_SIZE_DESCRIPTION)
512 601 @RequestParam int pageSize,
  602 + @ApiParam(value = PAGE_NUMBER_DESCRIPTION)
513 603 @RequestParam int page,
  604 + @ApiParam(value = ASSET_TYPE_DESCRIPTION)
514 605 @RequestParam(required = false) String type,
  606 + @ApiParam(value = ASSET_TEXT_SEARCH_DESCRIPTION)
515 607 @RequestParam(required = false) String textSearch,
  608 + @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = ASSET_SORT_PROPERTY_ALLOWABLE_VALUES)
516 609 @RequestParam(required = false) String sortProperty,
  610 + @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES)
517 611 @RequestParam(required = false) String sortOrder,
  612 + @ApiParam(value = "Timestamp. Assets with creation time before it won't be queried")
518 613 @RequestParam(required = false) Long startTime,
  614 + @ApiParam(value = "Timestamp. Assets with creation time after it won't be queried")
519 615 @RequestParam(required = false) Long endTime) throws ThingsboardException {
520 616 checkParameter(EDGE_ID, strEdgeId);
521 617 try {
... ... @@ -547,6 +643,8 @@ public class AssetController extends BaseController {
547 643 }
548 644 }
549 645
  646 + @ApiOperation(value = "Import the bulk of assets (processAssetsBulkImport)",
  647 + notes = "There's an ability to import the bulk of assets using the only .csv file.", produces = MediaType.APPLICATION_JSON_VALUE)
550 648 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')")
551 649 @PostMapping("/asset/bulk_import")
552 650 public BulkImportResult<Asset> processAssetsBulkImport(@RequestBody BulkImportRequest request) throws Exception {
... ...
... ... @@ -154,6 +154,10 @@ import static org.thingsboard.server.dao.service.Validator.validateId;
154 154 public abstract class BaseController {
155 155
156 156 /*Swagger UI description*/
  157 +
  158 + public static final String CUSTOMER_ID = "customerId";
  159 + public static final String TENANT_ID = "tenantId";
  160 +
157 161 public static final String PAGE_DATA_PARAMETERS = "You can specify parameters to filter the results. " +
158 162 "The result is wrapped with PageData object that allows you to iterate over result set using pagination. " +
159 163 "See the 'Model' tab of the Response Class for more details. ";
... ... @@ -163,24 +167,31 @@ public abstract class BaseController {
163 167 public static final String TENANT_ID_PARAM_DESCRIPTION = "A string value representing the tenant id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";
164 168 public static final String EDGE_ID_PARAM_DESCRIPTION = "A string value representing the edge id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";
165 169 public static final String CUSTOMER_ID_PARAM_DESCRIPTION = "A string value representing the customer id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";
166   - public static final String CUSTOMER_ID = "customerId";
167   - public static final String TENANT_ID = "tenantId";
  170 + public static final String ASSET_ID_PARAM_DESCRIPTION = "A string value representing the asset id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";
  171 +
168 172
169 173 protected final String PAGE_SIZE_DESCRIPTION = "Maximum amount of entities in a one page";
170 174 protected final String PAGE_NUMBER_DESCRIPTION = "Sequence number of page starting from 0";
171 175 protected final String DEVICE_TYPE_DESCRIPTION = "Device type as the name of the device profile";
  176 + protected final String ASSET_TYPE_DESCRIPTION = "Asset type";
  177 +
  178 + protected final String ASSET_TEXT_SEARCH_DESCRIPTION = "The case insensitive 'startsWith' filter based on the asset name.";
172 179 protected final String DASHBOARD_TEXT_SEARCH_DESCRIPTION = "The case insensitive 'startsWith' filter based on the dashboard title.";
173 180 protected final String DEVICE_TEXT_SEARCH_DESCRIPTION = "The case insensitive 'startsWith' filter based on the device name.";
174 181 protected final String CUSTOMER_TEXT_SEARCH_DESCRIPTION = "The case insensitive 'startsWith' filter based on the customer title.";
175   - protected final String SORT_PROPERTY_DESCRIPTION = "Property of device to sort by";
  182 + protected final String SORT_PROPERTY_DESCRIPTION = "Property of entity to sort by";
176 183 protected final String DASHBOARD_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, title";
177 184 protected final String CUSTOMER_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, title, email, country, city";
178   - protected final String DEVICE_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, name, label, type";
179   - protected final String SORT_ORDER_DESCRIPTION = "Sort order. ASC (ASCENDING) or DESCENDING (DESC)";
  185 + protected final String DEVICE_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, name, deviceProfileName, label, customerTitle";
  186 + protected final String ASSET_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, name, type, label, customerTitle";
  187 + protected final String SORT_ORDER_DESCRIPTION = "Sort order. ASC (ASCENDING) or DESC (DESCENDING)";
180 188 protected final String SORT_ORDER_ALLOWABLE_VALUES = "ASC, DESC";
181 189 protected final String DEVICE_INFO_DESCRIPTION = "Device Info is an extension of the default Device object that contains information about the assigned customer name and device profile name. ";
  190 + protected final String ASSET_INFO_DESCRIPTION = "Asset Info is an extension of the default Asset object that contains information about the assigned customer name. ";
182 191
183 192
  193 + protected final String DEVICE_NAME_DESCRIPTION = "A string value representing the Device name.";
  194 + protected final String ASSET_NAME_DESCRIPTION = "A string value representing the Asset name.";
184 195
185 196 public static final String INCORRECT_TENANT_ID = "Incorrect tenantId ";
186 197 protected static final String DEFAULT_DASHBOARD = "defaultDashboardId";
... ... @@ -926,7 +937,7 @@ public abstract class BaseController {
926 937 PageDataIterableByTenantIdEntityId<EdgeId> relatedEdgeIdsIterator =
927 938 new PageDataIterableByTenantIdEntityId<>(edgeService::findRelatedEdgeIdsByEntityId, tenantId, entityId, DEFAULT_PAGE_SIZE);
928 939 List<EdgeId> result = new ArrayList<>();
929   - for(EdgeId edgeId : relatedEdgeIdsIterator) {
  940 + for (EdgeId edgeId : relatedEdgeIdsIterator) {
930 941 result.add(edgeId);
931 942 }
932 943 return result;
... ...
... ... @@ -120,8 +120,8 @@ public class DeviceController extends BaseController {
120 120
121 121 @ApiOperation(value = "Get Device Info (getDeviceInfoById)",
122 122 notes = "Fetch the Device Info object based on the provided Device Id. " +
123   - "If the user has the authority of 'Tenant Administrator', the server checks that the device is owned by the same tenant. " +
124   - "If the user has the authority of 'Customer User', the server checks that the device is assigned to the same customer. " + DEVICE_INFO_DESCRIPTION)
  123 + "If the user has the authority of 'Tenant Administrator', the server checks that the device is owned by the same tenant. " +
  124 + "If the user has the authority of 'Customer User', the server checks that the device is assigned to the same customer. " + DEVICE_INFO_DESCRIPTION)
125 125 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
126 126 @RequestMapping(value = "/device/info/{deviceId}", method = RequestMethod.GET)
127 127 @ResponseBody
... ... @@ -185,7 +185,7 @@ public class DeviceController extends BaseController {
185 185 }
186 186
187 187 @ApiOperation(value = "Delete device (deleteDevice)",
188   - notes = "Deletes the device and it's credentials. Referencing non-existing device Id will cause an error.")
  188 + notes = "Deletes the device, it's credentials and all the relations (from and to the device). Referencing non-existing device Id will cause an error.")
189 189 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
190 190 @RequestMapping(value = "/device/{deviceId}", method = RequestMethod.DELETE)
191 191 @ResponseStatus(value = HttpStatus.OK)
... ... @@ -440,12 +440,13 @@ public class DeviceController extends BaseController {
440 440 }
441 441
442 442 @ApiOperation(value = "Get Tenant Device (getTenantDevice)",
443   - notes = "Requested device must be owned by tenant of customer that the user belongs to. " +
  443 + notes = "Requested device must be owned by tenant that the user belongs to. " +
444 444 "Device name is an unique property of device. So it can be used to identify the device.")
445 445 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
446 446 @RequestMapping(value = "/tenant/devices", params = {"deviceName"}, method = RequestMethod.GET)
447 447 @ResponseBody
448 448 public Device getTenantDevice(
  449 + @ApiParam(value = DEVICE_NAME_DESCRIPTION)
449 450 @RequestParam String deviceName) throws ThingsboardException {
450 451 try {
451 452 TenantId tenantId = getCurrentUser().getTenantId();
... ...
... ... @@ -15,6 +15,9 @@
15 15 */
16 16 package org.thingsboard.server.common.data.asset;
17 17
  18 +import com.fasterxml.jackson.databind.JsonNode;
  19 +import io.swagger.annotations.ApiModel;
  20 +import io.swagger.annotations.ApiModelProperty;
18 21 import lombok.EqualsAndHashCode;
19 22 import org.thingsboard.server.common.data.HasCustomerId;
20 23 import org.thingsboard.server.common.data.HasName;
... ... @@ -27,6 +30,7 @@ import org.thingsboard.server.common.data.validation.NoXss;
27 30
28 31 import java.util.Optional;
29 32
  33 +@ApiModel
30 34 @EqualsAndHashCode(callSuper = true)
31 35 public class Asset extends SearchTextBasedWithAdditionalInfo<AssetId> implements HasName, HasTenantId, HasCustomerId {
32 36
... ... @@ -67,6 +71,22 @@ public class Asset extends SearchTextBasedWithAdditionalInfo<AssetId> implements
67 71 Optional.ofNullable(asset.getAdditionalInfo()).ifPresent(this::setAdditionalInfo);
68 72 }
69 73
  74 + @ApiModelProperty(position = 1, value = "JSON object with the asset Id. " +
  75 + "Specify this field to update the asset. " +
  76 + "Referencing non-existing asset Id will cause error. " +
  77 + "Omit this field to create new asset.")
  78 + @Override
  79 + public AssetId getId() {
  80 + return super.getId();
  81 + }
  82 +
  83 + @ApiModelProperty(position = 2, value = "Timestamp of the asset creation, in milliseconds", example = "1609459200000", readOnly = true)
  84 + @Override
  85 + public long getCreatedTime() {
  86 + return super.getCreatedTime();
  87 + }
  88 +
  89 + @ApiModelProperty(position = 3, value = "JSON object with Tenant Id.", readOnly = true)
70 90 public TenantId getTenantId() {
71 91 return tenantId;
72 92 }
... ... @@ -75,6 +95,7 @@ public class Asset extends SearchTextBasedWithAdditionalInfo<AssetId> implements
75 95 this.tenantId = tenantId;
76 96 }
77 97
  98 + @ApiModelProperty(position = 4, value = "JSON object with Customer Id. Use 'assignAssetToCustomer' to change the Customer Id.", readOnly = true)
78 99 public CustomerId getCustomerId() {
79 100 return customerId;
80 101 }
... ... @@ -83,6 +104,7 @@ public class Asset extends SearchTextBasedWithAdditionalInfo<AssetId> implements
83 104 this.customerId = customerId;
84 105 }
85 106
  107 + @ApiModelProperty(position = 5, required = true, value = "Unique Asset Name in scope of Tenant", example = "Empire State Building")
86 108 @Override
87 109 public String getName() {
88 110 return name;
... ... @@ -92,6 +114,7 @@ public class Asset extends SearchTextBasedWithAdditionalInfo<AssetId> implements
92 114 this.name = name;
93 115 }
94 116
  117 + @ApiModelProperty(position = 6, required = true, value = "Asset type", example = "Building")
95 118 public String getType() {
96 119 return type;
97 120 }
... ... @@ -100,6 +123,7 @@ public class Asset extends SearchTextBasedWithAdditionalInfo<AssetId> implements
100 123 this.type = type;
101 124 }
102 125
  126 + @ApiModelProperty(position = 7, required = true, value = "Label that may be used in widgets", example = "NY Building")
103 127 public String getLabel() {
104 128 return label;
105 129 }
... ... @@ -113,6 +137,12 @@ public class Asset extends SearchTextBasedWithAdditionalInfo<AssetId> implements
113 137 return getName();
114 138 }
115 139
  140 + @ApiModelProperty(position = 8, value = "Additional parameters of the asset", dataType = "com.fasterxml.jackson.databind.JsonNode")
  141 + @Override
  142 + public JsonNode getAdditionalInfo() {
  143 + return super.getAdditionalInfo();
  144 + }
  145 +
116 146 @Override
117 147 public String toString() {
118 148 StringBuilder builder = new StringBuilder();
... ...
... ... @@ -15,13 +15,18 @@
15 15 */
16 16 package org.thingsboard.server.common.data.asset;
17 17
  18 +import io.swagger.annotations.ApiModel;
  19 +import io.swagger.annotations.ApiModelProperty;
18 20 import lombok.Data;
19 21 import org.thingsboard.server.common.data.id.AssetId;
20 22
  23 +@ApiModel
21 24 @Data
22 25 public class AssetInfo extends Asset {
23 26
  27 + @ApiModelProperty(position = 9, value = "Title of the Customer that owns the asset.", readOnly = true)
24 28 private String customerTitle;
  29 + @ApiModelProperty(position = 10, value = "Indicates special 'Public' Customer that is auto-generated to use the assets on public dashboards.", readOnly = true)
25 30 private boolean customerIsPublic;
26 31
27 32 public AssetInfo() {
... ...
... ... @@ -15,6 +15,7 @@
15 15 */
16 16 package org.thingsboard.server.common.data.asset;
17 17
  18 +import io.swagger.annotations.ApiModelProperty;
18 19 import lombok.Data;
19 20 import org.thingsboard.server.common.data.EntityType;
20 21 import org.thingsboard.server.common.data.relation.EntityRelation;
... ... @@ -31,8 +32,11 @@ import java.util.List;
31 32 @Data
32 33 public class AssetSearchQuery {
33 34
  35 + @ApiModelProperty(position = 3, value = "Main search parameters.")
34 36 private RelationsSearchParameters parameters;
  37 + @ApiModelProperty(position = 1, value = "Type of the relation between root entity and asset (e.g. 'Contains' or 'Manages').")
35 38 private String relationType;
  39 + @ApiModelProperty(position = 2, value = "Array of asset types to filter the related entities (e.g. 'Building', 'Vehicle').")
36 40 private List<String> assetTypes;
37 41
38 42 public EntityRelationsQuery toEntitySearchQuery() {
... ...