Commit 3f163e3ee54679a6ad2b62252bd51d4ce98ccb65

Authored by Andrew Shvayka
Committed by GitHub
2 parents 33823336 36bb7f36

Merge pull request #5418 from YevhenBondarenko/feature/swagger

[3.3.2] added descriptions for the queue, ota and resource controllers
... ... @@ -177,10 +177,12 @@ public abstract class BaseController {
177 177 public static final String ASSET_ID_PARAM_DESCRIPTION = "A string value representing the asset id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";
178 178 public static final String ALARM_ID_PARAM_DESCRIPTION = "A string value representing the alarm id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";
179 179 public static final String ENTITY_ID_PARAM_DESCRIPTION = "A string value representing the entity id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";
  180 + public static final String OTA_PACKAGE_ID_PARAM_DESCRIPTION = "A string value representing the ota package id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";
180 181 public static final String ENTITY_TYPE_PARAM_DESCRIPTION = "A string value representing the entity type. For example, 'DEVICE'";
181 182 public static final String RULE_CHAIN_ID_PARAM_DESCRIPTION = "A string value representing the rule chain id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";
182 183 public static final String WIDGET_BUNDLE_ID_PARAM_DESCRIPTION = "A string value representing the widget bundle id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";
183 184 public static final String WIDGET_TYPE_ID_PARAM_DESCRIPTION = "A string value representing the widget type id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";
  185 + public static final String RESOURCE_ID_PARAM_DESCRIPTION = "A string value representing the resource id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";
184 186
185 187
186 188 protected static final String SYSTEM_AUTHORITY_PARAGRAPH = "\n\nAvailable for users with 'SYS_ADMIN' authority.";
... ... @@ -240,6 +242,19 @@ public abstract class BaseController {
240 242 protected static final String RELATION_INFO_DESCRIPTION = "Relation Info is an extension of the default Relation object that contains information about the 'from' and 'to' entity names. ";
241 243 protected static final String EDGE_INFO_DESCRIPTION = "Edge Info is an extension of the default Edge object that contains information about the assigned customer name. ";
242 244 protected static final String DEVICE_PROFILE_INFO_DESCRIPTION = "Device Profile Info is a lightweight object that includes main information about Device Profile excluding the heavyweight configuration object. ";
  245 + protected static final String QUEUE_SERVICE_TYPE_DESCRIPTION = "Service type (implemented only for the TB-RULE-ENGINE)";
  246 + protected static final String QUEUE_SERVICE_TYPE_ALLOWABLE_VALUES = "TB-RULE-ENGINE, TB-CORE, TB-TRANSPORT, JS-EXECUTOR";
  247 + protected static final String OTA_PACKAGE_INFO_DESCRIPTION = "OTA Package Info is a lightweight object that includes main information about the OTA Package excluding the heavyweight data. ";
  248 + protected static final String OTA_PACKAGE_DESCRIPTION = "OTA Package is a heavyweight object that includes main information about the OTA Package and also data. ";
  249 + protected static final String OTA_PACKAGE_CHECKSUM_ALGORITHM_ALLOWABLE_VALUES = "MD5, SHA256, SHA384, SHA512, CRC32, MURMUR3_32, MURMUR3_128";
  250 + protected static final String OTA_PACKAGE_TEXT_SEARCH_DESCRIPTION = "The case insensitive 'startsWith' filter based on the ota package title.";
  251 + protected static final String OTA_PACKAGE_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, type, title, version, tag, url, fileName, dataSize, checksum";
  252 + protected static final String RESOURCE_INFO_DESCRIPTION = "Resource Info is a lightweight object that includes main information about the Resource excluding the heavyweight data. ";
  253 + protected static final String RESOURCE_DESCRIPTION = "Resource is a heavyweight object that includes main information about the Resource and also data. ";
  254 + protected static final String RESOURCE_TEXT_SEARCH_DESCRIPTION = "The case insensitive 'startsWith' filter based on the resource title.";
  255 + protected static final String RESOURCE_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, title, resourceType, tenantId";
  256 + protected static final String LWM2M_OBJECT_DESCRIPTION = "LwM2M Object is a object that includes information about the LwM2M model which can be used in transport configuration for the LwM2M device profile. ";
  257 + protected static final String LWM2M_OBJECT_SORT_PROPERTY_ALLOWABLE_VALUES = "id, name";
243 258
244 259 protected static final String DEVICE_NAME_DESCRIPTION = "A string value representing the Device name.";
245 260 protected static final String ASSET_NAME_DESCRIPTION = "A string value representing the Asset name.";
... ...
... ... @@ -15,6 +15,8 @@
15 15 */
16 16 package org.thingsboard.server.controller;
17 17
  18 +import io.swagger.annotations.ApiOperation;
  19 +import io.swagger.annotations.ApiParam;
18 20 import lombok.extern.slf4j.Slf4j;
19 21 import org.apache.commons.lang3.StringUtils;
20 22 import org.springframework.core.io.ByteArrayResource;
... ... @@ -56,10 +58,12 @@ public class OtaPackageController extends BaseController {
56 58 public static final String OTA_PACKAGE_ID = "otaPackageId";
57 59 public static final String CHECKSUM_ALGORITHM = "checksumAlgorithm";
58 60
  61 + @ApiOperation(value = "Download OTA Package (downloadOtaPackage)", notes = "Download OTA Package based on the provided OTA Package Id." + TENANT_AUTHORITY_PARAGRAPH)
59 62 @PreAuthorize("hasAnyAuthority( 'TENANT_ADMIN')")
60 63 @RequestMapping(value = "/otaPackage/{otaPackageId}/download", method = RequestMethod.GET)
61 64 @ResponseBody
62   - public ResponseEntity<org.springframework.core.io.Resource> downloadOtaPackage(@PathVariable(OTA_PACKAGE_ID) String strOtaPackageId) throws ThingsboardException {
  65 + public ResponseEntity<org.springframework.core.io.Resource> downloadOtaPackage(@ApiParam(value = OTA_PACKAGE_ID_PARAM_DESCRIPTION)
  66 + @PathVariable(OTA_PACKAGE_ID) String strOtaPackageId) throws ThingsboardException {
63 67 checkParameter(OTA_PACKAGE_ID, strOtaPackageId);
64 68 try {
65 69 OtaPackageId otaPackageId = new OtaPackageId(toUUID(strOtaPackageId));
... ... @@ -81,10 +85,15 @@ public class OtaPackageController extends BaseController {
81 85 }
82 86 }
83 87
  88 + @ApiOperation(value = "Get OTA Package Info (getOtaPackageInfoById)",
  89 + notes = "Fetch the OTA Package Info object based on the provided OTA Package Id. " +
  90 + OTA_PACKAGE_INFO_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH,
  91 + produces = "application/json")
84 92 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
85 93 @RequestMapping(value = "/otaPackage/info/{otaPackageId}", method = RequestMethod.GET)
86 94 @ResponseBody
87   - public OtaPackageInfo getOtaPackageInfoById(@PathVariable(OTA_PACKAGE_ID) String strOtaPackageId) throws ThingsboardException {
  95 + public OtaPackageInfo getOtaPackageInfoById(@ApiParam(value = OTA_PACKAGE_ID_PARAM_DESCRIPTION)
  96 + @PathVariable(OTA_PACKAGE_ID) String strOtaPackageId) throws ThingsboardException {
88 97 checkParameter(OTA_PACKAGE_ID, strOtaPackageId);
89 98 try {
90 99 OtaPackageId otaPackageId = new OtaPackageId(toUUID(strOtaPackageId));
... ... @@ -94,10 +103,15 @@ public class OtaPackageController extends BaseController {
94 103 }
95 104 }
96 105
  106 + @ApiOperation(value = "Get OTA Package (getOtaPackageById)",
  107 + notes = "Fetch the OTA Package object based on the provided OTA Package Id. " +
  108 + "The server checks that the OTA Package is owned by the same tenant. " + OTA_PACKAGE_DESCRIPTION + TENANT_AUTHORITY_PARAGRAPH,
  109 + produces = "application/json")
97 110 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')")
98 111 @RequestMapping(value = "/otaPackage/{otaPackageId}", method = RequestMethod.GET)
99 112 @ResponseBody
100   - public OtaPackage getOtaPackageById(@PathVariable(OTA_PACKAGE_ID) String strOtaPackageId) throws ThingsboardException {
  113 + public OtaPackage getOtaPackageById(@ApiParam(value = OTA_PACKAGE_ID_PARAM_DESCRIPTION)
  114 + @PathVariable(OTA_PACKAGE_ID) String strOtaPackageId) throws ThingsboardException {
101 115 checkParameter(OTA_PACKAGE_ID, strOtaPackageId);
102 116 try {
103 117 OtaPackageId otaPackageId = new OtaPackageId(toUUID(strOtaPackageId));
... ... @@ -107,10 +121,19 @@ public class OtaPackageController extends BaseController {
107 121 }
108 122 }
109 123
  124 + @ApiOperation(value = "Create Or Update OTA Package Info (saveOtaPackageInfo)",
  125 + notes = "Create or update the OTA Package Info. When creating OTA Package Info, platform generates OTA Package id as [time-based UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_1_(date-time_and_MAC_address). " +
  126 + "The newly created OTA Package id will be present in the response. " +
  127 + "Specify existing OTA Package id to update the OTA Package Info. " +
  128 + "Referencing non-existing OTA Package Id will cause 'Not Found' error. " +
  129 + "\n\nOTA Package combination of the title with the version is unique in the scope of tenant. " + TENANT_AUTHORITY_PARAGRAPH,
  130 + produces = "application/json",
  131 + consumes = "application/json")
110 132 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')")
111 133 @RequestMapping(value = "/otaPackage", method = RequestMethod.POST)
112 134 @ResponseBody
113   - public OtaPackageInfo saveOtaPackageInfo(@RequestBody SaveOtaPackageInfoRequest otaPackageInfo) throws ThingsboardException {
  135 + public OtaPackageInfo saveOtaPackageInfo(@ApiParam(value = "A JSON value representing the OTA Package.")
  136 + @RequestBody SaveOtaPackageInfoRequest otaPackageInfo) throws ThingsboardException {
114 137 boolean created = otaPackageInfo.getId() == null;
115 138 try {
116 139 otaPackageInfo.setTenantId(getTenantId());
... ... @@ -126,13 +149,20 @@ public class OtaPackageController extends BaseController {
126 149 }
127 150 }
128 151
  152 + @ApiOperation(value = "Save OTA Package data (saveOtaPackageData)",
  153 + notes = "Update the OTA Package. Adds the date to the existing OTA Package Info" + TENANT_AUTHORITY_PARAGRAPH,
  154 + produces = "application/json")
129 155 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')")
130 156 @RequestMapping(value = "/otaPackage/{otaPackageId}", method = RequestMethod.POST)
131 157 @ResponseBody
132   - public OtaPackageInfo saveOtaPackageData(@PathVariable(OTA_PACKAGE_ID) String strOtaPackageId,
133   - @RequestParam(required = false) String checksum,
134   - @RequestParam(CHECKSUM_ALGORITHM) String checksumAlgorithmStr,
135   - @RequestBody MultipartFile file) throws ThingsboardException {
  158 + public OtaPackageInfo saveOtaPackageData(@ApiParam(value = OTA_PACKAGE_ID_PARAM_DESCRIPTION)
  159 + @PathVariable(OTA_PACKAGE_ID) String strOtaPackageId,
  160 + @ApiParam(value = "OTA Package checksum. For example, '0xd87f7e0c'")
  161 + @RequestParam(required = false) String checksum,
  162 + @ApiParam(value = "OTA Package checksum algorithm.", allowableValues = OTA_PACKAGE_CHECKSUM_ALGORITHM_ALLOWABLE_VALUES)
  163 + @RequestParam(CHECKSUM_ALGORITHM) String checksumAlgorithmStr,
  164 + @ApiParam(value = "OTA Package data.")
  165 + @RequestBody MultipartFile file) throws ThingsboardException {
136 166 checkParameter(OTA_PACKAGE_ID, strOtaPackageId);
137 167 checkParameter(CHECKSUM_ALGORITHM, checksumAlgorithmStr);
138 168 try {
... ... @@ -171,14 +201,23 @@ public class OtaPackageController extends BaseController {
171 201 }
172 202 }
173 203
  204 + @ApiOperation(value = "Get OTA Package Infos (getOtaPackages)",
  205 + notes = "Returns a page of OTA Package Info objects owned by tenant. " +
  206 + PAGE_DATA_PARAMETERS + OTA_PACKAGE_INFO_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH,
  207 + produces = "application/json")
174 208 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
175 209 @RequestMapping(value = "/otaPackages", method = RequestMethod.GET)
176 210 @ResponseBody
177   - public PageData<OtaPackageInfo> getOtaPackages(@RequestParam int pageSize,
178   - @RequestParam int page,
179   - @RequestParam(required = false) String textSearch,
180   - @RequestParam(required = false) String sortProperty,
181   - @RequestParam(required = false) String sortOrder) throws ThingsboardException {
  211 + public PageData<OtaPackageInfo> getOtaPackages(@ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true)
  212 + @RequestParam int pageSize,
  213 + @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true)
  214 + @RequestParam int page,
  215 + @ApiParam(value = OTA_PACKAGE_TEXT_SEARCH_DESCRIPTION)
  216 + @RequestParam(required = false) String textSearch,
  217 + @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = OTA_PACKAGE_SORT_PROPERTY_ALLOWABLE_VALUES)
  218 + @RequestParam(required = false) String sortProperty,
  219 + @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES)
  220 + @RequestParam(required = false) String sortOrder) throws ThingsboardException {
182 221 try {
183 222 PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder);
184 223 return checkNotNull(otaPackageService.findTenantOtaPackagesByTenantId(getTenantId(), pageLink));
... ... @@ -187,15 +226,26 @@ public class OtaPackageController extends BaseController {
187 226 }
188 227 }
189 228
  229 + @ApiOperation(value = "Get OTA Package Infos (getOtaPackages)",
  230 + notes = "Returns a page of OTA Package Info objects owned by tenant. " +
  231 + PAGE_DATA_PARAMETERS + OTA_PACKAGE_INFO_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH,
  232 + produces = "application/json")
190 233 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
191 234 @RequestMapping(value = "/otaPackages/{deviceProfileId}/{type}", method = RequestMethod.GET)
192 235 @ResponseBody
193   - public PageData<OtaPackageInfo> getOtaPackages(@PathVariable("deviceProfileId") String strDeviceProfileId,
  236 + public PageData<OtaPackageInfo> getOtaPackages(@ApiParam(value = DEVICE_PROFILE_ID_PARAM_DESCRIPTION)
  237 + @PathVariable("deviceProfileId") String strDeviceProfileId,
  238 + @ApiParam(value = "OTA Package type.", allowableValues = "FIRMWARE, SOFTWARE")
194 239 @PathVariable("type") String strType,
  240 + @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true)
195 241 @RequestParam int pageSize,
  242 + @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true)
196 243 @RequestParam int page,
  244 + @ApiParam(value = OTA_PACKAGE_TEXT_SEARCH_DESCRIPTION)
197 245 @RequestParam(required = false) String textSearch,
  246 + @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = OTA_PACKAGE_SORT_PROPERTY_ALLOWABLE_VALUES)
198 247 @RequestParam(required = false) String sortProperty,
  248 + @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES)
199 249 @RequestParam(required = false) String sortOrder) throws ThingsboardException {
200 250 checkParameter("deviceProfileId", strDeviceProfileId);
201 251 checkParameter("type", strType);
... ... @@ -208,10 +258,15 @@ public class OtaPackageController extends BaseController {
208 258 }
209 259 }
210 260
  261 + @ApiOperation(value = "Delete OTA Package (deleteOtaPackage)",
  262 + notes = "Deletes the OTA Package. Referencing non-existing OTA Package Id will cause an error. " +
  263 + "Can't delete the OTA Package if it is referenced by existing devices or device profile." + TENANT_AUTHORITY_PARAGRAPH,
  264 + produces = "application/json")
211 265 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')")
212 266 @RequestMapping(value = "/otaPackage/{otaPackageId}", method = RequestMethod.DELETE)
213 267 @ResponseBody
214   - public void deleteOtaPackage(@PathVariable("otaPackageId") String strOtaPackageId) throws ThingsboardException {
  268 + public void deleteOtaPackage(@ApiParam(value = OTA_PACKAGE_ID_PARAM_DESCRIPTION)
  269 + @PathVariable("otaPackageId") String strOtaPackageId) throws ThingsboardException {
215 270 checkParameter(OTA_PACKAGE_ID, strOtaPackageId);
216 271 try {
217 272 OtaPackageId otaPackageId = new OtaPackageId(toUUID(strOtaPackageId));
... ...
... ... @@ -15,7 +15,10 @@
15 15 */
16 16 package org.thingsboard.server.controller;
17 17
  18 +import io.swagger.annotations.ApiOperation;
  19 +import io.swagger.annotations.ApiParam;
18 20 import lombok.RequiredArgsConstructor;
  21 +import org.springframework.http.MediaType;
19 22 import org.springframework.security.access.prepost.PreAuthorize;
20 23 import org.springframework.web.bind.annotation.RequestMapping;
21 24 import org.springframework.web.bind.annotation.RequestMethod;
... ... @@ -37,10 +40,13 @@ public class QueueController extends BaseController {
37 40
38 41 private final QueueService queueService;
39 42
  43 + @ApiOperation(value = "Get queue names (getTenantQueuesByServiceType)",
  44 + notes = "Returns a set of unique queue names based on service type. " + TENANT_AUTHORITY_PARAGRAPH)
40 45 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
41   - @RequestMapping(value = "/tenant/queues", params = {"serviceType"}, method = RequestMethod.GET)
42   - @ResponseBody
43   - public Set<String> getTenantQueuesByServiceType(@RequestParam String serviceType) throws ThingsboardException {
  46 + @RequestMapping(value = "/tenant/queues", params = {"serviceType"}, produces = MediaType.APPLICATION_JSON_VALUE, method = RequestMethod.GET)
  47 + @ResponseBody()
  48 + public Set<String> getTenantQueuesByServiceType(@ApiParam(value = QUEUE_SERVICE_TYPE_DESCRIPTION, allowableValues = QUEUE_SERVICE_TYPE_ALLOWABLE_VALUES)
  49 + @RequestParam String serviceType) throws ThingsboardException {
44 50 checkParameter("serviceType", serviceType);
45 51 try {
46 52 return queueService.getQueuesByServiceType(ServiceType.valueOf(serviceType));
... ...
... ... @@ -15,6 +15,8 @@
15 15 */
16 16 package org.thingsboard.server.controller;
17 17
  18 +import io.swagger.annotations.ApiOperation;
  19 +import io.swagger.annotations.ApiParam;
18 20 import lombok.extern.slf4j.Slf4j;
19 21 import org.springframework.core.io.ByteArrayResource;
20 22 import org.springframework.http.HttpHeaders;
... ... @@ -53,10 +55,12 @@ public class TbResourceController extends BaseController {
53 55
54 56 public static final String RESOURCE_ID = "resourceId";
55 57
  58 + @ApiOperation(value = "Download Resource (downloadResource)", notes = "Download Resource based on the provided Resource Id." + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH)
56 59 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
57 60 @RequestMapping(value = "/resource/{resourceId}/download", method = RequestMethod.GET)
58 61 @ResponseBody
59   - public ResponseEntity<org.springframework.core.io.Resource> downloadResource(@PathVariable(RESOURCE_ID) String strResourceId) throws ThingsboardException {
  62 + public ResponseEntity<org.springframework.core.io.Resource> downloadResource(@ApiParam(value = RESOURCE_ID_PARAM_DESCRIPTION)
  63 + @PathVariable(RESOURCE_ID) String strResourceId) throws ThingsboardException {
60 64 checkParameter(RESOURCE_ID, strResourceId);
61 65 try {
62 66 TbResourceId resourceId = new TbResourceId(toUUID(strResourceId));
... ... @@ -74,10 +78,15 @@ public class TbResourceController extends BaseController {
74 78 }
75 79 }
76 80
  81 + @ApiOperation(value = "Get Resource Info (getResourceInfoById)",
  82 + notes = "Fetch the Resource Info object based on the provided Resource Id. " +
  83 + RESOURCE_INFO_DESCRIPTION + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH,
  84 + produces = "application/json")
77 85 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
78 86 @RequestMapping(value = "/resource/info/{resourceId}", method = RequestMethod.GET)
79 87 @ResponseBody
80   - public TbResourceInfo getResourceInfoById(@PathVariable(RESOURCE_ID) String strResourceId) throws ThingsboardException {
  88 + public TbResourceInfo getResourceInfoById(@ApiParam(value = RESOURCE_ID_PARAM_DESCRIPTION)
  89 + @PathVariable(RESOURCE_ID) String strResourceId) throws ThingsboardException {
81 90 checkParameter(RESOURCE_ID, strResourceId);
82 91 try {
83 92 TbResourceId resourceId = new TbResourceId(toUUID(strResourceId));
... ... @@ -87,10 +96,15 @@ public class TbResourceController extends BaseController {
87 96 }
88 97 }
89 98
  99 + @ApiOperation(value = "Get Resource (getResourceById)",
  100 + notes = "Fetch the Resource object based on the provided Resource Id. " +
  101 + RESOURCE_DESCRIPTION + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH,
  102 + produces = "application/json")
90 103 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
91 104 @RequestMapping(value = "/resource/{resourceId}", method = RequestMethod.GET)
92 105 @ResponseBody
93   - public TbResource getResourceById(@PathVariable(RESOURCE_ID) String strResourceId) throws ThingsboardException {
  106 + public TbResource getResourceById(@ApiParam(value = RESOURCE_ID_PARAM_DESCRIPTION)
  107 + @PathVariable(RESOURCE_ID) String strResourceId) throws ThingsboardException {
94 108 checkParameter(RESOURCE_ID, strResourceId);
95 109 try {
96 110 TbResourceId resourceId = new TbResourceId(toUUID(strResourceId));
... ... @@ -100,10 +114,19 @@ public class TbResourceController extends BaseController {
100 114 }
101 115 }
102 116
  117 + @ApiOperation(value = "Create Or Update Resource (saveResource)",
  118 + notes = "Create or update the Resource. When creating the Resource, platform generates Resource id as [time-based UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_1_(date-time_and_MAC_address). " +
  119 + "The newly created Resource id will be present in the response. " +
  120 + "Specify existing Resource id to update the Resource. " +
  121 + "Referencing non-existing Resource Id will cause 'Not Found' error. " +
  122 + "\n\nResource combination of the title with the key is unique in the scope of tenant. " + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH,
  123 + produces = "application/json",
  124 + consumes = "application/json")
103 125 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
104 126 @RequestMapping(value = "/resource", method = RequestMethod.POST)
105 127 @ResponseBody
106   - public TbResource saveResource(@RequestBody TbResource resource) throws ThingsboardException {
  128 + public TbResource saveResource(@ApiParam(value = "A JSON value representing the Resource.")
  129 + @RequestBody TbResource resource) throws ThingsboardException {
107 130 boolean created = resource.getId() == null;
108 131 try {
109 132 resource.setTenantId(getTenantId());
... ... @@ -120,13 +143,22 @@ public class TbResourceController extends BaseController {
120 143 }
121 144 }
122 145
  146 + @ApiOperation(value = "Get Resource Infos (getResources)",
  147 + notes = "Returns a page of Resource Info objects owned by tenant or sysadmin. " +
  148 + PAGE_DATA_PARAMETERS + RESOURCE_INFO_DESCRIPTION + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH,
  149 + produces = "application/json")
123 150 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
124 151 @RequestMapping(value = "/resource", method = RequestMethod.GET)
125 152 @ResponseBody
126   - public PageData<TbResourceInfo> getResources(@RequestParam int pageSize,
  153 + public PageData<TbResourceInfo> getResources(@ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true)
  154 + @RequestParam int pageSize,
  155 + @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true)
127 156 @RequestParam int page,
  157 + @ApiParam(value = RESOURCE_TEXT_SEARCH_DESCRIPTION)
128 158 @RequestParam(required = false) String textSearch,
  159 + @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = RESOURCE_SORT_PROPERTY_ALLOWABLE_VALUES)
129 160 @RequestParam(required = false) String sortProperty,
  161 + @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES)
130 162 @RequestParam(required = false) String sortOrder) throws ThingsboardException {
131 163 try {
132 164 PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder);
... ... @@ -140,13 +172,22 @@ public class TbResourceController extends BaseController {
140 172 }
141 173 }
142 174
  175 + @ApiOperation(value = "Get LwM2M Objects (getLwm2mListObjectsPage)",
  176 + notes = "Returns a page of LwM2M objects parsed from Resources with type 'LWM2M_MODEL' owned by tenant or sysadmin. " +
  177 + PAGE_DATA_PARAMETERS + LWM2M_OBJECT_DESCRIPTION + TENANT_AUTHORITY_PARAGRAPH,
  178 + produces = "application/json")
143 179 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')")
144 180 @RequestMapping(value = "/resource/lwm2m/page", method = RequestMethod.GET)
145 181 @ResponseBody
146   - public List<LwM2mObject> getLwm2mListObjectsPage(@RequestParam int pageSize,
  182 + public List<LwM2mObject> getLwm2mListObjectsPage(@ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true)
  183 + @RequestParam int pageSize,
  184 + @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true)
147 185 @RequestParam int page,
  186 + @ApiParam(value = RESOURCE_TEXT_SEARCH_DESCRIPTION)
148 187 @RequestParam(required = false) String textSearch,
  188 + @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = LWM2M_OBJECT_SORT_PROPERTY_ALLOWABLE_VALUES)
149 189 @RequestParam(required = false) String sortProperty,
  190 + @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES)
150 191 @RequestParam(required = false) String sortOrder) throws ThingsboardException {
151 192 try {
152 193 PageLink pageLink = new PageLink(pageSize, page, textSearch);
... ... @@ -156,11 +197,18 @@ public class TbResourceController extends BaseController {
156 197 }
157 198 }
158 199
  200 + @ApiOperation(value = "Get LwM2M Objects (getLwm2mListObjects)",
  201 + notes = "Returns a page of LwM2M objects parsed from Resources with type 'LWM2M_MODEL' owned by tenant or sysadmin. " +
  202 + "You can specify parameters to filter the results. " + LWM2M_OBJECT_DESCRIPTION + TENANT_AUTHORITY_PARAGRAPH,
  203 + produces = "application/json")
159 204 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')")
160 205 @RequestMapping(value = "/resource/lwm2m", method = RequestMethod.GET)
161 206 @ResponseBody
162   - public List<LwM2mObject> getLwm2mListObjects(@RequestParam String sortOrder,
  207 + public List<LwM2mObject> getLwm2mListObjects(@ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES, required = true)
  208 + @RequestParam String sortOrder,
  209 + @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = LWM2M_OBJECT_SORT_PROPERTY_ALLOWABLE_VALUES, required = true)
163 210 @RequestParam String sortProperty,
  211 + @ApiParam(value = "LwM2M Object ids.", required = true)
164 212 @RequestParam(required = false) String[] objectIds) throws ThingsboardException {
165 213 try {
166 214 return checkNotNull(resourceService.findLwM2mObject(getTenantId(), sortOrder, sortProperty, objectIds));
... ... @@ -169,10 +217,13 @@ public class TbResourceController extends BaseController {
169 217 }
170 218 }
171 219
  220 + @ApiOperation(value = "Delete Resource (deleteResource)",
  221 + notes = "Deletes the Resource. Referencing non-existing Resource Id will cause an error." + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH)
172 222 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
173 223 @RequestMapping(value = "/resource/{resourceId}", method = RequestMethod.DELETE)
174 224 @ResponseBody
175   - public void deleteResource(@PathVariable("resourceId") String strResourceId) throws ThingsboardException {
  225 + public void deleteResource(@ApiParam(value = RESOURCE_ID_PARAM_DESCRIPTION)
  226 + @PathVariable("resourceId") String strResourceId) throws ThingsboardException {
176 227 checkParameter(RESOURCE_ID, strResourceId);
177 228 try {
178 229 TbResourceId resourceId = new TbResourceId(toUUID(strResourceId));
... ...
... ... @@ -15,18 +15,22 @@
15 15 */
16 16 package org.thingsboard.server.common.data;
17 17
  18 +import io.swagger.annotations.ApiModel;
  19 +import io.swagger.annotations.ApiModelProperty;
18 20 import lombok.Data;
19 21 import lombok.EqualsAndHashCode;
20 22 import org.thingsboard.server.common.data.id.OtaPackageId;
21 23
22 24 import java.nio.ByteBuffer;
23 25
  26 +@ApiModel
24 27 @Data
25 28 @EqualsAndHashCode(callSuper = true)
26 29 public class OtaPackage extends OtaPackageInfo {
27 30
28 31 private static final long serialVersionUID = 3091601761339422546L;
29 32
  33 + @ApiModelProperty(position = 16, value = "OTA Package data.", readOnly = true)
30 34 private transient ByteBuffer data;
31 35
32 36 public OtaPackage() {
... ...
... ... @@ -16,15 +16,19 @@
16 16 package org.thingsboard.server.common.data;
17 17
18 18 import com.fasterxml.jackson.annotation.JsonIgnore;
  19 +import com.fasterxml.jackson.databind.JsonNode;
  20 +import io.swagger.annotations.ApiModel;
  21 +import io.swagger.annotations.ApiModelProperty;
19 22 import lombok.Data;
20 23 import lombok.EqualsAndHashCode;
21 24 import lombok.extern.slf4j.Slf4j;
22   -import org.thingsboard.server.common.data.ota.ChecksumAlgorithm;
23   -import org.thingsboard.server.common.data.ota.OtaPackageType;
24 25 import org.thingsboard.server.common.data.id.DeviceProfileId;
25 26 import org.thingsboard.server.common.data.id.OtaPackageId;
26 27 import org.thingsboard.server.common.data.id.TenantId;
  28 +import org.thingsboard.server.common.data.ota.ChecksumAlgorithm;
  29 +import org.thingsboard.server.common.data.ota.OtaPackageType;
27 30
  31 +@ApiModel
28 32 @Slf4j
29 33 @Data
30 34 @EqualsAndHashCode(callSuper = true)
... ... @@ -32,21 +36,33 @@ public class OtaPackageInfo extends SearchTextBasedWithAdditionalInfo<OtaPackage
32 36
33 37 private static final long serialVersionUID = 3168391583570815419L;
34 38
  39 + @ApiModelProperty(position = 3, value = "JSON object with Tenant Id. Tenant Id of the ota package can't be changed.", readOnly = true)
35 40 private TenantId tenantId;
  41 + @ApiModelProperty(position = 4, value = "JSON object with Device Profile Id. Device Profile Id of the ota package can't be changed.", readOnly = true)
36 42 private DeviceProfileId deviceProfileId;
  43 + @ApiModelProperty(position = 5, value = "OTA Package type.", example = "FIRMWARE", readOnly = true)
37 44 private OtaPackageType type;
  45 + @ApiModelProperty(position = 6, value = "OTA Package title.", example = "fw", readOnly = true)
38 46 private String title;
  47 + @ApiModelProperty(position = 7, value = "OTA Package version.", example = "1.0", readOnly = true)
39 48 private String version;
  49 + @ApiModelProperty(position = 8, value = "OTA Package tag.", example = "fw_1.0", readOnly = true)
40 50 private String tag;
  51 + @ApiModelProperty(position = 9, value = "OTA Package url.", example = "http://thingsboard.org/fw/1", readOnly = true)
41 52 private String url;
  53 + @ApiModelProperty(position = 10, value = "Indicates OTA Package 'has data'. Field is returned from DB ('true' if data exists or url is set). If OTA Package 'has data' is 'false' we can not assign the OTA Package to the Device or Device Profile.", example = "true", readOnly = true)
42 54 private boolean hasData;
  55 + @ApiModelProperty(position = 11, value = "OTA Package file name.", example = "fw_1.0", readOnly = true)
43 56 private String fileName;
  57 + @ApiModelProperty(position = 12, value = "OTA Package content type.", example = "APPLICATION_OCTET_STREAM", readOnly = true)
44 58 private String contentType;
  59 + @ApiModelProperty(position = 13, value = "OTA Package checksum algorithm.", example = "CRC32", readOnly = true)
45 60 private ChecksumAlgorithm checksumAlgorithm;
  61 + @ApiModelProperty(position = 14, value = "OTA Package checksum.", example = "0xd87f7e0c", readOnly = true)
46 62 private String checksum;
  63 + @ApiModelProperty(position = 15, value = "OTA Package data size.", example = "8", readOnly = true)
47 64 private Long dataSize;
48 65
49   -
50 66 public OtaPackageInfo() {
51 67 super();
52 68 }
... ... @@ -72,6 +88,21 @@ public class OtaPackageInfo extends SearchTextBasedWithAdditionalInfo<OtaPackage
72 88 this.dataSize = otaPackageInfo.getDataSize();
73 89 }
74 90
  91 + @ApiModelProperty(position = 1, value = "JSON object with the ota package Id. " +
  92 + "Specify existing ota package Id to update the ota package. " +
  93 + "Referencing non-existing ota package id will cause error. " +
  94 + "Omit this field to create new ota package.")
  95 + @Override
  96 + public OtaPackageId getId() {
  97 + return super.getId();
  98 + }
  99 +
  100 + @ApiModelProperty(position = 2, value = "Timestamp of the ota package creation, in milliseconds", example = "1609459200000", readOnly = true)
  101 + @Override
  102 + public long getCreatedTime() {
  103 + return super.getCreatedTime();
  104 + }
  105 +
75 106 @Override
76 107 public String getSearchText() {
77 108 return title;
... ... @@ -87,4 +118,10 @@ public class OtaPackageInfo extends SearchTextBasedWithAdditionalInfo<OtaPackage
87 118 public boolean hasUrl() {
88 119 return StringUtils.isNotEmpty(url);
89 120 }
  121 +
  122 + @ApiModelProperty(position = 17, value = "OTA Package description.", example = "Description for the OTA Package fw_1.0")
  123 + @Override
  124 + public JsonNode getAdditionalInfo() {
  125 + return super.getAdditionalInfo();
  126 + }
90 127 }
... ...
... ... @@ -15,14 +15,18 @@
15 15 */
16 16 package org.thingsboard.server.common.data;
17 17
  18 +import io.swagger.annotations.ApiModel;
  19 +import io.swagger.annotations.ApiModelProperty;
18 20 import lombok.Data;
19 21 import lombok.EqualsAndHashCode;
20 22 import lombok.NoArgsConstructor;
21 23
  24 +@ApiModel
22 25 @Data
23 26 @EqualsAndHashCode(callSuper = true)
24 27 @NoArgsConstructor
25   -public class SaveOtaPackageInfoRequest extends OtaPackageInfo{
  28 +public class SaveOtaPackageInfoRequest extends OtaPackageInfo {
  29 + @ApiModelProperty(position = 16, value = "Indicates OTA Package uses url. Should be 'true' if uses url or 'false' if will be used data.", example = "true", readOnly = true)
26 30 boolean usesUrl;
27 31
28 32 public SaveOtaPackageInfoRequest(OtaPackageInfo otaPackageInfo, boolean usesUrl) {
... ...
... ... @@ -15,6 +15,7 @@
15 15 */
16 16 package org.thingsboard.server.common.data;
17 17
  18 +import io.swagger.annotations.ApiModelProperty;
18 19 import lombok.Data;
19 20 import lombok.EqualsAndHashCode;
20 21 import lombok.extern.slf4j.Slf4j;
... ... @@ -29,8 +30,10 @@ public class TbResource extends TbResourceInfo {
29 30 private static final long serialVersionUID = 7379609705527272306L;
30 31
31 32 @NoXss
  33 + @ApiModelProperty(position = 8, value = "Resource file name.", example = "19.xml", readOnly = true)
32 34 private String fileName;
33 35
  36 + @ApiModelProperty(position = 9, value = "Resource data.", example = "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPCEtLQpGSUxFIElORk9STUFUSU9OCgpPTUEgUGVybWFuZW50IERvY3VtZW50CiAgIEZpbGU6IE9NQS1TVVAtTHdNMk1fQmluYXJ5QXBwRGF0YUNvbnRhaW5lci1WMV8wXzEtMjAxOTAyMjEtQQogICBUeXBlOiB4bWwKClB1YmxpYyBSZWFjaGFibGUgSW5mb3JtYXRpb24KICAgUGF0aDogaHR0cDovL3d3dy5vcGVubW9iaWxlYWxsaWFuY2Uub3JnL3RlY2gvcHJvZmlsZXMKICAgTmFtZTogTHdNMk1fQmluYXJ5QXBwRGF0YUNvbnRhaW5lci12MV8wXzEueG1sCgpOT1JNQVRJVkUgSU5GT1JNQVRJT04KCiAgSW5mb3JtYXRpb24gYWJvdXQgdGhpcyBmaWxlIGNhbiBiZSBmb3VuZCBpbiB0aGUgbGF0ZXN0IHJldmlzaW9uIG9mCgogIE9NQS1UUy1MV00yTV9CaW5hcnlBcHBEYXRhQ29udGFpbmVyLVYxXzBfMQoKICBUaGlzIGlzIGF2YWlsYWJsZSBhdCBodHRwOi8vd3d3Lm9wZW5tb2JpbGVhbGxpYW5jZS5vcmcvCgogIFNlbmQgY29tbWVudHMgdG8gaHR0cHM6Ly9naXRodWIuY29tL09wZW5Nb2JpbGVBbGxpYW5jZS9PTUFfTHdNMk1fZm9yX0RldmVsb3BlcnMvaXNzdWVzCgpDSEFOR0UgSElTVE9SWQoKMTUwNjIwMTggU3RhdHVzIGNoYW5nZWQgdG8gQXBwcm92ZWQgYnkgRE0sIERvYyBSZWYgIyBPTUEtRE0mU0UtMjAxOC0wMDYxLUlOUF9MV00yTV9BUFBEQVRBX1YxXzBfRVJQX2Zvcl9maW5hbF9BcHByb3ZhbAoyMTAyMjAxOSBTdGF0dXMgY2hhbmdlZCB0byBBcHByb3ZlZCBieSBJUFNPLCBEb2MgUmVmICMgT01BLUlQU08tMjAxOS0wMDI1LUlOUF9Md00yTV9PYmplY3RfQXBwX0RhdGFfQ29udGFpbmVyXzFfMF8xX2Zvcl9GaW5hbF9BcHByb3ZhbAoKTEVHQUwgRElTQ0xBSU1FUgoKQ29weXJpZ2h0IDIwMTkgT3BlbiBNb2JpbGUgQWxsaWFuY2UuCgpSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCmFyZSBtZXQ6CgoxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodApub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCjIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Cm5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGUKZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi4KMy4gTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgY29weXJpZ2h0IGhvbGRlciBub3IgdGhlIG5hbWVzIG9mIGl0cwpjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQKZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgoKVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUwoiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVApMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUwpGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRQpDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULApJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLApCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7CkxPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIKQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUCkxJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOCkFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRQpQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KClRoZSBhYm92ZSBsaWNlbnNlIGlzIHVzZWQgYXMgYSBsaWNlbnNlIHVuZGVyIGNvcHlyaWdodCBvbmx5LiBQbGVhc2UKcmVmZXJlbmNlIHRoZSBPTUEgSVBSIFBvbGljeSBmb3IgcGF0ZW50IGxpY2Vuc2luZyB0ZXJtczoKaHR0cHM6Ly93d3cub21hc3BlY3dvcmtzLm9yZy9hYm91dC9pbnRlbGxlY3R1YWwtcHJvcGVydHktcmlnaHRzLwoKLS0+CjxMV00yTSB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiB4c2k6bm9OYW1lc3BhY2VTY2hlbWFMb2NhdGlvbj0iaHR0cDovL29wZW5tb2JpbGVhbGxpYW5jZS5vcmcvdGVjaC9wcm9maWxlcy9MV00yTS54c2QiPgoJPE9iamVjdCBPYmplY3RUeXBlPSJNT0RlZmluaXRpb24iPgoJCTxOYW1lPkJpbmFyeUFwcERhdGFDb250YWluZXI8L05hbWU+CgkJPERlc2NyaXB0aW9uMT48IVtDREFUQVtUaGlzIEx3TTJNIE9iamVjdHMgcHJvdmlkZXMgdGhlIGFwcGxpY2F0aW9uIHNlcnZpY2UgZGF0YSByZWxhdGVkIHRvIGEgTHdNMk0gU2VydmVyLCBlZy4gV2F0ZXIgbWV0ZXIgZGF0YS4gClRoZXJlIGFyZSBzZXZlcmFsIG1ldGhvZHMgdG8gY3JlYXRlIGluc3RhbmNlIHRvIGluZGljYXRlIHRoZSBtZXNzYWdlIGRpcmVjdGlvbiBiYXNlZCBvbiB0aGUgbmVnb3RpYXRpb24gYmV0d2VlbiBBcHBsaWNhdGlvbiBhbmQgTHdNMk0uIFRoZSBDbGllbnQgYW5kIFNlcnZlciBzaG91bGQgbmVnb3RpYXRlIHRoZSBpbnN0YW5jZShzKSB1c2VkIHRvIGV4Y2hhbmdlIHRoZSBkYXRhLiBGb3IgZXhhbXBsZToKIC0gVXNpbmcgYSBzaW5nbGUgaW5zdGFuY2UgZm9yIGJvdGggZGlyZWN0aW9ucyBjb21tdW5pY2F0aW9uLCBmcm9tIENsaWVudCB0byBTZXJ2ZXIgYW5kIGZyb20gU2VydmVyIHRvIENsaWVudC4KIC0gVXNpbmcgYW4gaW5zdGFuY2UgZm9yIGNvbW11bmljYXRpb24gZnJvbSBDbGllbnQgdG8gU2VydmVyIGFuZCBhbm90aGVyIG9uZSBmb3IgY29tbXVuaWNhdGlvbiBmcm9tIFNlcnZlciB0byBDbGllbnQKIC0gVXNpbmcgc2V2ZXJhbCBpbnN0YW5jZXMKXV0+PC9EZXNjcmlwdGlvbjE+CgkJPE9iamVjdElEPjE5PC9PYmplY3RJRD4KCQk8T2JqZWN0VVJOPnVybjpvbWE6bHdtMm06b21hOjE5PC9PYmplY3RVUk4+CgkJPExXTTJNVmVyc2lvbj4xLjA8L0xXTTJNVmVyc2lvbj4KCQk8T2JqZWN0VmVyc2lvbj4xLjA8L09iamVjdFZlcnNpb24+CgkJPE11bHRpcGxlSW5zdGFuY2VzPk11bHRpcGxlPC9NdWx0aXBsZUluc3RhbmNlcz4KCQk8TWFuZGF0b3J5Pk9wdGlvbmFsPC9NYW5kYXRvcnk+CgkJPFJlc291cmNlcz4KCQkJPEl0ZW0gSUQ9IjAiPjxOYW1lPkRhdGE8L05hbWU+CgkJCQk8T3BlcmF0aW9ucz5SVzwvT3BlcmF0aW9ucz4KCQkJCTxNdWx0aXBsZUluc3RhbmNlcz5NdWx0aXBsZTwvTXVsdGlwbGVJbnN0YW5jZXM+CgkJCQk8TWFuZGF0b3J5Pk1hbmRhdG9yeTwvTWFuZGF0b3J5PgoJCQkJPFR5cGU+T3BhcXVlPC9UeXBlPgoJCQkJPFJhbmdlRW51bWVyYXRpb24gLz4KCQkJCTxVbml0cyAvPgoJCQkJPERlc2NyaXB0aW9uPjwhW0NEQVRBW0luZGljYXRlcyB0aGUgYXBwbGljYXRpb24gZGF0YSBjb250ZW50Ll1dPjwvRGVzY3JpcHRpb24+CgkJCTwvSXRlbT4KCQkJPEl0ZW0gSUQ9IjEiPjxOYW1lPkRhdGEgUHJpb3JpdHk8L05hbWU+CgkJCQk8T3BlcmF0aW9ucz5SVzwvT3BlcmF0aW9ucz4KCQkJCTxNdWx0aXBsZUluc3RhbmNlcz5TaW5nbGU8L011bHRpcGxlSW5zdGFuY2VzPgoJCQkJPE1hbmRhdG9yeT5PcHRpb25hbDwvTWFuZGF0b3J5PgoJCQkJPFR5cGU+SW50ZWdlcjwvVHlwZT4KCQkJCTxSYW5nZUVudW1lcmF0aW9uPjEgYnl0ZXM8L1JhbmdlRW51bWVyYXRpb24+CgkJCQk8VW5pdHMgLz4KCQkJCTxEZXNjcmlwdGlvbj48IVtDREFUQVtJbmRpY2F0ZXMgdGhlIEFwcGxpY2F0aW9uIGRhdGEgcHJpb3JpdHk6CjA6SW1tZWRpYXRlCjE6QmVzdEVmZm9ydAoyOkxhdGVzdAozLTEwMDogUmVzZXJ2ZWQgZm9yIGZ1dHVyZSB1c2UuCjEwMS0yNTQ6IFByb3ByaWV0YXJ5IG1vZGUuXV0+PC9EZXNjcmlwdGlvbj4KCQkJPC9JdGVtPgoJCQk8SXRlbSBJRD0iMiI+PE5hbWU+RGF0YSBDcmVhdGlvbiBUaW1lPC9OYW1lPgoJCQkJPE9wZXJhdGlvbnM+Ulc8L09wZXJhdGlvbnM+CgkJCQk8TXVsdGlwbGVJbnN0YW5jZXM+U2luZ2xlPC9NdWx0aXBsZUluc3RhbmNlcz4KCQkJCTxNYW5kYXRvcnk+T3B0aW9uYWw8L01hbmRhdG9yeT4KCQkJCTxUeXBlPlRpbWU8L1R5cGU+CgkJCQk8UmFuZ2VFbnVtZXJhdGlvbiAvPgoJCQkJPFVuaXRzIC8+CgkJCQk8RGVzY3JpcHRpb24+PCFbQ0RBVEFbSW5kaWNhdGVzIHRoZSBEYXRhIGluc3RhbmNlIGNyZWF0aW9uIHRpbWVzdGFtcC5dXT48L0Rlc2NyaXB0aW9uPgoJCQk8L0l0ZW0+CgkJCTxJdGVtIElEPSIzIj48TmFtZT5EYXRhIERlc2NyaXB0aW9uPC9OYW1lPgoJCQkJPE9wZXJhdGlvbnM+Ulc8L09wZXJhdGlvbnM+CgkJCQk8TXVsdGlwbGVJbnN0YW5jZXM+U2luZ2xlPC9NdWx0aXBsZUluc3RhbmNlcz4KCQkJCTxNYW5kYXRvcnk+T3B0aW9uYWw8L01hbmRhdG9yeT4KCQkJCTxUeXBlPlN0cmluZzwvVHlwZT4KCQkJCTxSYW5nZUVudW1lcmF0aW9uPjMyIGJ5dGVzPC9SYW5nZUVudW1lcmF0aW9uPgoJCQkJPFVuaXRzIC8+CgkJCQk8RGVzY3JpcHRpb24+PCFbQ0RBVEFbSW5kaWNhdGVzIHRoZSBkYXRhIGRlc2NyaXB0aW9uLgplLmcuICJtZXRlciByZWFkaW5nIi5dXT48L0Rlc2NyaXB0aW9uPgoJCQk8L0l0ZW0+CgkJCTxJdGVtIElEPSI0Ij48TmFtZT5EYXRhIEZvcm1hdDwvTmFtZT4KCQkJCTxPcGVyYXRpb25zPlJXPC9PcGVyYXRpb25zPgoJCQkJPE11bHRpcGxlSW5zdGFuY2VzPlNpbmdsZTwvTXVsdGlwbGVJbnN0YW5jZXM+CgkJCQk8TWFuZGF0b3J5Pk9wdGlvbmFsPC9NYW5kYXRvcnk+CgkJCQk8VHlwZT5TdHJpbmc8L1R5cGU+CgkJCQk8UmFuZ2VFbnVtZXJhdGlvbj4zMiBieXRlczwvUmFuZ2VFbnVtZXJhdGlvbj4KCQkJCTxVbml0cyAvPgoJCQkJPERlc2NyaXB0aW9uPjwhW0NEQVRBW0luZGljYXRlcyB0aGUgZm9ybWF0IG9mIHRoZSBBcHBsaWNhdGlvbiBEYXRhLgplLmcuIFlHLU1ldGVyLVdhdGVyLVJlYWRpbmcKVVRGOC1zdHJpbmcKXV0+PC9EZXNjcmlwdGlvbj4KCQkJPC9JdGVtPgoJCQk8SXRlbSBJRD0iNSI+PE5hbWU+QXBwIElEPC9OYW1lPgoJCQkJPE9wZXJhdGlvbnM+Ulc8L09wZXJhdGlvbnM+CgkJCQk8TXVsdGlwbGVJbnN0YW5jZXM+U2luZ2xlPC9NdWx0aXBsZUluc3RhbmNlcz4KCQkJCTxNYW5kYXRvcnk+T3B0aW9uYWw8L01hbmRhdG9yeT4KCQkJCTxUeXBlPkludGVnZXI8L1R5cGU+CgkJCQk8UmFuZ2VFbnVtZXJhdGlvbj4yIGJ5dGVzPC9SYW5nZUVudW1lcmF0aW9uPgoJCQkJPFVuaXRzIC8+CgkJCQk8RGVzY3JpcHRpb24+PCFbQ0RBVEFbSW5kaWNhdGVzIHRoZSBkZXN0aW5hdGlvbiBBcHBsaWNhdGlvbiBJRC5dXT48L0Rlc2NyaXB0aW9uPgoJCQk8L0l0ZW0+PC9SZXNvdXJjZXM+CgkJPERlc2NyaXB0aW9uMj48IVtDREFUQVtdXT48L0Rlc2NyaXB0aW9uMj4KCTwvT2JqZWN0Pgo8L0xXTTJNPgo=", readOnly = true)
34 37 private String data;
35 38
36 39 public TbResource() {
... ...
... ... @@ -16,6 +16,8 @@
16 16 package org.thingsboard.server.common.data;
17 17
18 18 import com.fasterxml.jackson.annotation.JsonIgnore;
  19 +import io.swagger.annotations.ApiModel;
  20 +import io.swagger.annotations.ApiModelProperty;
19 21 import lombok.Data;
20 22 import lombok.EqualsAndHashCode;
21 23 import lombok.extern.slf4j.Slf4j;
... ... @@ -23,6 +25,7 @@ import org.thingsboard.server.common.data.id.TbResourceId;
23 25 import org.thingsboard.server.common.data.id.TenantId;
24 26 import org.thingsboard.server.common.data.validation.NoXss;
25 27
  28 +@ApiModel
26 29 @Slf4j
27 30 @Data
28 31 @EqualsAndHashCode(callSuper = true)
... ... @@ -30,11 +33,16 @@ public class TbResourceInfo extends SearchTextBased<TbResourceId> implements Has
30 33
31 34 private static final long serialVersionUID = 7282664529021651736L;
32 35
  36 + @ApiModelProperty(position = 3, value = "JSON object with Tenant Id. Tenant Id of the resource can't be changed.", readOnly = true)
33 37 private TenantId tenantId;
34 38 @NoXss
  39 + @ApiModelProperty(position = 4, value = "Resource title.", example = "BinaryAppDataContainer id=19 v1.0")
35 40 private String title;
  41 + @ApiModelProperty(position = 5, value = "Resource type.", example = "LWM2M_MODEL", readOnly = true)
36 42 private ResourceType resourceType;
  43 + @ApiModelProperty(position = 6, value = "Resource key.", example = "19_1.0", readOnly = true)
37 44 private String resourceKey;
  45 + @ApiModelProperty(position = 7, value = "Resource search text.", example = "19_1.0:binaryappdatacontainer", readOnly = true)
38 46 private String searchText;
39 47
40 48 public TbResourceInfo() {
... ... @@ -54,6 +62,21 @@ public class TbResourceInfo extends SearchTextBased<TbResourceId> implements Has
54 62 this.searchText = resourceInfo.getSearchText();
55 63 }
56 64
  65 + @ApiModelProperty(position = 1, value = "JSON object with the Resource Id. " +
  66 + "Specify this field to update the Resource. " +
  67 + "Referencing non-existing Resource Id will cause error. " +
  68 + "Omit this field to create new Resource." )
  69 + @Override
  70 + public TbResourceId getId() {
  71 + return super.getId();
  72 + }
  73 +
  74 + @ApiModelProperty(position = 2, value = "Timestamp of the resource creation, in milliseconds", example = "1609459200000", readOnly = true)
  75 + @Override
  76 + public long getCreatedTime() {
  77 + return super.getCreatedTime();
  78 + }
  79 +
57 80 @Override
58 81 @JsonIgnore
59 82 public String getName() {
... ...
... ... @@ -15,11 +15,16 @@
15 15 */
16 16 package org.thingsboard.server.common.data.lwm2m;
17 17
  18 +import io.swagger.annotations.ApiModel;
  19 +import io.swagger.annotations.ApiModelProperty;
18 20 import lombok.Data;
19 21
  22 +@ApiModel
20 23 @Data
21 24 public class LwM2mInstance {
  25 + @ApiModelProperty(position = 1, value = "LwM2M Instance id.", example = "0")
22 26 int id;
  27 + @ApiModelProperty(position = 2, value = "LwM2M Resource observe.")
23 28 LwM2mResourceObserve[] resources;
24 29
25 30 }
... ...
... ... @@ -15,14 +15,23 @@
15 15 */
16 16 package org.thingsboard.server.common.data.lwm2m;
17 17
  18 +import io.swagger.annotations.ApiModel;
  19 +import io.swagger.annotations.ApiModelProperty;
18 20 import lombok.Data;
19 21
  22 +@ApiModel
20 23 @Data
21 24 public class LwM2mObject {
  25 + @ApiModelProperty(position = 1, value = "LwM2M Object id.", example = "19")
22 26 int id;
  27 + @ApiModelProperty(position = 2, value = "LwM2M Object key id.", example = "19_1.0")
23 28 String keyId;
  29 + @ApiModelProperty(position = 3, value = "LwM2M Object name.", example = "BinaryAppDataContainer")
24 30 String name;
  31 + @ApiModelProperty(position = 4, value = "LwM2M Object multiple.", example = "true")
25 32 boolean multiple;
  33 + @ApiModelProperty(position = 5, value = "LwM2M Object mandatory.", example = "false")
26 34 boolean mandatory;
  35 + @ApiModelProperty(position = 6, value = "LwM2M Object instances.")
27 36 LwM2mInstance [] instances;
28 37 }
... ...
... ... @@ -15,19 +15,28 @@
15 15 */
16 16 package org.thingsboard.server.common.data.lwm2m;
17 17
  18 +import io.swagger.annotations.ApiModel;
  19 +import io.swagger.annotations.ApiModelProperty;
18 20 import lombok.AllArgsConstructor;
19 21 import lombok.Data;
20 22
21 23 import java.util.stream.Stream;
22 24
  25 +@ApiModel
23 26 @Data
24 27 @AllArgsConstructor
25 28 public class LwM2mResourceObserve {
  29 + @ApiModelProperty(position = 1, value = "LwM2M Resource Observe id.", example = "0")
26 30 int id;
  31 + @ApiModelProperty(position = 2, value = "LwM2M Resource Observe name.", example = "Data")
27 32 String name;
  33 + @ApiModelProperty(position = 3, value = "LwM2M Resource Observe observe.", example = "false")
28 34 boolean observe;
  35 + @ApiModelProperty(position = 4, value = "LwM2M Resource Observe attribute.", example = "false")
29 36 boolean attribute;
  37 + @ApiModelProperty(position = 5, value = "LwM2M Resource Observe telemetry.", example = "false")
30 38 boolean telemetry;
  39 + @ApiModelProperty(position = 6, value = "LwM2M Resource Observe key name.", example = "data")
31 40 String keyName;
32 41
33 42 public LwM2mResourceObserve(int id, String name, boolean observe, boolean attribute, boolean telemetry) {
... ...