Commit ab356a4bc97528d29926733bd85ad13c61264509
Committed by
GitHub
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); | ... | ... |
application/src/main/java/org/thingsboard/server/service/security/model/ActivateUserRequest.java
0 → 100644
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 | +} | ... | ... |
application/src/main/java/org/thingsboard/server/service/security/model/ChangePasswordRequest.java
0 → 100644
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 | +} | ... | ... |
application/src/main/java/org/thingsboard/server/service/security/model/JwtTokenPair.java
0 → 100644
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 | +} | ... | ... |
application/src/main/java/org/thingsboard/server/service/security/model/ResetPasswordRequest.java
0 → 100644
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, | ... | ... |
... | ... | @@ -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 | } | ... | ... |
common/data/src/main/java/org/thingsboard/server/common/data/relation/RelationsSearchParameters.java
... | ... | @@ -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> | ... | ... |