Commit ab356a4bc97528d29926733bd85ad13c61264509

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

Merge pull request #5279 from thingsboard/feature/swagger

Swagger Annotations to improve the auto-generated REST API doc.
Showing 64 changed files with 1191 additions and 136 deletions
@@ -16,6 +16,8 @@ @@ -16,6 +16,8 @@
16 package org.thingsboard.server.controller; 16 package org.thingsboard.server.controller;
17 17
18 import com.fasterxml.jackson.databind.node.ObjectNode; 18 import com.fasterxml.jackson.databind.node.ObjectNode;
  19 +import io.swagger.annotations.ApiOperation;
  20 +import io.swagger.annotations.ApiParam;
19 import org.springframework.beans.factory.annotation.Autowired; 21 import org.springframework.beans.factory.annotation.Autowired;
20 import org.springframework.security.access.prepost.PreAuthorize; 22 import org.springframework.security.access.prepost.PreAuthorize;
21 import org.springframework.web.bind.annotation.PathVariable; 23 import org.springframework.web.bind.annotation.PathVariable;
@@ -44,6 +46,7 @@ import org.thingsboard.server.service.update.UpdateService; @@ -44,6 +46,7 @@ import org.thingsboard.server.service.update.UpdateService;
44 @RequestMapping("/api/admin") 46 @RequestMapping("/api/admin")
45 public class AdminController extends BaseController { 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 @Autowired 50 @Autowired
48 private MailService mailService; 51 private MailService mailService;
49 52
@@ -59,10 +62,14 @@ public class AdminController extends BaseController { @@ -59,10 +62,14 @@ public class AdminController extends BaseController {
59 @Autowired 62 @Autowired
60 private UpdateService updateService; 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 @PreAuthorize("hasAuthority('SYS_ADMIN')") 67 @PreAuthorize("hasAuthority('SYS_ADMIN')")
63 @RequestMapping(value = "/settings/{key}", method = RequestMethod.GET) 68 @RequestMapping(value = "/settings/{key}", method = RequestMethod.GET)
64 @ResponseBody 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 try { 73 try {
67 accessControlService.checkPermission(getCurrentUser(), Resource.ADMIN_SETTINGS, Operation.READ); 74 accessControlService.checkPermission(getCurrentUser(), Resource.ADMIN_SETTINGS, Operation.READ);
68 AdminSettings adminSettings = checkNotNull(adminSettingsService.findAdminSettingsByKey(TenantId.SYS_TENANT_ID, key)); 75 AdminSettings adminSettings = checkNotNull(adminSettingsService.findAdminSettingsByKey(TenantId.SYS_TENANT_ID, key));
@@ -75,10 +82,17 @@ public class AdminController extends BaseController { @@ -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 @PreAuthorize("hasAuthority('SYS_ADMIN')") 90 @PreAuthorize("hasAuthority('SYS_ADMIN')")
79 @RequestMapping(value = "/settings", method = RequestMethod.POST) 91 @RequestMapping(value = "/settings", method = RequestMethod.POST)
80 @ResponseBody 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 try { 96 try {
83 accessControlService.checkPermission(getCurrentUser(), Resource.ADMIN_SETTINGS, Operation.WRITE); 97 accessControlService.checkPermission(getCurrentUser(), Resource.ADMIN_SETTINGS, Operation.WRITE);
84 adminSettings = checkNotNull(adminSettingsService.saveAdminSettings(TenantId.SYS_TENANT_ID, adminSettings)); 98 adminSettings = checkNotNull(adminSettingsService.saveAdminSettings(TenantId.SYS_TENANT_ID, adminSettings));
@@ -94,6 +108,8 @@ public class AdminController extends BaseController { @@ -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 @PreAuthorize("hasAuthority('SYS_ADMIN')") 113 @PreAuthorize("hasAuthority('SYS_ADMIN')")
98 @RequestMapping(value = "/securitySettings", method = RequestMethod.GET) 114 @RequestMapping(value = "/securitySettings", method = RequestMethod.GET)
99 @ResponseBody 115 @ResponseBody
@@ -106,10 +122,14 @@ public class AdminController extends BaseController { @@ -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 @PreAuthorize("hasAuthority('SYS_ADMIN')") 127 @PreAuthorize("hasAuthority('SYS_ADMIN')")
110 @RequestMapping(value = "/securitySettings", method = RequestMethod.POST) 128 @RequestMapping(value = "/securitySettings", method = RequestMethod.POST)
111 @ResponseBody 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 try { 133 try {
114 accessControlService.checkPermission(getCurrentUser(), Resource.ADMIN_SETTINGS, Operation.WRITE); 134 accessControlService.checkPermission(getCurrentUser(), Resource.ADMIN_SETTINGS, Operation.WRITE);
115 securitySettings = checkNotNull(systemSecurityService.saveSecuritySettings(TenantId.SYS_TENANT_ID, securitySettings)); 135 securitySettings = checkNotNull(systemSecurityService.saveSecuritySettings(TenantId.SYS_TENANT_ID, securitySettings));
@@ -119,14 +139,19 @@ public class AdminController extends BaseController { @@ -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 @PreAuthorize("hasAuthority('SYS_ADMIN')") 145 @PreAuthorize("hasAuthority('SYS_ADMIN')")
123 @RequestMapping(value = "/settings/testMail", method = RequestMethod.POST) 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 try { 150 try {
126 accessControlService.checkPermission(getCurrentUser(), Resource.ADMIN_SETTINGS, Operation.READ); 151 accessControlService.checkPermission(getCurrentUser(), Resource.ADMIN_SETTINGS, Operation.READ);
127 adminSettings = checkNotNull(adminSettings); 152 adminSettings = checkNotNull(adminSettings);
128 if (adminSettings.getKey().equals("mail")) { 153 if (adminSettings.getKey().equals("mail")) {
129 - if(!adminSettings.getJsonValue().has("password")) { 154 + if (!adminSettings.getJsonValue().has("password")) {
130 AdminSettings mailSettings = checkNotNull(adminSettingsService.findAdminSettingsByKey(TenantId.SYS_TENANT_ID, "mail")); 155 AdminSettings mailSettings = checkNotNull(adminSettingsService.findAdminSettingsByKey(TenantId.SYS_TENANT_ID, "mail"));
131 ((ObjectNode) adminSettings.getJsonValue()).put("password", mailSettings.getJsonValue().get("password").asText()); 156 ((ObjectNode) adminSettings.getJsonValue()).put("password", mailSettings.getJsonValue().get("password").asText());
132 } 157 }
@@ -138,9 +163,14 @@ public class AdminController extends BaseController { @@ -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 @PreAuthorize("hasAuthority('SYS_ADMIN')") 169 @PreAuthorize("hasAuthority('SYS_ADMIN')")
142 @RequestMapping(value = "/settings/testSms", method = RequestMethod.POST) 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 try { 174 try {
145 accessControlService.checkPermission(getCurrentUser(), Resource.ADMIN_SETTINGS, Operation.READ); 175 accessControlService.checkPermission(getCurrentUser(), Resource.ADMIN_SETTINGS, Operation.READ);
146 smsService.sendTestSms(testSmsRequest); 176 smsService.sendTestSms(testSmsRequest);
@@ -149,6 +179,9 @@ public class AdminController extends BaseController { @@ -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 @PreAuthorize("hasAuthority('SYS_ADMIN')") 185 @PreAuthorize("hasAuthority('SYS_ADMIN')")
153 @RequestMapping(value = "/updates", method = RequestMethod.GET) 186 @RequestMapping(value = "/updates", method = RequestMethod.GET)
154 @ResponseBody 187 @ResponseBody
@@ -16,9 +16,12 @@ @@ -16,9 +16,12 @@
16 package org.thingsboard.server.controller; 16 package org.thingsboard.server.controller;
17 17
18 import com.google.common.util.concurrent.ListenableFuture; 18 import com.google.common.util.concurrent.ListenableFuture;
  19 +import io.swagger.annotations.ApiOperation;
  20 +import io.swagger.annotations.ApiParam;
19 import lombok.RequiredArgsConstructor; 21 import lombok.RequiredArgsConstructor;
20 import lombok.extern.slf4j.Slf4j; 22 import lombok.extern.slf4j.Slf4j;
21 import org.springframework.http.HttpStatus; 23 import org.springframework.http.HttpStatus;
  24 +import org.springframework.http.MediaType;
22 import org.springframework.security.access.prepost.PreAuthorize; 25 import org.springframework.security.access.prepost.PreAuthorize;
23 import org.springframework.web.bind.annotation.PathVariable; 26 import org.springframework.web.bind.annotation.PathVariable;
24 import org.springframework.web.bind.annotation.PostMapping; 27 import org.springframework.web.bind.annotation.PostMapping;
@@ -37,8 +40,8 @@ import org.thingsboard.server.common.data.asset.AssetInfo; @@ -37,8 +40,8 @@ import org.thingsboard.server.common.data.asset.AssetInfo;
37 import org.thingsboard.server.common.data.asset.AssetSearchQuery; 40 import org.thingsboard.server.common.data.asset.AssetSearchQuery;
38 import org.thingsboard.server.common.data.audit.ActionType; 41 import org.thingsboard.server.common.data.audit.ActionType;
39 import org.thingsboard.server.common.data.edge.Edge; 42 import org.thingsboard.server.common.data.edge.Edge;
40 -import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;  
41 import org.thingsboard.server.common.data.edge.EdgeEventActionType; 43 import org.thingsboard.server.common.data.edge.EdgeEventActionType;
  44 +import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
42 import org.thingsboard.server.common.data.exception.ThingsboardException; 45 import org.thingsboard.server.common.data.exception.ThingsboardException;
43 import org.thingsboard.server.common.data.id.AssetId; 46 import org.thingsboard.server.common.data.id.AssetId;
44 import org.thingsboard.server.common.data.id.CustomerId; 47 import org.thingsboard.server.common.data.id.CustomerId;
@@ -61,9 +64,8 @@ import java.util.ArrayList; @@ -61,9 +64,8 @@ import java.util.ArrayList;
61 import java.util.List; 64 import java.util.List;
62 import java.util.stream.Collectors; 65 import java.util.stream.Collectors;
63 66
64 -import static org.thingsboard.server.dao.asset.BaseAssetService.TB_SERVICE_QUEUE;  
65 -  
66 import static org.thingsboard.server.controller.EdgeController.EDGE_ID; 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 @RestController 70 @RestController
69 @TbCoreComponent 71 @TbCoreComponent
@@ -75,10 +77,15 @@ public class AssetController extends BaseController { @@ -75,10 +77,15 @@ public class AssetController extends BaseController {
75 77
76 public static final String ASSET_ID = "assetId"; 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 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") 84 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
79 @RequestMapping(value = "/asset/{assetId}", method = RequestMethod.GET) 85 @RequestMapping(value = "/asset/{assetId}", method = RequestMethod.GET)
80 @ResponseBody 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 checkParameter(ASSET_ID, strAssetId); 89 checkParameter(ASSET_ID, strAssetId);
83 try { 90 try {
84 AssetId assetId = new AssetId(toUUID(strAssetId)); 91 AssetId assetId = new AssetId(toUUID(strAssetId));
@@ -88,10 +95,15 @@ public class AssetController extends BaseController { @@ -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 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") 102 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
92 @RequestMapping(value = "/asset/info/{assetId}", method = RequestMethod.GET) 103 @RequestMapping(value = "/asset/info/{assetId}", method = RequestMethod.GET)
93 @ResponseBody 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 checkParameter(ASSET_ID, strAssetId); 107 checkParameter(ASSET_ID, strAssetId);
96 try { 108 try {
97 AssetId assetId = new AssetId(toUUID(strAssetId)); 109 AssetId assetId = new AssetId(toUUID(strAssetId));
@@ -101,10 +113,15 @@ public class AssetController extends BaseController { @@ -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 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") 121 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
105 @RequestMapping(value = "/asset", method = RequestMethod.POST) 122 @RequestMapping(value = "/asset", method = RequestMethod.POST)
106 @ResponseBody 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 try { 125 try {
109 if (TB_SERVICE_QUEUE.equals(asset.getType())) { 126 if (TB_SERVICE_QUEUE.equals(asset.getType())) {
110 throw new ThingsboardException("Unable to save asset with type " + TB_SERVICE_QUEUE, ThingsboardErrorCode.BAD_REQUEST_PARAMS); 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,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 @PreAuthorize("hasAuthority('TENANT_ADMIN')") 162 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
144 @RequestMapping(value = "/asset/{assetId}", method = RequestMethod.DELETE) 163 @RequestMapping(value = "/asset/{assetId}", method = RequestMethod.DELETE)
145 @ResponseStatus(value = HttpStatus.OK) 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 checkParameter(ASSET_ID, strAssetId); 166 checkParameter(ASSET_ID, strAssetId);
148 try { 167 try {
149 AssetId assetId = new AssetId(toUUID(strAssetId)); 168 AssetId assetId = new AssetId(toUUID(strAssetId));
@@ -167,11 +186,13 @@ public class AssetController extends BaseController { @@ -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 @PreAuthorize("hasAuthority('TENANT_ADMIN')") 191 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
171 @RequestMapping(value = "/customer/{customerId}/asset/{assetId}", method = RequestMethod.POST) 192 @RequestMapping(value = "/customer/{customerId}/asset/{assetId}", method = RequestMethod.POST)
172 @ResponseBody 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 checkParameter("customerId", strCustomerId); 196 checkParameter("customerId", strCustomerId);
176 checkParameter(ASSET_ID, strAssetId); 197 checkParameter(ASSET_ID, strAssetId);
177 try { 198 try {
@@ -201,10 +222,12 @@ public class AssetController extends BaseController { @@ -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 @PreAuthorize("hasAuthority('TENANT_ADMIN')") 227 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
205 @RequestMapping(value = "/customer/asset/{assetId}", method = RequestMethod.DELETE) 228 @RequestMapping(value = "/customer/asset/{assetId}", method = RequestMethod.DELETE)
206 @ResponseBody 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 checkParameter(ASSET_ID, strAssetId); 231 checkParameter(ASSET_ID, strAssetId);
209 try { 232 try {
210 AssetId assetId = new AssetId(toUUID(strAssetId)); 233 AssetId assetId = new AssetId(toUUID(strAssetId));
@@ -235,10 +258,14 @@ public class AssetController extends BaseController { @@ -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 @PreAuthorize("hasAuthority('TENANT_ADMIN')") 265 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
239 @RequestMapping(value = "/customer/public/asset/{assetId}", method = RequestMethod.POST) 266 @RequestMapping(value = "/customer/public/asset/{assetId}", method = RequestMethod.POST)
240 @ResponseBody 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 checkParameter(ASSET_ID, strAssetId); 269 checkParameter(ASSET_ID, strAssetId);
243 try { 270 try {
244 AssetId assetId = new AssetId(toUUID(strAssetId)); 271 AssetId assetId = new AssetId(toUUID(strAssetId));
@@ -261,15 +288,24 @@ public class AssetController extends BaseController { @@ -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 @PreAuthorize("hasAuthority('TENANT_ADMIN')") 294 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
265 @RequestMapping(value = "/tenant/assets", params = {"pageSize", "page"}, method = RequestMethod.GET) 295 @RequestMapping(value = "/tenant/assets", params = {"pageSize", "page"}, method = RequestMethod.GET)
266 @ResponseBody 296 @ResponseBody
267 public PageData<Asset> getTenantAssets( 297 public PageData<Asset> getTenantAssets(
  298 + @ApiParam(value = PAGE_SIZE_DESCRIPTION)
268 @RequestParam int pageSize, 299 @RequestParam int pageSize,
  300 + @ApiParam(value = PAGE_NUMBER_DESCRIPTION)
269 @RequestParam int page, 301 @RequestParam int page,
  302 + @ApiParam(value = ASSET_TYPE_DESCRIPTION)
270 @RequestParam(required = false) String type, 303 @RequestParam(required = false) String type,
  304 + @ApiParam(value = ASSET_TEXT_SEARCH_DESCRIPTION)
271 @RequestParam(required = false) String textSearch, 305 @RequestParam(required = false) String textSearch,
  306 + @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = ASSET_SORT_PROPERTY_ALLOWABLE_VALUES)
272 @RequestParam(required = false) String sortProperty, 307 @RequestParam(required = false) String sortProperty,
  308 + @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES)
273 @RequestParam(required = false) String sortOrder) throws ThingsboardException { 309 @RequestParam(required = false) String sortOrder) throws ThingsboardException {
274 try { 310 try {
275 TenantId tenantId = getCurrentUser().getTenantId(); 311 TenantId tenantId = getCurrentUser().getTenantId();
@@ -284,15 +320,24 @@ public class AssetController extends BaseController { @@ -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 @PreAuthorize("hasAuthority('TENANT_ADMIN')") 326 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
288 @RequestMapping(value = "/tenant/assetInfos", params = {"pageSize", "page"}, method = RequestMethod.GET) 327 @RequestMapping(value = "/tenant/assetInfos", params = {"pageSize", "page"}, method = RequestMethod.GET)
289 @ResponseBody 328 @ResponseBody
290 public PageData<AssetInfo> getTenantAssetInfos( 329 public PageData<AssetInfo> getTenantAssetInfos(
  330 + @ApiParam(value = PAGE_SIZE_DESCRIPTION)
291 @RequestParam int pageSize, 331 @RequestParam int pageSize,
  332 + @ApiParam(value = PAGE_NUMBER_DESCRIPTION)
292 @RequestParam int page, 333 @RequestParam int page,
  334 + @ApiParam(value = ASSET_TYPE_DESCRIPTION)
293 @RequestParam(required = false) String type, 335 @RequestParam(required = false) String type,
  336 + @ApiParam(value = ASSET_TEXT_SEARCH_DESCRIPTION)
294 @RequestParam(required = false) String textSearch, 337 @RequestParam(required = false) String textSearch,
  338 + @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = ASSET_SORT_PROPERTY_ALLOWABLE_VALUES)
295 @RequestParam(required = false) String sortProperty, 339 @RequestParam(required = false) String sortProperty,
  340 + @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES)
296 @RequestParam(required = false) String sortOrder) throws ThingsboardException { 341 @RequestParam(required = false) String sortOrder) throws ThingsboardException {
297 try { 342 try {
298 TenantId tenantId = getCurrentUser().getTenantId(); 343 TenantId tenantId = getCurrentUser().getTenantId();
@@ -307,10 +352,14 @@ public class AssetController extends BaseController { @@ -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 @PreAuthorize("hasAuthority('TENANT_ADMIN')") 358 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
311 @RequestMapping(value = "/tenant/assets", params = {"assetName"}, method = RequestMethod.GET) 359 @RequestMapping(value = "/tenant/assets", params = {"assetName"}, method = RequestMethod.GET)
312 @ResponseBody 360 @ResponseBody
313 public Asset getTenantAsset( 361 public Asset getTenantAsset(
  362 + @ApiParam(value = ASSET_NAME_DESCRIPTION)
314 @RequestParam String assetName) throws ThingsboardException { 363 @RequestParam String assetName) throws ThingsboardException {
315 try { 364 try {
316 TenantId tenantId = getCurrentUser().getTenantId(); 365 TenantId tenantId = getCurrentUser().getTenantId();
@@ -320,16 +369,26 @@ public class AssetController extends BaseController { @@ -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 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") 375 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
324 @RequestMapping(value = "/customer/{customerId}/assets", params = {"pageSize", "page"}, method = RequestMethod.GET) 376 @RequestMapping(value = "/customer/{customerId}/assets", params = {"pageSize", "page"}, method = RequestMethod.GET)
325 @ResponseBody 377 @ResponseBody
326 public PageData<Asset> getCustomerAssets( 378 public PageData<Asset> getCustomerAssets(
  379 + @ApiParam(value = CUSTOMER_ID_PARAM_DESCRIPTION)
327 @PathVariable("customerId") String strCustomerId, 380 @PathVariable("customerId") String strCustomerId,
  381 + @ApiParam(value = PAGE_SIZE_DESCRIPTION)
328 @RequestParam int pageSize, 382 @RequestParam int pageSize,
  383 + @ApiParam(value = PAGE_NUMBER_DESCRIPTION)
329 @RequestParam int page, 384 @RequestParam int page,
  385 + @ApiParam(value = ASSET_TYPE_DESCRIPTION)
330 @RequestParam(required = false) String type, 386 @RequestParam(required = false) String type,
  387 + @ApiParam(value = ASSET_TEXT_SEARCH_DESCRIPTION)
331 @RequestParam(required = false) String textSearch, 388 @RequestParam(required = false) String textSearch,
  389 + @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = ASSET_SORT_PROPERTY_ALLOWABLE_VALUES)
332 @RequestParam(required = false) String sortProperty, 390 @RequestParam(required = false) String sortProperty,
  391 + @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES)
333 @RequestParam(required = false) String sortOrder) throws ThingsboardException { 392 @RequestParam(required = false) String sortOrder) throws ThingsboardException {
334 checkParameter("customerId", strCustomerId); 393 checkParameter("customerId", strCustomerId);
335 try { 394 try {
@@ -347,16 +406,26 @@ public class AssetController extends BaseController { @@ -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 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") 412 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
351 @RequestMapping(value = "/customer/{customerId}/assetInfos", params = {"pageSize", "page"}, method = RequestMethod.GET) 413 @RequestMapping(value = "/customer/{customerId}/assetInfos", params = {"pageSize", "page"}, method = RequestMethod.GET)
352 @ResponseBody 414 @ResponseBody
353 public PageData<AssetInfo> getCustomerAssetInfos( 415 public PageData<AssetInfo> getCustomerAssetInfos(
  416 + @ApiParam(value = CUSTOMER_ID_PARAM_DESCRIPTION)
354 @PathVariable("customerId") String strCustomerId, 417 @PathVariable("customerId") String strCustomerId,
  418 + @ApiParam(value = PAGE_SIZE_DESCRIPTION)
355 @RequestParam int pageSize, 419 @RequestParam int pageSize,
  420 + @ApiParam(value = PAGE_NUMBER_DESCRIPTION)
356 @RequestParam int page, 421 @RequestParam int page,
  422 + @ApiParam(value = ASSET_TYPE_DESCRIPTION)
357 @RequestParam(required = false) String type, 423 @RequestParam(required = false) String type,
  424 + @ApiParam(value = ASSET_TEXT_SEARCH_DESCRIPTION)
358 @RequestParam(required = false) String textSearch, 425 @RequestParam(required = false) String textSearch,
  426 + @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = ASSET_SORT_PROPERTY_ALLOWABLE_VALUES)
359 @RequestParam(required = false) String sortProperty, 427 @RequestParam(required = false) String sortProperty,
  428 + @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES)
360 @RequestParam(required = false) String sortOrder) throws ThingsboardException { 429 @RequestParam(required = false) String sortOrder) throws ThingsboardException {
361 checkParameter("customerId", strCustomerId); 430 checkParameter("customerId", strCustomerId);
362 try { 431 try {
@@ -374,10 +443,13 @@ public class AssetController extends BaseController { @@ -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 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") 448 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
378 @RequestMapping(value = "/assets", params = {"assetIds"}, method = RequestMethod.GET) 449 @RequestMapping(value = "/assets", params = {"assetIds"}, method = RequestMethod.GET)
379 @ResponseBody 450 @ResponseBody
380 public List<Asset> getAssetsByIds( 451 public List<Asset> getAssetsByIds(
  452 + @ApiParam(value = "A list of assets ids, separated by comma ','")
381 @RequestParam("assetIds") String[] strAssetIds) throws ThingsboardException { 453 @RequestParam("assetIds") String[] strAssetIds) throws ThingsboardException {
382 checkArrayParameter("assetIds", strAssetIds); 454 checkArrayParameter("assetIds", strAssetIds);
383 try { 455 try {
@@ -400,6 +472,10 @@ public class AssetController extends BaseController { @@ -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 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") 479 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
404 @RequestMapping(value = "/assets", method = RequestMethod.POST) 480 @RequestMapping(value = "/assets", method = RequestMethod.POST)
405 @ResponseBody 481 @ResponseBody
@@ -424,6 +500,8 @@ public class AssetController extends BaseController { @@ -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 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") 505 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
428 @RequestMapping(value = "/asset/types", method = RequestMethod.GET) 506 @RequestMapping(value = "/asset/types", method = RequestMethod.GET)
429 @ResponseBody 507 @ResponseBody
@@ -438,11 +516,15 @@ public class AssetController extends BaseController { @@ -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 @PreAuthorize("hasAuthority('TENANT_ADMIN')") 523 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
442 @RequestMapping(value = "/edge/{edgeId}/asset/{assetId}", method = RequestMethod.POST) 524 @RequestMapping(value = "/edge/{edgeId}/asset/{assetId}", method = RequestMethod.POST)
443 @ResponseBody 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 checkParameter(EDGE_ID, strEdgeId); 528 checkParameter(EDGE_ID, strEdgeId);
447 checkParameter(ASSET_ID, strAssetId); 529 checkParameter(ASSET_ID, strAssetId);
448 try { 530 try {
@@ -471,11 +553,13 @@ public class AssetController extends BaseController { @@ -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 @PreAuthorize("hasAuthority('TENANT_ADMIN')") 558 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
475 @RequestMapping(value = "/edge/{edgeId}/asset/{assetId}", method = RequestMethod.DELETE) 559 @RequestMapping(value = "/edge/{edgeId}/asset/{assetId}", method = RequestMethod.DELETE)
476 @ResponseBody 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 checkParameter(EDGE_ID, strEdgeId); 563 checkParameter(EDGE_ID, strEdgeId);
480 checkParameter(ASSET_ID, strAssetId); 564 checkParameter(ASSET_ID, strAssetId);
481 try { 565 try {
@@ -504,18 +588,30 @@ public class AssetController extends BaseController { @@ -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 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") 594 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
508 @RequestMapping(value = "/edge/{edgeId}/assets", params = {"pageSize", "page"}, method = RequestMethod.GET) 595 @RequestMapping(value = "/edge/{edgeId}/assets", params = {"pageSize", "page"}, method = RequestMethod.GET)
509 @ResponseBody 596 @ResponseBody
510 public PageData<Asset> getEdgeAssets( 597 public PageData<Asset> getEdgeAssets(
  598 + @ApiParam(value = EDGE_ID_PARAM_DESCRIPTION)
511 @PathVariable(EDGE_ID) String strEdgeId, 599 @PathVariable(EDGE_ID) String strEdgeId,
  600 + @ApiParam(value = PAGE_SIZE_DESCRIPTION)
512 @RequestParam int pageSize, 601 @RequestParam int pageSize,
  602 + @ApiParam(value = PAGE_NUMBER_DESCRIPTION)
513 @RequestParam int page, 603 @RequestParam int page,
  604 + @ApiParam(value = ASSET_TYPE_DESCRIPTION)
514 @RequestParam(required = false) String type, 605 @RequestParam(required = false) String type,
  606 + @ApiParam(value = ASSET_TEXT_SEARCH_DESCRIPTION)
515 @RequestParam(required = false) String textSearch, 607 @RequestParam(required = false) String textSearch,
  608 + @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = ASSET_SORT_PROPERTY_ALLOWABLE_VALUES)
516 @RequestParam(required = false) String sortProperty, 609 @RequestParam(required = false) String sortProperty,
  610 + @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES)
517 @RequestParam(required = false) String sortOrder, 611 @RequestParam(required = false) String sortOrder,
  612 + @ApiParam(value = "Timestamp. Assets with creation time before it won't be queried")
518 @RequestParam(required = false) Long startTime, 613 @RequestParam(required = false) Long startTime,
  614 + @ApiParam(value = "Timestamp. Assets with creation time after it won't be queried")
519 @RequestParam(required = false) Long endTime) throws ThingsboardException { 615 @RequestParam(required = false) Long endTime) throws ThingsboardException {
520 checkParameter(EDGE_ID, strEdgeId); 616 checkParameter(EDGE_ID, strEdgeId);
521 try { 617 try {
@@ -547,6 +643,8 @@ public class AssetController extends BaseController { @@ -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 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") 648 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')")
551 @PostMapping("/asset/bulk_import") 649 @PostMapping("/asset/bulk_import")
552 public BulkImportResult<Asset> processAssetsBulkImport(@RequestBody BulkImportRequest request) throws Exception { 650 public BulkImportResult<Asset> processAssetsBulkImport(@RequestBody BulkImportRequest request) throws Exception {
@@ -18,6 +18,8 @@ package org.thingsboard.server.controller; @@ -18,6 +18,8 @@ package org.thingsboard.server.controller;
18 import com.fasterxml.jackson.databind.JsonNode; 18 import com.fasterxml.jackson.databind.JsonNode;
19 import com.fasterxml.jackson.databind.ObjectMapper; 19 import com.fasterxml.jackson.databind.ObjectMapper;
20 import com.fasterxml.jackson.databind.node.ObjectNode; 20 import com.fasterxml.jackson.databind.node.ObjectNode;
  21 +import io.swagger.annotations.ApiOperation;
  22 +import io.swagger.annotations.ApiParam;
21 import lombok.RequiredArgsConstructor; 23 import lombok.RequiredArgsConstructor;
22 import lombok.extern.slf4j.Slf4j; 24 import lombok.extern.slf4j.Slf4j;
23 import org.springframework.context.ApplicationEventPublisher; 25 import org.springframework.context.ApplicationEventPublisher;
@@ -48,8 +50,13 @@ import org.thingsboard.server.common.data.security.model.SecuritySettings; @@ -48,8 +50,13 @@ import org.thingsboard.server.common.data.security.model.SecuritySettings;
48 import org.thingsboard.server.common.data.security.model.UserPasswordPolicy; 50 import org.thingsboard.server.common.data.security.model.UserPasswordPolicy;
49 import org.thingsboard.server.dao.audit.AuditLogService; 51 import org.thingsboard.server.dao.audit.AuditLogService;
50 import org.thingsboard.server.queue.util.TbCoreComponent; 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 import org.thingsboard.server.service.security.auth.jwt.RefreshTokenRepository; 57 import org.thingsboard.server.service.security.auth.jwt.RefreshTokenRepository;
52 import org.thingsboard.server.service.security.auth.rest.RestAuthenticationDetails; 58 import org.thingsboard.server.service.security.auth.rest.RestAuthenticationDetails;
  59 +import org.thingsboard.server.service.security.model.JwtTokenPair;
53 import org.thingsboard.server.service.security.model.SecurityUser; 60 import org.thingsboard.server.service.security.model.SecurityUser;
54 import org.thingsboard.server.service.security.model.UserPrincipal; 61 import org.thingsboard.server.service.security.model.UserPrincipal;
55 import org.thingsboard.server.service.security.model.token.JwtTokenFactory; 62 import org.thingsboard.server.service.security.model.token.JwtTokenFactory;
@@ -74,9 +81,13 @@ public class AuthController extends BaseController { @@ -74,9 +81,13 @@ public class AuthController extends BaseController {
74 private final AuditLogService auditLogService; 81 private final AuditLogService auditLogService;
75 private final ApplicationEventPublisher eventPublisher; 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 @PreAuthorize("isAuthenticated()") 87 @PreAuthorize("isAuthenticated()")
78 @RequestMapping(value = "/auth/user", method = RequestMethod.GET) 88 @RequestMapping(value = "/auth/user", method = RequestMethod.GET)
79 - public @ResponseBody User getUser() throws ThingsboardException { 89 + public @ResponseBody
  90 + User getUser() throws ThingsboardException {
80 try { 91 try {
81 SecurityUser securityUser = getCurrentUser(); 92 SecurityUser securityUser = getCurrentUser();
82 return userService.findUserById(securityUser.getTenantId(), securityUser.getId()); 93 return userService.findUserById(securityUser.getTenantId(), securityUser.getId());
@@ -85,6 +96,8 @@ public class AuthController extends BaseController { @@ -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 @PreAuthorize("isAuthenticated()") 101 @PreAuthorize("isAuthenticated()")
89 @RequestMapping(value = "/auth/logout", method = RequestMethod.POST) 102 @RequestMapping(value = "/auth/logout", method = RequestMethod.POST)
90 @ResponseStatus(value = HttpStatus.OK) 103 @ResponseStatus(value = HttpStatus.OK)
@@ -92,13 +105,17 @@ public class AuthController extends BaseController { @@ -92,13 +105,17 @@ public class AuthController extends BaseController {
92 logLogoutAction(request); 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 @PreAuthorize("isAuthenticated()") 110 @PreAuthorize("isAuthenticated()")
96 @RequestMapping(value = "/auth/changePassword", method = RequestMethod.POST) 111 @RequestMapping(value = "/auth/changePassword", method = RequestMethod.POST)
97 @ResponseStatus(value = HttpStatus.OK) 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 try { 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 SecurityUser securityUser = getCurrentUser(); 119 SecurityUser securityUser = getCurrentUser();
103 UserCredentials userCredentials = userService.findUserCredentialsByUserId(TenantId.SYS_TENANT_ID, securityUser.getId()); 120 UserCredentials userCredentials = userService.findUserCredentialsByUserId(TenantId.SYS_TENANT_ID, securityUser.getId());
104 if (!passwordEncoder.matches(currentPassword, userCredentials.getPassword())) { 121 if (!passwordEncoder.matches(currentPassword, userCredentials.getPassword())) {
@@ -123,6 +140,8 @@ public class AuthController extends BaseController { @@ -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 @RequestMapping(value = "/noauth/userPasswordPolicy", method = RequestMethod.GET) 145 @RequestMapping(value = "/noauth/userPasswordPolicy", method = RequestMethod.GET)
127 @ResponseBody 146 @ResponseBody
128 public UserPasswordPolicy getUserPasswordPolicy() throws ThingsboardException { 147 public UserPasswordPolicy getUserPasswordPolicy() throws ThingsboardException {
@@ -135,8 +154,13 @@ public class AuthController extends BaseController { @@ -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 @RequestMapping(value = "/noauth/activate", params = {"activateToken"}, method = RequestMethod.GET) 161 @RequestMapping(value = "/noauth/activate", params = {"activateToken"}, method = RequestMethod.GET)
139 public ResponseEntity<String> checkActivateToken( 162 public ResponseEntity<String> checkActivateToken(
  163 + @ApiParam(value = "The activate token string.")
140 @RequestParam(value = "activateToken") String activateToken) { 164 @RequestParam(value = "activateToken") String activateToken) {
141 HttpHeaders headers = new HttpHeaders(); 165 HttpHeaders headers = new HttpHeaders();
142 HttpStatus responseStatus; 166 HttpStatus responseStatus;
@@ -157,13 +181,17 @@ public class AuthController extends BaseController { @@ -157,13 +181,17 @@ public class AuthController extends BaseController {
157 return new ResponseEntity<>(headers, responseStatus); 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 @RequestMapping(value = "/noauth/resetPasswordByEmail", method = RequestMethod.POST) 187 @RequestMapping(value = "/noauth/resetPasswordByEmail", method = RequestMethod.POST)
161 @ResponseStatus(value = HttpStatus.OK) 188 @ResponseStatus(value = HttpStatus.OK)
162 public void requestResetPasswordByEmail( 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 HttpServletRequest request) throws ThingsboardException { 192 HttpServletRequest request) throws ThingsboardException {
165 try { 193 try {
166 - String email = resetPasswordByEmailRequest.get("email").asText(); 194 + String email = resetPasswordByEmailRequest.getEmail();
167 UserCredentials userCredentials = userService.requestPasswordReset(TenantId.SYS_TENANT_ID, email); 195 UserCredentials userCredentials = userService.requestPasswordReset(TenantId.SYS_TENANT_ID, email);
168 User user = userService.findUserById(TenantId.SYS_TENANT_ID, userCredentials.getUserId()); 196 User user = userService.findUserById(TenantId.SYS_TENANT_ID, userCredentials.getUserId());
169 String baseUrl = systemSecurityService.getBaseUrl(user.getTenantId(), user.getCustomerId(), request); 197 String baseUrl = systemSecurityService.getBaseUrl(user.getTenantId(), user.getCustomerId(), request);
@@ -176,8 +204,13 @@ public class AuthController extends BaseController { @@ -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 @RequestMapping(value = "/noauth/resetPassword", params = {"resetToken"}, method = RequestMethod.GET) 211 @RequestMapping(value = "/noauth/resetPassword", params = {"resetToken"}, method = RequestMethod.GET)
180 public ResponseEntity<String> checkResetToken( 212 public ResponseEntity<String> checkResetToken(
  213 + @ApiParam(value = "The reset token string.")
181 @RequestParam(value = "resetToken") String resetToken) { 214 @RequestParam(value = "resetToken") String resetToken) {
182 HttpHeaders headers = new HttpHeaders(); 215 HttpHeaders headers = new HttpHeaders();
183 HttpStatus responseStatus; 216 HttpStatus responseStatus;
@@ -198,16 +231,24 @@ public class AuthController extends BaseController { @@ -198,16 +231,24 @@ public class AuthController extends BaseController {
198 return new ResponseEntity<>(headers, responseStatus); 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 @RequestMapping(value = "/noauth/activate", method = RequestMethod.POST) 241 @RequestMapping(value = "/noauth/activate", method = RequestMethod.POST)
202 @ResponseStatus(value = HttpStatus.OK) 242 @ResponseStatus(value = HttpStatus.OK)
203 @ResponseBody 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 @RequestParam(required = false, defaultValue = "true") boolean sendActivationMail, 247 @RequestParam(required = false, defaultValue = "true") boolean sendActivationMail,
207 HttpServletRequest request) throws ThingsboardException { 248 HttpServletRequest request) throws ThingsboardException {
208 try { 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 systemSecurityService.validatePassword(TenantId.SYS_TENANT_ID, password, null); 252 systemSecurityService.validatePassword(TenantId.SYS_TENANT_ID, password, null);
212 String encodedPassword = passwordEncoder.encode(password); 253 String encodedPassword = passwordEncoder.encode(password);
213 UserCredentials credentials = userService.activateUserCredentials(TenantId.SYS_TENANT_ID, activateToken, encodedPassword); 254 UserCredentials credentials = userService.activateUserCredentials(TenantId.SYS_TENANT_ID, activateToken, encodedPassword);
@@ -232,25 +273,26 @@ public class AuthController extends BaseController { @@ -232,25 +273,26 @@ public class AuthController extends BaseController {
232 JwtToken accessToken = tokenFactory.createAccessJwtToken(securityUser); 273 JwtToken accessToken = tokenFactory.createAccessJwtToken(securityUser);
233 JwtToken refreshToken = refreshTokenRepository.requestRefreshToken(securityUser); 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 } catch (Exception e) { 277 } catch (Exception e) {
241 throw handleException(e); 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 @RequestMapping(value = "/noauth/resetPassword", method = RequestMethod.POST) 286 @RequestMapping(value = "/noauth/resetPassword", method = RequestMethod.POST)
246 @ResponseStatus(value = HttpStatus.OK) 287 @ResponseStatus(value = HttpStatus.OK)
247 @ResponseBody 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 HttpServletRequest request) throws ThingsboardException { 292 HttpServletRequest request) throws ThingsboardException {
251 try { 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 UserCredentials userCredentials = userService.findUserCredentialsByResetToken(TenantId.SYS_TENANT_ID, resetToken); 296 UserCredentials userCredentials = userService.findUserCredentialsByResetToken(TenantId.SYS_TENANT_ID, resetToken);
255 if (userCredentials != null) { 297 if (userCredentials != null) {
256 systemSecurityService.validatePassword(TenantId.SYS_TENANT_ID, password, userCredentials); 298 systemSecurityService.validatePassword(TenantId.SYS_TENANT_ID, password, userCredentials);
@@ -273,11 +315,7 @@ public class AuthController extends BaseController { @@ -273,11 +315,7 @@ public class AuthController extends BaseController {
273 JwtToken accessToken = tokenFactory.createAccessJwtToken(securityUser); 315 JwtToken accessToken = tokenFactory.createAccessJwtToken(securityUser);
274 JwtToken refreshToken = refreshTokenRepository.requestRefreshToken(securityUser); 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 } else { 319 } else {
282 throw new ThingsboardException("Invalid reset token!", ThingsboardErrorCode.BAD_REQUEST_PARAMS); 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,6 +153,46 @@ import static org.thingsboard.server.dao.service.Validator.validateId;
153 @TbCoreComponent 153 @TbCoreComponent
154 public abstract class BaseController { 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 public static final String INCORRECT_TENANT_ID = "Incorrect tenantId "; 196 public static final String INCORRECT_TENANT_ID = "Incorrect tenantId ";
157 protected static final String DEFAULT_DASHBOARD = "defaultDashboardId"; 197 protected static final String DEFAULT_DASHBOARD = "defaultDashboardId";
158 protected static final String HOME_DASHBOARD = "homeDashboardId"; 198 protected static final String HOME_DASHBOARD = "homeDashboardId";
@@ -897,7 +937,7 @@ public abstract class BaseController { @@ -897,7 +937,7 @@ public abstract class BaseController {
897 PageDataIterableByTenantIdEntityId<EdgeId> relatedEdgeIdsIterator = 937 PageDataIterableByTenantIdEntityId<EdgeId> relatedEdgeIdsIterator =
898 new PageDataIterableByTenantIdEntityId<>(edgeService::findRelatedEdgeIdsByEntityId, tenantId, entityId, DEFAULT_PAGE_SIZE); 938 new PageDataIterableByTenantIdEntityId<>(edgeService::findRelatedEdgeIdsByEntityId, tenantId, entityId, DEFAULT_PAGE_SIZE);
899 List<EdgeId> result = new ArrayList<>(); 939 List<EdgeId> result = new ArrayList<>();
900 - for(EdgeId edgeId : relatedEdgeIdsIterator) { 940 + for (EdgeId edgeId : relatedEdgeIdsIterator) {
901 result.add(edgeId); 941 result.add(edgeId);
902 } 942 }
903 return result; 943 return result;
@@ -15,6 +15,8 @@ @@ -15,6 +15,8 @@
15 */ 15 */
16 package org.thingsboard.server.controller; 16 package org.thingsboard.server.controller;
17 17
  18 +import io.swagger.annotations.ApiOperation;
  19 +import io.swagger.annotations.ApiParam;
18 import org.apache.commons.lang3.StringUtils; 20 import org.apache.commons.lang3.StringUtils;
19 import org.springframework.security.access.prepost.PreAuthorize; 21 import org.springframework.security.access.prepost.PreAuthorize;
20 import org.springframework.web.bind.annotation.PathVariable; 22 import org.springframework.web.bind.annotation.PathVariable;
@@ -38,10 +40,20 @@ import java.util.Set; @@ -38,10 +40,20 @@ import java.util.Set;
38 @RequestMapping("/api") 40 @RequestMapping("/api")
39 public class ComponentDescriptorController extends BaseController { 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 @PreAuthorize("hasAnyAuthority('SYS_ADMIN','TENANT_ADMIN')") 51 @PreAuthorize("hasAnyAuthority('SYS_ADMIN','TENANT_ADMIN')")
42 @RequestMapping(value = "/component/{componentDescriptorClazz:.+}", method = RequestMethod.GET) 52 @RequestMapping(value = "/component/{componentDescriptorClazz:.+}", method = RequestMethod.GET)
43 @ResponseBody 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 checkParameter("strComponentDescriptorClazz", strComponentDescriptorClazz); 57 checkParameter("strComponentDescriptorClazz", strComponentDescriptorClazz);
46 try { 58 try {
47 return checkComponentDescriptorByClazz(strComponentDescriptorClazz); 59 return checkComponentDescriptorByClazz(strComponentDescriptorClazz);
@@ -50,11 +62,17 @@ public class ComponentDescriptorController extends BaseController { @@ -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 @PreAuthorize("hasAnyAuthority('SYS_ADMIN','TENANT_ADMIN')") 68 @PreAuthorize("hasAnyAuthority('SYS_ADMIN','TENANT_ADMIN')")
54 @RequestMapping(value = "/components/{componentType}", method = RequestMethod.GET) 69 @RequestMapping(value = "/components/{componentType}", method = RequestMethod.GET)
55 @ResponseBody 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 checkParameter("componentType", strComponentType); 76 checkParameter("componentType", strComponentType);
59 try { 77 try {
60 return checkComponentDescriptorsByType(ComponentType.valueOf(strComponentType), getRuleChainType(strRuleChainType)); 78 return checkComponentDescriptorsByType(ComponentType.valueOf(strComponentType), getRuleChainType(strRuleChainType));
@@ -63,11 +81,17 @@ public class ComponentDescriptorController extends BaseController { @@ -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 @PreAuthorize("hasAnyAuthority('SYS_ADMIN','TENANT_ADMIN')") 87 @PreAuthorize("hasAnyAuthority('SYS_ADMIN','TENANT_ADMIN')")
67 @RequestMapping(value = "/components", params = {"componentTypes"}, method = RequestMethod.GET) 88 @RequestMapping(value = "/components", params = {"componentTypes"}, method = RequestMethod.GET)
68 @ResponseBody 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 checkArrayParameter("componentTypes", strComponentTypes); 95 checkArrayParameter("componentTypes", strComponentTypes);
72 try { 96 try {
73 Set<ComponentType> componentTypes = new HashSet<>(); 97 Set<ComponentType> componentTypes = new HashSet<>();
@@ -18,6 +18,8 @@ package org.thingsboard.server.controller; @@ -18,6 +18,8 @@ package org.thingsboard.server.controller;
18 import com.fasterxml.jackson.databind.JsonNode; 18 import com.fasterxml.jackson.databind.JsonNode;
19 import com.fasterxml.jackson.databind.ObjectMapper; 19 import com.fasterxml.jackson.databind.ObjectMapper;
20 import com.fasterxml.jackson.databind.node.ObjectNode; 20 import com.fasterxml.jackson.databind.node.ObjectNode;
  21 +import io.swagger.annotations.ApiOperation;
  22 +import io.swagger.annotations.ApiParam;
21 import org.springframework.http.HttpStatus; 23 import org.springframework.http.HttpStatus;
22 import org.springframework.security.access.prepost.PreAuthorize; 24 import org.springframework.security.access.prepost.PreAuthorize;
23 import org.springframework.web.bind.annotation.PathVariable; 25 import org.springframework.web.bind.annotation.PathVariable;
@@ -50,18 +52,23 @@ import java.util.List; @@ -50,18 +52,23 @@ import java.util.List;
50 @RequestMapping("/api") 52 @RequestMapping("/api")
51 public class CustomerController extends BaseController { 53 public class CustomerController extends BaseController {
52 54
53 - public static final String CUSTOMER_ID = "customerId";  
54 public static final String IS_PUBLIC = "isPublic"; 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 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") 61 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
57 @RequestMapping(value = "/customer/{customerId}", method = RequestMethod.GET) 62 @RequestMapping(value = "/customer/{customerId}", method = RequestMethod.GET)
58 @ResponseBody 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 checkParameter(CUSTOMER_ID, strCustomerId); 67 checkParameter(CUSTOMER_ID, strCustomerId);
61 try { 68 try {
62 CustomerId customerId = new CustomerId(toUUID(strCustomerId)); 69 CustomerId customerId = new CustomerId(toUUID(strCustomerId));
63 Customer customer = checkCustomerId(customerId, Operation.READ); 70 Customer customer = checkCustomerId(customerId, Operation.READ);
64 - if(!customer.getAdditionalInfo().isNull()) { 71 + if (!customer.getAdditionalInfo().isNull()) {
65 processDashboardIdFromAdditionalInfo((ObjectNode) customer.getAdditionalInfo(), HOME_DASHBOARD); 72 processDashboardIdFromAdditionalInfo((ObjectNode) customer.getAdditionalInfo(), HOME_DASHBOARD);
66 } 73 }
67 return customer; 74 return customer;
@@ -70,10 +77,15 @@ public class CustomerController extends BaseController { @@ -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 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") 83 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
74 @RequestMapping(value = "/customer/{customerId}/shortInfo", method = RequestMethod.GET) 84 @RequestMapping(value = "/customer/{customerId}/shortInfo", method = RequestMethod.GET)
75 @ResponseBody 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 checkParameter(CUSTOMER_ID, strCustomerId); 89 checkParameter(CUSTOMER_ID, strCustomerId);
78 try { 90 try {
79 CustomerId customerId = new CustomerId(toUUID(strCustomerId)); 91 CustomerId customerId = new CustomerId(toUUID(strCustomerId));
@@ -88,10 +100,14 @@ public class CustomerController extends BaseController { @@ -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 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") 105 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
92 @RequestMapping(value = "/customer/{customerId}/title", method = RequestMethod.GET, produces = "application/text") 106 @RequestMapping(value = "/customer/{customerId}/title", method = RequestMethod.GET, produces = "application/text")
93 @ResponseBody 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 checkParameter(CUSTOMER_ID, strCustomerId); 111 checkParameter(CUSTOMER_ID, strCustomerId);
96 try { 112 try {
97 CustomerId customerId = new CustomerId(toUUID(strCustomerId)); 113 CustomerId customerId = new CustomerId(toUUID(strCustomerId));
@@ -102,10 +118,15 @@ public class CustomerController extends BaseController { @@ -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 @PreAuthorize("hasAuthority('TENANT_ADMIN')") 126 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
106 @RequestMapping(value = "/customer", method = RequestMethod.POST) 127 @RequestMapping(value = "/customer", method = RequestMethod.POST)
107 @ResponseBody 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 try { 130 try {
110 customer.setTenantId(getCurrentUser().getTenantId()); 131 customer.setTenantId(getCurrentUser().getTenantId());
111 132
@@ -131,10 +152,13 @@ public class CustomerController extends BaseController { @@ -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 @PreAuthorize("hasAuthority('TENANT_ADMIN')") 157 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
135 @RequestMapping(value = "/customer/{customerId}", method = RequestMethod.DELETE) 158 @RequestMapping(value = "/customer/{customerId}", method = RequestMethod.DELETE)
136 @ResponseStatus(value = HttpStatus.OK) 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 checkParameter(CUSTOMER_ID, strCustomerId); 162 checkParameter(CUSTOMER_ID, strCustomerId);
139 try { 163 try {
140 CustomerId customerId = new CustomerId(toUUID(strCustomerId)); 164 CustomerId customerId = new CustomerId(toUUID(strCustomerId));
@@ -161,14 +185,23 @@ public class CustomerController extends BaseController { @@ -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 @PreAuthorize("hasAuthority('TENANT_ADMIN')") 191 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
165 @RequestMapping(value = "/customers", params = {"pageSize", "page"}, method = RequestMethod.GET) 192 @RequestMapping(value = "/customers", params = {"pageSize", "page"}, method = RequestMethod.GET)
166 @ResponseBody 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 try { 205 try {
173 PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); 206 PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder);
174 TenantId tenantId = getCurrentUser().getTenantId(); 207 TenantId tenantId = getCurrentUser().getTenantId();
@@ -178,10 +211,13 @@ public class CustomerController extends BaseController { @@ -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 @PreAuthorize("hasAuthority('TENANT_ADMIN')") 216 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
182 @RequestMapping(value = "/tenant/customers", params = {"customerTitle"}, method = RequestMethod.GET) 217 @RequestMapping(value = "/tenant/customers", params = {"customerTitle"}, method = RequestMethod.GET)
183 @ResponseBody 218 @ResponseBody
184 public Customer getTenantCustomer( 219 public Customer getTenantCustomer(
  220 + @ApiParam(value = "A string value representing the Customer title.")
185 @RequestParam String customerTitle) throws ThingsboardException { 221 @RequestParam String customerTitle) throws ThingsboardException {
186 try { 222 try {
187 TenantId tenantId = getCurrentUser().getTenantId(); 223 TenantId tenantId = getCurrentUser().getTenantId();
@@ -17,8 +17,11 @@ package org.thingsboard.server.controller; @@ -17,8 +17,11 @@ package org.thingsboard.server.controller;
17 17
18 import com.fasterxml.jackson.databind.JsonNode; 18 import com.fasterxml.jackson.databind.JsonNode;
19 import com.fasterxml.jackson.databind.node.ObjectNode; 19 import com.fasterxml.jackson.databind.node.ObjectNode;
  20 +import io.swagger.annotations.ApiOperation;
  21 +import io.swagger.annotations.ApiParam;
20 import org.springframework.beans.factory.annotation.Value; 22 import org.springframework.beans.factory.annotation.Value;
21 import org.springframework.http.HttpStatus; 23 import org.springframework.http.HttpStatus;
  24 +import org.springframework.http.MediaType;
22 import org.springframework.security.access.prepost.PreAuthorize; 25 import org.springframework.security.access.prepost.PreAuthorize;
23 import org.springframework.web.bind.annotation.PathVariable; 26 import org.springframework.web.bind.annotation.PathVariable;
24 import org.springframework.web.bind.annotation.RequestBody; 27 import org.springframework.web.bind.annotation.RequestBody;
@@ -68,11 +71,16 @@ public class DashboardController extends BaseController { @@ -68,11 +71,16 @@ public class DashboardController extends BaseController {
68 71
69 private static final String HOME_DASHBOARD_ID = "homeDashboardId"; 72 private static final String HOME_DASHBOARD_ID = "homeDashboardId";
70 private static final String HOME_DASHBOARD_HIDE_TOOLBAR = "homeDashboardHideToolbar"; 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 @Value("${dashboard.max_datapoints_limit}") 78 @Value("${dashboard.max_datapoints_limit}")
73 private long maxDatapointsLimit; 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 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") 84 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
77 @RequestMapping(value = "/dashboard/serverTime", method = RequestMethod.GET) 85 @RequestMapping(value = "/dashboard/serverTime", method = RequestMethod.GET)
78 @ResponseBody 86 @ResponseBody
@@ -80,6 +88,11 @@ public class DashboardController extends BaseController { @@ -80,6 +88,11 @@ public class DashboardController extends BaseController {
80 return System.currentTimeMillis(); 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 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") 96 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
84 @RequestMapping(value = "/dashboard/maxDatapointsLimit", method = RequestMethod.GET) 97 @RequestMapping(value = "/dashboard/maxDatapointsLimit", method = RequestMethod.GET)
85 @ResponseBody 98 @ResponseBody
@@ -87,10 +100,16 @@ public class DashboardController extends BaseController { @@ -87,10 +100,16 @@ public class DashboardController extends BaseController {
87 return maxDatapointsLimit; 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 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") 107 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
91 @RequestMapping(value = "/dashboard/info/{dashboardId}", method = RequestMethod.GET) 108 @RequestMapping(value = "/dashboard/info/{dashboardId}", method = RequestMethod.GET)
92 @ResponseBody 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 checkParameter(DASHBOARD_ID, strDashboardId); 113 checkParameter(DASHBOARD_ID, strDashboardId);
95 try { 114 try {
96 DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); 115 DashboardId dashboardId = new DashboardId(toUUID(strDashboardId));
@@ -100,10 +119,16 @@ public class DashboardController extends BaseController { @@ -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 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") 126 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
104 @RequestMapping(value = "/dashboard/{dashboardId}", method = RequestMethod.GET) 127 @RequestMapping(value = "/dashboard/{dashboardId}", method = RequestMethod.GET)
105 @ResponseBody 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 checkParameter(DASHBOARD_ID, strDashboardId); 132 checkParameter(DASHBOARD_ID, strDashboardId);
108 try { 133 try {
109 DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); 134 DashboardId dashboardId = new DashboardId(toUUID(strDashboardId));
@@ -113,10 +138,20 @@ public class DashboardController extends BaseController { @@ -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 @PreAuthorize("hasAuthority('TENANT_ADMIN')") 149 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
117 @RequestMapping(value = "/dashboard", method = RequestMethod.POST) 150 @RequestMapping(value = "/dashboard", method = RequestMethod.POST)
118 @ResponseBody 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 try { 155 try {
121 dashboard.setTenantId(getCurrentUser().getTenantId()); 156 dashboard.setTenantId(getCurrentUser().getTenantId());
122 157
@@ -141,10 +176,14 @@ public class DashboardController extends BaseController { @@ -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 @PreAuthorize("hasAuthority('TENANT_ADMIN')") 181 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
145 @RequestMapping(value = "/dashboard/{dashboardId}", method = RequestMethod.DELETE) 182 @RequestMapping(value = "/dashboard/{dashboardId}", method = RequestMethod.DELETE)
146 @ResponseStatus(value = HttpStatus.OK) 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 checkParameter(DASHBOARD_ID, strDashboardId); 187 checkParameter(DASHBOARD_ID, strDashboardId);
149 try { 188 try {
150 DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); 189 DashboardId dashboardId = new DashboardId(toUUID(strDashboardId));
@@ -170,12 +209,19 @@ public class DashboardController extends BaseController { @@ -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 @PreAuthorize("hasAuthority('TENANT_ADMIN')") 216 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
174 @RequestMapping(value = "/customer/{customerId}/dashboard/{dashboardId}", method = RequestMethod.POST) 217 @RequestMapping(value = "/customer/{customerId}/dashboard/{dashboardId}", method = RequestMethod.POST)
175 @ResponseBody 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 checkParameter(DASHBOARD_ID, strDashboardId); 225 checkParameter(DASHBOARD_ID, strDashboardId);
180 try { 226 try {
181 CustomerId customerId = new CustomerId(toUUID(strCustomerId)); 227 CustomerId customerId = new CustomerId(toUUID(strCustomerId));
@@ -203,11 +249,18 @@ public class DashboardController extends BaseController { @@ -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 @PreAuthorize("hasAuthority('TENANT_ADMIN')") 256 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
207 @RequestMapping(value = "/customer/{customerId}/dashboard/{dashboardId}", method = RequestMethod.DELETE) 257 @RequestMapping(value = "/customer/{customerId}/dashboard/{dashboardId}", method = RequestMethod.DELETE)
208 @ResponseBody 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 checkParameter("customerId", strCustomerId); 264 checkParameter("customerId", strCustomerId);
212 checkParameter(DASHBOARD_ID, strDashboardId); 265 checkParameter(DASHBOARD_ID, strDashboardId);
213 try { 266 try {
@@ -235,11 +288,20 @@ public class DashboardController extends BaseController { @@ -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 @PreAuthorize("hasAuthority('TENANT_ADMIN')") 297 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
239 @RequestMapping(value = "/dashboard/{dashboardId}/customers", method = RequestMethod.POST) 298 @RequestMapping(value = "/dashboard/{dashboardId}/customers", method = RequestMethod.POST)
240 @ResponseBody 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 checkParameter(DASHBOARD_ID, strDashboardId); 305 checkParameter(DASHBOARD_ID, strDashboardId);
244 try { 306 try {
245 DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); 307 DashboardId dashboardId = new DashboardId(toUUID(strDashboardId));
@@ -301,11 +363,19 @@ public class DashboardController extends BaseController { @@ -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 @PreAuthorize("hasAuthority('TENANT_ADMIN')") 371 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
305 @RequestMapping(value = "/dashboard/{dashboardId}/customers/add", method = RequestMethod.POST) 372 @RequestMapping(value = "/dashboard/{dashboardId}/customers/add", method = RequestMethod.POST)
306 @ResponseBody 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 checkParameter(DASHBOARD_ID, strDashboardId); 379 checkParameter(DASHBOARD_ID, strDashboardId);
310 try { 380 try {
311 DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); 381 DashboardId dashboardId = new DashboardId(toUUID(strDashboardId));
@@ -345,11 +415,19 @@ public class DashboardController extends BaseController { @@ -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 @PreAuthorize("hasAuthority('TENANT_ADMIN')") 423 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
349 @RequestMapping(value = "/dashboard/{dashboardId}/customers/remove", method = RequestMethod.POST) 424 @RequestMapping(value = "/dashboard/{dashboardId}/customers/remove", method = RequestMethod.POST)
350 @ResponseBody 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 checkParameter(DASHBOARD_ID, strDashboardId); 431 checkParameter(DASHBOARD_ID, strDashboardId);
354 try { 432 try {
355 DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); 433 DashboardId dashboardId = new DashboardId(toUUID(strDashboardId));
@@ -389,10 +467,20 @@ public class DashboardController extends BaseController { @@ -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 @PreAuthorize("hasAuthority('TENANT_ADMIN')") 478 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
393 @RequestMapping(value = "/customer/public/dashboard/{dashboardId}", method = RequestMethod.POST) 479 @RequestMapping(value = "/customer/public/dashboard/{dashboardId}", method = RequestMethod.POST)
394 @ResponseBody 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 checkParameter(DASHBOARD_ID, strDashboardId); 484 checkParameter(DASHBOARD_ID, strDashboardId);
397 try { 485 try {
398 DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); 486 DashboardId dashboardId = new DashboardId(toUUID(strDashboardId));
@@ -415,10 +503,16 @@ public class DashboardController extends BaseController { @@ -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 @PreAuthorize("hasAuthority('TENANT_ADMIN')") 510 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
419 @RequestMapping(value = "/customer/public/dashboard/{dashboardId}", method = RequestMethod.DELETE) 511 @RequestMapping(value = "/customer/public/dashboard/{dashboardId}", method = RequestMethod.DELETE)
420 @ResponseBody 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 checkParameter(DASHBOARD_ID, strDashboardId); 516 checkParameter(DASHBOARD_ID, strDashboardId);
423 try { 517 try {
424 DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); 518 DashboardId dashboardId = new DashboardId(toUUID(strDashboardId));
@@ -442,15 +536,25 @@ public class DashboardController extends BaseController { @@ -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 @PreAuthorize("hasAuthority('SYS_ADMIN')") 543 @PreAuthorize("hasAuthority('SYS_ADMIN')")
446 @RequestMapping(value = "/tenant/{tenantId}/dashboards", params = {"pageSize", "page"}, method = RequestMethod.GET) 544 @RequestMapping(value = "/tenant/{tenantId}/dashboards", params = {"pageSize", "page"}, method = RequestMethod.GET)
447 @ResponseBody 545 @ResponseBody
448 public PageData<DashboardInfo> getTenantDashboards( 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 @RequestParam int pageSize, 550 @RequestParam int pageSize,
  551 + @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true)
451 @RequestParam int page, 552 @RequestParam int page,
  553 + @ApiParam(value = DASHBOARD_TEXT_SEARCH_DESCRIPTION)
452 @RequestParam(required = false) String textSearch, 554 @RequestParam(required = false) String textSearch,
  555 + @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = DASHBOARD_SORT_PROPERTY_ALLOWABLE_VALUES)
453 @RequestParam(required = false) String sortProperty, 556 @RequestParam(required = false) String sortProperty,
  557 + @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES)
454 @RequestParam(required = false) String sortOrder) throws ThingsboardException { 558 @RequestParam(required = false) String sortOrder) throws ThingsboardException {
455 try { 559 try {
456 TenantId tenantId = new TenantId(toUUID(strTenantId)); 560 TenantId tenantId = new TenantId(toUUID(strTenantId));
@@ -462,20 +566,30 @@ public class DashboardController extends BaseController { @@ -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 @PreAuthorize("hasAuthority('TENANT_ADMIN')") 573 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
466 @RequestMapping(value = "/tenant/dashboards", params = {"pageSize", "page"}, method = RequestMethod.GET) 574 @RequestMapping(value = "/tenant/dashboards", params = {"pageSize", "page"}, method = RequestMethod.GET)
467 @ResponseBody 575 @ResponseBody
468 public PageData<DashboardInfo> getTenantDashboards( 576 public PageData<DashboardInfo> getTenantDashboards(
  577 + @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true)
469 @RequestParam int pageSize, 578 @RequestParam int pageSize,
  579 + @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true)
470 @RequestParam int page, 580 @RequestParam int page,
  581 + @ApiParam(value = HIDDEN_FOR_MOBILE)
471 @RequestParam(required = false) Boolean mobile, 582 @RequestParam(required = false) Boolean mobile,
  583 + @ApiParam(value = DASHBOARD_TEXT_SEARCH_DESCRIPTION)
472 @RequestParam(required = false) String textSearch, 584 @RequestParam(required = false) String textSearch,
  585 + @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = DASHBOARD_SORT_PROPERTY_ALLOWABLE_VALUES)
473 @RequestParam(required = false) String sortProperty, 586 @RequestParam(required = false) String sortProperty,
  587 + @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES)
474 @RequestParam(required = false) String sortOrder) throws ThingsboardException { 588 @RequestParam(required = false) String sortOrder) throws ThingsboardException {
475 try { 589 try {
476 TenantId tenantId = getCurrentUser().getTenantId(); 590 TenantId tenantId = getCurrentUser().getTenantId();
477 PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); 591 PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder);
478 - if (mobile != null && mobile.booleanValue()) { 592 + if (mobile != null && mobile) {
479 return checkNotNull(dashboardService.findMobileDashboardsByTenantId(tenantId, pageLink)); 593 return checkNotNull(dashboardService.findMobileDashboardsByTenantId(tenantId, pageLink));
480 } else { 594 } else {
481 return checkNotNull(dashboardService.findDashboardsByTenantId(tenantId, pageLink)); 595 return checkNotNull(dashboardService.findDashboardsByTenantId(tenantId, pageLink));
@@ -485,24 +599,35 @@ public class DashboardController extends BaseController { @@ -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 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") 606 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
489 @RequestMapping(value = "/customer/{customerId}/dashboards", params = {"pageSize", "page"}, method = RequestMethod.GET) 607 @RequestMapping(value = "/customer/{customerId}/dashboards", params = {"pageSize", "page"}, method = RequestMethod.GET)
490 @ResponseBody 608 @ResponseBody
491 public PageData<DashboardInfo> getCustomerDashboards( 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 @RequestParam int pageSize, 613 @RequestParam int pageSize,
  614 + @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true)
494 @RequestParam int page, 615 @RequestParam int page,
  616 + @ApiParam(value = HIDDEN_FOR_MOBILE)
495 @RequestParam(required = false) Boolean mobile, 617 @RequestParam(required = false) Boolean mobile,
  618 + @ApiParam(value = DASHBOARD_TEXT_SEARCH_DESCRIPTION)
496 @RequestParam(required = false) String textSearch, 619 @RequestParam(required = false) String textSearch,
  620 + @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = DASHBOARD_SORT_PROPERTY_ALLOWABLE_VALUES)
497 @RequestParam(required = false) String sortProperty, 621 @RequestParam(required = false) String sortProperty,
  622 + @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES)
498 @RequestParam(required = false) String sortOrder) throws ThingsboardException { 623 @RequestParam(required = false) String sortOrder) throws ThingsboardException {
499 - checkParameter("customerId", strCustomerId); 624 + checkParameter(CUSTOMER_ID, strCustomerId);
500 try { 625 try {
501 TenantId tenantId = getCurrentUser().getTenantId(); 626 TenantId tenantId = getCurrentUser().getTenantId();
502 CustomerId customerId = new CustomerId(toUUID(strCustomerId)); 627 CustomerId customerId = new CustomerId(toUUID(strCustomerId));
503 checkCustomerId(customerId, Operation.READ); 628 checkCustomerId(customerId, Operation.READ);
504 PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); 629 PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder);
505 - if (mobile != null && mobile.booleanValue()) { 630 + if (mobile != null && mobile) {
506 return checkNotNull(dashboardService.findMobileDashboardsByTenantIdAndCustomerId(tenantId, customerId, pageLink)); 631 return checkNotNull(dashboardService.findMobileDashboardsByTenantIdAndCustomerId(tenantId, customerId, pageLink));
507 } else { 632 } else {
508 return checkNotNull(dashboardService.findDashboardsByTenantIdAndCustomerId(tenantId, customerId, pageLink)); 633 return checkNotNull(dashboardService.findDashboardsByTenantIdAndCustomerId(tenantId, customerId, pageLink));
@@ -512,6 +637,13 @@ public class DashboardController extends BaseController { @@ -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 @PreAuthorize("isAuthenticated()") 647 @PreAuthorize("isAuthenticated()")
516 @RequestMapping(value = "/dashboard/home", method = RequestMethod.GET) 648 @RequestMapping(value = "/dashboard/home", method = RequestMethod.GET)
517 @ResponseBody 649 @ResponseBody
@@ -543,6 +675,12 @@ public class DashboardController extends BaseController { @@ -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 @PreAuthorize("isAuthenticated()") 684 @PreAuthorize("isAuthenticated()")
547 @RequestMapping(value = "/dashboard/home/info", method = RequestMethod.GET) 685 @RequestMapping(value = "/dashboard/home/info", method = RequestMethod.GET)
548 @ResponseBody 686 @ResponseBody
@@ -574,6 +712,10 @@ public class DashboardController extends BaseController { @@ -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 @PreAuthorize("hasAuthority('TENANT_ADMIN')") 719 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
578 @RequestMapping(value = "/tenant/dashboard/home/info", method = RequestMethod.GET) 720 @RequestMapping(value = "/tenant/dashboard/home/info", method = RequestMethod.GET)
579 @ResponseBody 721 @ResponseBody
@@ -596,10 +738,16 @@ public class DashboardController extends BaseController { @@ -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 @PreAuthorize("hasAuthority('TENANT_ADMIN')") 745 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
600 @RequestMapping(value = "/tenant/dashboard/home/info", method = RequestMethod.POST) 746 @RequestMapping(value = "/tenant/dashboard/home/info", method = RequestMethod.POST)
601 @ResponseStatus(value = HttpStatus.OK) 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 try { 751 try {
604 if (homeDashboardInfo.getDashboardId() != null) { 752 if (homeDashboardInfo.getDashboardId() != null) {
605 checkDashboardId(homeDashboardInfo.getDashboardId(), Operation.READ); 753 checkDashboardId(homeDashboardInfo.getDashboardId(), Operation.READ);
@@ -635,7 +783,8 @@ public class DashboardController extends BaseController { @@ -635,7 +783,8 @@ public class DashboardController extends BaseController {
635 } 783 }
636 return new HomeDashboardInfo(dashboardId, hideDashboardToolbar); 784 return new HomeDashboardInfo(dashboardId, hideDashboardToolbar);
637 } 785 }
638 - } catch (Exception e) {} 786 + } catch (Exception e) {
  787 + }
639 return null; 788 return null;
640 } 789 }
641 790
@@ -651,7 +800,8 @@ public class DashboardController extends BaseController { @@ -651,7 +800,8 @@ public class DashboardController extends BaseController {
651 } 800 }
652 return new HomeDashboard(dashboard, hideDashboardToolbar); 801 return new HomeDashboard(dashboard, hideDashboardToolbar);
653 } 802 }
654 - } catch (Exception e) {} 803 + } catch (Exception e) {
  804 + }
655 return null; 805 return null;
656 } 806 }
657 807
@@ -19,6 +19,8 @@ import com.google.common.util.concurrent.FutureCallback; @@ -19,6 +19,8 @@ import com.google.common.util.concurrent.FutureCallback;
19 import com.google.common.util.concurrent.Futures; 19 import com.google.common.util.concurrent.Futures;
20 import com.google.common.util.concurrent.ListenableFuture; 20 import com.google.common.util.concurrent.ListenableFuture;
21 import com.google.common.util.concurrent.MoreExecutors; 21 import com.google.common.util.concurrent.MoreExecutors;
  22 +import io.swagger.annotations.ApiOperation;
  23 +import io.swagger.annotations.ApiParam;
22 import lombok.RequiredArgsConstructor; 24 import lombok.RequiredArgsConstructor;
23 import lombok.extern.slf4j.Slf4j; 25 import lombok.extern.slf4j.Slf4j;
24 import org.springframework.http.HttpStatus; 26 import org.springframework.http.HttpStatus;
@@ -91,16 +93,22 @@ import static org.thingsboard.server.controller.EdgeController.EDGE_ID; @@ -91,16 +93,22 @@ import static org.thingsboard.server.controller.EdgeController.EDGE_ID;
91 @RequiredArgsConstructor 93 @RequiredArgsConstructor
92 @Slf4j 94 @Slf4j
93 public class DeviceController extends BaseController { 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 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") 107 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
101 @RequestMapping(value = "/device/{deviceId}", method = RequestMethod.GET) 108 @RequestMapping(value = "/device/{deviceId}", method = RequestMethod.GET)
102 @ResponseBody 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 checkParameter(DEVICE_ID, strDeviceId); 112 checkParameter(DEVICE_ID, strDeviceId);
105 try { 113 try {
106 DeviceId deviceId = new DeviceId(toUUID(strDeviceId)); 114 DeviceId deviceId = new DeviceId(toUUID(strDeviceId));
@@ -110,10 +118,15 @@ public class DeviceController extends BaseController { @@ -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 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") 125 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
114 @RequestMapping(value = "/device/info/{deviceId}", method = RequestMethod.GET) 126 @RequestMapping(value = "/device/info/{deviceId}", method = RequestMethod.GET)
115 @ResponseBody 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 checkParameter(DEVICE_ID, strDeviceId); 130 checkParameter(DEVICE_ID, strDeviceId);
118 try { 131 try {
119 DeviceId deviceId = new DeviceId(toUUID(strDeviceId)); 132 DeviceId deviceId = new DeviceId(toUUID(strDeviceId));
@@ -123,11 +136,18 @@ public class DeviceController extends BaseController { @@ -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 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") 145 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
127 @RequestMapping(value = "/device", method = RequestMethod.POST) 146 @RequestMapping(value = "/device", method = RequestMethod.POST)
128 @ResponseBody 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 boolean created = device.getId() == null; 151 boolean created = device.getId() == null;
132 try { 152 try {
133 device.setTenantId(getCurrentUser().getTenantId()); 153 device.setTenantId(getCurrentUser().getTenantId());
@@ -164,10 +184,13 @@ public class DeviceController extends BaseController { @@ -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 @PreAuthorize("hasAuthority('TENANT_ADMIN')") 189 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
168 @RequestMapping(value = "/device/{deviceId}", method = RequestMethod.DELETE) 190 @RequestMapping(value = "/device/{deviceId}", method = RequestMethod.DELETE)
169 @ResponseStatus(value = HttpStatus.OK) 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 checkParameter(DEVICE_ID, strDeviceId); 194 checkParameter(DEVICE_ID, strDeviceId);
172 try { 195 try {
173 DeviceId deviceId = new DeviceId(toUUID(strDeviceId)); 196 DeviceId deviceId = new DeviceId(toUUID(strDeviceId));
@@ -193,10 +216,14 @@ public class DeviceController extends BaseController { @@ -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 @PreAuthorize("hasAuthority('TENANT_ADMIN')") 221 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
197 @RequestMapping(value = "/customer/{customerId}/device/{deviceId}", method = RequestMethod.POST) 222 @RequestMapping(value = "/customer/{customerId}/device/{deviceId}", method = RequestMethod.POST)
198 @ResponseBody 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 @PathVariable(DEVICE_ID) String strDeviceId) throws ThingsboardException { 227 @PathVariable(DEVICE_ID) String strDeviceId) throws ThingsboardException {
201 checkParameter("customerId", strCustomerId); 228 checkParameter("customerId", strCustomerId);
202 checkParameter(DEVICE_ID, strDeviceId); 229 checkParameter(DEVICE_ID, strDeviceId);
@@ -225,10 +252,13 @@ public class DeviceController extends BaseController { @@ -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 @PreAuthorize("hasAuthority('TENANT_ADMIN')") 257 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
229 @RequestMapping(value = "/customer/device/{deviceId}", method = RequestMethod.DELETE) 258 @RequestMapping(value = "/customer/device/{deviceId}", method = RequestMethod.DELETE)
230 @ResponseBody 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 checkParameter(DEVICE_ID, strDeviceId); 262 checkParameter(DEVICE_ID, strDeviceId);
233 try { 263 try {
234 DeviceId deviceId = new DeviceId(toUUID(strDeviceId)); 264 DeviceId deviceId = new DeviceId(toUUID(strDeviceId));
@@ -256,10 +286,15 @@ public class DeviceController extends BaseController { @@ -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 @PreAuthorize("hasAuthority('TENANT_ADMIN')") 293 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
260 @RequestMapping(value = "/customer/public/device/{deviceId}", method = RequestMethod.POST) 294 @RequestMapping(value = "/customer/public/device/{deviceId}", method = RequestMethod.POST)
261 @ResponseBody 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 checkParameter(DEVICE_ID, strDeviceId); 298 checkParameter(DEVICE_ID, strDeviceId);
264 try { 299 try {
265 DeviceId deviceId = new DeviceId(toUUID(strDeviceId)); 300 DeviceId deviceId = new DeviceId(toUUID(strDeviceId));
@@ -280,10 +315,13 @@ public class DeviceController extends BaseController { @@ -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 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") 320 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
284 @RequestMapping(value = "/device/{deviceId}/credentials", method = RequestMethod.GET) 321 @RequestMapping(value = "/device/{deviceId}/credentials", method = RequestMethod.GET)
285 @ResponseBody 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 checkParameter(DEVICE_ID, strDeviceId); 325 checkParameter(DEVICE_ID, strDeviceId);
288 try { 326 try {
289 DeviceId deviceId = new DeviceId(toUUID(strDeviceId)); 327 DeviceId deviceId = new DeviceId(toUUID(strDeviceId));
@@ -301,10 +339,16 @@ public class DeviceController extends BaseController { @@ -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 @PreAuthorize("hasAuthority('TENANT_ADMIN')") 346 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
305 @RequestMapping(value = "/device/credentials", method = RequestMethod.POST) 347 @RequestMapping(value = "/device/credentials", method = RequestMethod.POST)
306 @ResponseBody 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 checkNotNull(deviceCredentials); 352 checkNotNull(deviceCredentials);
309 try { 353 try {
310 Device device = checkDeviceId(deviceCredentials.getDeviceId(), Operation.WRITE_CREDENTIALS); 354 Device device = checkDeviceId(deviceCredentials.getDeviceId(), Operation.WRITE_CREDENTIALS);
@@ -325,15 +369,24 @@ public class DeviceController extends BaseController { @@ -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 @PreAuthorize("hasAuthority('TENANT_ADMIN')") 375 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
329 @RequestMapping(value = "/tenant/devices", params = {"pageSize", "page"}, method = RequestMethod.GET) 376 @RequestMapping(value = "/tenant/devices", params = {"pageSize", "page"}, method = RequestMethod.GET)
330 @ResponseBody 377 @ResponseBody
331 public PageData<Device> getTenantDevices( 378 public PageData<Device> getTenantDevices(
  379 + @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true)
332 @RequestParam int pageSize, 380 @RequestParam int pageSize,
  381 + @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true)
333 @RequestParam int page, 382 @RequestParam int page,
  383 + @ApiParam(value = DEVICE_TYPE_DESCRIPTION)
334 @RequestParam(required = false) String type, 384 @RequestParam(required = false) String type,
  385 + @ApiParam(value = DEVICE_TEXT_SEARCH_DESCRIPTION)
335 @RequestParam(required = false) String textSearch, 386 @RequestParam(required = false) String textSearch,
  387 + @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = DEVICE_SORT_PROPERTY_ALLOWABLE_VALUES)
336 @RequestParam(required = false) String sortProperty, 388 @RequestParam(required = false) String sortProperty,
  389 + @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES)
337 @RequestParam(required = false) String sortOrder) throws ThingsboardException { 390 @RequestParam(required = false) String sortOrder) throws ThingsboardException {
338 try { 391 try {
339 TenantId tenantId = getCurrentUser().getTenantId(); 392 TenantId tenantId = getCurrentUser().getTenantId();
@@ -348,17 +401,28 @@ public class DeviceController extends BaseController { @@ -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 @PreAuthorize("hasAuthority('TENANT_ADMIN')") 407 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
352 @RequestMapping(value = "/tenant/deviceInfos", params = {"pageSize", "page"}, method = RequestMethod.GET) 408 @RequestMapping(value = "/tenant/deviceInfos", params = {"pageSize", "page"}, method = RequestMethod.GET)
353 @ResponseBody 409 @ResponseBody
354 public PageData<DeviceInfo> getTenantDeviceInfos( 410 public PageData<DeviceInfo> getTenantDeviceInfos(
  411 + @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true)
355 @RequestParam int pageSize, 412 @RequestParam int pageSize,
  413 + @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true)
356 @RequestParam int page, 414 @RequestParam int page,
  415 + @ApiParam(value = DEVICE_TYPE_DESCRIPTION)
357 @RequestParam(required = false) String type, 416 @RequestParam(required = false) String type,
  417 + @ApiParam(value = DEVICE_PROFILE_ID_DESCRIPTION)
358 @RequestParam(required = false) String deviceProfileId, 418 @RequestParam(required = false) String deviceProfileId,
  419 + @ApiParam(value = DEVICE_TEXT_SEARCH_DESCRIPTION)
359 @RequestParam(required = false) String textSearch, 420 @RequestParam(required = false) String textSearch,
  421 + @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = DEVICE_SORT_PROPERTY_ALLOWABLE_VALUES)
360 @RequestParam(required = false) String sortProperty, 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 try { 426 try {
363 TenantId tenantId = getCurrentUser().getTenantId(); 427 TenantId tenantId = getCurrentUser().getTenantId();
364 PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); 428 PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder);
@@ -375,10 +439,14 @@ public class DeviceController extends BaseController { @@ -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 @PreAuthorize("hasAuthority('TENANT_ADMIN')") 445 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
379 @RequestMapping(value = "/tenant/devices", params = {"deviceName"}, method = RequestMethod.GET) 446 @RequestMapping(value = "/tenant/devices", params = {"deviceName"}, method = RequestMethod.GET)
380 @ResponseBody 447 @ResponseBody
381 public Device getTenantDevice( 448 public Device getTenantDevice(
  449 + @ApiParam(value = DEVICE_NAME_DESCRIPTION)
382 @RequestParam String deviceName) throws ThingsboardException { 450 @RequestParam String deviceName) throws ThingsboardException {
383 try { 451 try {
384 TenantId tenantId = getCurrentUser().getTenantId(); 452 TenantId tenantId = getCurrentUser().getTenantId();
@@ -388,16 +456,26 @@ public class DeviceController extends BaseController { @@ -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 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") 462 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
392 @RequestMapping(value = "/customer/{customerId}/devices", params = {"pageSize", "page"}, method = RequestMethod.GET) 463 @RequestMapping(value = "/customer/{customerId}/devices", params = {"pageSize", "page"}, method = RequestMethod.GET)
393 @ResponseBody 464 @ResponseBody
394 public PageData<Device> getCustomerDevices( 465 public PageData<Device> getCustomerDevices(
  466 + @ApiParam(value = CUSTOMER_ID_PARAM_DESCRIPTION, required = true)
395 @PathVariable("customerId") String strCustomerId, 467 @PathVariable("customerId") String strCustomerId,
  468 + @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true)
396 @RequestParam int pageSize, 469 @RequestParam int pageSize,
  470 + @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true)
397 @RequestParam int page, 471 @RequestParam int page,
  472 + @ApiParam(value = DEVICE_TYPE_DESCRIPTION)
398 @RequestParam(required = false) String type, 473 @RequestParam(required = false) String type,
  474 + @ApiParam(value = DEVICE_TEXT_SEARCH_DESCRIPTION)
399 @RequestParam(required = false) String textSearch, 475 @RequestParam(required = false) String textSearch,
  476 + @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = DEVICE_SORT_PROPERTY_ALLOWABLE_VALUES)
400 @RequestParam(required = false) String sortProperty, 477 @RequestParam(required = false) String sortProperty,
  478 + @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES)
401 @RequestParam(required = false) String sortOrder) throws ThingsboardException { 479 @RequestParam(required = false) String sortOrder) throws ThingsboardException {
402 checkParameter("customerId", strCustomerId); 480 checkParameter("customerId", strCustomerId);
403 try { 481 try {
@@ -415,17 +493,28 @@ public class DeviceController extends BaseController { @@ -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 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") 499 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
419 @RequestMapping(value = "/customer/{customerId}/deviceInfos", params = {"pageSize", "page"}, method = RequestMethod.GET) 500 @RequestMapping(value = "/customer/{customerId}/deviceInfos", params = {"pageSize", "page"}, method = RequestMethod.GET)
420 @ResponseBody 501 @ResponseBody
421 public PageData<DeviceInfo> getCustomerDeviceInfos( 502 public PageData<DeviceInfo> getCustomerDeviceInfos(
  503 + @ApiParam(value = CUSTOMER_ID_PARAM_DESCRIPTION, required = true)
422 @PathVariable("customerId") String strCustomerId, 504 @PathVariable("customerId") String strCustomerId,
  505 + @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true)
423 @RequestParam int pageSize, 506 @RequestParam int pageSize,
  507 + @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true)
424 @RequestParam int page, 508 @RequestParam int page,
  509 + @ApiParam(value = DEVICE_TYPE_DESCRIPTION)
425 @RequestParam(required = false) String type, 510 @RequestParam(required = false) String type,
  511 + @ApiParam(value = DEVICE_PROFILE_ID_DESCRIPTION)
426 @RequestParam(required = false) String deviceProfileId, 512 @RequestParam(required = false) String deviceProfileId,
  513 + @ApiParam(value = DEVICE_TEXT_SEARCH_DESCRIPTION)
427 @RequestParam(required = false) String textSearch, 514 @RequestParam(required = false) String textSearch,
  515 + @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = DEVICE_SORT_PROPERTY_ALLOWABLE_VALUES)
428 @RequestParam(required = false) String sortProperty, 516 @RequestParam(required = false) String sortProperty,
  517 + @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES)
429 @RequestParam(required = false) String sortOrder) throws ThingsboardException { 518 @RequestParam(required = false) String sortOrder) throws ThingsboardException {
430 checkParameter("customerId", strCustomerId); 519 checkParameter("customerId", strCustomerId);
431 try { 520 try {
@@ -446,10 +535,13 @@ public class DeviceController extends BaseController { @@ -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 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") 540 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
450 @RequestMapping(value = "/devices", params = {"deviceIds"}, method = RequestMethod.GET) 541 @RequestMapping(value = "/devices", params = {"deviceIds"}, method = RequestMethod.GET)
451 @ResponseBody 542 @ResponseBody
452 public List<Device> getDevicesByIds( 543 public List<Device> getDevicesByIds(
  544 + @ApiParam(value = "A list of devices ids, separated by comma ','")
453 @RequestParam("deviceIds") String[] strDeviceIds) throws ThingsboardException { 545 @RequestParam("deviceIds") String[] strDeviceIds) throws ThingsboardException {
454 checkArrayParameter("deviceIds", strDeviceIds); 546 checkArrayParameter("deviceIds", strDeviceIds);
455 try { 547 try {
@@ -472,6 +564,10 @@ public class DeviceController extends BaseController { @@ -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 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") 571 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
476 @RequestMapping(value = "/devices", method = RequestMethod.POST) 572 @RequestMapping(value = "/devices", method = RequestMethod.POST)
477 @ResponseBody 573 @ResponseBody
@@ -496,6 +592,8 @@ public class DeviceController extends BaseController { @@ -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 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") 597 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
500 @RequestMapping(value = "/device/types", method = RequestMethod.GET) 598 @RequestMapping(value = "/device/types", method = RequestMethod.GET)
501 @ResponseBody 599 @ResponseBody
@@ -510,10 +608,19 @@ public class DeviceController extends BaseController { @@ -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 @PreAuthorize("hasAuthority('CUSTOMER_USER')") 618 @PreAuthorize("hasAuthority('CUSTOMER_USER')")
514 @RequestMapping(value = "/customer/device/{deviceName}/claim", method = RequestMethod.POST) 619 @RequestMapping(value = "/customer/device/{deviceName}/claim", method = RequestMethod.POST)
515 @ResponseBody 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 @RequestBody(required = false) ClaimRequest claimRequest) throws ThingsboardException { 624 @RequestBody(required = false) ClaimRequest claimRequest) throws ThingsboardException {
518 checkParameter(DEVICE_NAME, deviceName); 625 checkParameter(DEVICE_NAME, deviceName);
519 try { 626 try {
@@ -564,10 +671,13 @@ public class DeviceController extends BaseController { @@ -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 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") 676 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
568 @RequestMapping(value = "/customer/device/{deviceName}/claim", method = RequestMethod.DELETE) 677 @RequestMapping(value = "/customer/device/{deviceName}/claim", method = RequestMethod.DELETE)
569 @ResponseStatus(value = HttpStatus.OK) 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 checkParameter(DEVICE_NAME, deviceName); 681 checkParameter(DEVICE_NAME, deviceName);
572 try { 682 try {
573 final DeferredResult<ResponseEntity> deferredResult = new DeferredResult<>(); 683 final DeferredResult<ResponseEntity> deferredResult = new DeferredResult<>();
@@ -615,10 +725,14 @@ public class DeviceController extends BaseController { @@ -615,10 +725,14 @@ public class DeviceController extends BaseController {
615 return DataConstants.DEFAULT_SECRET_KEY; 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 @PreAuthorize("hasAuthority('TENANT_ADMIN')") 730 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
619 @RequestMapping(value = "/tenant/{tenantId}/device/{deviceId}", method = RequestMethod.POST) 731 @RequestMapping(value = "/tenant/{tenantId}/device/{deviceId}", method = RequestMethod.POST)
620 @ResponseBody 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 @PathVariable(DEVICE_ID) String strDeviceId) throws ThingsboardException { 736 @PathVariable(DEVICE_ID) String strDeviceId) throws ThingsboardException {
623 checkParameter(TENANT_ID, strTenantId); 737 checkParameter(TENANT_ID, strTenantId);
624 checkParameter(DEVICE_ID, strDeviceId); 738 checkParameter(DEVICE_ID, strDeviceId);
@@ -665,10 +779,16 @@ public class DeviceController extends BaseController { @@ -665,10 +779,16 @@ public class DeviceController extends BaseController {
665 return metaData; 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 @PreAuthorize("hasAuthority('TENANT_ADMIN')") 786 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
669 @RequestMapping(value = "/edge/{edgeId}/device/{deviceId}", method = RequestMethod.POST) 787 @RequestMapping(value = "/edge/{edgeId}/device/{deviceId}", method = RequestMethod.POST)
670 @ResponseBody 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 @PathVariable(DEVICE_ID) String strDeviceId) throws ThingsboardException { 792 @PathVariable(DEVICE_ID) String strDeviceId) throws ThingsboardException {
673 checkParameter(EDGE_ID, strEdgeId); 793 checkParameter(EDGE_ID, strEdgeId);
674 checkParameter(DEVICE_ID, strDeviceId); 794 checkParameter(DEVICE_ID, strDeviceId);
@@ -699,10 +819,14 @@ public class DeviceController extends BaseController { @@ -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 @PreAuthorize("hasAuthority('TENANT_ADMIN')") 824 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
703 @RequestMapping(value = "/edge/{edgeId}/device/{deviceId}", method = RequestMethod.DELETE) 825 @RequestMapping(value = "/edge/{edgeId}/device/{deviceId}", method = RequestMethod.DELETE)
704 @ResponseBody 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 @PathVariable(DEVICE_ID) String strDeviceId) throws ThingsboardException { 830 @PathVariable(DEVICE_ID) String strDeviceId) throws ThingsboardException {
707 checkParameter(EDGE_ID, strEdgeId); 831 checkParameter(EDGE_ID, strEdgeId);
708 checkParameter(DEVICE_ID, strDeviceId); 832 checkParameter(DEVICE_ID, strDeviceId);
@@ -733,18 +857,30 @@ public class DeviceController extends BaseController { @@ -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 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") 863 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
737 @RequestMapping(value = "/edge/{edgeId}/devices", params = {"pageSize", "page"}, method = RequestMethod.GET) 864 @RequestMapping(value = "/edge/{edgeId}/devices", params = {"pageSize", "page"}, method = RequestMethod.GET)
738 @ResponseBody 865 @ResponseBody
739 public PageData<Device> getEdgeDevices( 866 public PageData<Device> getEdgeDevices(
  867 + @ApiParam(value = EDGE_ID_PARAM_DESCRIPTION, required = true)
740 @PathVariable(EDGE_ID) String strEdgeId, 868 @PathVariable(EDGE_ID) String strEdgeId,
  869 + @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true)
741 @RequestParam int pageSize, 870 @RequestParam int pageSize,
  871 + @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true)
742 @RequestParam int page, 872 @RequestParam int page,
  873 + @ApiParam(value = DEVICE_TYPE_DESCRIPTION)
743 @RequestParam(required = false) String type, 874 @RequestParam(required = false) String type,
  875 + @ApiParam(value = DEVICE_TEXT_SEARCH_DESCRIPTION)
744 @RequestParam(required = false) String textSearch, 876 @RequestParam(required = false) String textSearch,
  877 + @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = DEVICE_SORT_PROPERTY_ALLOWABLE_VALUES)
745 @RequestParam(required = false) String sortProperty, 878 @RequestParam(required = false) String sortProperty,
  879 + @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES)
746 @RequestParam(required = false) String sortOrder, 880 @RequestParam(required = false) String sortOrder,
  881 + @ApiParam(value = "Timestamp. Devices with creation time before it won't be queried")
747 @RequestParam(required = false) Long startTime, 882 @RequestParam(required = false) Long startTime,
  883 + @ApiParam(value = "Timestamp. Devices with creation time after it won't be queried")
748 @RequestParam(required = false) Long endTime) throws ThingsboardException { 884 @RequestParam(required = false) Long endTime) throws ThingsboardException {
749 checkParameter(EDGE_ID, strEdgeId); 885 checkParameter(EDGE_ID, strEdgeId);
750 try { 886 try {
@@ -776,10 +912,17 @@ public class DeviceController extends BaseController { @@ -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 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") 920 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
780 @RequestMapping(value = "/devices/count/{otaPackageType}/{deviceProfileId}", method = RequestMethod.GET) 921 @RequestMapping(value = "/devices/count/{otaPackageType}/{deviceProfileId}", method = RequestMethod.GET)
781 @ResponseBody 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 @PathVariable("deviceProfileId") String deviceProfileId) throws ThingsboardException { 926 @PathVariable("deviceProfileId") String deviceProfileId) throws ThingsboardException {
784 checkParameter("OtaPackageType", otaPackageType); 927 checkParameter("OtaPackageType", otaPackageType);
785 checkParameter("DeviceProfileId", deviceProfileId); 928 checkParameter("DeviceProfileId", deviceProfileId);
@@ -793,6 +936,8 @@ public class DeviceController extends BaseController { @@ -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 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") 941 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')")
797 @PostMapping("/device/bulk_import") 942 @PostMapping("/device/bulk_import")
798 public BulkImportResult<Device> processDevicesBulkImport(@RequestBody BulkImportRequest request) throws Exception { 943 public BulkImportResult<Device> processDevicesBulkImport(@RequestBody BulkImportRequest request) throws Exception {
@@ -38,7 +38,6 @@ import org.thingsboard.server.common.data.EntitySubtype; @@ -38,7 +38,6 @@ import org.thingsboard.server.common.data.EntitySubtype;
38 import org.thingsboard.server.common.data.EntityType; 38 import org.thingsboard.server.common.data.EntityType;
39 import org.thingsboard.server.common.data.EntityView; 39 import org.thingsboard.server.common.data.EntityView;
40 import org.thingsboard.server.common.data.EntityViewInfo; 40 import org.thingsboard.server.common.data.EntityViewInfo;
41 -import org.thingsboard.server.common.data.asset.Asset;  
42 import org.thingsboard.server.common.data.audit.ActionType; 41 import org.thingsboard.server.common.data.audit.ActionType;
43 import org.thingsboard.server.common.data.edge.Edge; 42 import org.thingsboard.server.common.data.edge.Edge;
44 import org.thingsboard.server.common.data.edge.EdgeEventActionType; 43 import org.thingsboard.server.common.data.edge.EdgeEventActionType;
@@ -49,7 +48,6 @@ import org.thingsboard.server.common.data.id.EdgeId; @@ -49,7 +48,6 @@ import org.thingsboard.server.common.data.id.EdgeId;
49 import org.thingsboard.server.common.data.id.EntityId; 48 import org.thingsboard.server.common.data.id.EntityId;
50 import org.thingsboard.server.common.data.id.EntityViewId; 49 import org.thingsboard.server.common.data.id.EntityViewId;
51 import org.thingsboard.server.common.data.id.TenantId; 50 import org.thingsboard.server.common.data.id.TenantId;
52 -import org.thingsboard.server.common.data.id.UUIDBased;  
53 import org.thingsboard.server.common.data.kv.AttributeKvEntry; 51 import org.thingsboard.server.common.data.kv.AttributeKvEntry;
54 import org.thingsboard.server.common.data.kv.BaseReadTsKvQuery; 52 import org.thingsboard.server.common.data.kv.BaseReadTsKvQuery;
55 import org.thingsboard.server.common.data.kv.ReadTsKvQuery; 53 import org.thingsboard.server.common.data.kv.ReadTsKvQuery;
@@ -74,7 +72,6 @@ import java.util.concurrent.ExecutionException; @@ -74,7 +72,6 @@ import java.util.concurrent.ExecutionException;
74 import java.util.stream.Collectors; 72 import java.util.stream.Collectors;
75 73
76 import static org.apache.commons.lang3.StringUtils.isBlank; 74 import static org.apache.commons.lang3.StringUtils.isBlank;
77 -import static org.thingsboard.server.controller.CustomerController.CUSTOMER_ID;  
78 import static org.thingsboard.server.controller.EdgeController.EDGE_ID; 75 import static org.thingsboard.server.controller.EdgeController.EDGE_ID;
79 76
80 /** 77 /**
@@ -57,7 +57,7 @@ public class TenantController extends BaseController { @@ -57,7 +57,7 @@ public class TenantController extends BaseController {
57 @RequestMapping(value = "/tenant/{tenantId}", method = RequestMethod.GET) 57 @RequestMapping(value = "/tenant/{tenantId}", method = RequestMethod.GET)
58 @ResponseBody 58 @ResponseBody
59 public Tenant getTenantById(@PathVariable("tenantId") String strTenantId) throws ThingsboardException { 59 public Tenant getTenantById(@PathVariable("tenantId") String strTenantId) throws ThingsboardException {
60 - checkParameter("tenantId", strTenantId); 60 + checkParameter(TENANT_ID, strTenantId);
61 try { 61 try {
62 TenantId tenantId = new TenantId(toUUID(strTenantId)); 62 TenantId tenantId = new TenantId(toUUID(strTenantId));
63 Tenant tenant = checkTenantId(tenantId, Operation.READ); 63 Tenant tenant = checkTenantId(tenantId, Operation.READ);
@@ -74,7 +74,7 @@ public class TenantController extends BaseController { @@ -74,7 +74,7 @@ public class TenantController extends BaseController {
74 @RequestMapping(value = "/tenant/info/{tenantId}", method = RequestMethod.GET) 74 @RequestMapping(value = "/tenant/info/{tenantId}", method = RequestMethod.GET)
75 @ResponseBody 75 @ResponseBody
76 public TenantInfo getTenantInfoById(@PathVariable("tenantId") String strTenantId) throws ThingsboardException { 76 public TenantInfo getTenantInfoById(@PathVariable("tenantId") String strTenantId) throws ThingsboardException {
77 - checkParameter("tenantId", strTenantId); 77 + checkParameter(TENANT_ID, strTenantId);
78 try { 78 try {
79 TenantId tenantId = new TenantId(toUUID(strTenantId)); 79 TenantId tenantId = new TenantId(toUUID(strTenantId));
80 return checkTenantInfoId(tenantId, Operation.READ); 80 return checkTenantInfoId(tenantId, Operation.READ);
  1 +/**
  2 + * Copyright © 2016-2021 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.service.security.model;
  17 +
  18 +import io.swagger.annotations.ApiModel;
  19 +import io.swagger.annotations.ApiModelProperty;
  20 +import lombok.Data;
  21 +
  22 +@ApiModel
  23 +@Data
  24 +public class ActivateUserRequest {
  25 +
  26 + @ApiModelProperty(position = 1, value = "The activate token to verify", example = "AAB254FF67D..")
  27 + private String activateToken;
  28 + @ApiModelProperty(position = 2, value = "The new password to set", example = "secret")
  29 + private String password;
  30 +}
  1 +/**
  2 + * Copyright © 2016-2021 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.service.security.model;
  17 +
  18 +import io.swagger.annotations.ApiModel;
  19 +import io.swagger.annotations.ApiModelProperty;
  20 +import lombok.Data;
  21 +
  22 +@ApiModel
  23 +@Data
  24 +public class ChangePasswordRequest {
  25 +
  26 + @ApiModelProperty(position = 1, value = "The old password", example = "OldPassword")
  27 + private String currentPassword;
  28 + @ApiModelProperty(position = 1, value = "The new password", example = "NewPassword")
  29 + private String newPassword;
  30 +
  31 +}
  1 +/**
  2 + * Copyright © 2016-2021 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.service.security.model;
  17 +
  18 +import io.swagger.annotations.ApiModel;
  19 +import io.swagger.annotations.ApiModelProperty;
  20 +import lombok.AllArgsConstructor;
  21 +import lombok.Data;
  22 +
  23 +@ApiModel(value = "JWT Token Pair")
  24 +@Data
  25 +@AllArgsConstructor
  26 +public class JwtTokenPair {
  27 +
  28 + @ApiModelProperty(position = 1, value = "The JWT Access Token. Used to perform API calls.", example = "AAB254FF67D..")
  29 + private String token;
  30 + @ApiModelProperty(position = 1, value = "The JWT Refresh Token. Used to get new JWT Access Token if old one has expired.", example = "AAB254FF67D..")
  31 + private String refreshToken;
  32 +}
  1 +/**
  2 + * Copyright © 2016-2021 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.service.security.model;
  17 +
  18 +import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
  19 +import io.swagger.annotations.ApiModel;
  20 +import io.swagger.annotations.ApiModelProperty;
  21 +import lombok.Data;
  22 +
  23 +@ApiModel
  24 +@Data
  25 +public class ResetPasswordEmailRequest {
  26 +
  27 + @ApiModelProperty(position = 1, value = "The email of the user", example = "user@example.com")
  28 + private String email;
  29 +}
  1 +/**
  2 + * Copyright © 2016-2021 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.service.security.model;
  17 +
  18 +import io.swagger.annotations.ApiModel;
  19 +import io.swagger.annotations.ApiModelProperty;
  20 +import lombok.Data;
  21 +
  22 +@ApiModel
  23 +@Data
  24 +public class ResetPasswordRequest {
  25 +
  26 + @ApiModelProperty(position = 1, value = "The reset token to verify", example = "AAB254FF67D..")
  27 + private String resetToken;
  28 + @ApiModelProperty(position = 2, value = "The new password to set", example = "secret")
  29 + private String password;
  30 +}
@@ -96,6 +96,10 @@ @@ -96,6 +96,10 @@
96 <groupId>org.apache.commons</groupId> 96 <groupId>org.apache.commons</groupId>
97 <artifactId>commons-lang3</artifactId> 97 <artifactId>commons-lang3</artifactId>
98 </dependency> 98 </dependency>
  99 + <dependency>
  100 + <groupId>io.swagger</groupId>
  101 + <artifactId>swagger-annotations</artifactId>
  102 + </dependency>
99 </dependencies> 103 </dependencies>
100 104
101 <build> 105 <build>
@@ -15,11 +15,15 @@ @@ -15,11 +15,15 @@
15 */ 15 */
16 package org.thingsboard.server.common.data; 16 package org.thingsboard.server.common.data;
17 17
  18 +import io.swagger.annotations.ApiModel;
  19 +import io.swagger.annotations.ApiModelProperty;
18 import org.thingsboard.server.common.data.id.AdminSettingsId; 20 import org.thingsboard.server.common.data.id.AdminSettingsId;
19 21
20 import com.fasterxml.jackson.databind.JsonNode; 22 import com.fasterxml.jackson.databind.JsonNode;
  23 +import org.thingsboard.server.common.data.id.DeviceId;
21 import org.thingsboard.server.common.data.validation.NoXss; 24 import org.thingsboard.server.common.data.validation.NoXss;
22 25
  26 +@ApiModel
23 public class AdminSettings extends BaseData<AdminSettingsId> { 27 public class AdminSettings extends BaseData<AdminSettingsId> {
24 28
25 private static final long serialVersionUID = -7670322981725511892L; 29 private static final long serialVersionUID = -7670322981725511892L;
@@ -42,6 +46,19 @@ public class AdminSettings extends BaseData<AdminSettingsId> { @@ -42,6 +46,19 @@ public class AdminSettings extends BaseData<AdminSettingsId> {
42 this.jsonValue = adminSettings.getJsonValue(); 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 public String getKey() { 62 public String getKey() {
46 return key; 63 return key;
47 } 64 }
@@ -50,6 +67,7 @@ public class AdminSettings extends BaseData<AdminSettingsId> { @@ -50,6 +67,7 @@ public class AdminSettings extends BaseData<AdminSettingsId> {
50 this.key = key; 67 this.key = key;
51 } 68 }
52 69
  70 + @ApiModelProperty(position = 4, value = "JSON representation of the Administration Settings value")
53 public JsonNode getJsonValue() { 71 public JsonNode getJsonValue() {
54 return jsonValue; 72 return jsonValue;
55 } 73 }
@@ -16,6 +16,7 @@ @@ -16,6 +16,7 @@
16 package org.thingsboard.server.common.data; 16 package org.thingsboard.server.common.data;
17 17
18 import com.fasterxml.jackson.databind.JsonNode; 18 import com.fasterxml.jackson.databind.JsonNode;
  19 +import io.swagger.annotations.ApiModelProperty;
19 import org.thingsboard.server.common.data.id.DashboardId; 20 import org.thingsboard.server.common.data.id.DashboardId;
20 21
21 public class Dashboard extends DashboardInfo { 22 public class Dashboard extends DashboardInfo {
@@ -41,6 +42,10 @@ public class Dashboard extends DashboardInfo { @@ -41,6 +42,10 @@ public class Dashboard extends DashboardInfo {
41 this.configuration = dashboard.getConfiguration(); 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 public JsonNode getConfiguration() { 49 public JsonNode getConfiguration() {
45 return configuration; 50 return configuration;
46 } 51 }
@@ -16,6 +16,8 @@ @@ -16,6 +16,8 @@
16 package org.thingsboard.server.common.data; 16 package org.thingsboard.server.common.data;
17 17
18 import com.fasterxml.jackson.annotation.JsonProperty; 18 import com.fasterxml.jackson.annotation.JsonProperty;
  19 +import io.swagger.annotations.ApiModel;
  20 +import io.swagger.annotations.ApiModelProperty;
19 import org.thingsboard.server.common.data.id.CustomerId; 21 import org.thingsboard.server.common.data.id.CustomerId;
20 import org.thingsboard.server.common.data.id.DashboardId; 22 import org.thingsboard.server.common.data.id.DashboardId;
21 import org.thingsboard.server.common.data.id.TenantId; 23 import org.thingsboard.server.common.data.id.TenantId;
@@ -25,6 +27,7 @@ import javax.validation.Valid; @@ -25,6 +27,7 @@ import javax.validation.Valid;
25 import java.util.HashSet; 27 import java.util.HashSet;
26 import java.util.Set; 28 import java.util.Set;
27 29
  30 +@ApiModel
28 public class DashboardInfo extends SearchTextBased<DashboardId> implements HasName, HasTenantId { 31 public class DashboardInfo extends SearchTextBased<DashboardId> implements HasName, HasTenantId {
29 32
30 private TenantId tenantId; 33 private TenantId tenantId;
@@ -54,6 +57,22 @@ public class DashboardInfo extends SearchTextBased<DashboardId> implements HasNa @@ -54,6 +57,22 @@ public class DashboardInfo extends SearchTextBased<DashboardId> implements HasNa
54 this.mobileOrder = dashboardInfo.getMobileOrder(); 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 public TenantId getTenantId() { 76 public TenantId getTenantId() {
58 return tenantId; 77 return tenantId;
59 } 78 }
@@ -62,6 +81,7 @@ public class DashboardInfo extends SearchTextBased<DashboardId> implements HasNa @@ -62,6 +81,7 @@ public class DashboardInfo extends SearchTextBased<DashboardId> implements HasNa
62 this.tenantId = tenantId; 81 this.tenantId = tenantId;
63 } 82 }
64 83
  84 + @ApiModelProperty(position = 4, value = "Title of the dashboard.")
65 public String getTitle() { 85 public String getTitle() {
66 return title; 86 return title;
67 } 87 }
@@ -70,6 +90,7 @@ public class DashboardInfo extends SearchTextBased<DashboardId> implements HasNa @@ -70,6 +90,7 @@ public class DashboardInfo extends SearchTextBased<DashboardId> implements HasNa
70 this.title = title; 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 public String getImage() { 94 public String getImage() {
74 return image; 95 return image;
75 } 96 }
@@ -78,6 +99,7 @@ public class DashboardInfo extends SearchTextBased<DashboardId> implements HasNa @@ -78,6 +99,7 @@ public class DashboardInfo extends SearchTextBased<DashboardId> implements HasNa
78 this.image = image; 99 this.image = image;
79 } 100 }
80 101
  102 + @ApiModelProperty(position = 5, value = "List of assigned customers with their info.", readOnly = true)
81 public Set<ShortCustomerInfo> getAssignedCustomers() { 103 public Set<ShortCustomerInfo> getAssignedCustomers() {
82 return assignedCustomers; 104 return assignedCustomers;
83 } 105 }
@@ -86,6 +108,7 @@ public class DashboardInfo extends SearchTextBased<DashboardId> implements HasNa @@ -86,6 +108,7 @@ public class DashboardInfo extends SearchTextBased<DashboardId> implements HasNa
86 this.assignedCustomers = assignedCustomers; 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 public boolean isMobileHide() { 112 public boolean isMobileHide() {
90 return mobileHide; 113 return mobileHide;
91 } 114 }
@@ -94,6 +117,7 @@ public class DashboardInfo extends SearchTextBased<DashboardId> implements HasNa @@ -94,6 +117,7 @@ public class DashboardInfo extends SearchTextBased<DashboardId> implements HasNa
94 this.mobileHide = mobileHide; 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 public Integer getMobileOrder() { 121 public Integer getMobileOrder() {
98 return mobileOrder; 122 return mobileOrder;
99 } 123 }
@@ -152,6 +176,7 @@ public class DashboardInfo extends SearchTextBased<DashboardId> implements HasNa @@ -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 @Override 180 @Override
156 @JsonProperty(access = JsonProperty.Access.READ_ONLY) 181 @JsonProperty(access = JsonProperty.Access.READ_ONLY)
157 public String getName() { 182 public String getName() {
@@ -17,6 +17,9 @@ package org.thingsboard.server.common.data; @@ -17,6 +17,9 @@ package org.thingsboard.server.common.data;
17 17
18 import com.fasterxml.jackson.annotation.JsonIgnore; 18 import com.fasterxml.jackson.annotation.JsonIgnore;
19 import com.fasterxml.jackson.core.JsonProcessingException; 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 import lombok.EqualsAndHashCode; 23 import lombok.EqualsAndHashCode;
21 import lombok.extern.slf4j.Slf4j; 24 import lombok.extern.slf4j.Slf4j;
22 import org.thingsboard.server.common.data.device.data.DeviceData; 25 import org.thingsboard.server.common.data.device.data.DeviceData;
@@ -31,6 +34,7 @@ import java.io.ByteArrayInputStream; @@ -31,6 +34,7 @@ import java.io.ByteArrayInputStream;
31 import java.io.IOException; 34 import java.io.IOException;
32 import java.util.Optional; 35 import java.util.Optional;
33 36
  37 +@ApiModel
34 @EqualsAndHashCode(callSuper = true) 38 @EqualsAndHashCode(callSuper = true)
35 @Slf4j 39 @Slf4j
36 public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implements HasName, HasTenantId, HasCustomerId, HasOtaPackage { 40 public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implements HasName, HasTenantId, HasCustomerId, HasOtaPackage {
@@ -88,6 +92,22 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen @@ -88,6 +92,22 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen
88 return this; 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 public TenantId getTenantId() { 111 public TenantId getTenantId() {
92 return tenantId; 112 return tenantId;
93 } 113 }
@@ -96,6 +116,7 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen @@ -96,6 +116,7 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen
96 this.tenantId = tenantId; 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 public CustomerId getCustomerId() { 120 public CustomerId getCustomerId() {
100 return customerId; 121 return customerId;
101 } 122 }
@@ -104,6 +125,7 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen @@ -104,6 +125,7 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen
104 this.customerId = customerId; 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 @Override 129 @Override
108 public String getName() { 130 public String getName() {
109 return name; 131 return name;
@@ -113,6 +135,7 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen @@ -113,6 +135,7 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen
113 this.name = name; 135 this.name = name;
114 } 136 }
115 137
  138 + @ApiModelProperty(position = 6, required = true, value = "Device Profile Name", example = "Temperature Sensor")
116 public String getType() { 139 public String getType() {
117 return type; 140 return type;
118 } 141 }
@@ -121,6 +144,7 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen @@ -121,6 +144,7 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen
121 this.type = type; 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 public String getLabel() { 148 public String getLabel() {
125 return label; 149 return label;
126 } 150 }
@@ -129,6 +153,7 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen @@ -129,6 +153,7 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen
129 this.label = label; 153 this.label = label;
130 } 154 }
131 155
  156 + @ApiModelProperty(position = 8, required = true, value = "JSON object with Device Profile Id.")
132 public DeviceProfileId getDeviceProfileId() { 157 public DeviceProfileId getDeviceProfileId() {
133 return deviceProfileId; 158 return deviceProfileId;
134 } 159 }
@@ -137,6 +162,7 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen @@ -137,6 +162,7 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen
137 this.deviceProfileId = deviceProfileId; 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 public DeviceData getDeviceData() { 166 public DeviceData getDeviceData() {
141 if (deviceData != null) { 167 if (deviceData != null) {
142 return deviceData; 168 return deviceData;
@@ -169,6 +195,7 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen @@ -169,6 +195,7 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen
169 return getName(); 195 return getName();
170 } 196 }
171 197
  198 + @ApiModelProperty(position = 10, value = "JSON object with Ota Package Id.")
172 public OtaPackageId getFirmwareId() { 199 public OtaPackageId getFirmwareId() {
173 return firmwareId; 200 return firmwareId;
174 } 201 }
@@ -177,6 +204,7 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen @@ -177,6 +204,7 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen
177 this.firmwareId = firmwareId; 204 this.firmwareId = firmwareId;
178 } 205 }
179 206
  207 + @ApiModelProperty(position = 11, value = "JSON object with Ota Package Id.")
180 public OtaPackageId getSoftwareId() { 208 public OtaPackageId getSoftwareId() {
181 return softwareId; 209 return softwareId;
182 } 210 }
@@ -185,6 +213,12 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen @@ -185,6 +213,12 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen
185 this.softwareId = softwareId; 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 @Override 222 @Override
189 public String toString() { 223 public String toString() {
190 StringBuilder builder = new StringBuilder(); 224 StringBuilder builder = new StringBuilder();
@@ -15,14 +15,20 @@ @@ -15,14 +15,20 @@
15 */ 15 */
16 package org.thingsboard.server.common.data; 16 package org.thingsboard.server.common.data;
17 17
  18 +import io.swagger.annotations.ApiModel;
  19 +import io.swagger.annotations.ApiModelProperty;
18 import lombok.Data; 20 import lombok.Data;
19 import org.thingsboard.server.common.data.id.DeviceId; 21 import org.thingsboard.server.common.data.id.DeviceId;
20 22
  23 +@ApiModel
21 @Data 24 @Data
22 public class DeviceInfo extends Device { 25 public class DeviceInfo extends Device {
23 26
  27 + @ApiModelProperty(position = 13, value = "Title of the Customer that owns the device.", readOnly = true)
24 private String customerTitle; 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 private boolean customerIsPublic; 30 private boolean customerIsPublic;
  31 + @ApiModelProperty(position = 15, value = "Name of the corresponding Device Profile.", readOnly = true)
26 private String deviceProfileName; 32 private String deviceProfileName;
27 33
28 public DeviceInfo() { 34 public DeviceInfo() {
@@ -15,11 +15,17 @@ @@ -15,11 +15,17 @@
15 */ 15 */
16 package org.thingsboard.server.common.data; 16 package org.thingsboard.server.common.data;
17 17
  18 +import io.swagger.annotations.ApiModel;
  19 +import io.swagger.annotations.ApiModelProperty;
18 import lombok.Data; 20 import lombok.Data;
19 21
  22 +@ApiModel
20 @Data 23 @Data
21 public class HomeDashboard extends Dashboard { 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 private boolean hideDashboardToolbar; 29 private boolean hideDashboardToolbar;
24 30
25 public HomeDashboard(Dashboard dashboard, boolean hideDashboardToolbar) { 31 public HomeDashboard(Dashboard dashboard, boolean hideDashboardToolbar) {
@@ -15,13 +15,18 @@ @@ -15,13 +15,18 @@
15 */ 15 */
16 package org.thingsboard.server.common.data; 16 package org.thingsboard.server.common.data;
17 17
  18 +import io.swagger.annotations.ApiModel;
  19 +import io.swagger.annotations.ApiModelProperty;
18 import lombok.AllArgsConstructor; 20 import lombok.AllArgsConstructor;
19 import lombok.Data; 21 import lombok.Data;
20 import org.thingsboard.server.common.data.id.DashboardId; 22 import org.thingsboard.server.common.data.id.DashboardId;
21 23
  24 +@ApiModel
22 @Data 25 @Data
23 @AllArgsConstructor 26 @AllArgsConstructor
24 public class HomeDashboardInfo { 27 public class HomeDashboardInfo {
  28 + @ApiModelProperty(position = 1, value = "JSON object with the dashboard Id.")
25 private DashboardId dashboardId; 29 private DashboardId dashboardId;
  30 + @ApiModelProperty(position = 1, value = HomeDashboard.HIDE_DASHBOARD_TOOLBAR_DESCRIPTION)
26 private boolean hideDashboardToolbar; 31 private boolean hideDashboardToolbar;
27 } 32 }
@@ -15,6 +15,8 @@ @@ -15,6 +15,8 @@
15 */ 15 */
16 package org.thingsboard.server.common.data; 16 package org.thingsboard.server.common.data;
17 17
  18 +import io.swagger.annotations.ApiModel;
  19 +import io.swagger.annotations.ApiModelProperty;
18 import lombok.AllArgsConstructor; 20 import lombok.AllArgsConstructor;
19 import lombok.Getter; 21 import lombok.Getter;
20 import lombok.Setter; 22 import lombok.Setter;
@@ -25,16 +27,20 @@ import org.thingsboard.server.common.data.validation.NoXss; @@ -25,16 +27,20 @@ import org.thingsboard.server.common.data.validation.NoXss;
25 * Created by igor on 2/27/18. 27 * Created by igor on 2/27/18.
26 */ 28 */
27 29
  30 +@ApiModel
28 @AllArgsConstructor 31 @AllArgsConstructor
29 public class ShortCustomerInfo { 32 public class ShortCustomerInfo {
30 33
  34 + @ApiModelProperty(position = 1, value = "JSON object with the customer Id.")
31 @Getter @Setter 35 @Getter @Setter
32 private CustomerId customerId; 36 private CustomerId customerId;
33 37
  38 + @ApiModelProperty(position = 2, value = "Title of the customer.")
34 @Getter @Setter 39 @Getter @Setter
35 @NoXss 40 @NoXss
36 private String title; 41 private String title;
37 42
  43 + @ApiModelProperty(position = 3, value = "Indicates special 'Public' customer used to embed dashboards on public websites.")
38 @Getter @Setter 44 @Getter @Setter
39 private boolean isPublic; 45 private boolean isPublic;
40 46
@@ -15,12 +15,17 @@ @@ -15,12 +15,17 @@
15 */ 15 */
16 package org.thingsboard.server.common.data; 16 package org.thingsboard.server.common.data;
17 17
  18 +import io.swagger.annotations.ApiModel;
  19 +import io.swagger.annotations.ApiModelProperty;
18 import lombok.Data; 20 import lombok.Data;
19 21
  22 +@ApiModel
20 @Data 23 @Data
21 public class UpdateMessage { 24 public class UpdateMessage {
22 25
  26 + @ApiModelProperty(position = 1, value = "The message about new platform update available.")
23 private final String message; 27 private final String message;
  28 + @ApiModelProperty(position = 1, value = "'True' if new platform update is available.")
24 private final boolean isUpdateAvailable; 29 private final boolean isUpdateAvailable;
25 30
26 } 31 }
@@ -17,6 +17,9 @@ package org.thingsboard.server.common.data; @@ -17,6 +17,9 @@ package org.thingsboard.server.common.data;
17 17
18 import com.fasterxml.jackson.annotation.JsonIgnore; 18 import com.fasterxml.jackson.annotation.JsonIgnore;
19 import com.fasterxml.jackson.annotation.JsonProperty; 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 import lombok.EqualsAndHashCode; 23 import lombok.EqualsAndHashCode;
21 import org.thingsboard.server.common.data.id.CustomerId; 24 import org.thingsboard.server.common.data.id.CustomerId;
22 import org.thingsboard.server.common.data.id.EntityId; 25 import org.thingsboard.server.common.data.id.EntityId;
@@ -26,6 +29,7 @@ import org.thingsboard.server.common.data.security.Authority; @@ -26,6 +29,7 @@ import org.thingsboard.server.common.data.security.Authority;
26 29
27 import org.thingsboard.server.common.data.validation.NoXss; 30 import org.thingsboard.server.common.data.validation.NoXss;
28 31
  32 +@ApiModel
29 @EqualsAndHashCode(callSuper = true) 33 @EqualsAndHashCode(callSuper = true)
30 public class User extends SearchTextBasedWithAdditionalInfo<UserId> implements HasName, HasTenantId, HasCustomerId { 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,6 +62,23 @@ public class User extends SearchTextBasedWithAdditionalInfo<UserId> implements H
58 this.lastName = user.getLastName(); 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 public TenantId getTenantId() { 82 public TenantId getTenantId() {
62 return tenantId; 83 return tenantId;
63 } 84 }
@@ -66,6 +87,7 @@ public class User extends SearchTextBasedWithAdditionalInfo<UserId> implements H @@ -66,6 +87,7 @@ public class User extends SearchTextBasedWithAdditionalInfo<UserId> implements H
66 this.tenantId = tenantId; 87 this.tenantId = tenantId;
67 } 88 }
68 89
  90 + @ApiModelProperty(position = 4, value = "JSON object with the Customer Id.", readOnly = true)
69 public CustomerId getCustomerId() { 91 public CustomerId getCustomerId() {
70 return customerId; 92 return customerId;
71 } 93 }
@@ -74,6 +96,7 @@ public class User extends SearchTextBasedWithAdditionalInfo<UserId> implements H @@ -74,6 +96,7 @@ public class User extends SearchTextBasedWithAdditionalInfo<UserId> implements H
74 this.customerId = customerId; 96 this.customerId = customerId;
75 } 97 }
76 98
  99 + @ApiModelProperty(position = 5, required = true, value = "Email of the user", example = "user@example.com")
77 public String getEmail() { 100 public String getEmail() {
78 return email; 101 return email;
79 } 102 }
@@ -82,12 +105,14 @@ public class User extends SearchTextBasedWithAdditionalInfo<UserId> implements H @@ -82,12 +105,14 @@ public class User extends SearchTextBasedWithAdditionalInfo<UserId> implements H
82 this.email = email; 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 @Override 109 @Override
86 @JsonProperty(access = JsonProperty.Access.READ_ONLY) 110 @JsonProperty(access = JsonProperty.Access.READ_ONLY)
87 public String getName() { 111 public String getName() {
88 return email; 112 return email;
89 } 113 }
90 114
  115 + @ApiModelProperty(position = 7, required = true, value = "Authority", example = "SYS_ADMIN, TENANT_ADMIN or CUSTOMER_USER")
91 public Authority getAuthority() { 116 public Authority getAuthority() {
92 return authority; 117 return authority;
93 } 118 }
@@ -96,6 +121,7 @@ public class User extends SearchTextBasedWithAdditionalInfo<UserId> implements H @@ -96,6 +121,7 @@ public class User extends SearchTextBasedWithAdditionalInfo<UserId> implements H
96 this.authority = authority; 121 this.authority = authority;
97 } 122 }
98 123
  124 + @ApiModelProperty(position = 8, required = true, value = "First name of the user", example = "John")
99 public String getFirstName() { 125 public String getFirstName() {
100 return firstName; 126 return firstName;
101 } 127 }
@@ -104,6 +130,7 @@ public class User extends SearchTextBasedWithAdditionalInfo<UserId> implements H @@ -104,6 +130,7 @@ public class User extends SearchTextBasedWithAdditionalInfo<UserId> implements H
104 this.firstName = firstName; 130 this.firstName = firstName;
105 } 131 }
106 132
  133 + @ApiModelProperty(position = 9, required = true, value = "Last name of the user", example = "Doe")
107 public String getLastName() { 134 public String getLastName() {
108 return lastName; 135 return lastName;
109 } 136 }
@@ -112,6 +139,12 @@ public class User extends SearchTextBasedWithAdditionalInfo<UserId> implements H @@ -112,6 +139,12 @@ public class User extends SearchTextBasedWithAdditionalInfo<UserId> implements H
112 this.lastName = lastName; 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 @Override 148 @Override
116 public String getSearchText() { 149 public String getSearchText() {
117 return getEmail(); 150 return getEmail();
@@ -15,6 +15,9 @@ @@ -15,6 +15,9 @@
15 */ 15 */
16 package org.thingsboard.server.common.data.asset; 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 import lombok.EqualsAndHashCode; 21 import lombok.EqualsAndHashCode;
19 import org.thingsboard.server.common.data.HasCustomerId; 22 import org.thingsboard.server.common.data.HasCustomerId;
20 import org.thingsboard.server.common.data.HasName; 23 import org.thingsboard.server.common.data.HasName;
@@ -27,6 +30,7 @@ import org.thingsboard.server.common.data.validation.NoXss; @@ -27,6 +30,7 @@ import org.thingsboard.server.common.data.validation.NoXss;
27 30
28 import java.util.Optional; 31 import java.util.Optional;
29 32
  33 +@ApiModel
30 @EqualsAndHashCode(callSuper = true) 34 @EqualsAndHashCode(callSuper = true)
31 public class Asset extends SearchTextBasedWithAdditionalInfo<AssetId> implements HasName, HasTenantId, HasCustomerId { 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,6 +71,22 @@ public class Asset extends SearchTextBasedWithAdditionalInfo<AssetId> implements
67 Optional.ofNullable(asset.getAdditionalInfo()).ifPresent(this::setAdditionalInfo); 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 public TenantId getTenantId() { 90 public TenantId getTenantId() {
71 return tenantId; 91 return tenantId;
72 } 92 }
@@ -75,6 +95,7 @@ public class Asset extends SearchTextBasedWithAdditionalInfo<AssetId> implements @@ -75,6 +95,7 @@ public class Asset extends SearchTextBasedWithAdditionalInfo<AssetId> implements
75 this.tenantId = tenantId; 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 public CustomerId getCustomerId() { 99 public CustomerId getCustomerId() {
79 return customerId; 100 return customerId;
80 } 101 }
@@ -83,6 +104,7 @@ public class Asset extends SearchTextBasedWithAdditionalInfo<AssetId> implements @@ -83,6 +104,7 @@ public class Asset extends SearchTextBasedWithAdditionalInfo<AssetId> implements
83 this.customerId = customerId; 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 @Override 108 @Override
87 public String getName() { 109 public String getName() {
88 return name; 110 return name;
@@ -92,6 +114,7 @@ public class Asset extends SearchTextBasedWithAdditionalInfo<AssetId> implements @@ -92,6 +114,7 @@ public class Asset extends SearchTextBasedWithAdditionalInfo<AssetId> implements
92 this.name = name; 114 this.name = name;
93 } 115 }
94 116
  117 + @ApiModelProperty(position = 6, required = true, value = "Asset type", example = "Building")
95 public String getType() { 118 public String getType() {
96 return type; 119 return type;
97 } 120 }
@@ -100,6 +123,7 @@ public class Asset extends SearchTextBasedWithAdditionalInfo<AssetId> implements @@ -100,6 +123,7 @@ public class Asset extends SearchTextBasedWithAdditionalInfo<AssetId> implements
100 this.type = type; 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 public String getLabel() { 127 public String getLabel() {
104 return label; 128 return label;
105 } 129 }
@@ -113,6 +137,12 @@ public class Asset extends SearchTextBasedWithAdditionalInfo<AssetId> implements @@ -113,6 +137,12 @@ public class Asset extends SearchTextBasedWithAdditionalInfo<AssetId> implements
113 return getName(); 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 @Override 146 @Override
117 public String toString() { 147 public String toString() {
118 StringBuilder builder = new StringBuilder(); 148 StringBuilder builder = new StringBuilder();
@@ -15,13 +15,18 @@ @@ -15,13 +15,18 @@
15 */ 15 */
16 package org.thingsboard.server.common.data.asset; 16 package org.thingsboard.server.common.data.asset;
17 17
  18 +import io.swagger.annotations.ApiModel;
  19 +import io.swagger.annotations.ApiModelProperty;
18 import lombok.Data; 20 import lombok.Data;
19 import org.thingsboard.server.common.data.id.AssetId; 21 import org.thingsboard.server.common.data.id.AssetId;
20 22
  23 +@ApiModel
21 @Data 24 @Data
22 public class AssetInfo extends Asset { 25 public class AssetInfo extends Asset {
23 26
  27 + @ApiModelProperty(position = 9, value = "Title of the Customer that owns the asset.", readOnly = true)
24 private String customerTitle; 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 private boolean customerIsPublic; 30 private boolean customerIsPublic;
26 31
27 public AssetInfo() { 32 public AssetInfo() {
@@ -15,6 +15,7 @@ @@ -15,6 +15,7 @@
15 */ 15 */
16 package org.thingsboard.server.common.data.asset; 16 package org.thingsboard.server.common.data.asset;
17 17
  18 +import io.swagger.annotations.ApiModelProperty;
18 import lombok.Data; 19 import lombok.Data;
19 import org.thingsboard.server.common.data.EntityType; 20 import org.thingsboard.server.common.data.EntityType;
20 import org.thingsboard.server.common.data.relation.EntityRelation; 21 import org.thingsboard.server.common.data.relation.EntityRelation;
@@ -31,8 +32,11 @@ import java.util.List; @@ -31,8 +32,11 @@ import java.util.List;
31 @Data 32 @Data
32 public class AssetSearchQuery { 33 public class AssetSearchQuery {
33 34
  35 + @ApiModelProperty(position = 3, value = "Main search parameters.")
34 private RelationsSearchParameters parameters; 36 private RelationsSearchParameters parameters;
  37 + @ApiModelProperty(position = 1, value = "Type of the relation between root entity and asset (e.g. 'Contains' or 'Manages').")
35 private String relationType; 38 private String relationType;
  39 + @ApiModelProperty(position = 2, value = "Array of asset types to filter the related entities (e.g. 'Building', 'Vehicle').")
36 private List<String> assetTypes; 40 private List<String> assetTypes;
37 41
38 public EntityRelationsQuery toEntitySearchQuery() { 42 public EntityRelationsQuery toEntitySearchQuery() {
@@ -15,6 +15,8 @@ @@ -15,6 +15,8 @@
15 */ 15 */
16 package org.thingsboard.server.common.data.device; 16 package org.thingsboard.server.common.data.device;
17 17
  18 +import io.swagger.annotations.ApiModel;
  19 +import io.swagger.annotations.ApiModelProperty;
18 import lombok.Data; 20 import lombok.Data;
19 import org.thingsboard.server.common.data.EntityType; 21 import org.thingsboard.server.common.data.EntityType;
20 import org.thingsboard.server.common.data.relation.EntityRelation; 22 import org.thingsboard.server.common.data.relation.EntityRelation;
@@ -25,11 +27,15 @@ import org.thingsboard.server.common.data.relation.RelationsSearchParameters; @@ -25,11 +27,15 @@ import org.thingsboard.server.common.data.relation.RelationsSearchParameters;
25 import java.util.Collections; 27 import java.util.Collections;
26 import java.util.List; 28 import java.util.List;
27 29
  30 +@ApiModel
28 @Data 31 @Data
29 public class DeviceSearchQuery { 32 public class DeviceSearchQuery {
30 33
  34 + @ApiModelProperty(position = 3, value = "Main search parameters.")
31 private RelationsSearchParameters parameters; 35 private RelationsSearchParameters parameters;
  36 + @ApiModelProperty(position = 1, value = "Type of the relation between root entity and device (e.g. 'Contains' or 'Manages').")
32 private String relationType; 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 private List<String> deviceTypes; 39 private List<String> deviceTypes;
34 40
35 public EntityRelationsQuery toEntitySearchQuery() { 41 public EntityRelationsQuery toEntitySearchQuery() {
@@ -15,9 +15,11 @@ @@ -15,9 +15,11 @@
15 */ 15 */
16 package org.thingsboard.server.common.data.device.data; 16 package org.thingsboard.server.common.data.device.data;
17 17
  18 +import io.swagger.annotations.ApiModel;
18 import lombok.Data; 19 import lombok.Data;
19 import org.thingsboard.server.common.data.DeviceProfileType; 20 import org.thingsboard.server.common.data.DeviceProfileType;
20 21
  22 +@ApiModel
21 @Data 23 @Data
22 public class DefaultDeviceConfiguration implements DeviceConfiguration { 24 public class DefaultDeviceConfiguration implements DeviceConfiguration {
23 25
@@ -19,8 +19,10 @@ import com.fasterxml.jackson.annotation.JsonIgnore; @@ -19,8 +19,10 @@ import com.fasterxml.jackson.annotation.JsonIgnore;
19 import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 19 import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
20 import com.fasterxml.jackson.annotation.JsonSubTypes; 20 import com.fasterxml.jackson.annotation.JsonSubTypes;
21 import com.fasterxml.jackson.annotation.JsonTypeInfo; 21 import com.fasterxml.jackson.annotation.JsonTypeInfo;
  22 +import io.swagger.annotations.ApiModel;
22 import org.thingsboard.server.common.data.DeviceProfileType; 23 import org.thingsboard.server.common.data.DeviceProfileType;
23 24
  25 +@ApiModel
24 @JsonIgnoreProperties(ignoreUnknown = true) 26 @JsonIgnoreProperties(ignoreUnknown = true)
25 @JsonTypeInfo( 27 @JsonTypeInfo(
26 use = JsonTypeInfo.Id.NAME, 28 use = JsonTypeInfo.Id.NAME,
@@ -15,8 +15,10 @@ @@ -15,8 +15,10 @@
15 */ 15 */
16 package org.thingsboard.server.common.data.device.data; 16 package org.thingsboard.server.common.data.device.data;
17 17
  18 +import io.swagger.annotations.ApiModel;
18 import lombok.Data; 19 import lombok.Data;
19 20
  21 +@ApiModel
20 @Data 22 @Data
21 public class DeviceData { 23 public class DeviceData {
22 24
@@ -19,10 +19,12 @@ import com.fasterxml.jackson.annotation.JsonIgnore; @@ -19,10 +19,12 @@ import com.fasterxml.jackson.annotation.JsonIgnore;
19 import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 19 import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
20 import com.fasterxml.jackson.annotation.JsonSubTypes; 20 import com.fasterxml.jackson.annotation.JsonSubTypes;
21 import com.fasterxml.jackson.annotation.JsonTypeInfo; 21 import com.fasterxml.jackson.annotation.JsonTypeInfo;
  22 +import io.swagger.annotations.ApiModel;
22 import org.thingsboard.server.common.data.DeviceTransportType; 23 import org.thingsboard.server.common.data.DeviceTransportType;
23 24
24 import java.io.Serializable; 25 import java.io.Serializable;
25 26
  27 +@ApiModel
26 @JsonIgnoreProperties(ignoreUnknown = true) 28 @JsonIgnoreProperties(ignoreUnknown = true)
27 @JsonTypeInfo( 29 @JsonTypeInfo(
28 use = JsonTypeInfo.Id.NAME, 30 use = JsonTypeInfo.Id.NAME,
@@ -18,10 +18,13 @@ package org.thingsboard.server.common.data.id; @@ -18,10 +18,13 @@ package org.thingsboard.server.common.data.id;
18 import com.fasterxml.jackson.annotation.JsonCreator; 18 import com.fasterxml.jackson.annotation.JsonCreator;
19 import com.fasterxml.jackson.annotation.JsonIgnore; 19 import com.fasterxml.jackson.annotation.JsonIgnore;
20 import com.fasterxml.jackson.annotation.JsonProperty; 20 import com.fasterxml.jackson.annotation.JsonProperty;
  21 +import io.swagger.annotations.ApiModel;
  22 +import io.swagger.annotations.ApiModelProperty;
21 import org.thingsboard.server.common.data.EntityType; 23 import org.thingsboard.server.common.data.EntityType;
22 24
23 import java.util.UUID; 25 import java.util.UUID;
24 26
  27 +@ApiModel
25 public class AlarmId extends UUIDBased implements EntityId { 28 public class AlarmId extends UUIDBased implements EntityId {
26 29
27 private static final long serialVersionUID = 1L; 30 private static final long serialVersionUID = 1L;
@@ -35,7 +38,7 @@ public class AlarmId extends UUIDBased implements EntityId { @@ -35,7 +38,7 @@ public class AlarmId extends UUIDBased implements EntityId {
35 return new AlarmId(UUID.fromString(alarmId)); 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 @Override 42 @Override
40 public EntityType getEntityType() { 43 public EntityType getEntityType() {
41 return EntityType.ALARM; 44 return EntityType.ALARM;
@@ -18,10 +18,13 @@ package org.thingsboard.server.common.data.id; @@ -18,10 +18,13 @@ package org.thingsboard.server.common.data.id;
18 import com.fasterxml.jackson.annotation.JsonCreator; 18 import com.fasterxml.jackson.annotation.JsonCreator;
19 import com.fasterxml.jackson.annotation.JsonIgnore; 19 import com.fasterxml.jackson.annotation.JsonIgnore;
20 import com.fasterxml.jackson.annotation.JsonProperty; 20 import com.fasterxml.jackson.annotation.JsonProperty;
  21 +import io.swagger.annotations.ApiModel;
  22 +import io.swagger.annotations.ApiModelProperty;
21 import org.thingsboard.server.common.data.EntityType; 23 import org.thingsboard.server.common.data.EntityType;
22 24
23 import java.util.UUID; 25 import java.util.UUID;
24 26
  27 +@ApiModel
25 public class ApiUsageStateId extends UUIDBased implements EntityId { 28 public class ApiUsageStateId extends UUIDBased implements EntityId {
26 29
27 @JsonCreator 30 @JsonCreator
@@ -33,7 +36,7 @@ public class ApiUsageStateId extends UUIDBased implements EntityId { @@ -33,7 +36,7 @@ public class ApiUsageStateId extends UUIDBased implements EntityId {
33 return new ApiUsageStateId(UUID.fromString(userId)); 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 @Override 40 @Override
38 public EntityType getEntityType() { 41 public EntityType getEntityType() {
39 return EntityType.API_USAGE_STATE; 42 return EntityType.API_USAGE_STATE;
@@ -18,10 +18,13 @@ package org.thingsboard.server.common.data.id; @@ -18,10 +18,13 @@ package org.thingsboard.server.common.data.id;
18 import com.fasterxml.jackson.annotation.JsonCreator; 18 import com.fasterxml.jackson.annotation.JsonCreator;
19 import com.fasterxml.jackson.annotation.JsonIgnore; 19 import com.fasterxml.jackson.annotation.JsonIgnore;
20 import com.fasterxml.jackson.annotation.JsonProperty; 20 import com.fasterxml.jackson.annotation.JsonProperty;
  21 +import io.swagger.annotations.ApiModel;
  22 +import io.swagger.annotations.ApiModelProperty;
21 import org.thingsboard.server.common.data.EntityType; 23 import org.thingsboard.server.common.data.EntityType;
22 24
23 import java.util.UUID; 25 import java.util.UUID;
24 26
  27 +@ApiModel
25 public class AssetId extends UUIDBased implements EntityId { 28 public class AssetId extends UUIDBased implements EntityId {
26 29
27 private static final long serialVersionUID = 1L; 30 private static final long serialVersionUID = 1L;
@@ -35,7 +38,7 @@ public class AssetId extends UUIDBased implements EntityId { @@ -35,7 +38,7 @@ public class AssetId extends UUIDBased implements EntityId {
35 return new AssetId(UUID.fromString(assetId)); 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 @Override 42 @Override
40 public EntityType getEntityType() { 43 public EntityType getEntityType() {
41 return EntityType.ASSET; 44 return EntityType.ASSET;
@@ -20,8 +20,11 @@ import java.util.UUID; @@ -20,8 +20,11 @@ import java.util.UUID;
20 import com.fasterxml.jackson.annotation.JsonCreator; 20 import com.fasterxml.jackson.annotation.JsonCreator;
21 import com.fasterxml.jackson.annotation.JsonIgnore; 21 import com.fasterxml.jackson.annotation.JsonIgnore;
22 import com.fasterxml.jackson.annotation.JsonProperty; 22 import com.fasterxml.jackson.annotation.JsonProperty;
  23 +import io.swagger.annotations.ApiModel;
  24 +import io.swagger.annotations.ApiModelProperty;
23 import org.thingsboard.server.common.data.EntityType; 25 import org.thingsboard.server.common.data.EntityType;
24 26
  27 +@ApiModel
25 public final class CustomerId extends UUIDBased implements EntityId { 28 public final class CustomerId extends UUIDBased implements EntityId {
26 29
27 private static final long serialVersionUID = 1L; 30 private static final long serialVersionUID = 1L;
@@ -31,7 +34,7 @@ public final class CustomerId extends UUIDBased implements EntityId { @@ -31,7 +34,7 @@ public final class CustomerId extends UUIDBased implements EntityId {
31 super(id); 34 super(id);
32 } 35 }
33 36
34 - @JsonIgnore 37 + @ApiModelProperty(position = 2, required = true, value = "string", example = "CUSTOMER", allowableValues = "CUSTOMER")
35 @Override 38 @Override
36 public EntityType getEntityType() { 39 public EntityType getEntityType() {
37 return EntityType.CUSTOMER; 40 return EntityType.CUSTOMER;
@@ -20,8 +20,11 @@ import java.util.UUID; @@ -20,8 +20,11 @@ import java.util.UUID;
20 import com.fasterxml.jackson.annotation.JsonCreator; 20 import com.fasterxml.jackson.annotation.JsonCreator;
21 import com.fasterxml.jackson.annotation.JsonIgnore; 21 import com.fasterxml.jackson.annotation.JsonIgnore;
22 import com.fasterxml.jackson.annotation.JsonProperty; 22 import com.fasterxml.jackson.annotation.JsonProperty;
  23 +import io.swagger.annotations.ApiModel;
  24 +import io.swagger.annotations.ApiModelProperty;
23 import org.thingsboard.server.common.data.EntityType; 25 import org.thingsboard.server.common.data.EntityType;
24 26
  27 +@ApiModel
25 public class DashboardId extends UUIDBased implements EntityId { 28 public class DashboardId extends UUIDBased implements EntityId {
26 29
27 @JsonCreator 30 @JsonCreator
@@ -33,7 +36,7 @@ public class DashboardId extends UUIDBased implements EntityId { @@ -33,7 +36,7 @@ public class DashboardId extends UUIDBased implements EntityId {
33 return new DashboardId(UUID.fromString(dashboardId)); 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 @Override 40 @Override
38 public EntityType getEntityType() { 41 public EntityType getEntityType() {
39 return EntityType.DASHBOARD; 42 return EntityType.DASHBOARD;
@@ -20,8 +20,11 @@ import java.util.UUID; @@ -20,8 +20,11 @@ import java.util.UUID;
20 import com.fasterxml.jackson.annotation.JsonCreator; 20 import com.fasterxml.jackson.annotation.JsonCreator;
21 import com.fasterxml.jackson.annotation.JsonIgnore; 21 import com.fasterxml.jackson.annotation.JsonIgnore;
22 import com.fasterxml.jackson.annotation.JsonProperty; 22 import com.fasterxml.jackson.annotation.JsonProperty;
  23 +import io.swagger.annotations.ApiModel;
  24 +import io.swagger.annotations.ApiModelProperty;
23 import org.thingsboard.server.common.data.EntityType; 25 import org.thingsboard.server.common.data.EntityType;
24 26
  27 +@ApiModel
25 public class DeviceId extends UUIDBased implements EntityId { 28 public class DeviceId extends UUIDBased implements EntityId {
26 29
27 private static final long serialVersionUID = 1L; 30 private static final long serialVersionUID = 1L;
@@ -35,8 +38,8 @@ public class DeviceId extends UUIDBased implements EntityId { @@ -35,8 +38,8 @@ public class DeviceId extends UUIDBased implements EntityId {
35 return new DeviceId(UUID.fromString(deviceId)); 38 return new DeviceId(UUID.fromString(deviceId));
36 } 39 }
37 40
38 - @JsonIgnore  
39 @Override 41 @Override
  42 + @ApiModelProperty(position = 2, required = true, value = "string", example = "DEVICE", allowableValues = "DEVICE")
40 public EntityType getEntityType() { 43 public EntityType getEntityType() {
41 return EntityType.DEVICE; 44 return EntityType.DEVICE;
42 } 45 }
@@ -20,6 +20,7 @@ import java.util.UUID; @@ -20,6 +20,7 @@ import java.util.UUID;
20 import com.fasterxml.jackson.annotation.JsonCreator; 20 import com.fasterxml.jackson.annotation.JsonCreator;
21 import com.fasterxml.jackson.annotation.JsonIgnore; 21 import com.fasterxml.jackson.annotation.JsonIgnore;
22 import com.fasterxml.jackson.annotation.JsonProperty; 22 import com.fasterxml.jackson.annotation.JsonProperty;
  23 +import io.swagger.annotations.ApiModelProperty;
23 import org.thingsboard.server.common.data.EntityType; 24 import org.thingsboard.server.common.data.EntityType;
24 25
25 public class DeviceProfileId extends UUIDBased implements EntityId { 26 public class DeviceProfileId extends UUIDBased implements EntityId {
@@ -35,7 +36,7 @@ public class DeviceProfileId extends UUIDBased implements EntityId { @@ -35,7 +36,7 @@ public class DeviceProfileId extends UUIDBased implements EntityId {
35 return new DeviceProfileId(UUID.fromString(deviceProfileId)); 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 @Override 40 @Override
40 public EntityType getEntityType() { 41 public EntityType getEntityType() {
41 return EntityType.DEVICE_PROFILE; 42 return EntityType.DEVICE_PROFILE;
@@ -18,6 +18,7 @@ package org.thingsboard.server.common.data.id; @@ -18,6 +18,7 @@ package org.thingsboard.server.common.data.id;
18 import com.fasterxml.jackson.annotation.JsonCreator; 18 import com.fasterxml.jackson.annotation.JsonCreator;
19 import com.fasterxml.jackson.annotation.JsonIgnore; 19 import com.fasterxml.jackson.annotation.JsonIgnore;
20 import com.fasterxml.jackson.annotation.JsonProperty; 20 import com.fasterxml.jackson.annotation.JsonProperty;
  21 +import io.swagger.annotations.ApiModelProperty;
21 import org.thingsboard.server.common.data.EntityType; 22 import org.thingsboard.server.common.data.EntityType;
22 23
23 import java.util.UUID; 24 import java.util.UUID;
@@ -35,7 +36,7 @@ public class EdgeId extends UUIDBased implements EntityId { @@ -35,7 +36,7 @@ public class EdgeId extends UUIDBased implements EntityId {
35 return new EdgeId(UUID.fromString(integrationId)); 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 @Override 40 @Override
40 public EntityType getEntityType() { 41 public EntityType getEntityType() {
41 return EntityType.EDGE; 42 return EntityType.EDGE;
@@ -17,6 +17,7 @@ package org.thingsboard.server.common.data.id; @@ -17,6 +17,7 @@ package org.thingsboard.server.common.data.id;
17 17
18 import com.fasterxml.jackson.annotation.JsonCreator; 18 import com.fasterxml.jackson.annotation.JsonCreator;
19 import com.fasterxml.jackson.annotation.JsonProperty; 19 import com.fasterxml.jackson.annotation.JsonProperty;
  20 +import io.swagger.annotations.ApiModelProperty;
20 import org.thingsboard.server.common.data.EntityType; 21 import org.thingsboard.server.common.data.EntityType;
21 22
22 import java.util.UUID; 23 import java.util.UUID;
@@ -37,6 +38,7 @@ public class EntityViewId extends UUIDBased implements EntityId { @@ -37,6 +38,7 @@ public class EntityViewId extends UUIDBased implements EntityId {
37 return new EntityViewId(UUID.fromString(entityViewID)); 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 @Override 42 @Override
41 public EntityType getEntityType() { 43 public EntityType getEntityType() {
42 return EntityType.ENTITY_VIEW; 44 return EntityType.ENTITY_VIEW;
@@ -18,6 +18,7 @@ package org.thingsboard.server.common.data.id; @@ -18,6 +18,7 @@ package org.thingsboard.server.common.data.id;
18 import com.fasterxml.jackson.annotation.JsonCreator; 18 import com.fasterxml.jackson.annotation.JsonCreator;
19 import com.fasterxml.jackson.annotation.JsonIgnore; 19 import com.fasterxml.jackson.annotation.JsonIgnore;
20 import com.fasterxml.jackson.annotation.JsonProperty; 20 import com.fasterxml.jackson.annotation.JsonProperty;
  21 +import io.swagger.annotations.ApiModelProperty;
21 import org.thingsboard.server.common.data.EntityType; 22 import org.thingsboard.server.common.data.EntityType;
22 23
23 import java.util.UUID; 24 import java.util.UUID;
@@ -35,7 +36,7 @@ public class OtaPackageId extends UUIDBased implements EntityId { @@ -35,7 +36,7 @@ public class OtaPackageId extends UUIDBased implements EntityId {
35 return new OtaPackageId(UUID.fromString(firmwareId)); 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 @Override 40 @Override
40 public EntityType getEntityType() { 41 public EntityType getEntityType() {
41 return EntityType.OTA_PACKAGE; 42 return EntityType.OTA_PACKAGE;
@@ -18,6 +18,7 @@ package org.thingsboard.server.common.data.id; @@ -18,6 +18,7 @@ package org.thingsboard.server.common.data.id;
18 import com.fasterxml.jackson.annotation.JsonCreator; 18 import com.fasterxml.jackson.annotation.JsonCreator;
19 import com.fasterxml.jackson.annotation.JsonIgnore; 19 import com.fasterxml.jackson.annotation.JsonIgnore;
20 import com.fasterxml.jackson.annotation.JsonProperty; 20 import com.fasterxml.jackson.annotation.JsonProperty;
  21 +import io.swagger.annotations.ApiModelProperty;
21 import org.thingsboard.server.common.data.EntityType; 22 import org.thingsboard.server.common.data.EntityType;
22 23
23 import java.util.UUID; 24 import java.util.UUID;
@@ -31,7 +32,7 @@ public final class RpcId extends UUIDBased implements EntityId { @@ -31,7 +32,7 @@ public final class RpcId extends UUIDBased implements EntityId {
31 super(id); 32 super(id);
32 } 33 }
33 34
34 - @JsonIgnore 35 + @ApiModelProperty(position = 2, required = true, value = "string", example = "RPC", allowableValues = "RPC")
35 @Override 36 @Override
36 public EntityType getEntityType() { 37 public EntityType getEntityType() {
37 return EntityType.RPC; 38 return EntityType.RPC;
@@ -18,6 +18,7 @@ package org.thingsboard.server.common.data.id; @@ -18,6 +18,7 @@ package org.thingsboard.server.common.data.id;
18 import com.fasterxml.jackson.annotation.JsonCreator; 18 import com.fasterxml.jackson.annotation.JsonCreator;
19 import com.fasterxml.jackson.annotation.JsonIgnore; 19 import com.fasterxml.jackson.annotation.JsonIgnore;
20 import com.fasterxml.jackson.annotation.JsonProperty; 20 import com.fasterxml.jackson.annotation.JsonProperty;
  21 +import io.swagger.annotations.ApiModelProperty;
21 import org.thingsboard.server.common.data.EntityType; 22 import org.thingsboard.server.common.data.EntityType;
22 23
23 import java.util.UUID; 24 import java.util.UUID;
@@ -29,7 +30,7 @@ public class RuleChainId extends UUIDBased implements EntityId { @@ -29,7 +30,7 @@ public class RuleChainId extends UUIDBased implements EntityId {
29 super(id); 30 super(id);
30 } 31 }
31 32
32 - @JsonIgnore 33 + @ApiModelProperty(position = 2, required = true, value = "string", example = "RULE_CHAIN", allowableValues = "RULE_CHAIN")
33 @Override 34 @Override
34 public EntityType getEntityType() { 35 public EntityType getEntityType() {
35 return EntityType.RULE_CHAIN; 36 return EntityType.RULE_CHAIN;
@@ -18,6 +18,7 @@ package org.thingsboard.server.common.data.id; @@ -18,6 +18,7 @@ package org.thingsboard.server.common.data.id;
18 import com.fasterxml.jackson.annotation.JsonCreator; 18 import com.fasterxml.jackson.annotation.JsonCreator;
19 import com.fasterxml.jackson.annotation.JsonIgnore; 19 import com.fasterxml.jackson.annotation.JsonIgnore;
20 import com.fasterxml.jackson.annotation.JsonProperty; 20 import com.fasterxml.jackson.annotation.JsonProperty;
  21 +import io.swagger.annotations.ApiModelProperty;
21 import org.thingsboard.server.common.data.EntityType; 22 import org.thingsboard.server.common.data.EntityType;
22 23
23 import java.util.UUID; 24 import java.util.UUID;
@@ -29,7 +30,7 @@ public class RuleNodeId extends UUIDBased implements EntityId { @@ -29,7 +30,7 @@ public class RuleNodeId extends UUIDBased implements EntityId {
29 super(id); 30 super(id);
30 } 31 }
31 32
32 - @JsonIgnore 33 + @ApiModelProperty(position = 2, required = true, value = "string", example = "RULE_NODE", allowableValues = "RULE_NODE")
33 @Override 34 @Override
34 public EntityType getEntityType() { 35 public EntityType getEntityType() {
35 return EntityType.RULE_NODE; 36 return EntityType.RULE_NODE;
@@ -18,6 +18,7 @@ package org.thingsboard.server.common.data.id; @@ -18,6 +18,7 @@ package org.thingsboard.server.common.data.id;
18 import com.fasterxml.jackson.annotation.JsonCreator; 18 import com.fasterxml.jackson.annotation.JsonCreator;
19 import com.fasterxml.jackson.annotation.JsonIgnore; 19 import com.fasterxml.jackson.annotation.JsonIgnore;
20 import com.fasterxml.jackson.annotation.JsonProperty; 20 import com.fasterxml.jackson.annotation.JsonProperty;
  21 +import io.swagger.annotations.ApiModelProperty;
21 import org.thingsboard.server.common.data.EntityType; 22 import org.thingsboard.server.common.data.EntityType;
22 23
23 import java.util.UUID; 24 import java.util.UUID;
@@ -31,7 +32,7 @@ public class TbResourceId extends UUIDBased implements EntityId { @@ -31,7 +32,7 @@ public class TbResourceId extends UUIDBased implements EntityId {
31 super(id); 32 super(id);
32 } 33 }
33 34
34 - @JsonIgnore 35 + @ApiModelProperty(position = 2, required = true, value = "string", example = "TB_RESOURCE", allowableValues = "TB_RESOURCE")
35 @Override 36 @Override
36 public EntityType getEntityType() { 37 public EntityType getEntityType() {
37 return EntityType.TB_RESOURCE; 38 return EntityType.TB_RESOURCE;
@@ -20,6 +20,7 @@ import java.util.UUID; @@ -20,6 +20,7 @@ import java.util.UUID;
20 import com.fasterxml.jackson.annotation.JsonCreator; 20 import com.fasterxml.jackson.annotation.JsonCreator;
21 import com.fasterxml.jackson.annotation.JsonIgnore; 21 import com.fasterxml.jackson.annotation.JsonIgnore;
22 import com.fasterxml.jackson.annotation.JsonProperty; 22 import com.fasterxml.jackson.annotation.JsonProperty;
  23 +import io.swagger.annotations.ApiModelProperty;
23 import org.thingsboard.server.common.data.EntityType; 24 import org.thingsboard.server.common.data.EntityType;
24 25
25 public final class TenantId extends UUIDBased implements EntityId { 26 public final class TenantId extends UUIDBased implements EntityId {
@@ -34,7 +35,7 @@ public final class TenantId extends UUIDBased implements EntityId { @@ -34,7 +35,7 @@ public final class TenantId extends UUIDBased implements EntityId {
34 super(id); 35 super(id);
35 } 36 }
36 37
37 - @JsonIgnore 38 + @ApiModelProperty(position = 2, required = true, value = "string", example = "TENANT", allowableValues = "TENANT")
38 @Override 39 @Override
39 public EntityType getEntityType() { 40 public EntityType getEntityType() {
40 return EntityType.TENANT; 41 return EntityType.TENANT;
@@ -20,6 +20,7 @@ import java.util.UUID; @@ -20,6 +20,7 @@ import java.util.UUID;
20 import com.fasterxml.jackson.annotation.JsonCreator; 20 import com.fasterxml.jackson.annotation.JsonCreator;
21 import com.fasterxml.jackson.annotation.JsonIgnore; 21 import com.fasterxml.jackson.annotation.JsonIgnore;
22 import com.fasterxml.jackson.annotation.JsonProperty; 22 import com.fasterxml.jackson.annotation.JsonProperty;
  23 +import io.swagger.annotations.ApiModelProperty;
23 import org.thingsboard.server.common.data.EntityType; 24 import org.thingsboard.server.common.data.EntityType;
24 25
25 public class TenantProfileId extends UUIDBased implements EntityId { 26 public class TenantProfileId extends UUIDBased implements EntityId {
@@ -35,7 +36,7 @@ public class TenantProfileId extends UUIDBased implements EntityId { @@ -35,7 +36,7 @@ public class TenantProfileId extends UUIDBased implements EntityId {
35 return new TenantProfileId(UUID.fromString(tenantProfileId)); 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 @Override 40 @Override
40 public EntityType getEntityType() { 41 public EntityType getEntityType() {
41 return EntityType.TENANT_PROFILE; 42 return EntityType.TENANT_PROFILE;
@@ -15,9 +15,13 @@ @@ -15,9 +15,13 @@
15 */ 15 */
16 package org.thingsboard.server.common.data.id; 16 package org.thingsboard.server.common.data.id;
17 17
  18 +import io.swagger.annotations.ApiModel;
  19 +import io.swagger.annotations.ApiModelProperty;
  20 +
18 import java.io.Serializable; 21 import java.io.Serializable;
19 import java.util.UUID; 22 import java.util.UUID;
20 23
  24 +@ApiModel
21 public abstract class UUIDBased implements HasUUID, Serializable { 25 public abstract class UUIDBased implements HasUUID, Serializable {
22 26
23 private static final long serialVersionUID = 1L; 27 private static final long serialVersionUID = 1L;
@@ -33,6 +37,7 @@ public abstract class UUIDBased implements HasUUID, Serializable { @@ -33,6 +37,7 @@ public abstract class UUIDBased implements HasUUID, Serializable {
33 this.id = id; 37 this.id = id;
34 } 38 }
35 39
  40 + @ApiModelProperty(position = 1, required = true, value = "string", example = "784f394c-42b6-435a-983c-b7beff2784f9")
36 public UUID getId() { 41 public UUID getId() {
37 return id; 42 return id;
38 } 43 }
@@ -20,6 +20,7 @@ import java.util.UUID; @@ -20,6 +20,7 @@ import java.util.UUID;
20 import com.fasterxml.jackson.annotation.JsonCreator; 20 import com.fasterxml.jackson.annotation.JsonCreator;
21 import com.fasterxml.jackson.annotation.JsonIgnore; 21 import com.fasterxml.jackson.annotation.JsonIgnore;
22 import com.fasterxml.jackson.annotation.JsonProperty; 22 import com.fasterxml.jackson.annotation.JsonProperty;
  23 +import io.swagger.annotations.ApiModelProperty;
23 import org.thingsboard.server.common.data.EntityType; 24 import org.thingsboard.server.common.data.EntityType;
24 25
25 public class UserId extends UUIDBased implements EntityId { 26 public class UserId extends UUIDBased implements EntityId {
@@ -33,7 +34,7 @@ public class UserId extends UUIDBased implements EntityId { @@ -33,7 +34,7 @@ public class UserId extends UUIDBased implements EntityId {
33 return new UserId(UUID.fromString(userId)); 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 @Override 38 @Override
38 public EntityType getEntityType() { 39 public EntityType getEntityType() {
39 return EntityType.USER; 40 return EntityType.USER;
@@ -20,6 +20,7 @@ import java.util.UUID; @@ -20,6 +20,7 @@ import java.util.UUID;
20 import com.fasterxml.jackson.annotation.JsonCreator; 20 import com.fasterxml.jackson.annotation.JsonCreator;
21 import com.fasterxml.jackson.annotation.JsonIgnore; 21 import com.fasterxml.jackson.annotation.JsonIgnore;
22 import com.fasterxml.jackson.annotation.JsonProperty; 22 import com.fasterxml.jackson.annotation.JsonProperty;
  23 +import io.swagger.annotations.ApiModelProperty;
23 import org.thingsboard.server.common.data.EntityType; 24 import org.thingsboard.server.common.data.EntityType;
24 25
25 public final class WidgetTypeId extends UUIDBased implements EntityId { 26 public final class WidgetTypeId extends UUIDBased implements EntityId {
@@ -31,7 +32,7 @@ public final class WidgetTypeId extends UUIDBased implements EntityId { @@ -31,7 +32,7 @@ public final class WidgetTypeId extends UUIDBased implements EntityId {
31 super(id); 32 super(id);
32 } 33 }
33 34
34 - @JsonIgnore 35 + @ApiModelProperty(position = 2, required = true, value = "string", example = "WIDGET_TYPE", allowableValues = "WIDGET_TYPE")
35 @Override 36 @Override
36 public EntityType getEntityType() { 37 public EntityType getEntityType() {
37 return EntityType.WIDGET_TYPE; 38 return EntityType.WIDGET_TYPE;
@@ -20,6 +20,7 @@ import java.util.UUID; @@ -20,6 +20,7 @@ import java.util.UUID;
20 import com.fasterxml.jackson.annotation.JsonCreator; 20 import com.fasterxml.jackson.annotation.JsonCreator;
21 import com.fasterxml.jackson.annotation.JsonIgnore; 21 import com.fasterxml.jackson.annotation.JsonIgnore;
22 import com.fasterxml.jackson.annotation.JsonProperty; 22 import com.fasterxml.jackson.annotation.JsonProperty;
  23 +import io.swagger.annotations.ApiModelProperty;
23 import org.thingsboard.server.common.data.EntityType; 24 import org.thingsboard.server.common.data.EntityType;
24 25
25 public final class WidgetsBundleId extends UUIDBased implements EntityId { 26 public final class WidgetsBundleId extends UUIDBased implements EntityId {
@@ -31,7 +32,7 @@ public final class WidgetsBundleId extends UUIDBased implements EntityId { @@ -31,7 +32,7 @@ public final class WidgetsBundleId extends UUIDBased implements EntityId {
31 super(id); 32 super(id);
32 } 33 }
33 34
34 - @JsonIgnore 35 + @ApiModelProperty(position = 2, required = true, value = "string", example = "WIDGETS_BUNDLE", allowableValues = "WIDGETS_BUNDLE")
35 @Override 36 @Override
36 public EntityType getEntityType() { 37 public EntityType getEntityType() {
37 return EntityType.WIDGETS_BUNDLE; 38 return EntityType.WIDGETS_BUNDLE;
@@ -17,12 +17,15 @@ package org.thingsboard.server.common.data.page; @@ -17,12 +17,15 @@ package org.thingsboard.server.common.data.page;
17 17
18 import com.fasterxml.jackson.annotation.JsonCreator; 18 import com.fasterxml.jackson.annotation.JsonCreator;
19 import com.fasterxml.jackson.annotation.JsonProperty; 19 import com.fasterxml.jackson.annotation.JsonProperty;
  20 +import io.swagger.annotations.ApiModel;
  21 +import io.swagger.annotations.ApiModelProperty;
20 22
21 import java.util.Collections; 23 import java.util.Collections;
22 import java.util.List; 24 import java.util.List;
23 import java.util.function.Function; 25 import java.util.function.Function;
24 import java.util.stream.Collectors; 26 import java.util.stream.Collectors;
25 27
  28 +@ApiModel
26 public class PageData<T> { 29 public class PageData<T> {
27 30
28 private final List<T> data; 31 private final List<T> data;
@@ -45,18 +48,22 @@ public class PageData<T> { @@ -45,18 +48,22 @@ public class PageData<T> {
45 this.hasNext = hasNext; 48 this.hasNext = hasNext;
46 } 49 }
47 50
  51 + @ApiModelProperty(position = 1, value = "Array of the entities", readOnly = true)
48 public List<T> getData() { 52 public List<T> getData() {
49 return data; 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 public int getTotalPages() { 57 public int getTotalPages() {
53 return totalPages; 58 return totalPages;
54 } 59 }
55 60
  61 + @ApiModelProperty(position = 3, value = "Total number of elements in all available pages", readOnly = true)
56 public long getTotalElements() { 62 public long getTotalElements() {
57 return totalElements; 63 return totalElements;
58 } 64 }
59 65
  66 + @ApiModelProperty(position = 4, value = "'false' value indicates the end of the result set", readOnly = true)
60 @JsonProperty("hasNext") 67 @JsonProperty("hasNext")
61 public boolean hasNext() { 68 public boolean hasNext() {
62 return hasNext; 69 return hasNext;
@@ -16,6 +16,8 @@ @@ -16,6 +16,8 @@
16 package org.thingsboard.server.common.data.plugin; 16 package org.thingsboard.server.common.data.plugin;
17 17
18 import com.fasterxml.jackson.databind.JsonNode; 18 import com.fasterxml.jackson.databind.JsonNode;
  19 +import io.swagger.annotations.ApiModel;
  20 +import io.swagger.annotations.ApiModelProperty;
19 import lombok.*; 21 import lombok.*;
20 import org.thingsboard.server.common.data.SearchTextBased; 22 import org.thingsboard.server.common.data.SearchTextBased;
21 import org.thingsboard.server.common.data.id.ComponentDescriptorId; 23 import org.thingsboard.server.common.data.id.ComponentDescriptorId;
@@ -23,16 +25,23 @@ import org.thingsboard.server.common.data.id.ComponentDescriptorId; @@ -23,16 +25,23 @@ import org.thingsboard.server.common.data.id.ComponentDescriptorId;
23 /** 25 /**
24 * @author Andrew Shvayka 26 * @author Andrew Shvayka
25 */ 27 */
  28 +@ApiModel
26 @ToString 29 @ToString
27 public class ComponentDescriptor extends SearchTextBased<ComponentDescriptorId> { 30 public class ComponentDescriptor extends SearchTextBased<ComponentDescriptorId> {
28 31
29 private static final long serialVersionUID = 1L; 32 private static final long serialVersionUID = 1L;
30 33
  34 + @ApiModelProperty(position = 3, value = "Type of the Rule Node", readOnly = true)
31 @Getter @Setter private ComponentType type; 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 @Getter @Setter private ComponentScope scope; 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 @Getter @Setter private String name; 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 @Getter @Setter private String clazz; 41 @Getter @Setter private String clazz;
  42 + @ApiModelProperty(position = 7, value = "Complex JSON object that represents the Rule Node configuration.", readOnly = true)
35 @Getter @Setter private transient JsonNode configurationDescriptor; 43 @Getter @Setter private transient JsonNode configurationDescriptor;
  44 + @ApiModelProperty(position = 8, value = "Rule Node Actions. Deprecated. Always null.", readOnly = true)
36 @Getter @Setter private String actions; 45 @Getter @Setter private String actions;
37 46
38 public ComponentDescriptor() { 47 public ComponentDescriptor() {
@@ -53,12 +62,26 @@ public class ComponentDescriptor extends SearchTextBased<ComponentDescriptorId> @@ -53,12 +62,26 @@ public class ComponentDescriptor extends SearchTextBased<ComponentDescriptorId>
53 this.actions = plugin.getActions(); 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 @Override 80 @Override
57 public String getSearchText() { 81 public String getSearchText() {
58 return name; 82 return name;
59 } 83 }
60 84
61 -  
62 @Override 85 @Override
63 public boolean equals(Object o) { 86 public boolean equals(Object o) {
64 if (this == o) return true; 87 if (this == o) return true;
@@ -84,4 +107,5 @@ public class ComponentDescriptor extends SearchTextBased<ComponentDescriptorId> @@ -84,4 +107,5 @@ public class ComponentDescriptor extends SearchTextBased<ComponentDescriptorId>
84 result = 31 * result + (actions != null ? actions.hashCode() : 0); 107 result = 31 * result + (actions != null ? actions.hashCode() : 0);
85 return result; 108 return result;
86 } 109 }
  110 +
87 } 111 }
@@ -15,6 +15,8 @@ @@ -15,6 +15,8 @@
15 */ 15 */
16 package org.thingsboard.server.common.data.relation; 16 package org.thingsboard.server.common.data.relation;
17 17
  18 +import io.swagger.annotations.ApiModel;
  19 +import io.swagger.annotations.ApiModelProperty;
18 import lombok.AllArgsConstructor; 20 import lombok.AllArgsConstructor;
19 import lombok.Data; 21 import lombok.Data;
20 import org.thingsboard.server.common.data.EntityType; 22 import org.thingsboard.server.common.data.EntityType;
@@ -26,15 +28,22 @@ import java.util.UUID; @@ -26,15 +28,22 @@ import java.util.UUID;
26 /** 28 /**
27 * Created by ashvayka on 03.05.17. 29 * Created by ashvayka on 03.05.17.
28 */ 30 */
  31 +@ApiModel
29 @Data 32 @Data
30 @AllArgsConstructor 33 @AllArgsConstructor
31 public class RelationsSearchParameters { 34 public class RelationsSearchParameters {
32 35
  36 + @ApiModelProperty(position = 1, value = "Root entity id to start search from.")
33 private UUID rootId; 37 private UUID rootId;
  38 + @ApiModelProperty(position = 2, value = "Type of the root entity.")
34 private EntityType rootType; 39 private EntityType rootType;
  40 + @ApiModelProperty(position = 3, value = "Type of the root entity.")
35 private EntitySearchDirection direction; 41 private EntitySearchDirection direction;
  42 + @ApiModelProperty(position = 4, value = "Type of the relation.")
36 private RelationTypeGroup relationTypeGroup; 43 private RelationTypeGroup relationTypeGroup;
  44 + @ApiModelProperty(position = 5, value = "Maximum level of the search depth.")
37 private int maxLevel = 1; 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 private boolean fetchLastLevelOnly; 47 private boolean fetchLastLevelOnly;
39 48
40 public RelationsSearchParameters(EntityId entityId, EntitySearchDirection direction, int maxLevel, boolean fetchLastLevelOnly) { 49 public RelationsSearchParameters(EntityId entityId, EntitySearchDirection direction, int maxLevel, boolean fetchLastLevelOnly) {
@@ -15,16 +15,18 @@ @@ -15,16 +15,18 @@
15 */ 15 */
16 package org.thingsboard.server.common.data.security; 16 package org.thingsboard.server.common.data.security;
17 17
  18 +import io.swagger.annotations.ApiModel;
  19 +import io.swagger.annotations.ApiModelProperty;
18 import lombok.EqualsAndHashCode; 20 import lombok.EqualsAndHashCode;
19 import org.thingsboard.server.common.data.BaseData; 21 import org.thingsboard.server.common.data.BaseData;
20 import org.thingsboard.server.common.data.id.DeviceCredentialsId; 22 import org.thingsboard.server.common.data.id.DeviceCredentialsId;
21 import org.thingsboard.server.common.data.id.DeviceId; 23 import org.thingsboard.server.common.data.id.DeviceId;
22 24
  25 +@ApiModel
23 @EqualsAndHashCode(callSuper = true) 26 @EqualsAndHashCode(callSuper = true)
24 public class DeviceCredentials extends BaseData<DeviceCredentialsId> implements DeviceCredentialsFilter { 27 public class DeviceCredentials extends BaseData<DeviceCredentialsId> implements DeviceCredentialsFilter {
25 28
26 private static final long serialVersionUID = -7869261127032877765L; 29 private static final long serialVersionUID = -7869261127032877765L;
27 -  
28 private DeviceId deviceId; 30 private DeviceId deviceId;
29 private DeviceCredentialsType credentialsType; 31 private DeviceCredentialsType credentialsType;
30 private String credentialsId; 32 private String credentialsId;
@@ -46,6 +48,21 @@ public class DeviceCredentials extends BaseData<DeviceCredentialsId> implements @@ -46,6 +48,21 @@ public class DeviceCredentials extends BaseData<DeviceCredentialsId> implements
46 this.credentialsValue = deviceCredentials.getCredentialsValue(); 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 public DeviceId getDeviceId() { 66 public DeviceId getDeviceId() {
50 return deviceId; 67 return deviceId;
51 } 68 }
@@ -54,6 +71,7 @@ public class DeviceCredentials extends BaseData<DeviceCredentialsId> implements @@ -54,6 +71,7 @@ public class DeviceCredentials extends BaseData<DeviceCredentialsId> implements
54 this.deviceId = deviceId; 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 @Override 75 @Override
58 public DeviceCredentialsType getCredentialsType() { 76 public DeviceCredentialsType getCredentialsType() {
59 return credentialsType; 77 return credentialsType;
@@ -63,6 +81,11 @@ public class DeviceCredentials extends BaseData<DeviceCredentialsId> implements @@ -63,6 +81,11 @@ public class DeviceCredentials extends BaseData<DeviceCredentialsId> implements
63 this.credentialsType = credentialsType; 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 @Override 89 @Override
67 public String getCredentialsId() { 90 public String getCredentialsId() {
68 return credentialsId; 91 return credentialsId;
@@ -72,6 +95,9 @@ public class DeviceCredentials extends BaseData<DeviceCredentialsId> implements @@ -72,6 +95,9 @@ public class DeviceCredentials extends BaseData<DeviceCredentialsId> implements
72 this.credentialsId = credentialsId; 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 public String getCredentialsValue() { 101 public String getCredentialsValue() {
76 return credentialsValue; 102 return credentialsValue;
77 } 103 }
@@ -15,15 +15,20 @@ @@ -15,15 +15,20 @@
15 */ 15 */
16 package org.thingsboard.server.common.data.security.model; 16 package org.thingsboard.server.common.data.security.model;
17 17
  18 +import io.swagger.annotations.ApiModel;
  19 +import io.swagger.annotations.ApiModelProperty;
18 import lombok.Data; 20 import lombok.Data;
19 21
20 import java.io.Serializable; 22 import java.io.Serializable;
21 23
  24 +@ApiModel
22 @Data 25 @Data
23 public class SecuritySettings implements Serializable { 26 public class SecuritySettings implements Serializable {
24 27
  28 + @ApiModelProperty(position = 1, value = "The user password policy object." )
25 private UserPasswordPolicy passwordPolicy; 29 private UserPasswordPolicy passwordPolicy;
26 - 30 + @ApiModelProperty(position = 2, value = "Maximum number of failed login attempts allowed before user account is locked." )
27 private Integer maxFailedLoginAttempts; 31 private Integer maxFailedLoginAttempts;
  32 + @ApiModelProperty(position = 3, value = "Email to use for notifications about locked users." )
28 private String userLockoutNotificationEmail; 33 private String userLockoutNotificationEmail;
29 } 34 }
@@ -15,20 +15,30 @@ @@ -15,20 +15,30 @@
15 */ 15 */
16 package org.thingsboard.server.common.data.security.model; 16 package org.thingsboard.server.common.data.security.model;
17 17
  18 +import io.swagger.annotations.ApiModel;
  19 +import io.swagger.annotations.ApiModelProperty;
18 import lombok.Data; 20 import lombok.Data;
19 21
20 import java.io.Serializable; 22 import java.io.Serializable;
21 23
  24 +@ApiModel
22 @Data 25 @Data
23 public class UserPasswordPolicy implements Serializable { 26 public class UserPasswordPolicy implements Serializable {
24 27
  28 + @ApiModelProperty(position = 1, value = "Minimum number of symbols in the password." )
25 private Integer minimumLength; 29 private Integer minimumLength;
  30 + @ApiModelProperty(position = 1, value = "Minimum number of uppercase letters in the password." )
26 private Integer minimumUppercaseLetters; 31 private Integer minimumUppercaseLetters;
  32 + @ApiModelProperty(position = 1, value = "Minimum number of lowercase letters in the password." )
27 private Integer minimumLowercaseLetters; 33 private Integer minimumLowercaseLetters;
  34 + @ApiModelProperty(position = 1, value = "Minimum number of digits in the password." )
28 private Integer minimumDigits; 35 private Integer minimumDigits;
  36 + @ApiModelProperty(position = 1, value = "Minimum number of special in the password." )
29 private Integer minimumSpecialCharacters; 37 private Integer minimumSpecialCharacters;
30 38
  39 + @ApiModelProperty(position = 1, value = "Password expiration period (days). Force expiration of the password." )
31 private Integer passwordExpirationPeriodDays; 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 private Integer passwordReuseFrequencyDays; 42 private Integer passwordReuseFrequencyDays;
33 43
34 } 44 }
@@ -15,13 +15,19 @@ @@ -15,13 +15,19 @@
15 */ 15 */
16 package org.thingsboard.server.common.data.sms.config; 16 package org.thingsboard.server.common.data.sms.config;
17 17
  18 +import io.swagger.annotations.ApiModel;
  19 +import io.swagger.annotations.ApiModelProperty;
18 import lombok.Data; 20 import lombok.Data;
19 21
  22 +@ApiModel
20 @Data 23 @Data
21 public class AwsSnsSmsProviderConfiguration implements SmsProviderConfiguration { 24 public class AwsSnsSmsProviderConfiguration implements SmsProviderConfiguration {
22 25
  26 + @ApiModelProperty(position = 1, value = "The AWS SNS Access Key ID.")
23 private String accessKeyId; 27 private String accessKeyId;
  28 + @ApiModelProperty(position = 2, value = "The AWS SNS Access Key.")
24 private String secretAccessKey; 29 private String secretAccessKey;
  30 + @ApiModelProperty(position = 3, value = "The AWS region.")
25 private String region; 31 private String region;
26 32
27 @Override 33 @Override
@@ -15,13 +15,19 @@ @@ -15,13 +15,19 @@
15 */ 15 */
16 package org.thingsboard.server.common.data.sms.config; 16 package org.thingsboard.server.common.data.sms.config;
17 17
  18 +import io.swagger.annotations.ApiModel;
  19 +import io.swagger.annotations.ApiModelProperty;
18 import lombok.Data; 20 import lombok.Data;
19 21
  22 +@ApiModel
20 @Data 23 @Data
21 public class TestSmsRequest { 24 public class TestSmsRequest {
22 25
  26 + @ApiModelProperty(position = 1, value = "The SMS provider configuration")
23 private SmsProviderConfiguration providerConfiguration; 27 private SmsProviderConfiguration providerConfiguration;
  28 + @ApiModelProperty(position = 2, value = "The phone number or other identifier to specify as a recipient of the SMS.")
24 private String numberTo; 29 private String numberTo;
  30 + @ApiModelProperty(position = 3, value = "The test message")
25 private String message; 31 private String message;
26 32
27 } 33 }
@@ -15,13 +15,19 @@ @@ -15,13 +15,19 @@
15 */ 15 */
16 package org.thingsboard.server.common.data.sms.config; 16 package org.thingsboard.server.common.data.sms.config;
17 17
  18 +import io.swagger.annotations.ApiModel;
  19 +import io.swagger.annotations.ApiModelProperty;
18 import lombok.Data; 20 import lombok.Data;
19 21
  22 +@ApiModel
20 @Data 23 @Data
21 public class TwilioSmsProviderConfiguration implements SmsProviderConfiguration { 24 public class TwilioSmsProviderConfiguration implements SmsProviderConfiguration {
22 25
  26 + @ApiModelProperty(position = 1, value = "Twilio account Sid.")
23 private String accountSid; 27 private String accountSid;
  28 + @ApiModelProperty(position = 2, value = "Twilio account Token.")
24 private String accountToken; 29 private String accountToken;
  30 + @ApiModelProperty(position = 3, value = "The number/id of a sender.")
25 private String numberFrom; 31 private String numberFrom;
26 32
27 @Override 33 @Override
@@ -85,6 +85,7 @@ @@ -85,6 +85,7 @@
85 <jar-plugin.version>3.0.2</jar-plugin.version> 85 <jar-plugin.version>3.0.2</jar-plugin.version>
86 <springfox-swagger.version>2.6.1</springfox-swagger.version> 86 <springfox-swagger.version>2.6.1</springfox-swagger.version>
87 <springfox-swagger-ui-rfc6570.version>1.0.0</springfox-swagger-ui-rfc6570.version> 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 <spatial4j.version>0.7</spatial4j.version> 89 <spatial4j.version>0.7</spatial4j.version>
89 <jts.version>1.15.0</jts.version> 90 <jts.version>1.15.0</jts.version>
90 <bouncycastle.version>1.67</bouncycastle.version> 91 <bouncycastle.version>1.67</bouncycastle.version>
@@ -1624,6 +1625,11 @@ @@ -1624,6 +1625,11 @@
1624 <version>${springfox-swagger.version}</version> 1625 <version>${springfox-swagger.version}</version>
1625 </dependency> 1626 </dependency>
1626 <dependency> 1627 <dependency>
  1628 + <groupId>io.swagger</groupId>
  1629 + <artifactId>swagger-annotations</artifactId>
  1630 + <version>${swagger-annotations.version}</version>
  1631 + </dependency>
  1632 + <dependency>
1627 <groupId>org.bouncycastle</groupId> 1633 <groupId>org.bouncycastle</groupId>
1628 <artifactId>bcprov-jdk15on</artifactId> 1634 <artifactId>bcprov-jdk15on</artifactId>
1629 <version>${bouncycastle.version}</version> 1635 <version>${bouncycastle.version}</version>