Commit ab356a4bc97528d29926733bd85ad13c61264509

Authored by Andrew Shvayka
Committed by GitHub
2 parents e264f7b8 8cb0622d

Merge pull request #5279 from thingsboard/feature/swagger

Swagger Annotations to improve the auto-generated REST API doc.
Showing 64 changed files with 1191 additions and 136 deletions
... ... @@ -16,6 +16,8 @@
16 16 package org.thingsboard.server.controller;
17 17
18 18 import com.fasterxml.jackson.databind.node.ObjectNode;
  19 +import io.swagger.annotations.ApiOperation;
  20 +import io.swagger.annotations.ApiParam;
19 21 import org.springframework.beans.factory.annotation.Autowired;
20 22 import org.springframework.security.access.prepost.PreAuthorize;
21 23 import org.springframework.web.bind.annotation.PathVariable;
... ... @@ -44,6 +46,7 @@ import org.thingsboard.server.service.update.UpdateService;
44 46 @RequestMapping("/api/admin")
45 47 public class AdminController extends BaseController {
46 48
  49 + public static final String SYS_ADMIN_AUTHORITY_ONLY = " Available for users with System Administrator ('SYS_ADMIN') authority only.";
47 50 @Autowired
48 51 private MailService mailService;
49 52
... ... @@ -59,10 +62,14 @@ public class AdminController extends BaseController {
59 62 @Autowired
60 63 private UpdateService updateService;
61 64
  65 + @ApiOperation(value = "Get the Administration Settings object using key (getAdminSettings)",
  66 + notes = "Get the Administration Settings object using specified string key. Referencing non-existing key will cause an error." + SYS_ADMIN_AUTHORITY_ONLY)
62 67 @PreAuthorize("hasAuthority('SYS_ADMIN')")
63 68 @RequestMapping(value = "/settings/{key}", method = RequestMethod.GET)
64 69 @ResponseBody
65   - public AdminSettings getAdminSettings(@PathVariable("key") String key) throws ThingsboardException {
  70 + public AdminSettings getAdminSettings(
  71 + @ApiParam(value = "A string value of the key (e.g. 'general' or 'mail').")
  72 + @PathVariable("key") String key) throws ThingsboardException {
66 73 try {
67 74 accessControlService.checkPermission(getCurrentUser(), Resource.ADMIN_SETTINGS, Operation.READ);
68 75 AdminSettings adminSettings = checkNotNull(adminSettingsService.findAdminSettingsByKey(TenantId.SYS_TENANT_ID, key));
... ... @@ -75,10 +82,17 @@ public class AdminController extends BaseController {
75 82 }
76 83 }
77 84
  85 +
  86 + @ApiOperation(value = "Get the Administration Settings object using key (getAdminSettings)",
  87 + notes = "Creates or Updates the Administration Settings. Platform generates random Administration Settings Id during settings creation. " +
  88 + "The Administration Settings Id will be present in the response. Specify the Administration Settings Id when you would like to update the Administration Settings. " +
  89 + "Referencing non-existing Administration Settings Id will cause an error." + SYS_ADMIN_AUTHORITY_ONLY)
78 90 @PreAuthorize("hasAuthority('SYS_ADMIN')")
79 91 @RequestMapping(value = "/settings", method = RequestMethod.POST)
80 92 @ResponseBody
81   - public AdminSettings saveAdminSettings(@RequestBody AdminSettings adminSettings) throws ThingsboardException {
  93 + public AdminSettings saveAdminSettings(
  94 + @ApiParam(value = "A JSON value representing the Administration Settings.")
  95 + @RequestBody AdminSettings adminSettings) throws ThingsboardException {
82 96 try {
83 97 accessControlService.checkPermission(getCurrentUser(), Resource.ADMIN_SETTINGS, Operation.WRITE);
84 98 adminSettings = checkNotNull(adminSettingsService.saveAdminSettings(TenantId.SYS_TENANT_ID, adminSettings));
... ... @@ -94,6 +108,8 @@ public class AdminController extends BaseController {
94 108 }
95 109 }
96 110
  111 + @ApiOperation(value = "Get the Security Settings object",
  112 + notes = "Get the Security Settings object that contains password policy, etc." + SYS_ADMIN_AUTHORITY_ONLY)
97 113 @PreAuthorize("hasAuthority('SYS_ADMIN')")
98 114 @RequestMapping(value = "/securitySettings", method = RequestMethod.GET)
99 115 @ResponseBody
... ... @@ -106,10 +122,14 @@ public class AdminController extends BaseController {
106 122 }
107 123 }
108 124
  125 + @ApiOperation(value = "Update Security Settings (saveSecuritySettings)",
  126 + notes = "Updates the Security Settings object that contains password policy, etc." + SYS_ADMIN_AUTHORITY_ONLY)
109 127 @PreAuthorize("hasAuthority('SYS_ADMIN')")
110 128 @RequestMapping(value = "/securitySettings", method = RequestMethod.POST)
111 129 @ResponseBody
112   - public SecuritySettings saveSecuritySettings(@RequestBody SecuritySettings securitySettings) throws ThingsboardException {
  130 + public SecuritySettings saveSecuritySettings(
  131 + @ApiParam(value = "A JSON value representing the Security Settings.")
  132 + @RequestBody SecuritySettings securitySettings) throws ThingsboardException {
113 133 try {
114 134 accessControlService.checkPermission(getCurrentUser(), Resource.ADMIN_SETTINGS, Operation.WRITE);
115 135 securitySettings = checkNotNull(systemSecurityService.saveSecuritySettings(TenantId.SYS_TENANT_ID, securitySettings));
... ... @@ -119,14 +139,19 @@ public class AdminController extends BaseController {
119 139 }
120 140 }
121 141
  142 + @ApiOperation(value = "Send test email (sendTestMail)",
  143 + notes = "Attempts to send test email to the System Administrator User using Mail Settings provided as a parameter. " +
  144 + "You may change the 'To' email in the user profile of the System Administrator. " + SYS_ADMIN_AUTHORITY_ONLY)
122 145 @PreAuthorize("hasAuthority('SYS_ADMIN')")
123 146 @RequestMapping(value = "/settings/testMail", method = RequestMethod.POST)
124   - public void sendTestMail(@RequestBody AdminSettings adminSettings) throws ThingsboardException {
  147 + public void sendTestMail(
  148 + @ApiParam(value = "A JSON value representing the Mail Settings.")
  149 + @RequestBody AdminSettings adminSettings) throws ThingsboardException {
125 150 try {
126 151 accessControlService.checkPermission(getCurrentUser(), Resource.ADMIN_SETTINGS, Operation.READ);
127 152 adminSettings = checkNotNull(adminSettings);
128 153 if (adminSettings.getKey().equals("mail")) {
129   - if(!adminSettings.getJsonValue().has("password")) {
  154 + if (!adminSettings.getJsonValue().has("password")) {
130 155 AdminSettings mailSettings = checkNotNull(adminSettingsService.findAdminSettingsByKey(TenantId.SYS_TENANT_ID, "mail"));
131 156 ((ObjectNode) adminSettings.getJsonValue()).put("password", mailSettings.getJsonValue().get("password").asText());
132 157 }
... ... @@ -138,9 +163,14 @@ public class AdminController extends BaseController {
138 163 }
139 164 }
140 165
  166 + @ApiOperation(value = "Send test sms (sendTestMail)",
  167 + notes = "Attempts to send test sms to the System Administrator User using SMS Settings and phone number provided as a parameters of the request. "
  168 + + SYS_ADMIN_AUTHORITY_ONLY)
141 169 @PreAuthorize("hasAuthority('SYS_ADMIN')")
142 170 @RequestMapping(value = "/settings/testSms", method = RequestMethod.POST)
143   - public void sendTestSms(@RequestBody TestSmsRequest testSmsRequest) throws ThingsboardException {
  171 + public void sendTestSms(
  172 + @ApiParam(value = "A JSON value representing the Test SMS request.")
  173 + @RequestBody TestSmsRequest testSmsRequest) throws ThingsboardException {
144 174 try {
145 175 accessControlService.checkPermission(getCurrentUser(), Resource.ADMIN_SETTINGS, Operation.READ);
146 176 smsService.sendTestSms(testSmsRequest);
... ... @@ -149,6 +179,9 @@ public class AdminController extends BaseController {
149 179 }
150 180 }
151 181
  182 + @ApiOperation(value = "Check for new Platform Releases (checkUpdates)",
  183 + notes = "Check notifications about new platform releases. "
  184 + + SYS_ADMIN_AUTHORITY_ONLY)
152 185 @PreAuthorize("hasAuthority('SYS_ADMIN')")
153 186 @RequestMapping(value = "/updates", method = RequestMethod.GET)
154 187 @ResponseBody
... ...
... ... @@ -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 {
... ...
... ... @@ -18,6 +18,8 @@ package org.thingsboard.server.controller;
18 18 import com.fasterxml.jackson.databind.JsonNode;
19 19 import com.fasterxml.jackson.databind.ObjectMapper;
20 20 import com.fasterxml.jackson.databind.node.ObjectNode;
  21 +import io.swagger.annotations.ApiOperation;
  22 +import io.swagger.annotations.ApiParam;
21 23 import lombok.RequiredArgsConstructor;
22 24 import lombok.extern.slf4j.Slf4j;
23 25 import org.springframework.context.ApplicationEventPublisher;
... ... @@ -48,8 +50,13 @@ import org.thingsboard.server.common.data.security.model.SecuritySettings;
48 50 import org.thingsboard.server.common.data.security.model.UserPasswordPolicy;
49 51 import org.thingsboard.server.dao.audit.AuditLogService;
50 52 import org.thingsboard.server.queue.util.TbCoreComponent;
  53 +import org.thingsboard.server.service.security.model.ActivateUserRequest;
  54 +import org.thingsboard.server.service.security.model.ChangePasswordRequest;
  55 +import org.thingsboard.server.service.security.model.ResetPasswordEmailRequest;
  56 +import org.thingsboard.server.service.security.model.ResetPasswordRequest;
51 57 import org.thingsboard.server.service.security.auth.jwt.RefreshTokenRepository;
52 58 import org.thingsboard.server.service.security.auth.rest.RestAuthenticationDetails;
  59 +import org.thingsboard.server.service.security.model.JwtTokenPair;
53 60 import org.thingsboard.server.service.security.model.SecurityUser;
54 61 import org.thingsboard.server.service.security.model.UserPrincipal;
55 62 import org.thingsboard.server.service.security.model.token.JwtTokenFactory;
... ... @@ -74,9 +81,13 @@ public class AuthController extends BaseController {
74 81 private final AuditLogService auditLogService;
75 82 private final ApplicationEventPublisher eventPublisher;
76 83
  84 +
  85 + @ApiOperation(value = "Get current User (getUser)",
  86 + notes = "Get the information about the User which credentials are used to perform this REST API call.")
77 87 @PreAuthorize("isAuthenticated()")
78 88 @RequestMapping(value = "/auth/user", method = RequestMethod.GET)
79   - public @ResponseBody User getUser() throws ThingsboardException {
  89 + public @ResponseBody
  90 + User getUser() throws ThingsboardException {
80 91 try {
81 92 SecurityUser securityUser = getCurrentUser();
82 93 return userService.findUserById(securityUser.getTenantId(), securityUser.getId());
... ... @@ -85,6 +96,8 @@ public class AuthController extends BaseController {
85 96 }
86 97 }
87 98
  99 + @ApiOperation(value = "Logout (logout)",
  100 + notes = "Special API call to record the 'logout' of the user to the Audit Logs. Since platform uses [JWT](https://jwt.io/), the actual logout is the procedure of clearing the [JWT](https://jwt.io/) token on the client side. ")
88 101 @PreAuthorize("isAuthenticated()")
89 102 @RequestMapping(value = "/auth/logout", method = RequestMethod.POST)
90 103 @ResponseStatus(value = HttpStatus.OK)
... ... @@ -92,13 +105,17 @@ public class AuthController extends BaseController {
92 105 logLogoutAction(request);
93 106 }
94 107
  108 + @ApiOperation(value = "Change password for current User (changePassword)",
  109 + notes = "Change the password for the User which credentials are used to perform this REST API call. Be aware that previously generated [JWT](https://jwt.io/) tokens will be still valid until they expire.")
95 110 @PreAuthorize("isAuthenticated()")
96 111 @RequestMapping(value = "/auth/changePassword", method = RequestMethod.POST)
97 112 @ResponseStatus(value = HttpStatus.OK)
98   - public ObjectNode changePassword(@RequestBody JsonNode changePasswordRequest) throws ThingsboardException {
  113 + public ObjectNode changePassword(
  114 + @ApiParam(value = "Change Password Request")
  115 + @RequestBody ChangePasswordRequest changePasswordRequest) throws ThingsboardException {
99 116 try {
100   - String currentPassword = changePasswordRequest.get("currentPassword").asText();
101   - String newPassword = changePasswordRequest.get("newPassword").asText();
  117 + String currentPassword = changePasswordRequest.getCurrentPassword();
  118 + String newPassword = changePasswordRequest.getNewPassword();
102 119 SecurityUser securityUser = getCurrentUser();
103 120 UserCredentials userCredentials = userService.findUserCredentialsByUserId(TenantId.SYS_TENANT_ID, securityUser.getId());
104 121 if (!passwordEncoder.matches(currentPassword, userCredentials.getPassword())) {
... ... @@ -123,6 +140,8 @@ public class AuthController extends BaseController {
123 140 }
124 141 }
125 142
  143 + @ApiOperation(value = "Get the current User password policy (getUserPasswordPolicy)",
  144 + notes = "API call to get the password policy for the password validation form(s).")
126 145 @RequestMapping(value = "/noauth/userPasswordPolicy", method = RequestMethod.GET)
127 146 @ResponseBody
128 147 public UserPasswordPolicy getUserPasswordPolicy() throws ThingsboardException {
... ... @@ -135,8 +154,13 @@ public class AuthController extends BaseController {
135 154 }
136 155 }
137 156
  157 + @ApiOperation(value = "Check Activate User Token (checkActivateToken)",
  158 + notes = "Checks the activation token and forwards user to 'Create Password' page. " +
  159 + "If token is valid, returns '303 See Other' (redirect) response code with the correct address of 'Create Password' page and same 'activateToken' specified in the URL parameters. " +
  160 + "If token is not valid, returns '409 Conflict'.")
138 161 @RequestMapping(value = "/noauth/activate", params = {"activateToken"}, method = RequestMethod.GET)
139 162 public ResponseEntity<String> checkActivateToken(
  163 + @ApiParam(value = "The activate token string.")
140 164 @RequestParam(value = "activateToken") String activateToken) {
141 165 HttpHeaders headers = new HttpHeaders();
142 166 HttpStatus responseStatus;
... ... @@ -157,13 +181,17 @@ public class AuthController extends BaseController {
157 181 return new ResponseEntity<>(headers, responseStatus);
158 182 }
159 183
  184 + @ApiOperation(value = "Request reset password email (requestResetPasswordByEmail)",
  185 + notes = "Request to send the reset password email if the user with specified email address is present in the database. " +
  186 + "Always return '200 OK' status for security purposes.")
160 187 @RequestMapping(value = "/noauth/resetPasswordByEmail", method = RequestMethod.POST)
161 188 @ResponseStatus(value = HttpStatus.OK)
162 189 public void requestResetPasswordByEmail(
163   - @RequestBody JsonNode resetPasswordByEmailRequest,
  190 + @ApiParam(value = "The JSON object representing the reset password email request.")
  191 + @RequestBody ResetPasswordEmailRequest resetPasswordByEmailRequest,
164 192 HttpServletRequest request) throws ThingsboardException {
165 193 try {
166   - String email = resetPasswordByEmailRequest.get("email").asText();
  194 + String email = resetPasswordByEmailRequest.getEmail();
167 195 UserCredentials userCredentials = userService.requestPasswordReset(TenantId.SYS_TENANT_ID, email);
168 196 User user = userService.findUserById(TenantId.SYS_TENANT_ID, userCredentials.getUserId());
169 197 String baseUrl = systemSecurityService.getBaseUrl(user.getTenantId(), user.getCustomerId(), request);
... ... @@ -176,8 +204,13 @@ public class AuthController extends BaseController {
176 204 }
177 205 }
178 206
  207 + @ApiOperation(value = "Check password reset token (checkResetToken)",
  208 + notes = "Checks the password reset token and forwards user to 'Reset Password' page. " +
  209 + "If token is valid, returns '303 See Other' (redirect) response code with the correct address of 'Reset Password' page and same 'resetToken' specified in the URL parameters. " +
  210 + "If token is not valid, returns '409 Conflict'.")
179 211 @RequestMapping(value = "/noauth/resetPassword", params = {"resetToken"}, method = RequestMethod.GET)
180 212 public ResponseEntity<String> checkResetToken(
  213 + @ApiParam(value = "The reset token string.")
181 214 @RequestParam(value = "resetToken") String resetToken) {
182 215 HttpHeaders headers = new HttpHeaders();
183 216 HttpStatus responseStatus;
... ... @@ -198,16 +231,24 @@ public class AuthController extends BaseController {
198 231 return new ResponseEntity<>(headers, responseStatus);
199 232 }
200 233
  234 + @ApiOperation(value = "Activate User",
  235 + notes = "Checks the activation token and updates corresponding user password in the database. " +
  236 + "Now the user may start using his password to login. " +
  237 + "The response already contains the [JWT](https://jwt.io) activation and refresh tokens, " +
  238 + "to simplify the user activation flow and avoid asking user to input password again after activation. " +
  239 + "If token is valid, returns the object that contains [JWT](https://jwt.io/) access and refresh tokens. " +
  240 + "If token is not valid, returns '404 Bad Request'.")
201 241 @RequestMapping(value = "/noauth/activate", method = RequestMethod.POST)
202 242 @ResponseStatus(value = HttpStatus.OK)
203 243 @ResponseBody
204   - public JsonNode activateUser(
205   - @RequestBody JsonNode activateRequest,
  244 + public JwtTokenPair activateUser(
  245 + @ApiParam(value = "Activate user request.")
  246 + @RequestBody ActivateUserRequest activateRequest,
206 247 @RequestParam(required = false, defaultValue = "true") boolean sendActivationMail,
207 248 HttpServletRequest request) throws ThingsboardException {
208 249 try {
209   - String activateToken = activateRequest.get("activateToken").asText();
210   - String password = activateRequest.get("password").asText();
  250 + String activateToken = activateRequest.getActivateToken();
  251 + String password = activateRequest.getPassword();
211 252 systemSecurityService.validatePassword(TenantId.SYS_TENANT_ID, password, null);
212 253 String encodedPassword = passwordEncoder.encode(password);
213 254 UserCredentials credentials = userService.activateUserCredentials(TenantId.SYS_TENANT_ID, activateToken, encodedPassword);
... ... @@ -232,25 +273,26 @@ public class AuthController extends BaseController {
232 273 JwtToken accessToken = tokenFactory.createAccessJwtToken(securityUser);
233 274 JwtToken refreshToken = refreshTokenRepository.requestRefreshToken(securityUser);
234 275
235   - ObjectMapper objectMapper = new ObjectMapper();
236   - ObjectNode tokenObject = objectMapper.createObjectNode();
237   - tokenObject.put("token", accessToken.getToken());
238   - tokenObject.put("refreshToken", refreshToken.getToken());
239   - return tokenObject;
  276 + return new JwtTokenPair(accessToken.getToken(), refreshToken.getToken());
240 277 } catch (Exception e) {
241 278 throw handleException(e);
242 279 }
243 280 }
244 281
  282 + @ApiOperation(value = "Reset password (resetPassword)",
  283 + notes = "Checks the password reset token and updates the password. " +
  284 + "If token is valid, returns the object that contains [JWT](https://jwt.io/) access and refresh tokens. " +
  285 + "If token is not valid, returns '404 Bad Request'.")
245 286 @RequestMapping(value = "/noauth/resetPassword", method = RequestMethod.POST)
246 287 @ResponseStatus(value = HttpStatus.OK)
247 288 @ResponseBody
248   - public JsonNode resetPassword(
249   - @RequestBody JsonNode resetPasswordRequest,
  289 + public JwtTokenPair resetPassword(
  290 + @ApiParam(value = "Reset password request.")
  291 + @RequestBody ResetPasswordRequest resetPasswordRequest,
250 292 HttpServletRequest request) throws ThingsboardException {
251 293 try {
252   - String resetToken = resetPasswordRequest.get("resetToken").asText();
253   - String password = resetPasswordRequest.get("password").asText();
  294 + String resetToken = resetPasswordRequest.getResetToken();
  295 + String password = resetPasswordRequest.getPassword();
254 296 UserCredentials userCredentials = userService.findUserCredentialsByResetToken(TenantId.SYS_TENANT_ID, resetToken);
255 297 if (userCredentials != null) {
256 298 systemSecurityService.validatePassword(TenantId.SYS_TENANT_ID, password, userCredentials);
... ... @@ -273,11 +315,7 @@ public class AuthController extends BaseController {
273 315 JwtToken accessToken = tokenFactory.createAccessJwtToken(securityUser);
274 316 JwtToken refreshToken = refreshTokenRepository.requestRefreshToken(securityUser);
275 317
276   - ObjectMapper objectMapper = new ObjectMapper();
277   - ObjectNode tokenObject = objectMapper.createObjectNode();
278   - tokenObject.put("token", accessToken.getToken());
279   - tokenObject.put("refreshToken", refreshToken.getToken());
280   - return tokenObject;
  318 + return new JwtTokenPair(accessToken.getToken(), refreshToken.getToken());
281 319 } else {
282 320 throw new ThingsboardException("Invalid reset token!", ThingsboardErrorCode.BAD_REQUEST_PARAMS);
283 321 }
... ...
... ... @@ -153,6 +153,46 @@ import static org.thingsboard.server.dao.service.Validator.validateId;
153 153 @TbCoreComponent
154 154 public abstract class BaseController {
155 155
  156 + /*Swagger UI description*/
  157 +
  158 + public static final String CUSTOMER_ID = "customerId";
  159 + public static final String TENANT_ID = "tenantId";
  160 +
  161 + public static final String PAGE_DATA_PARAMETERS = "You can specify parameters to filter the results. " +
  162 + "The result is wrapped with PageData object that allows you to iterate over result set using pagination. " +
  163 + "See the 'Model' tab of the Response Class for more details. ";
  164 + public static final String DASHBOARD_ID_PARAM_DESCRIPTION = "A string value representing the device id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";
  165 + public static final String DEVICE_ID_PARAM_DESCRIPTION = "A string value representing the device id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";
  166 + public static final String DEVICE_PROFILE_ID_DESCRIPTION = "A string value representing the device profile id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";
  167 + public static final String TENANT_ID_PARAM_DESCRIPTION = "A string value representing the tenant id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";
  168 + public static final String EDGE_ID_PARAM_DESCRIPTION = "A string value representing the edge id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";
  169 + public static final String CUSTOMER_ID_PARAM_DESCRIPTION = "A string value representing the customer id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";
  170 + public static final String ASSET_ID_PARAM_DESCRIPTION = "A string value representing the asset id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";
  171 +
  172 +
  173 + protected final String PAGE_SIZE_DESCRIPTION = "Maximum amount of entities in a one page";
  174 + protected final String PAGE_NUMBER_DESCRIPTION = "Sequence number of page starting from 0";
  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.";
  179 + protected final String DASHBOARD_TEXT_SEARCH_DESCRIPTION = "The case insensitive 'startsWith' filter based on the dashboard title.";
  180 + protected final String DEVICE_TEXT_SEARCH_DESCRIPTION = "The case insensitive 'startsWith' filter based on the device name.";
  181 + protected final String CUSTOMER_TEXT_SEARCH_DESCRIPTION = "The case insensitive 'startsWith' filter based on the customer title.";
  182 + protected final String SORT_PROPERTY_DESCRIPTION = "Property of entity to sort by";
  183 + protected final String DASHBOARD_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, title";
  184 + protected final String CUSTOMER_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, title, email, country, city";
  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)";
  188 + protected final String SORT_ORDER_ALLOWABLE_VALUES = "ASC, DESC";
  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. ";
  191 +
  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.";
  195 +
156 196 public static final String INCORRECT_TENANT_ID = "Incorrect tenantId ";
157 197 protected static final String DEFAULT_DASHBOARD = "defaultDashboardId";
158 198 protected static final String HOME_DASHBOARD = "homeDashboardId";
... ... @@ -897,7 +937,7 @@ public abstract class BaseController {
897 937 PageDataIterableByTenantIdEntityId<EdgeId> relatedEdgeIdsIterator =
898 938 new PageDataIterableByTenantIdEntityId<>(edgeService::findRelatedEdgeIdsByEntityId, tenantId, entityId, DEFAULT_PAGE_SIZE);
899 939 List<EdgeId> result = new ArrayList<>();
900   - for(EdgeId edgeId : relatedEdgeIdsIterator) {
  940 + for (EdgeId edgeId : relatedEdgeIdsIterator) {
901 941 result.add(edgeId);
902 942 }
903 943 return result;
... ...
... ... @@ -15,6 +15,8 @@
15 15 */
16 16 package org.thingsboard.server.controller;
17 17
  18 +import io.swagger.annotations.ApiOperation;
  19 +import io.swagger.annotations.ApiParam;
18 20 import org.apache.commons.lang3.StringUtils;
19 21 import org.springframework.security.access.prepost.PreAuthorize;
20 22 import org.springframework.web.bind.annotation.PathVariable;
... ... @@ -38,10 +40,20 @@ import java.util.Set;
38 40 @RequestMapping("/api")
39 41 public class ComponentDescriptorController extends BaseController {
40 42
  43 + private static final String COMPONENT_DESCRIPTOR_DEFINITION = "Each Component Descriptor represents configuration of specific rule node (e.g. 'Save Timeseries' or 'Send Email'.). " +
  44 + "The Component Descriptors are used by the rule chain Web UI to build the configuration forms for the rule nodes. " +
  45 + "The Component Descriptors are discovered at runtime by scanning the class path and searching for @RuleNode annotation. " +
  46 + "Once discovered, the up to date list of descriptors is persisted to the database.";
  47 +
  48 + @ApiOperation(value = "Get Component Descriptor (getComponentDescriptorByClazz)",
  49 + notes = "Gets the Component Descriptor object using class name from the path parameters. " +
  50 + COMPONENT_DESCRIPTOR_DEFINITION)
41 51 @PreAuthorize("hasAnyAuthority('SYS_ADMIN','TENANT_ADMIN')")
42 52 @RequestMapping(value = "/component/{componentDescriptorClazz:.+}", method = RequestMethod.GET)
43 53 @ResponseBody
44   - public ComponentDescriptor getComponentDescriptorByClazz(@PathVariable("componentDescriptorClazz") String strComponentDescriptorClazz) throws ThingsboardException {
  54 + public ComponentDescriptor getComponentDescriptorByClazz(
  55 + @ApiParam(value = "Component Descriptor class name", required = true)
  56 + @PathVariable("componentDescriptorClazz") String strComponentDescriptorClazz) throws ThingsboardException {
45 57 checkParameter("strComponentDescriptorClazz", strComponentDescriptorClazz);
46 58 try {
47 59 return checkComponentDescriptorByClazz(strComponentDescriptorClazz);
... ... @@ -50,11 +62,17 @@ public class ComponentDescriptorController extends BaseController {
50 62 }
51 63 }
52 64
  65 + @ApiOperation(value = "Get Component Descriptors (getComponentDescriptorsByType)",
  66 + notes = "Gets the Component Descriptors using rule node type and optional rule chain type request parameters. " +
  67 + COMPONENT_DESCRIPTOR_DEFINITION)
53 68 @PreAuthorize("hasAnyAuthority('SYS_ADMIN','TENANT_ADMIN')")
54 69 @RequestMapping(value = "/components/{componentType}", method = RequestMethod.GET)
55 70 @ResponseBody
56   - public List<ComponentDescriptor> getComponentDescriptorsByType(@PathVariable("componentType") String strComponentType,
57   - @RequestParam(value = "ruleChainType", required = false) String strRuleChainType) throws ThingsboardException {
  71 + public List<ComponentDescriptor> getComponentDescriptorsByType(
  72 + @ApiParam(value = "Type of the Rule Node", allowableValues = "ENRICHMENT,FILTER,TRANSFORMATION,ACTION,EXTERNAL", required = true)
  73 + @PathVariable("componentType") String strComponentType,
  74 + @ApiParam(value = "Type of the Rule Chain", allowableValues = "CORE,EDGE")
  75 + @RequestParam(value = "ruleChainType", required = false) String strRuleChainType) throws ThingsboardException {
58 76 checkParameter("componentType", strComponentType);
59 77 try {
60 78 return checkComponentDescriptorsByType(ComponentType.valueOf(strComponentType), getRuleChainType(strRuleChainType));
... ... @@ -63,11 +81,17 @@ public class ComponentDescriptorController extends BaseController {
63 81 }
64 82 }
65 83
  84 + @ApiOperation(value = "Get Component Descriptors (getComponentDescriptorsByTypes)",
  85 + notes = "Gets the Component Descriptors using coma separated list of rule node types and optional rule chain type request parameters. " +
  86 + COMPONENT_DESCRIPTOR_DEFINITION)
66 87 @PreAuthorize("hasAnyAuthority('SYS_ADMIN','TENANT_ADMIN')")
67 88 @RequestMapping(value = "/components", params = {"componentTypes"}, method = RequestMethod.GET)
68 89 @ResponseBody
69   - public List<ComponentDescriptor> getComponentDescriptorsByTypes(@RequestParam("componentTypes") String[] strComponentTypes,
70   - @RequestParam(value = "ruleChainType", required = false) String strRuleChainType) throws ThingsboardException {
  90 + public List<ComponentDescriptor> getComponentDescriptorsByTypes(
  91 + @ApiParam(value = "List of types of the Rule Nodes, (ENRICHMENT, FILTER, TRANSFORMATION, ACTION or EXTERNAL)", required = true)
  92 + @RequestParam("componentTypes") String[] strComponentTypes,
  93 + @ApiParam(value = "Type of the Rule Chain", allowableValues = "CORE,EDGE")
  94 + @RequestParam(value = "ruleChainType", required = false) String strRuleChainType) throws ThingsboardException {
71 95 checkArrayParameter("componentTypes", strComponentTypes);
72 96 try {
73 97 Set<ComponentType> componentTypes = new HashSet<>();
... ...
... ... @@ -18,6 +18,8 @@ package org.thingsboard.server.controller;
18 18 import com.fasterxml.jackson.databind.JsonNode;
19 19 import com.fasterxml.jackson.databind.ObjectMapper;
20 20 import com.fasterxml.jackson.databind.node.ObjectNode;
  21 +import io.swagger.annotations.ApiOperation;
  22 +import io.swagger.annotations.ApiParam;
21 23 import org.springframework.http.HttpStatus;
22 24 import org.springframework.security.access.prepost.PreAuthorize;
23 25 import org.springframework.web.bind.annotation.PathVariable;
... ... @@ -50,18 +52,23 @@ import java.util.List;
50 52 @RequestMapping("/api")
51 53 public class CustomerController extends BaseController {
52 54
53   - public static final String CUSTOMER_ID = "customerId";
54 55 public static final String IS_PUBLIC = "isPublic";
  56 + public static final String CUSTOMER_SECURITY_CHECK = "If the user has the authority of 'Tenant Administrator', the server checks that the customer is owned by the same tenant. " +
  57 + "If the user has the authority of 'Customer User', the server checks that the user belongs to the customer.";
55 58
  59 + @ApiOperation(value = "Get Customer (getCustomerById)",
  60 + notes = "Get the Customer object based on the provided Customer Id. " + CUSTOMER_SECURITY_CHECK)
56 61 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
57 62 @RequestMapping(value = "/customer/{customerId}", method = RequestMethod.GET)
58 63 @ResponseBody
59   - public Customer getCustomerById(@PathVariable(CUSTOMER_ID) String strCustomerId) throws ThingsboardException {
  64 + public Customer getCustomerById(
  65 + @ApiParam(value = CUSTOMER_ID_PARAM_DESCRIPTION)
  66 + @PathVariable(CUSTOMER_ID) String strCustomerId) throws ThingsboardException {
60 67 checkParameter(CUSTOMER_ID, strCustomerId);
61 68 try {
62 69 CustomerId customerId = new CustomerId(toUUID(strCustomerId));
63 70 Customer customer = checkCustomerId(customerId, Operation.READ);
64   - if(!customer.getAdditionalInfo().isNull()) {
  71 + if (!customer.getAdditionalInfo().isNull()) {
65 72 processDashboardIdFromAdditionalInfo((ObjectNode) customer.getAdditionalInfo(), HOME_DASHBOARD);
66 73 }
67 74 return customer;
... ... @@ -70,10 +77,15 @@ public class CustomerController extends BaseController {
70 77 }
71 78 }
72 79
  80 +
  81 + @ApiOperation(value = "Get short Customer info (getShortCustomerInfoById)",
  82 + notes = "Get the short customer object that contains only the title and 'isPublic' flag. " + CUSTOMER_SECURITY_CHECK)
73 83 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
74 84 @RequestMapping(value = "/customer/{customerId}/shortInfo", method = RequestMethod.GET)
75 85 @ResponseBody
76   - public JsonNode getShortCustomerInfoById(@PathVariable(CUSTOMER_ID) String strCustomerId) throws ThingsboardException {
  86 + public JsonNode getShortCustomerInfoById(
  87 + @ApiParam(value = CUSTOMER_ID_PARAM_DESCRIPTION)
  88 + @PathVariable(CUSTOMER_ID) String strCustomerId) throws ThingsboardException {
77 89 checkParameter(CUSTOMER_ID, strCustomerId);
78 90 try {
79 91 CustomerId customerId = new CustomerId(toUUID(strCustomerId));
... ... @@ -88,10 +100,14 @@ public class CustomerController extends BaseController {
88 100 }
89 101 }
90 102
  103 + @ApiOperation(value = "Get Customer Title (getCustomerTitleById)",
  104 + notes = "Get the title of the customer. " + CUSTOMER_SECURITY_CHECK)
91 105 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
92 106 @RequestMapping(value = "/customer/{customerId}/title", method = RequestMethod.GET, produces = "application/text")
93 107 @ResponseBody
94   - public String getCustomerTitleById(@PathVariable(CUSTOMER_ID) String strCustomerId) throws ThingsboardException {
  108 + public String getCustomerTitleById(
  109 + @ApiParam(value = CUSTOMER_ID_PARAM_DESCRIPTION)
  110 + @PathVariable(CUSTOMER_ID) String strCustomerId) throws ThingsboardException {
95 111 checkParameter(CUSTOMER_ID, strCustomerId);
96 112 try {
97 113 CustomerId customerId = new CustomerId(toUUID(strCustomerId));
... ... @@ -102,10 +118,15 @@ public class CustomerController extends BaseController {
102 118 }
103 119 }
104 120
  121 + @ApiOperation(value = "Create or update Customer (saveCustomer)",
  122 + notes = "Creates or Updates the Customer. When creating customer, platform generates Customer Id as [time-based UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_1_(date-time_and_MAC_address) " +
  123 + "The newly created Customer Id will be present in the response. " +
  124 + "Specify existing Customer Id to update the Customer. " +
  125 + "Referencing non-existing Customer Id will cause 'Not Found' error.")
105 126 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
106 127 @RequestMapping(value = "/customer", method = RequestMethod.POST)
107 128 @ResponseBody
108   - public Customer saveCustomer(@RequestBody Customer customer) throws ThingsboardException {
  129 + public Customer saveCustomer(@ApiParam(value = "A JSON value representing the customer.") @RequestBody Customer customer) throws ThingsboardException {
109 130 try {
110 131 customer.setTenantId(getCurrentUser().getTenantId());
111 132
... ... @@ -131,10 +152,13 @@ public class CustomerController extends BaseController {
131 152 }
132 153 }
133 154
  155 + @ApiOperation(value = "Delete Customer (deleteCustomer)",
  156 + notes = "Deletes the Customer and all customer Users. All assigned Dashboards, Assets, Devices, etc. will be unassigned but not deleted. Referencing non-existing Customer Id will cause an error.")
134 157 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
135 158 @RequestMapping(value = "/customer/{customerId}", method = RequestMethod.DELETE)
136 159 @ResponseStatus(value = HttpStatus.OK)
137   - public void deleteCustomer(@PathVariable(CUSTOMER_ID) String strCustomerId) throws ThingsboardException {
  160 + public void deleteCustomer(@ApiParam(value = CUSTOMER_ID_PARAM_DESCRIPTION)
  161 + @PathVariable(CUSTOMER_ID) String strCustomerId) throws ThingsboardException {
138 162 checkParameter(CUSTOMER_ID, strCustomerId);
139 163 try {
140 164 CustomerId customerId = new CustomerId(toUUID(strCustomerId));
... ... @@ -161,14 +185,23 @@ public class CustomerController extends BaseController {
161 185 }
162 186 }
163 187
  188 + @ApiOperation(value = "Get Tenant Customers (getCustomers)",
  189 + notes = "Returns a page of customers owned by tenant. " +
  190 + PAGE_DATA_PARAMETERS)
164 191 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
165 192 @RequestMapping(value = "/customers", params = {"pageSize", "page"}, method = RequestMethod.GET)
166 193 @ResponseBody
167   - public PageData<Customer> getCustomers(@RequestParam int pageSize,
168   - @RequestParam int page,
169   - @RequestParam(required = false) String textSearch,
170   - @RequestParam(required = false) String sortProperty,
171   - @RequestParam(required = false) String sortOrder) throws ThingsboardException {
  194 + public PageData<Customer> getCustomers(
  195 + @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true)
  196 + @RequestParam int pageSize,
  197 + @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true)
  198 + @RequestParam int page,
  199 + @ApiParam(value = CUSTOMER_TEXT_SEARCH_DESCRIPTION)
  200 + @RequestParam(required = false) String textSearch,
  201 + @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = CUSTOMER_SORT_PROPERTY_ALLOWABLE_VALUES)
  202 + @RequestParam(required = false) String sortProperty,
  203 + @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES)
  204 + @RequestParam(required = false) String sortOrder) throws ThingsboardException {
172 205 try {
173 206 PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder);
174 207 TenantId tenantId = getCurrentUser().getTenantId();
... ... @@ -178,10 +211,13 @@ public class CustomerController extends BaseController {
178 211 }
179 212 }
180 213
  214 + @ApiOperation(value = "Get Tenant Customer by Customer title (getTenantCustomer)",
  215 + notes = "Get the Customer using Customer Title. Available for users with 'Tenant Administrator' authority only.")
181 216 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
182 217 @RequestMapping(value = "/tenant/customers", params = {"customerTitle"}, method = RequestMethod.GET)
183 218 @ResponseBody
184 219 public Customer getTenantCustomer(
  220 + @ApiParam(value = "A string value representing the Customer title.")
185 221 @RequestParam String customerTitle) throws ThingsboardException {
186 222 try {
187 223 TenantId tenantId = getCurrentUser().getTenantId();
... ...
... ... @@ -17,8 +17,11 @@ package org.thingsboard.server.controller;
17 17
18 18 import com.fasterxml.jackson.databind.JsonNode;
19 19 import com.fasterxml.jackson.databind.node.ObjectNode;
  20 +import io.swagger.annotations.ApiOperation;
  21 +import io.swagger.annotations.ApiParam;
20 22 import org.springframework.beans.factory.annotation.Value;
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.RequestBody;
... ... @@ -68,11 +71,16 @@ public class DashboardController extends BaseController {
68 71
69 72 private static final String HOME_DASHBOARD_ID = "homeDashboardId";
70 73 private static final String HOME_DASHBOARD_HIDE_TOOLBAR = "homeDashboardHideToolbar";
  74 + public static final String DASHBOARD_INFO_DEFINITION = "The Dashboard Info object contains lightweight information about the dashboard (e.g. title, image, assigned customers) but does not contain the heavyweight configuration JSON.";
  75 + public static final String DASHBOARD_DEFINITION = "The Dashboard object is a heavyweight object that contains information about the dashboard (e.g. title, image, assigned customers) and also configuration JSON (e.g. layouts, widgets, entity aliases).";
  76 + public static final String HIDDEN_FOR_MOBILE = "Exclude dashboards that are hidden for mobile";
71 77
72 78 @Value("${dashboard.max_datapoints_limit}")
73 79 private long maxDatapointsLimit;
74 80
75   -
  81 + @ApiOperation(value = "Get server time (getServerTime)",
  82 + notes = "Get the server time (milliseconds since January 1, 1970 UTC). " +
  83 + "Used to adjust view of the dashboards according to the difference between browser and server time.")
76 84 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
77 85 @RequestMapping(value = "/dashboard/serverTime", method = RequestMethod.GET)
78 86 @ResponseBody
... ... @@ -80,6 +88,11 @@ public class DashboardController extends BaseController {
80 88 return System.currentTimeMillis();
81 89 }
82 90
  91 + @ApiOperation(value = "Get max data points limit (getMaxDatapointsLimit)",
  92 + notes = "Get the maximum number of data points that dashboard may request from the server per in a single subscription command. " +
  93 + "This value impacts the time window behavior. It impacts 'Max values' parameter in case user selects 'None' as 'Data aggregation function'. " +
  94 + "It also impacts the 'Grouping interval' in case of any other 'Data aggregation function' is selected. " +
  95 + "The actual value of the limit is configurable in the system configuration file.")
83 96 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
84 97 @RequestMapping(value = "/dashboard/maxDatapointsLimit", method = RequestMethod.GET)
85 98 @ResponseBody
... ... @@ -87,10 +100,16 @@ public class DashboardController extends BaseController {
87 100 return maxDatapointsLimit;
88 101 }
89 102
  103 + @ApiOperation(value = "Get Dashboard Info (getDashboardInfoById)",
  104 + notes = "Get the information about the dashboard based on 'dashboardId' parameter. " + DASHBOARD_INFO_DEFINITION,
  105 + produces = MediaType.APPLICATION_JSON_VALUE
  106 + )
90 107 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
91 108 @RequestMapping(value = "/dashboard/info/{dashboardId}", method = RequestMethod.GET)
92 109 @ResponseBody
93   - public DashboardInfo getDashboardInfoById(@PathVariable(DASHBOARD_ID) String strDashboardId) throws ThingsboardException {
  110 + public DashboardInfo getDashboardInfoById(
  111 + @ApiParam(value = DASHBOARD_ID_PARAM_DESCRIPTION)
  112 + @PathVariable(DASHBOARD_ID) String strDashboardId) throws ThingsboardException {
94 113 checkParameter(DASHBOARD_ID, strDashboardId);
95 114 try {
96 115 DashboardId dashboardId = new DashboardId(toUUID(strDashboardId));
... ... @@ -100,10 +119,16 @@ public class DashboardController extends BaseController {
100 119 }
101 120 }
102 121
  122 + @ApiOperation(value = "Get Dashboard (getDashboardById)",
  123 + notes = "Get the dashboard based on 'dashboardId' parameter. " + DASHBOARD_DEFINITION,
  124 + produces = MediaType.APPLICATION_JSON_VALUE
  125 + )
103 126 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
104 127 @RequestMapping(value = "/dashboard/{dashboardId}", method = RequestMethod.GET)
105 128 @ResponseBody
106   - public Dashboard getDashboardById(@PathVariable(DASHBOARD_ID) String strDashboardId) throws ThingsboardException {
  129 + public Dashboard getDashboardById(
  130 + @ApiParam(value = DASHBOARD_ID_PARAM_DESCRIPTION)
  131 + @PathVariable(DASHBOARD_ID) String strDashboardId) throws ThingsboardException {
107 132 checkParameter(DASHBOARD_ID, strDashboardId);
108 133 try {
109 134 DashboardId dashboardId = new DashboardId(toUUID(strDashboardId));
... ... @@ -113,10 +138,20 @@ public class DashboardController extends BaseController {
113 138 }
114 139 }
115 140
  141 + @ApiOperation(value = "Create Or Update Dashboard (saveDashboard)",
  142 + notes = "Create or update the Dashboard. When creating dashboard, platform generates Dashboard Id as [time-based UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_1_(date-time_and_MAC_address)." +
  143 + "The newly created Dashboard id will be present in the response. " +
  144 + "Specify existing Dashboard id to update the dashboard. " +
  145 + "Referencing non-existing dashboard Id will cause 'Not Found' error. " +
  146 + "Only users with 'TENANT_ADMIN') authority may create the dashboards.",
  147 + produces = MediaType.APPLICATION_JSON_VALUE,
  148 + consumes = MediaType.APPLICATION_JSON_VALUE)
116 149 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
117 150 @RequestMapping(value = "/dashboard", method = RequestMethod.POST)
118 151 @ResponseBody
119   - public Dashboard saveDashboard(@RequestBody Dashboard dashboard) throws ThingsboardException {
  152 + public Dashboard saveDashboard(
  153 + @ApiParam(value = "A JSON value representing the dashboard.")
  154 + @RequestBody Dashboard dashboard) throws ThingsboardException {
120 155 try {
121 156 dashboard.setTenantId(getCurrentUser().getTenantId());
122 157
... ... @@ -141,10 +176,14 @@ public class DashboardController extends BaseController {
141 176 }
142 177 }
143 178
  179 + @ApiOperation(value = "Delete the Dashboard (deleteDashboard)",
  180 + notes = "Delete the Dashboard. Only users with 'TENANT_ADMIN') authority may delete the dashboards.")
144 181 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
145 182 @RequestMapping(value = "/dashboard/{dashboardId}", method = RequestMethod.DELETE)
146 183 @ResponseStatus(value = HttpStatus.OK)
147   - public void deleteDashboard(@PathVariable(DASHBOARD_ID) String strDashboardId) throws ThingsboardException {
  184 + public void deleteDashboard(
  185 + @ApiParam(value = DASHBOARD_ID_PARAM_DESCRIPTION)
  186 + @PathVariable(DASHBOARD_ID) String strDashboardId) throws ThingsboardException {
148 187 checkParameter(DASHBOARD_ID, strDashboardId);
149 188 try {
150 189 DashboardId dashboardId = new DashboardId(toUUID(strDashboardId));
... ... @@ -170,12 +209,19 @@ public class DashboardController extends BaseController {
170 209 }
171 210 }
172 211
  212 + @ApiOperation(value = "Assign the Dashboard (assignDashboardToCustomer)",
  213 + notes = "Assign the Dashboard to specified Customer or do nothing if the Dashboard is already assigned to that Customer. " +
  214 + "Returns the Dashboard object. Only users with 'TENANT_ADMIN') authority may assign the dashboards to customers.",
  215 + produces = MediaType.APPLICATION_JSON_VALUE)
173 216 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
174 217 @RequestMapping(value = "/customer/{customerId}/dashboard/{dashboardId}", method = RequestMethod.POST)
175 218 @ResponseBody
176   - public Dashboard assignDashboardToCustomer(@PathVariable("customerId") String strCustomerId,
177   - @PathVariable(DASHBOARD_ID) String strDashboardId) throws ThingsboardException {
178   - checkParameter("customerId", strCustomerId);
  219 + public Dashboard assignDashboardToCustomer(
  220 + @ApiParam(value = CUSTOMER_ID_PARAM_DESCRIPTION)
  221 + @PathVariable(CUSTOMER_ID) String strCustomerId,
  222 + @ApiParam(value = DASHBOARD_ID_PARAM_DESCRIPTION)
  223 + @PathVariable(DASHBOARD_ID) String strDashboardId) throws ThingsboardException {
  224 + checkParameter(CUSTOMER_ID, strCustomerId);
179 225 checkParameter(DASHBOARD_ID, strDashboardId);
180 226 try {
181 227 CustomerId customerId = new CustomerId(toUUID(strCustomerId));
... ... @@ -203,11 +249,18 @@ public class DashboardController extends BaseController {
203 249 }
204 250 }
205 251
  252 + @ApiOperation(value = "Unassign the Dashboard (unassignDashboardFromCustomer)",
  253 + notes = "Unassign the Dashboard from specified Customer or do nothing if the Dashboard is already assigned to that Customer. " +
  254 + "Returns the Dashboard object. Only users with 'TENANT_ADMIN') authority may unassign the dashboards from customers.",
  255 + produces = MediaType.APPLICATION_JSON_VALUE)
206 256 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
207 257 @RequestMapping(value = "/customer/{customerId}/dashboard/{dashboardId}", method = RequestMethod.DELETE)
208 258 @ResponseBody
209   - public Dashboard unassignDashboardFromCustomer(@PathVariable("customerId") String strCustomerId,
210   - @PathVariable(DASHBOARD_ID) String strDashboardId) throws ThingsboardException {
  259 + public Dashboard unassignDashboardFromCustomer(
  260 + @ApiParam(value = CUSTOMER_ID_PARAM_DESCRIPTION)
  261 + @PathVariable(CUSTOMER_ID) String strCustomerId,
  262 + @ApiParam(value = DASHBOARD_ID_PARAM_DESCRIPTION)
  263 + @PathVariable(DASHBOARD_ID) String strDashboardId) throws ThingsboardException {
211 264 checkParameter("customerId", strCustomerId);
212 265 checkParameter(DASHBOARD_ID, strDashboardId);
213 266 try {
... ... @@ -235,11 +288,20 @@ public class DashboardController extends BaseController {
235 288 }
236 289 }
237 290
  291 + @ApiOperation(value = "Update the Dashboard Customers (updateDashboardCustomers)",
  292 + notes = "Updates the list of Customers that this Dashboard is assigned to. Removes previous assignments to customers that are not in the provided list. " +
  293 + "Returns the Dashboard object. Only users with 'TENANT_ADMIN') authority may assign the dashboards to customers.",
  294 + produces = MediaType.APPLICATION_JSON_VALUE,
  295 + consumes = MediaType.APPLICATION_JSON_VALUE)
  296 +
238 297 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
239 298 @RequestMapping(value = "/dashboard/{dashboardId}/customers", method = RequestMethod.POST)
240 299 @ResponseBody
241   - public Dashboard updateDashboardCustomers(@PathVariable(DASHBOARD_ID) String strDashboardId,
242   - @RequestBody(required = false) String[] strCustomerIds) throws ThingsboardException {
  300 + public Dashboard updateDashboardCustomers(
  301 + @ApiParam(value = DASHBOARD_ID_PARAM_DESCRIPTION)
  302 + @PathVariable(DASHBOARD_ID) String strDashboardId,
  303 + @ApiParam(value = "JSON array with the list of customer ids, or empty to remove all customers")
  304 + @RequestBody(required = false) String[] strCustomerIds) throws ThingsboardException {
243 305 checkParameter(DASHBOARD_ID, strDashboardId);
244 306 try {
245 307 DashboardId dashboardId = new DashboardId(toUUID(strDashboardId));
... ... @@ -301,11 +363,19 @@ public class DashboardController extends BaseController {
301 363 }
302 364 }
303 365
  366 + @ApiOperation(value = "Adds the Dashboard Customers (addDashboardCustomers)",
  367 + notes = "Adds the list of Customers to the existing list of assignments for the Dashboard. Keeps previous assignments to customers that are not in the provided list. " +
  368 + "Returns the Dashboard object. Only users with 'TENANT_ADMIN') authority may assign the dashboards to customers.",
  369 + produces = MediaType.APPLICATION_JSON_VALUE,
  370 + consumes = MediaType.APPLICATION_JSON_VALUE)
304 371 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
305 372 @RequestMapping(value = "/dashboard/{dashboardId}/customers/add", method = RequestMethod.POST)
306 373 @ResponseBody
307   - public Dashboard addDashboardCustomers(@PathVariable(DASHBOARD_ID) String strDashboardId,
308   - @RequestBody String[] strCustomerIds) throws ThingsboardException {
  374 + public Dashboard addDashboardCustomers(
  375 + @ApiParam(value = DASHBOARD_ID_PARAM_DESCRIPTION)
  376 + @PathVariable(DASHBOARD_ID) String strDashboardId,
  377 + @ApiParam(value = "JSON array with the list of customer ids")
  378 + @RequestBody String[] strCustomerIds) throws ThingsboardException {
309 379 checkParameter(DASHBOARD_ID, strDashboardId);
310 380 try {
311 381 DashboardId dashboardId = new DashboardId(toUUID(strDashboardId));
... ... @@ -345,11 +415,19 @@ public class DashboardController extends BaseController {
345 415 }
346 416 }
347 417
  418 + @ApiOperation(value = "Remove the Dashboard Customers (removeDashboardCustomers)",
  419 + notes = "Removes the list of Customers from the existing list of assignments for the Dashboard. Keeps other assignments to customers that are not in the provided list. " +
  420 + "Returns the Dashboard object. Only users with 'TENANT_ADMIN') authority may assign the dashboards to customers.",
  421 + produces = MediaType.APPLICATION_JSON_VALUE,
  422 + consumes = MediaType.APPLICATION_JSON_VALUE)
348 423 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
349 424 @RequestMapping(value = "/dashboard/{dashboardId}/customers/remove", method = RequestMethod.POST)
350 425 @ResponseBody
351   - public Dashboard removeDashboardCustomers(@PathVariable(DASHBOARD_ID) String strDashboardId,
352   - @RequestBody String[] strCustomerIds) throws ThingsboardException {
  426 + public Dashboard removeDashboardCustomers(
  427 + @ApiParam(value = DASHBOARD_ID_PARAM_DESCRIPTION)
  428 + @PathVariable(DASHBOARD_ID) String strDashboardId,
  429 + @ApiParam(value = "JSON array with the list of customer ids")
  430 + @RequestBody String[] strCustomerIds) throws ThingsboardException {
353 431 checkParameter(DASHBOARD_ID, strDashboardId);
354 432 try {
355 433 DashboardId dashboardId = new DashboardId(toUUID(strDashboardId));
... ... @@ -389,10 +467,20 @@ public class DashboardController extends BaseController {
389 467 }
390 468 }
391 469
  470 + @ApiOperation(value = "Assign the Dashboard to Public Customer (assignDashboardToPublicCustomer)",
  471 + notes = "Assigns the dashboard to a special, auto-generated 'Public' Customer. Once assigned, unauthenticated users may browse the dashboard. " +
  472 + "This method is useful if you like to embed the dashboard on public web pages to be available for users that are not logged in. " +
  473 + "Be aware that making the dashboard public does not mean that it automatically makes all devices and assets you use in the dashboard to be public." +
  474 + "Use [assign Asset to Public Customer](#!/asset-controller/assignAssetToPublicCustomerUsingPOST) and " +
  475 + "[assign Device to Public Customer](#!/device-controller/assignDeviceToPublicCustomerUsingPOST) for this purpose. " +
  476 + "Returns the Dashboard object. Only users with 'TENANT_ADMIN') authority may assign the dashboards to customers.",
  477 + produces = MediaType.APPLICATION_JSON_VALUE)
392 478 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
393 479 @RequestMapping(value = "/customer/public/dashboard/{dashboardId}", method = RequestMethod.POST)
394 480 @ResponseBody
395   - public Dashboard assignDashboardToPublicCustomer(@PathVariable(DASHBOARD_ID) String strDashboardId) throws ThingsboardException {
  481 + public Dashboard assignDashboardToPublicCustomer(
  482 + @ApiParam(value = DASHBOARD_ID_PARAM_DESCRIPTION)
  483 + @PathVariable(DASHBOARD_ID) String strDashboardId) throws ThingsboardException {
396 484 checkParameter(DASHBOARD_ID, strDashboardId);
397 485 try {
398 486 DashboardId dashboardId = new DashboardId(toUUID(strDashboardId));
... ... @@ -415,10 +503,16 @@ public class DashboardController extends BaseController {
415 503 }
416 504 }
417 505
  506 + @ApiOperation(value = "Unassign the Dashboard from Public Customer (unassignDashboardFromPublicCustomer)",
  507 + notes = "Unassigns the dashboard from a special, auto-generated 'Public' Customer. Once unassigned, unauthenticated users may no longer browse the dashboard. " +
  508 + "Returns the Dashboard object. Only users with 'TENANT_ADMIN') authority may assign the dashboards to customers.",
  509 + produces = MediaType.APPLICATION_JSON_VALUE)
418 510 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
419 511 @RequestMapping(value = "/customer/public/dashboard/{dashboardId}", method = RequestMethod.DELETE)
420 512 @ResponseBody
421   - public Dashboard unassignDashboardFromPublicCustomer(@PathVariable(DASHBOARD_ID) String strDashboardId) throws ThingsboardException {
  513 + public Dashboard unassignDashboardFromPublicCustomer(
  514 + @ApiParam(value = DASHBOARD_ID_PARAM_DESCRIPTION)
  515 + @PathVariable(DASHBOARD_ID) String strDashboardId) throws ThingsboardException {
422 516 checkParameter(DASHBOARD_ID, strDashboardId);
423 517 try {
424 518 DashboardId dashboardId = new DashboardId(toUUID(strDashboardId));
... ... @@ -442,15 +536,25 @@ public class DashboardController extends BaseController {
442 536 }
443 537 }
444 538
  539 + @ApiOperation(value = "Get Tenant Dashboards by System Administrator (getTenantDashboards)",
  540 + notes = "Returns a page of dashboard info objects owned by tenant. " + DASHBOARD_INFO_DEFINITION + " " + PAGE_DATA_PARAMETERS +
  541 + "Only users with 'SYS_ADMIN' authority may use this method.",
  542 + produces = MediaType.APPLICATION_JSON_VALUE)
445 543 @PreAuthorize("hasAuthority('SYS_ADMIN')")
446 544 @RequestMapping(value = "/tenant/{tenantId}/dashboards", params = {"pageSize", "page"}, method = RequestMethod.GET)
447 545 @ResponseBody
448 546 public PageData<DashboardInfo> getTenantDashboards(
449   - @PathVariable("tenantId") String strTenantId,
  547 + @ApiParam(value = TENANT_ID_PARAM_DESCRIPTION, required = true)
  548 + @PathVariable(TENANT_ID) String strTenantId,
  549 + @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true)
450 550 @RequestParam int pageSize,
  551 + @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true)
451 552 @RequestParam int page,
  553 + @ApiParam(value = DASHBOARD_TEXT_SEARCH_DESCRIPTION)
452 554 @RequestParam(required = false) String textSearch,
  555 + @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = DASHBOARD_SORT_PROPERTY_ALLOWABLE_VALUES)
453 556 @RequestParam(required = false) String sortProperty,
  557 + @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES)
454 558 @RequestParam(required = false) String sortOrder) throws ThingsboardException {
455 559 try {
456 560 TenantId tenantId = new TenantId(toUUID(strTenantId));
... ... @@ -462,20 +566,30 @@ public class DashboardController extends BaseController {
462 566 }
463 567 }
464 568
  569 + @ApiOperation(value = "Get Tenant Dashboards (getTenantDashboards)",
  570 + notes = "Returns a page of dashboard info objects owned by the tenant of a current user. " + DASHBOARD_INFO_DEFINITION + " " + PAGE_DATA_PARAMETERS +
  571 + "Only users with 'TENANT_ADMIN' authority may use this method.",
  572 + produces = MediaType.APPLICATION_JSON_VALUE)
465 573 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
466 574 @RequestMapping(value = "/tenant/dashboards", params = {"pageSize", "page"}, method = RequestMethod.GET)
467 575 @ResponseBody
468 576 public PageData<DashboardInfo> getTenantDashboards(
  577 + @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true)
469 578 @RequestParam int pageSize,
  579 + @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true)
470 580 @RequestParam int page,
  581 + @ApiParam(value = HIDDEN_FOR_MOBILE)
471 582 @RequestParam(required = false) Boolean mobile,
  583 + @ApiParam(value = DASHBOARD_TEXT_SEARCH_DESCRIPTION)
472 584 @RequestParam(required = false) String textSearch,
  585 + @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = DASHBOARD_SORT_PROPERTY_ALLOWABLE_VALUES)
473 586 @RequestParam(required = false) String sortProperty,
  587 + @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES)
474 588 @RequestParam(required = false) String sortOrder) throws ThingsboardException {
475 589 try {
476 590 TenantId tenantId = getCurrentUser().getTenantId();
477 591 PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder);
478   - if (mobile != null && mobile.booleanValue()) {
  592 + if (mobile != null && mobile) {
479 593 return checkNotNull(dashboardService.findMobileDashboardsByTenantId(tenantId, pageLink));
480 594 } else {
481 595 return checkNotNull(dashboardService.findDashboardsByTenantId(tenantId, pageLink));
... ... @@ -485,24 +599,35 @@ public class DashboardController extends BaseController {
485 599 }
486 600 }
487 601
  602 + @ApiOperation(value = "Get Customer Dashboards (getCustomerDashboards)",
  603 + notes = "Returns a page of dashboard info objects owned by the specified customer. " + DASHBOARD_INFO_DEFINITION + " " + PAGE_DATA_PARAMETERS +
  604 + "Only users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority may use this method.",
  605 + produces = MediaType.APPLICATION_JSON_VALUE)
488 606 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
489 607 @RequestMapping(value = "/customer/{customerId}/dashboards", params = {"pageSize", "page"}, method = RequestMethod.GET)
490 608 @ResponseBody
491 609 public PageData<DashboardInfo> getCustomerDashboards(
492   - @PathVariable("customerId") String strCustomerId,
  610 + @ApiParam(value = CUSTOMER_ID_PARAM_DESCRIPTION, required = true)
  611 + @PathVariable(CUSTOMER_ID) String strCustomerId,
  612 + @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true)
493 613 @RequestParam int pageSize,
  614 + @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true)
494 615 @RequestParam int page,
  616 + @ApiParam(value = HIDDEN_FOR_MOBILE)
495 617 @RequestParam(required = false) Boolean mobile,
  618 + @ApiParam(value = DASHBOARD_TEXT_SEARCH_DESCRIPTION)
496 619 @RequestParam(required = false) String textSearch,
  620 + @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = DASHBOARD_SORT_PROPERTY_ALLOWABLE_VALUES)
497 621 @RequestParam(required = false) String sortProperty,
  622 + @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES)
498 623 @RequestParam(required = false) String sortOrder) throws ThingsboardException {
499   - checkParameter("customerId", strCustomerId);
  624 + checkParameter(CUSTOMER_ID, strCustomerId);
500 625 try {
501 626 TenantId tenantId = getCurrentUser().getTenantId();
502 627 CustomerId customerId = new CustomerId(toUUID(strCustomerId));
503 628 checkCustomerId(customerId, Operation.READ);
504 629 PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder);
505   - if (mobile != null && mobile.booleanValue()) {
  630 + if (mobile != null && mobile) {
506 631 return checkNotNull(dashboardService.findMobileDashboardsByTenantIdAndCustomerId(tenantId, customerId, pageLink));
507 632 } else {
508 633 return checkNotNull(dashboardService.findDashboardsByTenantIdAndCustomerId(tenantId, customerId, pageLink));
... ... @@ -512,6 +637,13 @@ public class DashboardController extends BaseController {
512 637 }
513 638 }
514 639
  640 + @ApiOperation(value = "Get Home Dashboard (getHomeDashboard)",
  641 + notes = "Returns the home dashboard object that is configured as 'homeDashboardId' parameter in the 'additionalInfo' of the User. " +
  642 + "If 'homeDashboardId' parameter is not set on the User level and the User has authority 'CUSTOMER_USER', check the same parameter for the corresponding Customer. " +
  643 + "If 'homeDashboardId' parameter is not set on the User and Customer levels then checks the same parameter for the Tenant that owns the user. "
  644 + + DASHBOARD_DEFINITION + " " +
  645 + "Only users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority should use this method.",
  646 + produces = MediaType.APPLICATION_JSON_VALUE)
515 647 @PreAuthorize("isAuthenticated()")
516 648 @RequestMapping(value = "/dashboard/home", method = RequestMethod.GET)
517 649 @ResponseBody
... ... @@ -543,6 +675,12 @@ public class DashboardController extends BaseController {
543 675 }
544 676 }
545 677
  678 + @ApiOperation(value = "Get Home Dashboard Info (getHomeDashboardInfo)",
  679 + notes = "Returns the home dashboard info object that is configured as 'homeDashboardId' parameter in the 'additionalInfo' of the User. " +
  680 + "If 'homeDashboardId' parameter is not set on the User level and the User has authority 'CUSTOMER_USER', check the same parameter for the corresponding Customer. " +
  681 + "If 'homeDashboardId' parameter is not set on the User and Customer levels then checks the same parameter for the Tenant that owns the user. " +
  682 + "Only users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority should use this method.",
  683 + produces = MediaType.APPLICATION_JSON_VALUE)
546 684 @PreAuthorize("isAuthenticated()")
547 685 @RequestMapping(value = "/dashboard/home/info", method = RequestMethod.GET)
548 686 @ResponseBody
... ... @@ -574,6 +712,10 @@ public class DashboardController extends BaseController {
574 712 }
575 713 }
576 714
  715 + @ApiOperation(value = "Get Tenant Home Dashboard Info (getTenantHomeDashboardInfo)",
  716 + notes = "Returns the home dashboard info object that is configured as 'homeDashboardId' parameter in the 'additionalInfo' of the corresponding tenant. " +
  717 + "Only users with 'TENANT_ADMIN' authority may use this method.",
  718 + produces = MediaType.APPLICATION_JSON_VALUE)
577 719 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
578 720 @RequestMapping(value = "/tenant/dashboard/home/info", method = RequestMethod.GET)
579 721 @ResponseBody
... ... @@ -596,10 +738,16 @@ public class DashboardController extends BaseController {
596 738 }
597 739 }
598 740
  741 + @ApiOperation(value = "Update Tenant Home Dashboard Info (getTenantHomeDashboardInfo)",
  742 + notes = "Update the home dashboard assignment for the current tenant. " +
  743 + "Only users with 'TENANT_ADMIN' authority may use this method.",
  744 + produces = MediaType.APPLICATION_JSON_VALUE)
599 745 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
600 746 @RequestMapping(value = "/tenant/dashboard/home/info", method = RequestMethod.POST)
601 747 @ResponseStatus(value = HttpStatus.OK)
602   - public void setTenantHomeDashboardInfo(@RequestBody HomeDashboardInfo homeDashboardInfo) throws ThingsboardException {
  748 + public void setTenantHomeDashboardInfo(
  749 + @ApiParam(value = "A JSON object that represents home dashboard id and other parameters", required = true)
  750 + @RequestBody HomeDashboardInfo homeDashboardInfo) throws ThingsboardException {
603 751 try {
604 752 if (homeDashboardInfo.getDashboardId() != null) {
605 753 checkDashboardId(homeDashboardInfo.getDashboardId(), Operation.READ);
... ... @@ -635,7 +783,8 @@ public class DashboardController extends BaseController {
635 783 }
636 784 return new HomeDashboardInfo(dashboardId, hideDashboardToolbar);
637 785 }
638   - } catch (Exception e) {}
  786 + } catch (Exception e) {
  787 + }
639 788 return null;
640 789 }
641 790
... ... @@ -651,7 +800,8 @@ public class DashboardController extends BaseController {
651 800 }
652 801 return new HomeDashboard(dashboard, hideDashboardToolbar);
653 802 }
654   - } catch (Exception e) {}
  803 + } catch (Exception e) {
  804 + }
655 805 return null;
656 806 }
657 807
... ...
... ... @@ -19,6 +19,8 @@ import com.google.common.util.concurrent.FutureCallback;
19 19 import com.google.common.util.concurrent.Futures;
20 20 import com.google.common.util.concurrent.ListenableFuture;
21 21 import com.google.common.util.concurrent.MoreExecutors;
  22 +import io.swagger.annotations.ApiOperation;
  23 +import io.swagger.annotations.ApiParam;
22 24 import lombok.RequiredArgsConstructor;
23 25 import lombok.extern.slf4j.Slf4j;
24 26 import org.springframework.http.HttpStatus;
... ... @@ -91,16 +93,22 @@ import static org.thingsboard.server.controller.EdgeController.EDGE_ID;
91 93 @RequiredArgsConstructor
92 94 @Slf4j
93 95 public class DeviceController extends BaseController {
94   - private final DeviceBulkImportService deviceBulkImportService;
95 96
96   - private static final String DEVICE_ID = "deviceId";
97   - private static final String DEVICE_NAME = "deviceName";
98   - private static final String TENANT_ID = "tenantId";
  97 + protected static final String DEVICE_ID = "deviceId";
  98 + protected static final String DEVICE_NAME = "deviceName";
  99 + protected static final String TENANT_ID = "tenantId";
  100 +
  101 + private final DeviceBulkImportService deviceBulkImportService;
99 102
  103 + @ApiOperation(value = "Get Device (getDeviceById)",
  104 + notes = "Fetch the Device object based on the provided Device Id. " +
  105 + "If the user has the authority of 'Tenant Administrator', the server checks that the device is owned by the same tenant. " +
  106 + "If the user has the authority of 'Customer User', the server checks that the device is assigned to the same customer.")
100 107 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
101 108 @RequestMapping(value = "/device/{deviceId}", method = RequestMethod.GET)
102 109 @ResponseBody
103   - public Device getDeviceById(@PathVariable(DEVICE_ID) String strDeviceId) throws ThingsboardException {
  110 + public Device getDeviceById(@ApiParam(value = DEVICE_ID_PARAM_DESCRIPTION)
  111 + @PathVariable(DEVICE_ID) String strDeviceId) throws ThingsboardException {
104 112 checkParameter(DEVICE_ID, strDeviceId);
105 113 try {
106 114 DeviceId deviceId = new DeviceId(toUUID(strDeviceId));
... ... @@ -110,10 +118,15 @@ public class DeviceController extends BaseController {
110 118 }
111 119 }
112 120
  121 + @ApiOperation(value = "Get Device Info (getDeviceInfoById)",
  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)
113 125 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
114 126 @RequestMapping(value = "/device/info/{deviceId}", method = RequestMethod.GET)
115 127 @ResponseBody
116   - public DeviceInfo getDeviceInfoById(@PathVariable(DEVICE_ID) String strDeviceId) throws ThingsboardException {
  128 + public DeviceInfo getDeviceInfoById(@ApiParam(value = DEVICE_ID_PARAM_DESCRIPTION)
  129 + @PathVariable(DEVICE_ID) String strDeviceId) throws ThingsboardException {
117 130 checkParameter(DEVICE_ID, strDeviceId);
118 131 try {
119 132 DeviceId deviceId = new DeviceId(toUUID(strDeviceId));
... ... @@ -123,11 +136,18 @@ public class DeviceController extends BaseController {
123 136 }
124 137 }
125 138
  139 + @ApiOperation(value = "Create Or Update Device (saveDevice)",
  140 + notes = "Create or update the Device. When creating device, platform generates Device Id as [time-based UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_1_(date-time_and_MAC_address). " +
  141 + "Device credentials are also generated if not provided in the 'accessToken' request parameter. " +
  142 + "The newly created device id will be present in the response. " +
  143 + "Specify existing Device id to update the device. " +
  144 + "Referencing non-existing device Id will cause 'Not Found' error.")
126 145 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
127 146 @RequestMapping(value = "/device", method = RequestMethod.POST)
128 147 @ResponseBody
129   - public Device saveDevice(@RequestBody Device device,
130   - @RequestParam(name = "accessToken", required = false) String accessToken) throws ThingsboardException {
  148 + public Device saveDevice(@ApiParam(value = "A JSON value representing the device.") @RequestBody Device device,
  149 + @ApiParam(value = "Optional value of the device credentials to be used during device creation. " +
  150 + "If omitted, access token will be auto-generated.") @RequestParam(name = "accessToken", required = false) String accessToken) throws ThingsboardException {
131 151 boolean created = device.getId() == null;
132 152 try {
133 153 device.setTenantId(getCurrentUser().getTenantId());
... ... @@ -164,10 +184,13 @@ public class DeviceController extends BaseController {
164 184 }
165 185 }
166 186
  187 + @ApiOperation(value = "Delete device (deleteDevice)",
  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.")
167 189 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
168 190 @RequestMapping(value = "/device/{deviceId}", method = RequestMethod.DELETE)
169 191 @ResponseStatus(value = HttpStatus.OK)
170   - public void deleteDevice(@PathVariable(DEVICE_ID) String strDeviceId) throws ThingsboardException {
  192 + public void deleteDevice(@ApiParam(value = DEVICE_ID_PARAM_DESCRIPTION)
  193 + @PathVariable(DEVICE_ID) String strDeviceId) throws ThingsboardException {
171 194 checkParameter(DEVICE_ID, strDeviceId);
172 195 try {
173 196 DeviceId deviceId = new DeviceId(toUUID(strDeviceId));
... ... @@ -193,10 +216,14 @@ public class DeviceController extends BaseController {
193 216 }
194 217 }
195 218
  219 + @ApiOperation(value = "Assign device to customer (assignDeviceToCustomer)",
  220 + notes = "Creates assignment of the device to customer. Customer will be able to query device afterwards.")
196 221 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
197 222 @RequestMapping(value = "/customer/{customerId}/device/{deviceId}", method = RequestMethod.POST)
198 223 @ResponseBody
199   - public Device assignDeviceToCustomer(@PathVariable("customerId") String strCustomerId,
  224 + public Device assignDeviceToCustomer(@ApiParam(value = CUSTOMER_ID_PARAM_DESCRIPTION)
  225 + @PathVariable("customerId") String strCustomerId,
  226 + @ApiParam(value = DEVICE_ID_PARAM_DESCRIPTION)
200 227 @PathVariable(DEVICE_ID) String strDeviceId) throws ThingsboardException {
201 228 checkParameter("customerId", strCustomerId);
202 229 checkParameter(DEVICE_ID, strDeviceId);
... ... @@ -225,10 +252,13 @@ public class DeviceController extends BaseController {
225 252 }
226 253 }
227 254
  255 + @ApiOperation(value = "Unassign device from customer (unassignDeviceFromCustomer)",
  256 + notes = "Clears assignment of the device to customer. Customer will not be able to query device afterwards.")
228 257 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
229 258 @RequestMapping(value = "/customer/device/{deviceId}", method = RequestMethod.DELETE)
230 259 @ResponseBody
231   - public Device unassignDeviceFromCustomer(@PathVariable(DEVICE_ID) String strDeviceId) throws ThingsboardException {
  260 + public Device unassignDeviceFromCustomer(@ApiParam(value = DEVICE_ID_PARAM_DESCRIPTION)
  261 + @PathVariable(DEVICE_ID) String strDeviceId) throws ThingsboardException {
232 262 checkParameter(DEVICE_ID, strDeviceId);
233 263 try {
234 264 DeviceId deviceId = new DeviceId(toUUID(strDeviceId));
... ... @@ -256,10 +286,15 @@ public class DeviceController extends BaseController {
256 286 }
257 287 }
258 288
  289 + @ApiOperation(value = "Make device publicly available (assignDeviceToPublicCustomer)",
  290 + notes = "Device will be available for non-authorized (not logged-in) users. " +
  291 + "This is useful to create dashboards that you plan to share/embed on a publicly available website. " +
  292 + "However, users that are logged-in and belong to different tenant will not be able to access the device.")
259 293 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
260 294 @RequestMapping(value = "/customer/public/device/{deviceId}", method = RequestMethod.POST)
261 295 @ResponseBody
262   - public Device assignDeviceToPublicCustomer(@PathVariable(DEVICE_ID) String strDeviceId) throws ThingsboardException {
  296 + public Device assignDeviceToPublicCustomer(@ApiParam(value = DEVICE_ID_PARAM_DESCRIPTION)
  297 + @PathVariable(DEVICE_ID) String strDeviceId) throws ThingsboardException {
263 298 checkParameter(DEVICE_ID, strDeviceId);
264 299 try {
265 300 DeviceId deviceId = new DeviceId(toUUID(strDeviceId));
... ... @@ -280,10 +315,13 @@ public class DeviceController extends BaseController {
280 315 }
281 316 }
282 317
  318 + @ApiOperation(value = "Get Device Credentials (getDeviceCredentialsByDeviceId)",
  319 + notes = "If during device creation there wasn't specified any credentials, platform generates random 'ACCESS_TOKEN' credentials.")
283 320 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
284 321 @RequestMapping(value = "/device/{deviceId}/credentials", method = RequestMethod.GET)
285 322 @ResponseBody
286   - public DeviceCredentials getDeviceCredentialsByDeviceId(@PathVariable(DEVICE_ID) String strDeviceId) throws ThingsboardException {
  323 + public DeviceCredentials getDeviceCredentialsByDeviceId(@ApiParam(value = DEVICE_ID_PARAM_DESCRIPTION)
  324 + @PathVariable(DEVICE_ID) String strDeviceId) throws ThingsboardException {
287 325 checkParameter(DEVICE_ID, strDeviceId);
288 326 try {
289 327 DeviceId deviceId = new DeviceId(toUUID(strDeviceId));
... ... @@ -301,10 +339,16 @@ public class DeviceController extends BaseController {
301 339 }
302 340 }
303 341
  342 + @ApiOperation(value = "Update device credentials (updateDeviceCredentials)", notes = "During device creation, platform generates random 'ACCESS_TOKEN' credentials. " +
  343 + "Use this method to update the device credentials. First use 'getDeviceCredentialsByDeviceId' to get the credentials id and value. " +
  344 + "Then use current method to update the credentials type and value. It is not possible to create multiple device credentials for the same device. " +
  345 + "The structure of device credentials id and value is simple for the 'ACCESS_TOKEN' but is much more complex for the 'MQTT_BASIC' or 'LWM2M_CREDENTIALS'.")
304 346 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
305 347 @RequestMapping(value = "/device/credentials", method = RequestMethod.POST)
306 348 @ResponseBody
307   - public DeviceCredentials saveDeviceCredentials(@RequestBody DeviceCredentials deviceCredentials) throws ThingsboardException {
  349 + public DeviceCredentials updateDeviceCredentials(
  350 + @ApiParam(value = "A JSON value representing the device credentials.")
  351 + @RequestBody DeviceCredentials deviceCredentials) throws ThingsboardException {
308 352 checkNotNull(deviceCredentials);
309 353 try {
310 354 Device device = checkDeviceId(deviceCredentials.getDeviceId(), Operation.WRITE_CREDENTIALS);
... ... @@ -325,15 +369,24 @@ public class DeviceController extends BaseController {
325 369 }
326 370 }
327 371
  372 + @ApiOperation(value = "Get Tenant Devices (getTenantDevices)",
  373 + notes = "Returns a page of devices owned by tenant. " +
  374 + PAGE_DATA_PARAMETERS)
328 375 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
329 376 @RequestMapping(value = "/tenant/devices", params = {"pageSize", "page"}, method = RequestMethod.GET)
330 377 @ResponseBody
331 378 public PageData<Device> getTenantDevices(
  379 + @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true)
332 380 @RequestParam int pageSize,
  381 + @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true)
333 382 @RequestParam int page,
  383 + @ApiParam(value = DEVICE_TYPE_DESCRIPTION)
334 384 @RequestParam(required = false) String type,
  385 + @ApiParam(value = DEVICE_TEXT_SEARCH_DESCRIPTION)
335 386 @RequestParam(required = false) String textSearch,
  387 + @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = DEVICE_SORT_PROPERTY_ALLOWABLE_VALUES)
336 388 @RequestParam(required = false) String sortProperty,
  389 + @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES)
337 390 @RequestParam(required = false) String sortOrder) throws ThingsboardException {
338 391 try {
339 392 TenantId tenantId = getCurrentUser().getTenantId();
... ... @@ -348,17 +401,28 @@ public class DeviceController extends BaseController {
348 401 }
349 402 }
350 403
  404 + @ApiOperation(value = "Get Tenant Device Infos (getTenantDeviceInfos)",
  405 + notes = "Returns a page of devices info objects owned by tenant. " +
  406 + PAGE_DATA_PARAMETERS + DEVICE_INFO_DESCRIPTION)
351 407 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
352 408 @RequestMapping(value = "/tenant/deviceInfos", params = {"pageSize", "page"}, method = RequestMethod.GET)
353 409 @ResponseBody
354 410 public PageData<DeviceInfo> getTenantDeviceInfos(
  411 + @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true)
355 412 @RequestParam int pageSize,
  413 + @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true)
356 414 @RequestParam int page,
  415 + @ApiParam(value = DEVICE_TYPE_DESCRIPTION)
357 416 @RequestParam(required = false) String type,
  417 + @ApiParam(value = DEVICE_PROFILE_ID_DESCRIPTION)
358 418 @RequestParam(required = false) String deviceProfileId,
  419 + @ApiParam(value = DEVICE_TEXT_SEARCH_DESCRIPTION)
359 420 @RequestParam(required = false) String textSearch,
  421 + @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = DEVICE_SORT_PROPERTY_ALLOWABLE_VALUES)
360 422 @RequestParam(required = false) String sortProperty,
361   - @RequestParam(required = false) String sortOrder) throws ThingsboardException {
  423 + @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES)
  424 + @RequestParam(required = false) String sortOrder
  425 + ) throws ThingsboardException {
362 426 try {
363 427 TenantId tenantId = getCurrentUser().getTenantId();
364 428 PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder);
... ... @@ -375,10 +439,14 @@ public class DeviceController extends BaseController {
375 439 }
376 440 }
377 441
  442 + @ApiOperation(value = "Get Tenant Device (getTenantDevice)",
  443 + notes = "Requested device must be owned by tenant that the user belongs to. " +
  444 + "Device name is an unique property of device. So it can be used to identify the device.")
378 445 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
379 446 @RequestMapping(value = "/tenant/devices", params = {"deviceName"}, method = RequestMethod.GET)
380 447 @ResponseBody
381 448 public Device getTenantDevice(
  449 + @ApiParam(value = DEVICE_NAME_DESCRIPTION)
382 450 @RequestParam String deviceName) throws ThingsboardException {
383 451 try {
384 452 TenantId tenantId = getCurrentUser().getTenantId();
... ... @@ -388,16 +456,26 @@ public class DeviceController extends BaseController {
388 456 }
389 457 }
390 458
  459 + @ApiOperation(value = "Get Customer Devices (getCustomerDevices)",
  460 + notes = "Returns a page of devices objects assigned to customer. " +
  461 + PAGE_DATA_PARAMETERS)
391 462 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
392 463 @RequestMapping(value = "/customer/{customerId}/devices", params = {"pageSize", "page"}, method = RequestMethod.GET)
393 464 @ResponseBody
394 465 public PageData<Device> getCustomerDevices(
  466 + @ApiParam(value = CUSTOMER_ID_PARAM_DESCRIPTION, required = true)
395 467 @PathVariable("customerId") String strCustomerId,
  468 + @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true)
396 469 @RequestParam int pageSize,
  470 + @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true)
397 471 @RequestParam int page,
  472 + @ApiParam(value = DEVICE_TYPE_DESCRIPTION)
398 473 @RequestParam(required = false) String type,
  474 + @ApiParam(value = DEVICE_TEXT_SEARCH_DESCRIPTION)
399 475 @RequestParam(required = false) String textSearch,
  476 + @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = DEVICE_SORT_PROPERTY_ALLOWABLE_VALUES)
400 477 @RequestParam(required = false) String sortProperty,
  478 + @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES)
401 479 @RequestParam(required = false) String sortOrder) throws ThingsboardException {
402 480 checkParameter("customerId", strCustomerId);
403 481 try {
... ... @@ -415,17 +493,28 @@ public class DeviceController extends BaseController {
415 493 }
416 494 }
417 495
  496 + @ApiOperation(value = "Get Customer Device Infos (getCustomerDeviceInfos)",
  497 + notes = "Returns a page of devices info objects assigned to customer. " +
  498 + PAGE_DATA_PARAMETERS + DEVICE_INFO_DESCRIPTION)
418 499 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
419 500 @RequestMapping(value = "/customer/{customerId}/deviceInfos", params = {"pageSize", "page"}, method = RequestMethod.GET)
420 501 @ResponseBody
421 502 public PageData<DeviceInfo> getCustomerDeviceInfos(
  503 + @ApiParam(value = CUSTOMER_ID_PARAM_DESCRIPTION, required = true)
422 504 @PathVariable("customerId") String strCustomerId,
  505 + @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true)
423 506 @RequestParam int pageSize,
  507 + @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true)
424 508 @RequestParam int page,
  509 + @ApiParam(value = DEVICE_TYPE_DESCRIPTION)
425 510 @RequestParam(required = false) String type,
  511 + @ApiParam(value = DEVICE_PROFILE_ID_DESCRIPTION)
426 512 @RequestParam(required = false) String deviceProfileId,
  513 + @ApiParam(value = DEVICE_TEXT_SEARCH_DESCRIPTION)
427 514 @RequestParam(required = false) String textSearch,
  515 + @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = DEVICE_SORT_PROPERTY_ALLOWABLE_VALUES)
428 516 @RequestParam(required = false) String sortProperty,
  517 + @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES)
429 518 @RequestParam(required = false) String sortOrder) throws ThingsboardException {
430 519 checkParameter("customerId", strCustomerId);
431 520 try {
... ... @@ -446,10 +535,13 @@ public class DeviceController extends BaseController {
446 535 }
447 536 }
448 537
  538 + @ApiOperation(value = "Get Devices By Ids (getDevicesByIds)",
  539 + notes = "Requested devices must be owned by tenant or assigned to customer which user is performing the request. ")
449 540 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
450 541 @RequestMapping(value = "/devices", params = {"deviceIds"}, method = RequestMethod.GET)
451 542 @ResponseBody
452 543 public List<Device> getDevicesByIds(
  544 + @ApiParam(value = "A list of devices ids, separated by comma ','")
453 545 @RequestParam("deviceIds") String[] strDeviceIds) throws ThingsboardException {
454 546 checkArrayParameter("deviceIds", strDeviceIds);
455 547 try {
... ... @@ -472,6 +564,10 @@ public class DeviceController extends BaseController {
472 564 }
473 565 }
474 566
  567 + @ApiOperation(value = "Find related devices (findByQuery)",
  568 + notes = "Returns all devices that are related to the specific entity. " +
  569 + "The entity id, relation type, device types, depth of the search, and other query parameters defined using complex 'DeviceSearchQuery' object. " +
  570 + "See 'Model' tab of the Parameters for more info.")
475 571 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
476 572 @RequestMapping(value = "/devices", method = RequestMethod.POST)
477 573 @ResponseBody
... ... @@ -496,6 +592,8 @@ public class DeviceController extends BaseController {
496 592 }
497 593 }
498 594
  595 + @ApiOperation(value = "Get Device Types (getDeviceTypes)",
  596 + notes = "Returns a set of unique device profile names based on devices that are either owned by the tenant or assigned to the customer which user is performing the request.")
499 597 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
500 598 @RequestMapping(value = "/device/types", method = RequestMethod.GET)
501 599 @ResponseBody
... ... @@ -510,10 +608,19 @@ public class DeviceController extends BaseController {
510 608 }
511 609 }
512 610
  611 + @ApiOperation(value = "Claim device (claimDevice)",
  612 + notes = "Claiming makes it possible to assign a device to the specific customer using device/server side claiming data (in the form of secret key)." +
  613 + "To make this happen you have to provide unique device name and optional claiming data (it is needed only for device-side claiming)." +
  614 + "Once device is claimed, the customer becomes its owner and customer users may access device data as well as control the device. \n" +
  615 + "In order to enable claiming devices feature a system parameter security.claim.allowClaimingByDefault should be set to true, " +
  616 + "otherwise a server-side claimingAllowed attribute with the value true is obligatory for provisioned devices. \n" +
  617 + "See official documentation for more details regarding claiming.")
513 618 @PreAuthorize("hasAuthority('CUSTOMER_USER')")
514 619 @RequestMapping(value = "/customer/device/{deviceName}/claim", method = RequestMethod.POST)
515 620 @ResponseBody
516   - public DeferredResult<ResponseEntity> claimDevice(@PathVariable(DEVICE_NAME) String deviceName,
  621 + public DeferredResult<ResponseEntity> claimDevice(@ApiParam(value = "Unique name of the device which is going to be claimed")
  622 + @PathVariable(DEVICE_NAME) String deviceName,
  623 + @ApiParam(value = "Claiming request which can optionally contain secret key")
517 624 @RequestBody(required = false) ClaimRequest claimRequest) throws ThingsboardException {
518 625 checkParameter(DEVICE_NAME, deviceName);
519 626 try {
... ... @@ -564,10 +671,13 @@ public class DeviceController extends BaseController {
564 671 }
565 672 }
566 673
  674 + @ApiOperation(value = "Reclaim device (reClaimDevice)",
  675 + notes = "Reclaiming means the device will be unassigned from the customer and the device will be available for claiming again.")
567 676 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
568 677 @RequestMapping(value = "/customer/device/{deviceName}/claim", method = RequestMethod.DELETE)
569 678 @ResponseStatus(value = HttpStatus.OK)
570   - public DeferredResult<ResponseEntity> reClaimDevice(@PathVariable(DEVICE_NAME) String deviceName) throws ThingsboardException {
  679 + public DeferredResult<ResponseEntity> reClaimDevice(@ApiParam(value = "Unique name of the device which is going to be reclaimed")
  680 + @PathVariable(DEVICE_NAME) String deviceName) throws ThingsboardException {
571 681 checkParameter(DEVICE_NAME, deviceName);
572 682 try {
573 683 final DeferredResult<ResponseEntity> deferredResult = new DeferredResult<>();
... ... @@ -615,10 +725,14 @@ public class DeviceController extends BaseController {
615 725 return DataConstants.DEFAULT_SECRET_KEY;
616 726 }
617 727
  728 + @ApiOperation(value = "Assign device to tenant (assignDeviceToTenant)",
  729 + notes = "Creates assignment of the device to tenant. Thereafter tenant will be able to reassign the device to a customer.")
618 730 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
619 731 @RequestMapping(value = "/tenant/{tenantId}/device/{deviceId}", method = RequestMethod.POST)
620 732 @ResponseBody
621   - public Device assignDeviceToTenant(@PathVariable(TENANT_ID) String strTenantId,
  733 + public Device assignDeviceToTenant(@ApiParam(value = TENANT_ID_PARAM_DESCRIPTION)
  734 + @PathVariable(TENANT_ID) String strTenantId,
  735 + @ApiParam(value = DEVICE_ID_PARAM_DESCRIPTION)
622 736 @PathVariable(DEVICE_ID) String strDeviceId) throws ThingsboardException {
623 737 checkParameter(TENANT_ID, strTenantId);
624 738 checkParameter(DEVICE_ID, strDeviceId);
... ... @@ -665,10 +779,16 @@ public class DeviceController extends BaseController {
665 779 return metaData;
666 780 }
667 781
  782 + @ApiOperation(value = "Assign device to edge (assignDeviceToEdge)",
  783 + notes = "Creates assignment of an existing device to an instance of The Edge. " +
  784 + "The Edge is a software product for edge computing. " +
  785 + "It allows bringing data analysis and management to the edge, while seamlessly synchronizing with the platform server (cloud). ")
668 786 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
669 787 @RequestMapping(value = "/edge/{edgeId}/device/{deviceId}", method = RequestMethod.POST)
670 788 @ResponseBody
671   - public Device assignDeviceToEdge(@PathVariable(EDGE_ID) String strEdgeId,
  789 + public Device assignDeviceToEdge(@ApiParam(value = EDGE_ID_PARAM_DESCRIPTION)
  790 + @PathVariable(EDGE_ID) String strEdgeId,
  791 + @ApiParam(value = DEVICE_ID_PARAM_DESCRIPTION)
672 792 @PathVariable(DEVICE_ID) String strDeviceId) throws ThingsboardException {
673 793 checkParameter(EDGE_ID, strEdgeId);
674 794 checkParameter(DEVICE_ID, strDeviceId);
... ... @@ -699,10 +819,14 @@ public class DeviceController extends BaseController {
699 819 }
700 820 }
701 821
  822 + @ApiOperation(value = "Unassign device from edge (unassignDeviceFromEdge)",
  823 + notes = "Clears assignment of the device to the edge")
702 824 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
703 825 @RequestMapping(value = "/edge/{edgeId}/device/{deviceId}", method = RequestMethod.DELETE)
704 826 @ResponseBody
705   - public Device unassignDeviceFromEdge(@PathVariable(EDGE_ID) String strEdgeId,
  827 + public Device unassignDeviceFromEdge(@ApiParam(value = EDGE_ID_PARAM_DESCRIPTION)
  828 + @PathVariable(EDGE_ID) String strEdgeId,
  829 + @ApiParam(value = DEVICE_ID_PARAM_DESCRIPTION)
706 830 @PathVariable(DEVICE_ID) String strDeviceId) throws ThingsboardException {
707 831 checkParameter(EDGE_ID, strEdgeId);
708 832 checkParameter(DEVICE_ID, strDeviceId);
... ... @@ -733,18 +857,30 @@ public class DeviceController extends BaseController {
733 857 }
734 858 }
735 859
  860 + @ApiOperation(value = "Get devices assigned to edge (getEdgeDevices)",
  861 + notes = "Returns a page of devices assigned to edge. " +
  862 + PAGE_DATA_PARAMETERS)
736 863 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
737 864 @RequestMapping(value = "/edge/{edgeId}/devices", params = {"pageSize", "page"}, method = RequestMethod.GET)
738 865 @ResponseBody
739 866 public PageData<Device> getEdgeDevices(
  867 + @ApiParam(value = EDGE_ID_PARAM_DESCRIPTION, required = true)
740 868 @PathVariable(EDGE_ID) String strEdgeId,
  869 + @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true)
741 870 @RequestParam int pageSize,
  871 + @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true)
742 872 @RequestParam int page,
  873 + @ApiParam(value = DEVICE_TYPE_DESCRIPTION)
743 874 @RequestParam(required = false) String type,
  875 + @ApiParam(value = DEVICE_TEXT_SEARCH_DESCRIPTION)
744 876 @RequestParam(required = false) String textSearch,
  877 + @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = DEVICE_SORT_PROPERTY_ALLOWABLE_VALUES)
745 878 @RequestParam(required = false) String sortProperty,
  879 + @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES)
746 880 @RequestParam(required = false) String sortOrder,
  881 + @ApiParam(value = "Timestamp. Devices with creation time before it won't be queried")
747 882 @RequestParam(required = false) Long startTime,
  883 + @ApiParam(value = "Timestamp. Devices with creation time after it won't be queried")
748 884 @RequestParam(required = false) Long endTime) throws ThingsboardException {
749 885 checkParameter(EDGE_ID, strEdgeId);
750 886 try {
... ... @@ -776,10 +912,17 @@ public class DeviceController extends BaseController {
776 912 }
777 913 }
778 914
  915 + @ApiOperation(value = "Count devices by device profile (countByDeviceProfileAndEmptyOtaPackage)",
  916 + notes = "The platform gives an ability to load OTA (over-the-air) packages to devices. " +
  917 + "It can be done in two different ways: device scope or device profile scope." +
  918 + "In the response you will find the number of devices with specified device profile, but without previously defined device scope OTA package. " +
  919 + "It can be useful when you want to define number of devices that will be affected with future OTA package")
779 920 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
780 921 @RequestMapping(value = "/devices/count/{otaPackageType}/{deviceProfileId}", method = RequestMethod.GET)
781 922 @ResponseBody
782   - public Long countByDeviceProfileAndEmptyOtaPackage(@PathVariable("otaPackageType") String otaPackageType,
  923 + public Long countByDeviceProfileAndEmptyOtaPackage(@ApiParam(value = "OTA package type", allowableValues = "FIRMWARE, SOFTWARE")
  924 + @PathVariable("otaPackageType") String otaPackageType,
  925 + @ApiParam(value = "Device Profile Id. I.g. '784f394c-42b6-435a-983c-b7beff2784f9'")
783 926 @PathVariable("deviceProfileId") String deviceProfileId) throws ThingsboardException {
784 927 checkParameter("OtaPackageType", otaPackageType);
785 928 checkParameter("DeviceProfileId", deviceProfileId);
... ... @@ -793,6 +936,8 @@ public class DeviceController extends BaseController {
793 936 }
794 937 }
795 938
  939 + @ApiOperation(value = "Import the bulk of devices (processDevicesBulkImport)",
  940 + notes = "There's an ability to import the bulk of devices using the only .csv file.")
796 941 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')")
797 942 @PostMapping("/device/bulk_import")
798 943 public BulkImportResult<Device> processDevicesBulkImport(@RequestBody BulkImportRequest request) throws Exception {
... ...
... ... @@ -38,7 +38,6 @@ import org.thingsboard.server.common.data.EntitySubtype;
38 38 import org.thingsboard.server.common.data.EntityType;
39 39 import org.thingsboard.server.common.data.EntityView;
40 40 import org.thingsboard.server.common.data.EntityViewInfo;
41   -import org.thingsboard.server.common.data.asset.Asset;
42 41 import org.thingsboard.server.common.data.audit.ActionType;
43 42 import org.thingsboard.server.common.data.edge.Edge;
44 43 import org.thingsboard.server.common.data.edge.EdgeEventActionType;
... ... @@ -49,7 +48,6 @@ import org.thingsboard.server.common.data.id.EdgeId;
49 48 import org.thingsboard.server.common.data.id.EntityId;
50 49 import org.thingsboard.server.common.data.id.EntityViewId;
51 50 import org.thingsboard.server.common.data.id.TenantId;
52   -import org.thingsboard.server.common.data.id.UUIDBased;
53 51 import org.thingsboard.server.common.data.kv.AttributeKvEntry;
54 52 import org.thingsboard.server.common.data.kv.BaseReadTsKvQuery;
55 53 import org.thingsboard.server.common.data.kv.ReadTsKvQuery;
... ... @@ -74,7 +72,6 @@ import java.util.concurrent.ExecutionException;
74 72 import java.util.stream.Collectors;
75 73
76 74 import static org.apache.commons.lang3.StringUtils.isBlank;
77   -import static org.thingsboard.server.controller.CustomerController.CUSTOMER_ID;
78 75 import static org.thingsboard.server.controller.EdgeController.EDGE_ID;
79 76
80 77 /**
... ...
... ... @@ -57,7 +57,7 @@ public class TenantController extends BaseController {
57 57 @RequestMapping(value = "/tenant/{tenantId}", method = RequestMethod.GET)
58 58 @ResponseBody
59 59 public Tenant getTenantById(@PathVariable("tenantId") String strTenantId) throws ThingsboardException {
60   - checkParameter("tenantId", strTenantId);
  60 + checkParameter(TENANT_ID, strTenantId);
61 61 try {
62 62 TenantId tenantId = new TenantId(toUUID(strTenantId));
63 63 Tenant tenant = checkTenantId(tenantId, Operation.READ);
... ... @@ -74,7 +74,7 @@ public class TenantController extends BaseController {
74 74 @RequestMapping(value = "/tenant/info/{tenantId}", method = RequestMethod.GET)
75 75 @ResponseBody
76 76 public TenantInfo getTenantInfoById(@PathVariable("tenantId") String strTenantId) throws ThingsboardException {
77   - checkParameter("tenantId", strTenantId);
  77 + checkParameter(TENANT_ID, strTenantId);
78 78 try {
79 79 TenantId tenantId = new TenantId(toUUID(strTenantId));
80 80 return checkTenantInfoId(tenantId, Operation.READ);
... ...
  1 +/**
  2 + * Copyright © 2016-2021 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.service.security.model;
  17 +
  18 +import io.swagger.annotations.ApiModel;
  19 +import io.swagger.annotations.ApiModelProperty;
  20 +import lombok.Data;
  21 +
  22 +@ApiModel
  23 +@Data
  24 +public class ActivateUserRequest {
  25 +
  26 + @ApiModelProperty(position = 1, value = "The activate token to verify", example = "AAB254FF67D..")
  27 + private String activateToken;
  28 + @ApiModelProperty(position = 2, value = "The new password to set", example = "secret")
  29 + private String password;
  30 +}
... ...
  1 +/**
  2 + * Copyright © 2016-2021 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.service.security.model;
  17 +
  18 +import io.swagger.annotations.ApiModel;
  19 +import io.swagger.annotations.ApiModelProperty;
  20 +import lombok.Data;
  21 +
  22 +@ApiModel
  23 +@Data
  24 +public class ChangePasswordRequest {
  25 +
  26 + @ApiModelProperty(position = 1, value = "The old password", example = "OldPassword")
  27 + private String currentPassword;
  28 + @ApiModelProperty(position = 1, value = "The new password", example = "NewPassword")
  29 + private String newPassword;
  30 +
  31 +}
... ...
  1 +/**
  2 + * Copyright © 2016-2021 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.service.security.model;
  17 +
  18 +import io.swagger.annotations.ApiModel;
  19 +import io.swagger.annotations.ApiModelProperty;
  20 +import lombok.AllArgsConstructor;
  21 +import lombok.Data;
  22 +
  23 +@ApiModel(value = "JWT Token Pair")
  24 +@Data
  25 +@AllArgsConstructor
  26 +public class JwtTokenPair {
  27 +
  28 + @ApiModelProperty(position = 1, value = "The JWT Access Token. Used to perform API calls.", example = "AAB254FF67D..")
  29 + private String token;
  30 + @ApiModelProperty(position = 1, value = "The JWT Refresh Token. Used to get new JWT Access Token if old one has expired.", example = "AAB254FF67D..")
  31 + private String refreshToken;
  32 +}
... ...
  1 +/**
  2 + * Copyright © 2016-2021 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.service.security.model;
  17 +
  18 +import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
  19 +import io.swagger.annotations.ApiModel;
  20 +import io.swagger.annotations.ApiModelProperty;
  21 +import lombok.Data;
  22 +
  23 +@ApiModel
  24 +@Data
  25 +public class ResetPasswordEmailRequest {
  26 +
  27 + @ApiModelProperty(position = 1, value = "The email of the user", example = "user@example.com")
  28 + private String email;
  29 +}
... ...
  1 +/**
  2 + * Copyright © 2016-2021 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.service.security.model;
  17 +
  18 +import io.swagger.annotations.ApiModel;
  19 +import io.swagger.annotations.ApiModelProperty;
  20 +import lombok.Data;
  21 +
  22 +@ApiModel
  23 +@Data
  24 +public class ResetPasswordRequest {
  25 +
  26 + @ApiModelProperty(position = 1, value = "The reset token to verify", example = "AAB254FF67D..")
  27 + private String resetToken;
  28 + @ApiModelProperty(position = 2, value = "The new password to set", example = "secret")
  29 + private String password;
  30 +}
... ...
... ... @@ -96,6 +96,10 @@
96 96 <groupId>org.apache.commons</groupId>
97 97 <artifactId>commons-lang3</artifactId>
98 98 </dependency>
  99 + <dependency>
  100 + <groupId>io.swagger</groupId>
  101 + <artifactId>swagger-annotations</artifactId>
  102 + </dependency>
99 103 </dependencies>
100 104
101 105 <build>
... ...
... ... @@ -15,11 +15,15 @@
15 15 */
16 16 package org.thingsboard.server.common.data;
17 17
  18 +import io.swagger.annotations.ApiModel;
  19 +import io.swagger.annotations.ApiModelProperty;
18 20 import org.thingsboard.server.common.data.id.AdminSettingsId;
19 21
20 22 import com.fasterxml.jackson.databind.JsonNode;
  23 +import org.thingsboard.server.common.data.id.DeviceId;
21 24 import org.thingsboard.server.common.data.validation.NoXss;
22 25
  26 +@ApiModel
23 27 public class AdminSettings extends BaseData<AdminSettingsId> {
24 28
25 29 private static final long serialVersionUID = -7670322981725511892L;
... ... @@ -42,6 +46,19 @@ public class AdminSettings extends BaseData<AdminSettingsId> {
42 46 this.jsonValue = adminSettings.getJsonValue();
43 47 }
44 48
  49 + @ApiModelProperty(position = 1, value = "The Id of the Administration Settings, auto-generated, UUID")
  50 + @Override
  51 + public AdminSettingsId getId() {
  52 + return super.getId();
  53 + }
  54 +
  55 + @ApiModelProperty(position = 2, value = "Timestamp of the settings creation, in milliseconds", example = "1609459200000", readOnly = true)
  56 + @Override
  57 + public long getCreatedTime() {
  58 + return super.getCreatedTime();
  59 + }
  60 +
  61 + @ApiModelProperty(position = 3, value = "The Administration Settings key, (e.g. 'general' or 'mail')")
45 62 public String getKey() {
46 63 return key;
47 64 }
... ... @@ -50,6 +67,7 @@ public class AdminSettings extends BaseData<AdminSettingsId> {
50 67 this.key = key;
51 68 }
52 69
  70 + @ApiModelProperty(position = 4, value = "JSON representation of the Administration Settings value")
53 71 public JsonNode getJsonValue() {
54 72 return jsonValue;
55 73 }
... ...
... ... @@ -16,6 +16,7 @@
16 16 package org.thingsboard.server.common.data;
17 17
18 18 import com.fasterxml.jackson.databind.JsonNode;
  19 +import io.swagger.annotations.ApiModelProperty;
19 20 import org.thingsboard.server.common.data.id.DashboardId;
20 21
21 22 public class Dashboard extends DashboardInfo {
... ... @@ -41,6 +42,10 @@ public class Dashboard extends DashboardInfo {
41 42 this.configuration = dashboard.getConfiguration();
42 43 }
43 44
  45 + @ApiModelProperty(position = 9, value = "JSON object with main configuration of the dashboard: layouts, widgets, aliases, etc. " +
  46 + "The JSON structure of the dashboard configuration is quite complex. " +
  47 + "The easiest way to learn it is to export existing dashboard to JSON."
  48 + , dataType = "com.fasterxml.jackson.databind.JsonNode")
44 49 public JsonNode getConfiguration() {
45 50 return configuration;
46 51 }
... ...
... ... @@ -16,6 +16,8 @@
16 16 package org.thingsboard.server.common.data;
17 17
18 18 import com.fasterxml.jackson.annotation.JsonProperty;
  19 +import io.swagger.annotations.ApiModel;
  20 +import io.swagger.annotations.ApiModelProperty;
19 21 import org.thingsboard.server.common.data.id.CustomerId;
20 22 import org.thingsboard.server.common.data.id.DashboardId;
21 23 import org.thingsboard.server.common.data.id.TenantId;
... ... @@ -25,6 +27,7 @@ import javax.validation.Valid;
25 27 import java.util.HashSet;
26 28 import java.util.Set;
27 29
  30 +@ApiModel
28 31 public class DashboardInfo extends SearchTextBased<DashboardId> implements HasName, HasTenantId {
29 32
30 33 private TenantId tenantId;
... ... @@ -54,6 +57,22 @@ public class DashboardInfo extends SearchTextBased<DashboardId> implements HasNa
54 57 this.mobileOrder = dashboardInfo.getMobileOrder();
55 58 }
56 59
  60 + @ApiModelProperty(position = 1, value = "JSON object with the dashboard Id. " +
  61 + "Specify existing dashboard Id to update the dashboard. " +
  62 + "Referencing non-existing dashboard id will cause error. " +
  63 + "Omit this field to create new dashboard." )
  64 + @Override
  65 + public DashboardId getId() {
  66 + return super.getId();
  67 + }
  68 +
  69 + @ApiModelProperty(position = 2, value = "Timestamp of the dashboard creation, in milliseconds", example = "1609459200000", readOnly = true)
  70 + @Override
  71 + public long getCreatedTime() {
  72 + return super.getCreatedTime();
  73 + }
  74 +
  75 + @ApiModelProperty(position = 3, value = "JSON object with Tenant Id. Tenant Id of the dashboard can't be changed.", readOnly = true)
57 76 public TenantId getTenantId() {
58 77 return tenantId;
59 78 }
... ... @@ -62,6 +81,7 @@ public class DashboardInfo extends SearchTextBased<DashboardId> implements HasNa
62 81 this.tenantId = tenantId;
63 82 }
64 83
  84 + @ApiModelProperty(position = 4, value = "Title of the dashboard.")
65 85 public String getTitle() {
66 86 return title;
67 87 }
... ... @@ -70,6 +90,7 @@ public class DashboardInfo extends SearchTextBased<DashboardId> implements HasNa
70 90 this.title = title;
71 91 }
72 92
  93 + @ApiModelProperty(position = 8, value = "Thumbnail picture for rendering of the dashboards in a grid view on mobile devices.", readOnly = true)
73 94 public String getImage() {
74 95 return image;
75 96 }
... ... @@ -78,6 +99,7 @@ public class DashboardInfo extends SearchTextBased<DashboardId> implements HasNa
78 99 this.image = image;
79 100 }
80 101
  102 + @ApiModelProperty(position = 5, value = "List of assigned customers with their info.", readOnly = true)
81 103 public Set<ShortCustomerInfo> getAssignedCustomers() {
82 104 return assignedCustomers;
83 105 }
... ... @@ -86,6 +108,7 @@ public class DashboardInfo extends SearchTextBased<DashboardId> implements HasNa
86 108 this.assignedCustomers = assignedCustomers;
87 109 }
88 110
  111 + @ApiModelProperty(position = 6, value = "Hide dashboard from mobile devices. Useful if the dashboard is not designed for small screens.", readOnly = true)
89 112 public boolean isMobileHide() {
90 113 return mobileHide;
91 114 }
... ... @@ -94,6 +117,7 @@ public class DashboardInfo extends SearchTextBased<DashboardId> implements HasNa
94 117 this.mobileHide = mobileHide;
95 118 }
96 119
  120 + @ApiModelProperty(position = 7, value = "Order on mobile devices. Useful to adjust sorting of the dashboards for mobile applications", readOnly = true)
97 121 public Integer getMobileOrder() {
98 122 return mobileOrder;
99 123 }
... ... @@ -152,6 +176,7 @@ public class DashboardInfo extends SearchTextBased<DashboardId> implements HasNa
152 176 }
153 177 }
154 178
  179 + @ApiModelProperty(position = 4, value = "Same as title of the dashboard. Read-only field. Update the 'title' to change the 'name' of the dashboard.", readOnly = true)
155 180 @Override
156 181 @JsonProperty(access = JsonProperty.Access.READ_ONLY)
157 182 public String getName() {
... ...
... ... @@ -17,6 +17,9 @@ package org.thingsboard.server.common.data;
17 17
18 18 import com.fasterxml.jackson.annotation.JsonIgnore;
19 19 import com.fasterxml.jackson.core.JsonProcessingException;
  20 +import com.fasterxml.jackson.databind.JsonNode;
  21 +import io.swagger.annotations.ApiModel;
  22 +import io.swagger.annotations.ApiModelProperty;
20 23 import lombok.EqualsAndHashCode;
21 24 import lombok.extern.slf4j.Slf4j;
22 25 import org.thingsboard.server.common.data.device.data.DeviceData;
... ... @@ -31,6 +34,7 @@ import java.io.ByteArrayInputStream;
31 34 import java.io.IOException;
32 35 import java.util.Optional;
33 36
  37 +@ApiModel
34 38 @EqualsAndHashCode(callSuper = true)
35 39 @Slf4j
36 40 public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implements HasName, HasTenantId, HasCustomerId, HasOtaPackage {
... ... @@ -88,6 +92,22 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen
88 92 return this;
89 93 }
90 94
  95 + @ApiModelProperty(position = 1, value = "JSON object with the device Id. " +
  96 + "Specify this field to update the device. " +
  97 + "Referencing non-existing device Id will cause error. " +
  98 + "Omit this field to create new device." )
  99 + @Override
  100 + public DeviceId getId() {
  101 + return super.getId();
  102 + }
  103 +
  104 + @ApiModelProperty(position = 2, value = "Timestamp of the device creation, in milliseconds", example = "1609459200000", readOnly = true)
  105 + @Override
  106 + public long getCreatedTime() {
  107 + return super.getCreatedTime();
  108 + }
  109 +
  110 + @ApiModelProperty(position = 3, value = "JSON object with Tenant Id. Use 'assignDeviceToTenant' to change the Tenant Id.", readOnly = true)
91 111 public TenantId getTenantId() {
92 112 return tenantId;
93 113 }
... ... @@ -96,6 +116,7 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen
96 116 this.tenantId = tenantId;
97 117 }
98 118
  119 + @ApiModelProperty(position = 4, value = "JSON object with Customer Id. Use 'assignDeviceToCustomer' to change the Customer Id.", readOnly = true)
99 120 public CustomerId getCustomerId() {
100 121 return customerId;
101 122 }
... ... @@ -104,6 +125,7 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen
104 125 this.customerId = customerId;
105 126 }
106 127
  128 + @ApiModelProperty(position = 5, required = true, value = "Unique Device Name in scope of Tenant", example = "A4B72CCDFF33")
107 129 @Override
108 130 public String getName() {
109 131 return name;
... ... @@ -113,6 +135,7 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen
113 135 this.name = name;
114 136 }
115 137
  138 + @ApiModelProperty(position = 6, required = true, value = "Device Profile Name", example = "Temperature Sensor")
116 139 public String getType() {
117 140 return type;
118 141 }
... ... @@ -121,6 +144,7 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen
121 144 this.type = type;
122 145 }
123 146
  147 + @ApiModelProperty(position = 7, required = true, value = "Label that may be used in widgets", example = "Room 234 Sensor")
124 148 public String getLabel() {
125 149 return label;
126 150 }
... ... @@ -129,6 +153,7 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen
129 153 this.label = label;
130 154 }
131 155
  156 + @ApiModelProperty(position = 8, required = true, value = "JSON object with Device Profile Id.")
132 157 public DeviceProfileId getDeviceProfileId() {
133 158 return deviceProfileId;
134 159 }
... ... @@ -137,6 +162,7 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen
137 162 this.deviceProfileId = deviceProfileId;
138 163 }
139 164
  165 + @ApiModelProperty(position = 9, value = "JSON object with content specific to type of transport in the device profile.")
140 166 public DeviceData getDeviceData() {
141 167 if (deviceData != null) {
142 168 return deviceData;
... ... @@ -169,6 +195,7 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen
169 195 return getName();
170 196 }
171 197
  198 + @ApiModelProperty(position = 10, value = "JSON object with Ota Package Id.")
172 199 public OtaPackageId getFirmwareId() {
173 200 return firmwareId;
174 201 }
... ... @@ -177,6 +204,7 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen
177 204 this.firmwareId = firmwareId;
178 205 }
179 206
  207 + @ApiModelProperty(position = 11, value = "JSON object with Ota Package Id.")
180 208 public OtaPackageId getSoftwareId() {
181 209 return softwareId;
182 210 }
... ... @@ -185,6 +213,12 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen
185 213 this.softwareId = softwareId;
186 214 }
187 215
  216 + @ApiModelProperty(position = 12, value = "Additional parameters of the device", dataType = "com.fasterxml.jackson.databind.JsonNode")
  217 + @Override
  218 + public JsonNode getAdditionalInfo() {
  219 + return super.getAdditionalInfo();
  220 + }
  221 +
188 222 @Override
189 223 public String toString() {
190 224 StringBuilder builder = new StringBuilder();
... ...
... ... @@ -15,14 +15,20 @@
15 15 */
16 16 package org.thingsboard.server.common.data;
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.DeviceId;
20 22
  23 +@ApiModel
21 24 @Data
22 25 public class DeviceInfo extends Device {
23 26
  27 + @ApiModelProperty(position = 13, value = "Title of the Customer that owns the device.", readOnly = true)
24 28 private String customerTitle;
  29 + @ApiModelProperty(position = 14, value = "Indicates special 'Public' Customer that is auto-generated to use the devices on public dashboards.", readOnly = true)
25 30 private boolean customerIsPublic;
  31 + @ApiModelProperty(position = 15, value = "Name of the corresponding Device Profile.", readOnly = true)
26 32 private String deviceProfileName;
27 33
28 34 public DeviceInfo() {
... ...
... ... @@ -15,11 +15,17 @@
15 15 */
16 16 package org.thingsboard.server.common.data;
17 17
  18 +import io.swagger.annotations.ApiModel;
  19 +import io.swagger.annotations.ApiModelProperty;
18 20 import lombok.Data;
19 21
  22 +@ApiModel
20 23 @Data
21 24 public class HomeDashboard extends Dashboard {
22 25
  26 + public static final String HIDE_DASHBOARD_TOOLBAR_DESCRIPTION = "Hide dashboard toolbar flag. Useful for rendering dashboards on mobile.";
  27 +
  28 + @ApiModelProperty(position = 10, value = HIDE_DASHBOARD_TOOLBAR_DESCRIPTION)
23 29 private boolean hideDashboardToolbar;
24 30
25 31 public HomeDashboard(Dashboard dashboard, boolean hideDashboardToolbar) {
... ...
... ... @@ -15,13 +15,18 @@
15 15 */
16 16 package org.thingsboard.server.common.data;
17 17
  18 +import io.swagger.annotations.ApiModel;
  19 +import io.swagger.annotations.ApiModelProperty;
18 20 import lombok.AllArgsConstructor;
19 21 import lombok.Data;
20 22 import org.thingsboard.server.common.data.id.DashboardId;
21 23
  24 +@ApiModel
22 25 @Data
23 26 @AllArgsConstructor
24 27 public class HomeDashboardInfo {
  28 + @ApiModelProperty(position = 1, value = "JSON object with the dashboard Id.")
25 29 private DashboardId dashboardId;
  30 + @ApiModelProperty(position = 1, value = HomeDashboard.HIDE_DASHBOARD_TOOLBAR_DESCRIPTION)
26 31 private boolean hideDashboardToolbar;
27 32 }
... ...
... ... @@ -15,6 +15,8 @@
15 15 */
16 16 package org.thingsboard.server.common.data;
17 17
  18 +import io.swagger.annotations.ApiModel;
  19 +import io.swagger.annotations.ApiModelProperty;
18 20 import lombok.AllArgsConstructor;
19 21 import lombok.Getter;
20 22 import lombok.Setter;
... ... @@ -25,16 +27,20 @@ import org.thingsboard.server.common.data.validation.NoXss;
25 27 * Created by igor on 2/27/18.
26 28 */
27 29
  30 +@ApiModel
28 31 @AllArgsConstructor
29 32 public class ShortCustomerInfo {
30 33
  34 + @ApiModelProperty(position = 1, value = "JSON object with the customer Id.")
31 35 @Getter @Setter
32 36 private CustomerId customerId;
33 37
  38 + @ApiModelProperty(position = 2, value = "Title of the customer.")
34 39 @Getter @Setter
35 40 @NoXss
36 41 private String title;
37 42
  43 + @ApiModelProperty(position = 3, value = "Indicates special 'Public' customer used to embed dashboards on public websites.")
38 44 @Getter @Setter
39 45 private boolean isPublic;
40 46
... ...
... ... @@ -15,12 +15,17 @@
15 15 */
16 16 package org.thingsboard.server.common.data;
17 17
  18 +import io.swagger.annotations.ApiModel;
  19 +import io.swagger.annotations.ApiModelProperty;
18 20 import lombok.Data;
19 21
  22 +@ApiModel
20 23 @Data
21 24 public class UpdateMessage {
22 25
  26 + @ApiModelProperty(position = 1, value = "The message about new platform update available.")
23 27 private final String message;
  28 + @ApiModelProperty(position = 1, value = "'True' if new platform update is available.")
24 29 private final boolean isUpdateAvailable;
25 30
26 31 }
... ...
... ... @@ -17,6 +17,9 @@ package org.thingsboard.server.common.data;
17 17
18 18 import com.fasterxml.jackson.annotation.JsonIgnore;
19 19 import com.fasterxml.jackson.annotation.JsonProperty;
  20 +import com.fasterxml.jackson.databind.JsonNode;
  21 +import io.swagger.annotations.ApiModel;
  22 +import io.swagger.annotations.ApiModelProperty;
20 23 import lombok.EqualsAndHashCode;
21 24 import org.thingsboard.server.common.data.id.CustomerId;
22 25 import org.thingsboard.server.common.data.id.EntityId;
... ... @@ -26,6 +29,7 @@ import org.thingsboard.server.common.data.security.Authority;
26 29
27 30 import org.thingsboard.server.common.data.validation.NoXss;
28 31
  32 +@ApiModel
29 33 @EqualsAndHashCode(callSuper = true)
30 34 public class User extends SearchTextBasedWithAdditionalInfo<UserId> implements HasName, HasTenantId, HasCustomerId {
31 35
... ... @@ -58,6 +62,23 @@ public class User extends SearchTextBasedWithAdditionalInfo<UserId> implements H
58 62 this.lastName = user.getLastName();
59 63 }
60 64
  65 +
  66 + @ApiModelProperty(position = 1, value = "JSON object with the User Id. " +
  67 + "Specify this field to update the device. " +
  68 + "Referencing non-existing User Id will cause error. " +
  69 + "Omit this field to create new customer." )
  70 + @Override
  71 + public UserId getId() {
  72 + return super.getId();
  73 + }
  74 +
  75 + @ApiModelProperty(position = 2, value = "Timestamp of the user creation, in milliseconds", example = "1609459200000", readOnly = true)
  76 + @Override
  77 + public long getCreatedTime() {
  78 + return super.getCreatedTime();
  79 + }
  80 +
  81 + @ApiModelProperty(position = 3, value = "JSON object with the Tenant Id.", readOnly = true)
61 82 public TenantId getTenantId() {
62 83 return tenantId;
63 84 }
... ... @@ -66,6 +87,7 @@ public class User extends SearchTextBasedWithAdditionalInfo<UserId> implements H
66 87 this.tenantId = tenantId;
67 88 }
68 89
  90 + @ApiModelProperty(position = 4, value = "JSON object with the Customer Id.", readOnly = true)
69 91 public CustomerId getCustomerId() {
70 92 return customerId;
71 93 }
... ... @@ -74,6 +96,7 @@ public class User extends SearchTextBasedWithAdditionalInfo<UserId> implements H
74 96 this.customerId = customerId;
75 97 }
76 98
  99 + @ApiModelProperty(position = 5, required = true, value = "Email of the user", example = "user@example.com")
77 100 public String getEmail() {
78 101 return email;
79 102 }
... ... @@ -82,12 +105,14 @@ public class User extends SearchTextBasedWithAdditionalInfo<UserId> implements H
82 105 this.email = email;
83 106 }
84 107
  108 + @ApiModelProperty(position = 6, readOnly = true, value = "Duplicates the email of the user, readonly", example = "user@example.com")
85 109 @Override
86 110 @JsonProperty(access = JsonProperty.Access.READ_ONLY)
87 111 public String getName() {
88 112 return email;
89 113 }
90 114
  115 + @ApiModelProperty(position = 7, required = true, value = "Authority", example = "SYS_ADMIN, TENANT_ADMIN or CUSTOMER_USER")
91 116 public Authority getAuthority() {
92 117 return authority;
93 118 }
... ... @@ -96,6 +121,7 @@ public class User extends SearchTextBasedWithAdditionalInfo<UserId> implements H
96 121 this.authority = authority;
97 122 }
98 123
  124 + @ApiModelProperty(position = 8, required = true, value = "First name of the user", example = "John")
99 125 public String getFirstName() {
100 126 return firstName;
101 127 }
... ... @@ -104,6 +130,7 @@ public class User extends SearchTextBasedWithAdditionalInfo<UserId> implements H
104 130 this.firstName = firstName;
105 131 }
106 132
  133 + @ApiModelProperty(position = 9, required = true, value = "Last name of the user", example = "Doe")
107 134 public String getLastName() {
108 135 return lastName;
109 136 }
... ... @@ -112,6 +139,12 @@ public class User extends SearchTextBasedWithAdditionalInfo<UserId> implements H
112 139 this.lastName = lastName;
113 140 }
114 141
  142 + @ApiModelProperty(position = 10, value = "Additional parameters of the user", dataType = "com.fasterxml.jackson.databind.JsonNode")
  143 + @Override
  144 + public JsonNode getAdditionalInfo() {
  145 + return super.getAdditionalInfo();
  146 + }
  147 +
115 148 @Override
116 149 public String getSearchText() {
117 150 return getEmail();
... ...
... ... @@ -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() {
... ...
... ... @@ -15,6 +15,8 @@
15 15 */
16 16 package org.thingsboard.server.common.data.device;
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.EntityType;
20 22 import org.thingsboard.server.common.data.relation.EntityRelation;
... ... @@ -25,11 +27,15 @@ import org.thingsboard.server.common.data.relation.RelationsSearchParameters;
25 27 import java.util.Collections;
26 28 import java.util.List;
27 29
  30 +@ApiModel
28 31 @Data
29 32 public class DeviceSearchQuery {
30 33
  34 + @ApiModelProperty(position = 3, value = "Main search parameters.")
31 35 private RelationsSearchParameters parameters;
  36 + @ApiModelProperty(position = 1, value = "Type of the relation between root entity and device (e.g. 'Contains' or 'Manages').")
32 37 private String relationType;
  38 + @ApiModelProperty(position = 2, value = "Array of device types to filter the related entities (e.g. 'Temperature Sensor', 'Smoke Sensor').")
33 39 private List<String> deviceTypes;
34 40
35 41 public EntityRelationsQuery toEntitySearchQuery() {
... ...
... ... @@ -15,9 +15,11 @@
15 15 */
16 16 package org.thingsboard.server.common.data.device.data;
17 17
  18 +import io.swagger.annotations.ApiModel;
18 19 import lombok.Data;
19 20 import org.thingsboard.server.common.data.DeviceProfileType;
20 21
  22 +@ApiModel
21 23 @Data
22 24 public class DefaultDeviceConfiguration implements DeviceConfiguration {
23 25
... ...
... ... @@ -19,8 +19,10 @@ import com.fasterxml.jackson.annotation.JsonIgnore;
19 19 import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
20 20 import com.fasterxml.jackson.annotation.JsonSubTypes;
21 21 import com.fasterxml.jackson.annotation.JsonTypeInfo;
  22 +import io.swagger.annotations.ApiModel;
22 23 import org.thingsboard.server.common.data.DeviceProfileType;
23 24
  25 +@ApiModel
24 26 @JsonIgnoreProperties(ignoreUnknown = true)
25 27 @JsonTypeInfo(
26 28 use = JsonTypeInfo.Id.NAME,
... ...
... ... @@ -15,8 +15,10 @@
15 15 */
16 16 package org.thingsboard.server.common.data.device.data;
17 17
  18 +import io.swagger.annotations.ApiModel;
18 19 import lombok.Data;
19 20
  21 +@ApiModel
20 22 @Data
21 23 public class DeviceData {
22 24
... ...
... ... @@ -19,10 +19,12 @@ import com.fasterxml.jackson.annotation.JsonIgnore;
19 19 import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
20 20 import com.fasterxml.jackson.annotation.JsonSubTypes;
21 21 import com.fasterxml.jackson.annotation.JsonTypeInfo;
  22 +import io.swagger.annotations.ApiModel;
22 23 import org.thingsboard.server.common.data.DeviceTransportType;
23 24
24 25 import java.io.Serializable;
25 26
  27 +@ApiModel
26 28 @JsonIgnoreProperties(ignoreUnknown = true)
27 29 @JsonTypeInfo(
28 30 use = JsonTypeInfo.Id.NAME,
... ...
... ... @@ -18,10 +18,13 @@ package org.thingsboard.server.common.data.id;
18 18 import com.fasterxml.jackson.annotation.JsonCreator;
19 19 import com.fasterxml.jackson.annotation.JsonIgnore;
20 20 import com.fasterxml.jackson.annotation.JsonProperty;
  21 +import io.swagger.annotations.ApiModel;
  22 +import io.swagger.annotations.ApiModelProperty;
21 23 import org.thingsboard.server.common.data.EntityType;
22 24
23 25 import java.util.UUID;
24 26
  27 +@ApiModel
25 28 public class AlarmId extends UUIDBased implements EntityId {
26 29
27 30 private static final long serialVersionUID = 1L;
... ... @@ -35,7 +38,7 @@ public class AlarmId extends UUIDBased implements EntityId {
35 38 return new AlarmId(UUID.fromString(alarmId));
36 39 }
37 40
38   - @JsonIgnore
  41 + @ApiModelProperty(position = 2, required = true, value = "string", example = "ALARM", allowableValues = "ALARM")
39 42 @Override
40 43 public EntityType getEntityType() {
41 44 return EntityType.ALARM;
... ...
... ... @@ -18,10 +18,13 @@ package org.thingsboard.server.common.data.id;
18 18 import com.fasterxml.jackson.annotation.JsonCreator;
19 19 import com.fasterxml.jackson.annotation.JsonIgnore;
20 20 import com.fasterxml.jackson.annotation.JsonProperty;
  21 +import io.swagger.annotations.ApiModel;
  22 +import io.swagger.annotations.ApiModelProperty;
21 23 import org.thingsboard.server.common.data.EntityType;
22 24
23 25 import java.util.UUID;
24 26
  27 +@ApiModel
25 28 public class ApiUsageStateId extends UUIDBased implements EntityId {
26 29
27 30 @JsonCreator
... ... @@ -33,7 +36,7 @@ public class ApiUsageStateId extends UUIDBased implements EntityId {
33 36 return new ApiUsageStateId(UUID.fromString(userId));
34 37 }
35 38
36   - @JsonIgnore
  39 + @ApiModelProperty(position = 2, required = true, value = "string", example = "API_USAGE_STATE", allowableValues = "API_USAGE_STATE")
37 40 @Override
38 41 public EntityType getEntityType() {
39 42 return EntityType.API_USAGE_STATE;
... ...
... ... @@ -18,10 +18,13 @@ package org.thingsboard.server.common.data.id;
18 18 import com.fasterxml.jackson.annotation.JsonCreator;
19 19 import com.fasterxml.jackson.annotation.JsonIgnore;
20 20 import com.fasterxml.jackson.annotation.JsonProperty;
  21 +import io.swagger.annotations.ApiModel;
  22 +import io.swagger.annotations.ApiModelProperty;
21 23 import org.thingsboard.server.common.data.EntityType;
22 24
23 25 import java.util.UUID;
24 26
  27 +@ApiModel
25 28 public class AssetId extends UUIDBased implements EntityId {
26 29
27 30 private static final long serialVersionUID = 1L;
... ... @@ -35,7 +38,7 @@ public class AssetId extends UUIDBased implements EntityId {
35 38 return new AssetId(UUID.fromString(assetId));
36 39 }
37 40
38   - @JsonIgnore
  41 + @ApiModelProperty(position = 2, required = true, value = "string", example = "ASSET", allowableValues = "ASSET")
39 42 @Override
40 43 public EntityType getEntityType() {
41 44 return EntityType.ASSET;
... ...
... ... @@ -20,8 +20,11 @@ import java.util.UUID;
20 20 import com.fasterxml.jackson.annotation.JsonCreator;
21 21 import com.fasterxml.jackson.annotation.JsonIgnore;
22 22 import com.fasterxml.jackson.annotation.JsonProperty;
  23 +import io.swagger.annotations.ApiModel;
  24 +import io.swagger.annotations.ApiModelProperty;
23 25 import org.thingsboard.server.common.data.EntityType;
24 26
  27 +@ApiModel
25 28 public final class CustomerId extends UUIDBased implements EntityId {
26 29
27 30 private static final long serialVersionUID = 1L;
... ... @@ -31,7 +34,7 @@ public final class CustomerId extends UUIDBased implements EntityId {
31 34 super(id);
32 35 }
33 36
34   - @JsonIgnore
  37 + @ApiModelProperty(position = 2, required = true, value = "string", example = "CUSTOMER", allowableValues = "CUSTOMER")
35 38 @Override
36 39 public EntityType getEntityType() {
37 40 return EntityType.CUSTOMER;
... ...
... ... @@ -20,8 +20,11 @@ import java.util.UUID;
20 20 import com.fasterxml.jackson.annotation.JsonCreator;
21 21 import com.fasterxml.jackson.annotation.JsonIgnore;
22 22 import com.fasterxml.jackson.annotation.JsonProperty;
  23 +import io.swagger.annotations.ApiModel;
  24 +import io.swagger.annotations.ApiModelProperty;
23 25 import org.thingsboard.server.common.data.EntityType;
24 26
  27 +@ApiModel
25 28 public class DashboardId extends UUIDBased implements EntityId {
26 29
27 30 @JsonCreator
... ... @@ -33,7 +36,7 @@ public class DashboardId extends UUIDBased implements EntityId {
33 36 return new DashboardId(UUID.fromString(dashboardId));
34 37 }
35 38
36   - @JsonIgnore
  39 + @ApiModelProperty(position = 2, required = true, value = "string", example = "DASHBOARD", allowableValues = "DASHBOARD")
37 40 @Override
38 41 public EntityType getEntityType() {
39 42 return EntityType.DASHBOARD;
... ...
... ... @@ -20,8 +20,11 @@ import java.util.UUID;
20 20 import com.fasterxml.jackson.annotation.JsonCreator;
21 21 import com.fasterxml.jackson.annotation.JsonIgnore;
22 22 import com.fasterxml.jackson.annotation.JsonProperty;
  23 +import io.swagger.annotations.ApiModel;
  24 +import io.swagger.annotations.ApiModelProperty;
23 25 import org.thingsboard.server.common.data.EntityType;
24 26
  27 +@ApiModel
25 28 public class DeviceId extends UUIDBased implements EntityId {
26 29
27 30 private static final long serialVersionUID = 1L;
... ... @@ -35,8 +38,8 @@ public class DeviceId extends UUIDBased implements EntityId {
35 38 return new DeviceId(UUID.fromString(deviceId));
36 39 }
37 40
38   - @JsonIgnore
39 41 @Override
  42 + @ApiModelProperty(position = 2, required = true, value = "string", example = "DEVICE", allowableValues = "DEVICE")
40 43 public EntityType getEntityType() {
41 44 return EntityType.DEVICE;
42 45 }
... ...
... ... @@ -20,6 +20,7 @@ import java.util.UUID;
20 20 import com.fasterxml.jackson.annotation.JsonCreator;
21 21 import com.fasterxml.jackson.annotation.JsonIgnore;
22 22 import com.fasterxml.jackson.annotation.JsonProperty;
  23 +import io.swagger.annotations.ApiModelProperty;
23 24 import org.thingsboard.server.common.data.EntityType;
24 25
25 26 public class DeviceProfileId extends UUIDBased implements EntityId {
... ... @@ -35,7 +36,7 @@ public class DeviceProfileId extends UUIDBased implements EntityId {
35 36 return new DeviceProfileId(UUID.fromString(deviceProfileId));
36 37 }
37 38
38   - @JsonIgnore
  39 + @ApiModelProperty(position = 2, required = true, value = "string", example = "DEVICE_PROFILE", allowableValues = "DEVICE_PROFILE")
39 40 @Override
40 41 public EntityType getEntityType() {
41 42 return EntityType.DEVICE_PROFILE;
... ...
... ... @@ -18,6 +18,7 @@ package org.thingsboard.server.common.data.id;
18 18 import com.fasterxml.jackson.annotation.JsonCreator;
19 19 import com.fasterxml.jackson.annotation.JsonIgnore;
20 20 import com.fasterxml.jackson.annotation.JsonProperty;
  21 +import io.swagger.annotations.ApiModelProperty;
21 22 import org.thingsboard.server.common.data.EntityType;
22 23
23 24 import java.util.UUID;
... ... @@ -35,7 +36,7 @@ public class EdgeId extends UUIDBased implements EntityId {
35 36 return new EdgeId(UUID.fromString(integrationId));
36 37 }
37 38
38   - @JsonIgnore
  39 + @ApiModelProperty(position = 2, required = true, value = "string", example = "EDGE", allowableValues = "EDGE")
39 40 @Override
40 41 public EntityType getEntityType() {
41 42 return EntityType.EDGE;
... ...
... ... @@ -17,6 +17,7 @@ package org.thingsboard.server.common.data.id;
17 17
18 18 import com.fasterxml.jackson.annotation.JsonCreator;
19 19 import com.fasterxml.jackson.annotation.JsonProperty;
  20 +import io.swagger.annotations.ApiModelProperty;
20 21 import org.thingsboard.server.common.data.EntityType;
21 22
22 23 import java.util.UUID;
... ... @@ -37,6 +38,7 @@ public class EntityViewId extends UUIDBased implements EntityId {
37 38 return new EntityViewId(UUID.fromString(entityViewID));
38 39 }
39 40
  41 + @ApiModelProperty(position = 2, required = true, value = "string", example = "ENTITY_VIEW", allowableValues = "ENTITY_VIEW")
40 42 @Override
41 43 public EntityType getEntityType() {
42 44 return EntityType.ENTITY_VIEW;
... ...
... ... @@ -18,6 +18,7 @@ package org.thingsboard.server.common.data.id;
18 18 import com.fasterxml.jackson.annotation.JsonCreator;
19 19 import com.fasterxml.jackson.annotation.JsonIgnore;
20 20 import com.fasterxml.jackson.annotation.JsonProperty;
  21 +import io.swagger.annotations.ApiModelProperty;
21 22 import org.thingsboard.server.common.data.EntityType;
22 23
23 24 import java.util.UUID;
... ... @@ -35,7 +36,7 @@ public class OtaPackageId extends UUIDBased implements EntityId {
35 36 return new OtaPackageId(UUID.fromString(firmwareId));
36 37 }
37 38
38   - @JsonIgnore
  39 + @ApiModelProperty(position = 2, required = true, value = "string", example = "OTA_PACKAGE", allowableValues = "OTA_PACKAGE")
39 40 @Override
40 41 public EntityType getEntityType() {
41 42 return EntityType.OTA_PACKAGE;
... ...
... ... @@ -18,6 +18,7 @@ package org.thingsboard.server.common.data.id;
18 18 import com.fasterxml.jackson.annotation.JsonCreator;
19 19 import com.fasterxml.jackson.annotation.JsonIgnore;
20 20 import com.fasterxml.jackson.annotation.JsonProperty;
  21 +import io.swagger.annotations.ApiModelProperty;
21 22 import org.thingsboard.server.common.data.EntityType;
22 23
23 24 import java.util.UUID;
... ... @@ -31,7 +32,7 @@ public final class RpcId extends UUIDBased implements EntityId {
31 32 super(id);
32 33 }
33 34
34   - @JsonIgnore
  35 + @ApiModelProperty(position = 2, required = true, value = "string", example = "RPC", allowableValues = "RPC")
35 36 @Override
36 37 public EntityType getEntityType() {
37 38 return EntityType.RPC;
... ...
... ... @@ -18,6 +18,7 @@ package org.thingsboard.server.common.data.id;
18 18 import com.fasterxml.jackson.annotation.JsonCreator;
19 19 import com.fasterxml.jackson.annotation.JsonIgnore;
20 20 import com.fasterxml.jackson.annotation.JsonProperty;
  21 +import io.swagger.annotations.ApiModelProperty;
21 22 import org.thingsboard.server.common.data.EntityType;
22 23
23 24 import java.util.UUID;
... ... @@ -29,7 +30,7 @@ public class RuleChainId extends UUIDBased implements EntityId {
29 30 super(id);
30 31 }
31 32
32   - @JsonIgnore
  33 + @ApiModelProperty(position = 2, required = true, value = "string", example = "RULE_CHAIN", allowableValues = "RULE_CHAIN")
33 34 @Override
34 35 public EntityType getEntityType() {
35 36 return EntityType.RULE_CHAIN;
... ...
... ... @@ -18,6 +18,7 @@ package org.thingsboard.server.common.data.id;
18 18 import com.fasterxml.jackson.annotation.JsonCreator;
19 19 import com.fasterxml.jackson.annotation.JsonIgnore;
20 20 import com.fasterxml.jackson.annotation.JsonProperty;
  21 +import io.swagger.annotations.ApiModelProperty;
21 22 import org.thingsboard.server.common.data.EntityType;
22 23
23 24 import java.util.UUID;
... ... @@ -29,7 +30,7 @@ public class RuleNodeId extends UUIDBased implements EntityId {
29 30 super(id);
30 31 }
31 32
32   - @JsonIgnore
  33 + @ApiModelProperty(position = 2, required = true, value = "string", example = "RULE_NODE", allowableValues = "RULE_NODE")
33 34 @Override
34 35 public EntityType getEntityType() {
35 36 return EntityType.RULE_NODE;
... ...
... ... @@ -18,6 +18,7 @@ package org.thingsboard.server.common.data.id;
18 18 import com.fasterxml.jackson.annotation.JsonCreator;
19 19 import com.fasterxml.jackson.annotation.JsonIgnore;
20 20 import com.fasterxml.jackson.annotation.JsonProperty;
  21 +import io.swagger.annotations.ApiModelProperty;
21 22 import org.thingsboard.server.common.data.EntityType;
22 23
23 24 import java.util.UUID;
... ... @@ -31,7 +32,7 @@ public class TbResourceId extends UUIDBased implements EntityId {
31 32 super(id);
32 33 }
33 34
34   - @JsonIgnore
  35 + @ApiModelProperty(position = 2, required = true, value = "string", example = "TB_RESOURCE", allowableValues = "TB_RESOURCE")
35 36 @Override
36 37 public EntityType getEntityType() {
37 38 return EntityType.TB_RESOURCE;
... ...
... ... @@ -20,6 +20,7 @@ import java.util.UUID;
20 20 import com.fasterxml.jackson.annotation.JsonCreator;
21 21 import com.fasterxml.jackson.annotation.JsonIgnore;
22 22 import com.fasterxml.jackson.annotation.JsonProperty;
  23 +import io.swagger.annotations.ApiModelProperty;
23 24 import org.thingsboard.server.common.data.EntityType;
24 25
25 26 public final class TenantId extends UUIDBased implements EntityId {
... ... @@ -34,7 +35,7 @@ public final class TenantId extends UUIDBased implements EntityId {
34 35 super(id);
35 36 }
36 37
37   - @JsonIgnore
  38 + @ApiModelProperty(position = 2, required = true, value = "string", example = "TENANT", allowableValues = "TENANT")
38 39 @Override
39 40 public EntityType getEntityType() {
40 41 return EntityType.TENANT;
... ...
... ... @@ -20,6 +20,7 @@ import java.util.UUID;
20 20 import com.fasterxml.jackson.annotation.JsonCreator;
21 21 import com.fasterxml.jackson.annotation.JsonIgnore;
22 22 import com.fasterxml.jackson.annotation.JsonProperty;
  23 +import io.swagger.annotations.ApiModelProperty;
23 24 import org.thingsboard.server.common.data.EntityType;
24 25
25 26 public class TenantProfileId extends UUIDBased implements EntityId {
... ... @@ -35,7 +36,7 @@ public class TenantProfileId extends UUIDBased implements EntityId {
35 36 return new TenantProfileId(UUID.fromString(tenantProfileId));
36 37 }
37 38
38   - @JsonIgnore
  39 + @ApiModelProperty(position = 2, required = true, value = "string", example = "TENANT_PROFILE", allowableValues = "TENANT_PROFILE")
39 40 @Override
40 41 public EntityType getEntityType() {
41 42 return EntityType.TENANT_PROFILE;
... ...
... ... @@ -15,9 +15,13 @@
15 15 */
16 16 package org.thingsboard.server.common.data.id;
17 17
  18 +import io.swagger.annotations.ApiModel;
  19 +import io.swagger.annotations.ApiModelProperty;
  20 +
18 21 import java.io.Serializable;
19 22 import java.util.UUID;
20 23
  24 +@ApiModel
21 25 public abstract class UUIDBased implements HasUUID, Serializable {
22 26
23 27 private static final long serialVersionUID = 1L;
... ... @@ -33,6 +37,7 @@ public abstract class UUIDBased implements HasUUID, Serializable {
33 37 this.id = id;
34 38 }
35 39
  40 + @ApiModelProperty(position = 1, required = true, value = "string", example = "784f394c-42b6-435a-983c-b7beff2784f9")
36 41 public UUID getId() {
37 42 return id;
38 43 }
... ...
... ... @@ -20,6 +20,7 @@ import java.util.UUID;
20 20 import com.fasterxml.jackson.annotation.JsonCreator;
21 21 import com.fasterxml.jackson.annotation.JsonIgnore;
22 22 import com.fasterxml.jackson.annotation.JsonProperty;
  23 +import io.swagger.annotations.ApiModelProperty;
23 24 import org.thingsboard.server.common.data.EntityType;
24 25
25 26 public class UserId extends UUIDBased implements EntityId {
... ... @@ -33,7 +34,7 @@ public class UserId extends UUIDBased implements EntityId {
33 34 return new UserId(UUID.fromString(userId));
34 35 }
35 36
36   - @JsonIgnore
  37 + @ApiModelProperty(position = 2, required = true, value = "string", example = "USER", allowableValues = "USER")
37 38 @Override
38 39 public EntityType getEntityType() {
39 40 return EntityType.USER;
... ...
... ... @@ -20,6 +20,7 @@ import java.util.UUID;
20 20 import com.fasterxml.jackson.annotation.JsonCreator;
21 21 import com.fasterxml.jackson.annotation.JsonIgnore;
22 22 import com.fasterxml.jackson.annotation.JsonProperty;
  23 +import io.swagger.annotations.ApiModelProperty;
23 24 import org.thingsboard.server.common.data.EntityType;
24 25
25 26 public final class WidgetTypeId extends UUIDBased implements EntityId {
... ... @@ -31,7 +32,7 @@ public final class WidgetTypeId extends UUIDBased implements EntityId {
31 32 super(id);
32 33 }
33 34
34   - @JsonIgnore
  35 + @ApiModelProperty(position = 2, required = true, value = "string", example = "WIDGET_TYPE", allowableValues = "WIDGET_TYPE")
35 36 @Override
36 37 public EntityType getEntityType() {
37 38 return EntityType.WIDGET_TYPE;
... ...
... ... @@ -20,6 +20,7 @@ import java.util.UUID;
20 20 import com.fasterxml.jackson.annotation.JsonCreator;
21 21 import com.fasterxml.jackson.annotation.JsonIgnore;
22 22 import com.fasterxml.jackson.annotation.JsonProperty;
  23 +import io.swagger.annotations.ApiModelProperty;
23 24 import org.thingsboard.server.common.data.EntityType;
24 25
25 26 public final class WidgetsBundleId extends UUIDBased implements EntityId {
... ... @@ -31,7 +32,7 @@ public final class WidgetsBundleId extends UUIDBased implements EntityId {
31 32 super(id);
32 33 }
33 34
34   - @JsonIgnore
  35 + @ApiModelProperty(position = 2, required = true, value = "string", example = "WIDGETS_BUNDLE", allowableValues = "WIDGETS_BUNDLE")
35 36 @Override
36 37 public EntityType getEntityType() {
37 38 return EntityType.WIDGETS_BUNDLE;
... ...
... ... @@ -17,12 +17,15 @@ package org.thingsboard.server.common.data.page;
17 17
18 18 import com.fasterxml.jackson.annotation.JsonCreator;
19 19 import com.fasterxml.jackson.annotation.JsonProperty;
  20 +import io.swagger.annotations.ApiModel;
  21 +import io.swagger.annotations.ApiModelProperty;
20 22
21 23 import java.util.Collections;
22 24 import java.util.List;
23 25 import java.util.function.Function;
24 26 import java.util.stream.Collectors;
25 27
  28 +@ApiModel
26 29 public class PageData<T> {
27 30
28 31 private final List<T> data;
... ... @@ -45,18 +48,22 @@ public class PageData<T> {
45 48 this.hasNext = hasNext;
46 49 }
47 50
  51 + @ApiModelProperty(position = 1, value = "Array of the entities", readOnly = true)
48 52 public List<T> getData() {
49 53 return data;
50 54 }
51 55
  56 + @ApiModelProperty(position = 2, value = "Total number of available pages. Calculated based on the 'pageSize' request parameter and total number of entities that match search criteria", readOnly = true)
52 57 public int getTotalPages() {
53 58 return totalPages;
54 59 }
55 60
  61 + @ApiModelProperty(position = 3, value = "Total number of elements in all available pages", readOnly = true)
56 62 public long getTotalElements() {
57 63 return totalElements;
58 64 }
59 65
  66 + @ApiModelProperty(position = 4, value = "'false' value indicates the end of the result set", readOnly = true)
60 67 @JsonProperty("hasNext")
61 68 public boolean hasNext() {
62 69 return hasNext;
... ...
... ... @@ -16,6 +16,8 @@
16 16 package org.thingsboard.server.common.data.plugin;
17 17
18 18 import com.fasterxml.jackson.databind.JsonNode;
  19 +import io.swagger.annotations.ApiModel;
  20 +import io.swagger.annotations.ApiModelProperty;
19 21 import lombok.*;
20 22 import org.thingsboard.server.common.data.SearchTextBased;
21 23 import org.thingsboard.server.common.data.id.ComponentDescriptorId;
... ... @@ -23,16 +25,23 @@ import org.thingsboard.server.common.data.id.ComponentDescriptorId;
23 25 /**
24 26 * @author Andrew Shvayka
25 27 */
  28 +@ApiModel
26 29 @ToString
27 30 public class ComponentDescriptor extends SearchTextBased<ComponentDescriptorId> {
28 31
29 32 private static final long serialVersionUID = 1L;
30 33
  34 + @ApiModelProperty(position = 3, value = "Type of the Rule Node", readOnly = true)
31 35 @Getter @Setter private ComponentType type;
  36 + @ApiModelProperty(position = 4, value = "Scope of the Rule Node. Always set to 'TENANT', since no rule chains on the 'SYSTEM' level yet.", readOnly = true, allowableValues = "TENANT", example = "TENANT")
32 37 @Getter @Setter private ComponentScope scope;
  38 + @ApiModelProperty(position = 5, value = "Name of the Rule Node. Taken from the @RuleNode annotation.", readOnly = true, example = "Custom Rule Node")
33 39 @Getter @Setter private String name;
  40 + @ApiModelProperty(position = 6, value = "Full name of the Java class that implements the Rule Engine Node interface.", readOnly = true, example = "com.mycompany.CustomRuleNode")
34 41 @Getter @Setter private String clazz;
  42 + @ApiModelProperty(position = 7, value = "Complex JSON object that represents the Rule Node configuration.", readOnly = true)
35 43 @Getter @Setter private transient JsonNode configurationDescriptor;
  44 + @ApiModelProperty(position = 8, value = "Rule Node Actions. Deprecated. Always null.", readOnly = true)
36 45 @Getter @Setter private String actions;
37 46
38 47 public ComponentDescriptor() {
... ... @@ -53,12 +62,26 @@ public class ComponentDescriptor extends SearchTextBased<ComponentDescriptorId>
53 62 this.actions = plugin.getActions();
54 63 }
55 64
  65 + @ApiModelProperty(position = 1, value = "JSON object with the descriptor Id. " +
  66 + "Specify existing descriptor id to update the descriptor. " +
  67 + "Referencing non-existing descriptor Id will cause error. " +
  68 + "Omit this field to create new descriptor." )
  69 + @Override
  70 + public ComponentDescriptorId getId() {
  71 + return super.getId();
  72 + }
  73 +
  74 + @ApiModelProperty(position = 2, value = "Timestamp of the descriptor creation, in milliseconds", example = "1609459200000", readOnly = true)
  75 + @Override
  76 + public long getCreatedTime() {
  77 + return super.getCreatedTime();
  78 + }
  79 +
56 80 @Override
57 81 public String getSearchText() {
58 82 return name;
59 83 }
60 84
61   -
62 85 @Override
63 86 public boolean equals(Object o) {
64 87 if (this == o) return true;
... ... @@ -84,4 +107,5 @@ public class ComponentDescriptor extends SearchTextBased<ComponentDescriptorId>
84 107 result = 31 * result + (actions != null ? actions.hashCode() : 0);
85 108 return result;
86 109 }
  110 +
87 111 }
... ...
... ... @@ -15,6 +15,8 @@
15 15 */
16 16 package org.thingsboard.server.common.data.relation;
17 17
  18 +import io.swagger.annotations.ApiModel;
  19 +import io.swagger.annotations.ApiModelProperty;
18 20 import lombok.AllArgsConstructor;
19 21 import lombok.Data;
20 22 import org.thingsboard.server.common.data.EntityType;
... ... @@ -26,15 +28,22 @@ import java.util.UUID;
26 28 /**
27 29 * Created by ashvayka on 03.05.17.
28 30 */
  31 +@ApiModel
29 32 @Data
30 33 @AllArgsConstructor
31 34 public class RelationsSearchParameters {
32 35
  36 + @ApiModelProperty(position = 1, value = "Root entity id to start search from.")
33 37 private UUID rootId;
  38 + @ApiModelProperty(position = 2, value = "Type of the root entity.")
34 39 private EntityType rootType;
  40 + @ApiModelProperty(position = 3, value = "Type of the root entity.")
35 41 private EntitySearchDirection direction;
  42 + @ApiModelProperty(position = 4, value = "Type of the relation.")
36 43 private RelationTypeGroup relationTypeGroup;
  44 + @ApiModelProperty(position = 5, value = "Maximum level of the search depth.")
37 45 private int maxLevel = 1;
  46 + @ApiModelProperty(position = 6, value = "Fetch entities that match the last level of search. Useful to find Devices that are strictly 'maxLevel' relations away from the root entity.")
38 47 private boolean fetchLastLevelOnly;
39 48
40 49 public RelationsSearchParameters(EntityId entityId, EntitySearchDirection direction, int maxLevel, boolean fetchLastLevelOnly) {
... ...
... ... @@ -15,16 +15,18 @@
15 15 */
16 16 package org.thingsboard.server.common.data.security;
17 17
  18 +import io.swagger.annotations.ApiModel;
  19 +import io.swagger.annotations.ApiModelProperty;
18 20 import lombok.EqualsAndHashCode;
19 21 import org.thingsboard.server.common.data.BaseData;
20 22 import org.thingsboard.server.common.data.id.DeviceCredentialsId;
21 23 import org.thingsboard.server.common.data.id.DeviceId;
22 24
  25 +@ApiModel
23 26 @EqualsAndHashCode(callSuper = true)
24 27 public class DeviceCredentials extends BaseData<DeviceCredentialsId> implements DeviceCredentialsFilter {
25 28
26 29 private static final long serialVersionUID = -7869261127032877765L;
27   -
28 30 private DeviceId deviceId;
29 31 private DeviceCredentialsType credentialsType;
30 32 private String credentialsId;
... ... @@ -46,6 +48,21 @@ public class DeviceCredentials extends BaseData<DeviceCredentialsId> implements
46 48 this.credentialsValue = deviceCredentials.getCredentialsValue();
47 49 }
48 50
  51 + @ApiModelProperty(position = 1, required = true, readOnly = true, value = "The Id is automatically generated during device creation. " +
  52 + "Use 'getDeviceCredentialsByDeviceId' to obtain the id based on device id. " +
  53 + "Use 'updateDeviceCredentials' to update device credentials. ", example = "784f394c-42b6-435a-983c-b7beff2784f9")
  54 + @Override
  55 + public DeviceCredentialsId getId() {
  56 + return super.getId();
  57 + }
  58 +
  59 + @ApiModelProperty(position = 2, value = "Timestamp of the device credentials creation, in milliseconds", example = "1609459200000")
  60 + @Override
  61 + public long getCreatedTime() {
  62 + return super.getCreatedTime();
  63 + }
  64 +
  65 + @ApiModelProperty(position = 3, required = true, value = "JSON object with the device Id.")
49 66 public DeviceId getDeviceId() {
50 67 return deviceId;
51 68 }
... ... @@ -54,6 +71,7 @@ public class DeviceCredentials extends BaseData<DeviceCredentialsId> implements
54 71 this.deviceId = deviceId;
55 72 }
56 73
  74 + @ApiModelProperty(position = 4, value = "Type of the credentials", allowableValues="ACCESS_TOKEN, X509_CERTIFICATE, MQTT_BASIC, LWM2M_CREDENTIALS")
57 75 @Override
58 76 public DeviceCredentialsType getCredentialsType() {
59 77 return credentialsType;
... ... @@ -63,6 +81,11 @@ public class DeviceCredentials extends BaseData<DeviceCredentialsId> implements
63 81 this.credentialsType = credentialsType;
64 82 }
65 83
  84 + @ApiModelProperty(position = 5, required = true, value = "Unique Credentials Id per platform instance. " +
  85 + "Used to lookup credentials from the database. " +
  86 + "By default, new access token for your device. " +
  87 + "Depends on the type of the credentials."
  88 + , example = "Access token or other value that depends on the credentials type")
66 89 @Override
67 90 public String getCredentialsId() {
68 91 return credentialsId;
... ... @@ -72,6 +95,9 @@ public class DeviceCredentials extends BaseData<DeviceCredentialsId> implements
72 95 this.credentialsId = credentialsId;
73 96 }
74 97
  98 + @ApiModelProperty(position = 6, value = "Value of the credentials. " +
  99 + "Null in case of ACCESS_TOKEN credentials type. Base64 value in case of X509_CERTIFICATE. " +
  100 + "Complex object in case of MQTT_BASIC and LWM2M_CREDENTIALS", example = "Null in case of ACCESS_TOKEN. See model definition.")
75 101 public String getCredentialsValue() {
76 102 return credentialsValue;
77 103 }
... ...
... ... @@ -15,15 +15,20 @@
15 15 */
16 16 package org.thingsboard.server.common.data.security.model;
17 17
  18 +import io.swagger.annotations.ApiModel;
  19 +import io.swagger.annotations.ApiModelProperty;
18 20 import lombok.Data;
19 21
20 22 import java.io.Serializable;
21 23
  24 +@ApiModel
22 25 @Data
23 26 public class SecuritySettings implements Serializable {
24 27
  28 + @ApiModelProperty(position = 1, value = "The user password policy object." )
25 29 private UserPasswordPolicy passwordPolicy;
26   -
  30 + @ApiModelProperty(position = 2, value = "Maximum number of failed login attempts allowed before user account is locked." )
27 31 private Integer maxFailedLoginAttempts;
  32 + @ApiModelProperty(position = 3, value = "Email to use for notifications about locked users." )
28 33 private String userLockoutNotificationEmail;
29 34 }
... ...
... ... @@ -15,20 +15,30 @@
15 15 */
16 16 package org.thingsboard.server.common.data.security.model;
17 17
  18 +import io.swagger.annotations.ApiModel;
  19 +import io.swagger.annotations.ApiModelProperty;
18 20 import lombok.Data;
19 21
20 22 import java.io.Serializable;
21 23
  24 +@ApiModel
22 25 @Data
23 26 public class UserPasswordPolicy implements Serializable {
24 27
  28 + @ApiModelProperty(position = 1, value = "Minimum number of symbols in the password." )
25 29 private Integer minimumLength;
  30 + @ApiModelProperty(position = 1, value = "Minimum number of uppercase letters in the password." )
26 31 private Integer minimumUppercaseLetters;
  32 + @ApiModelProperty(position = 1, value = "Minimum number of lowercase letters in the password." )
27 33 private Integer minimumLowercaseLetters;
  34 + @ApiModelProperty(position = 1, value = "Minimum number of digits in the password." )
28 35 private Integer minimumDigits;
  36 + @ApiModelProperty(position = 1, value = "Minimum number of special in the password." )
29 37 private Integer minimumSpecialCharacters;
30 38
  39 + @ApiModelProperty(position = 1, value = "Password expiration period (days). Force expiration of the password." )
31 40 private Integer passwordExpirationPeriodDays;
  41 + @ApiModelProperty(position = 1, value = "Password reuse frequency (days). Disallow to use the same password for the defined number of days" )
32 42 private Integer passwordReuseFrequencyDays;
33 43
34 44 }
... ...
... ... @@ -15,13 +15,19 @@
15 15 */
16 16 package org.thingsboard.server.common.data.sms.config;
17 17
  18 +import io.swagger.annotations.ApiModel;
  19 +import io.swagger.annotations.ApiModelProperty;
18 20 import lombok.Data;
19 21
  22 +@ApiModel
20 23 @Data
21 24 public class AwsSnsSmsProviderConfiguration implements SmsProviderConfiguration {
22 25
  26 + @ApiModelProperty(position = 1, value = "The AWS SNS Access Key ID.")
23 27 private String accessKeyId;
  28 + @ApiModelProperty(position = 2, value = "The AWS SNS Access Key.")
24 29 private String secretAccessKey;
  30 + @ApiModelProperty(position = 3, value = "The AWS region.")
25 31 private String region;
26 32
27 33 @Override
... ...
... ... @@ -15,13 +15,19 @@
15 15 */
16 16 package org.thingsboard.server.common.data.sms.config;
17 17
  18 +import io.swagger.annotations.ApiModel;
  19 +import io.swagger.annotations.ApiModelProperty;
18 20 import lombok.Data;
19 21
  22 +@ApiModel
20 23 @Data
21 24 public class TestSmsRequest {
22 25
  26 + @ApiModelProperty(position = 1, value = "The SMS provider configuration")
23 27 private SmsProviderConfiguration providerConfiguration;
  28 + @ApiModelProperty(position = 2, value = "The phone number or other identifier to specify as a recipient of the SMS.")
24 29 private String numberTo;
  30 + @ApiModelProperty(position = 3, value = "The test message")
25 31 private String message;
26 32
27 33 }
... ...
... ... @@ -15,13 +15,19 @@
15 15 */
16 16 package org.thingsboard.server.common.data.sms.config;
17 17
  18 +import io.swagger.annotations.ApiModel;
  19 +import io.swagger.annotations.ApiModelProperty;
18 20 import lombok.Data;
19 21
  22 +@ApiModel
20 23 @Data
21 24 public class TwilioSmsProviderConfiguration implements SmsProviderConfiguration {
22 25
  26 + @ApiModelProperty(position = 1, value = "Twilio account Sid.")
23 27 private String accountSid;
  28 + @ApiModelProperty(position = 2, value = "Twilio account Token.")
24 29 private String accountToken;
  30 + @ApiModelProperty(position = 3, value = "The number/id of a sender.")
25 31 private String numberFrom;
26 32
27 33 @Override
... ...
... ... @@ -85,6 +85,7 @@
85 85 <jar-plugin.version>3.0.2</jar-plugin.version>
86 86 <springfox-swagger.version>2.6.1</springfox-swagger.version>
87 87 <springfox-swagger-ui-rfc6570.version>1.0.0</springfox-swagger-ui-rfc6570.version>
  88 + <swagger-annotations.version>1.5.10</swagger-annotations.version>
88 89 <spatial4j.version>0.7</spatial4j.version>
89 90 <jts.version>1.15.0</jts.version>
90 91 <bouncycastle.version>1.67</bouncycastle.version>
... ... @@ -1624,6 +1625,11 @@
1624 1625 <version>${springfox-swagger.version}</version>
1625 1626 </dependency>
1626 1627 <dependency>
  1628 + <groupId>io.swagger</groupId>
  1629 + <artifactId>swagger-annotations</artifactId>
  1630 + <version>${swagger-annotations.version}</version>
  1631 + </dependency>
  1632 + <dependency>
1627 1633 <groupId>org.bouncycastle</groupId>
1628 1634 <artifactId>bcprov-jdk15on</artifactId>
1629 1635 <version>${bouncycastle.version}</version>
... ...